diff --git a/.github/workflows/build_spacewarp.yml b/.github/workflows/build_spacewarp.yml
index 78309260..a69ea86a 100644
--- a/.github/workflows/build_spacewarp.yml
+++ b/.github/workflows/build_spacewarp.yml
@@ -19,6 +19,15 @@ jobs:
run: |
sudo curl -o /usr/local/bin/nuget.exe https://dist.nuget.org/win-x86-commandline/latest/nuget.exe
+ - name: Running automated tests
+ run: |
+ dotnet test "SpaceWarp.sln"
+ test_exit_code=$?
+ if [ $test_exit_code -ne 0 ]; then
+ echo "Tests failed. Cancelling the build."
+ exit $test_exit_code
+ fi
+
- name: Build the solution
run: dotnet build "SpaceWarp.sln" -c Release
diff --git a/.github/workflows/release_nuget.yml b/.github/workflows/release_nuget.yml
index a88f85ab..c16fb1f4 100644
--- a/.github/workflows/release_nuget.yml
+++ b/.github/workflows/release_nuget.yml
@@ -1,4 +1,7 @@
name: Publish NuGet Package
+env:
+ MOD_ID: 3277
+ KSP2_ID: 22407
on:
release:
@@ -7,7 +10,7 @@ on:
jobs:
publish:
runs-on: ubuntu-latest
-
+ permissions: write-all
steps:
- name: Check out repository
uses: actions/checkout@v3
@@ -32,6 +35,7 @@ jobs:
echo "artifact_name=spacewarp-release-$version.zip" >> $GITHUB_ENV
echo "zip=$(ls -1 dist/SpaceWarp-*.zip | head -n 1)" >> $GITHUB_ENV
echo "upload_url=$(wget -qO- https://api.github.com/repos/$GITHUB_REPOSITORY/releases | jq '.[0].upload_url' | tr -d \")" >> $GITHUB_ENV
+ wget -qO- https://api.github.com/repos/$GITHUB_REPOSITORY/releases | jq -r '.[0].body' > ./changelog.md
- name: Check if version exists
id: check-version
@@ -41,7 +45,6 @@ jobs:
exists=$(echo "$response" | jq -r --arg id "SpaceWarp" --arg version "$version" '.data[] | select(.id == $id) | .versions[] | select(.version == $version) | .version')
if [ "$exists" == "$version" ]; then
echo "Version $version already exists in the NuGet repository"
- exit 1
else
echo "Version $version does not exist in the NuGet repository"
echo "should_publish=true" >> $GITHUB_ENV
@@ -62,4 +65,17 @@ jobs:
asset_path: ${{ env.zip }}
asset_name: ${{ env.artifact_name }}
asset_content_type: application/zip
+
+ - name: Add Mask
+ run: echo "::add-mask::${{ secrets.SPACEDOCK_PASSWORD }}"
+ - name: Update spacedock
+ uses: KSP2Community/spacedock-upload@v1.0.0
+ with:
+ username: ${{ secrets.SPACEDOCK_USER }}
+ password: ${{ secrets.SPACEDOCK_PASSWORD }}
+ game_id: 22407
+ mod_id: 3277
+ version: ${{ env.version }}
+ zipball: ${{ env.zip }}
+ changelog: ./changelog.md
diff --git a/.gitignore b/.gitignore
index bfba49bc..8e3106ce 100644
--- a/.gitignore
+++ b/.gitignore
@@ -70,7 +70,6 @@ StyleCopReport.xml
*_p.c
*_h.h
*.ilk
-*.meta
*.obj
*.iobj
*.pch
diff --git a/Directory.Build.props b/Directory.Build.props
index 0fe657a8..e72d34f6 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -21,6 +21,9 @@
$(SolutionDir)build/obj/modules/$(Configuration)
$(SolutionDir)build/bin/patcher/$(Configuration)
$(SolutionDir)build/obj/patcher/$(Configuration)
+ $(SolutionDir)build/bin/restarter/$(Configuration)
+ $(SolutionDir)build/obj/restarter/$(Configuration)
+ $(SolutionDir)dist/$(Configuration)/BepInEx/plugins/SpaceWarp/restarter
$(ModulesBinPath)/$(MSBuildProjectName)
$(ModulesObjPath)/$(MSBuildProjectName)
$(MSBuildProjectName)
@@ -56,9 +59,9 @@
@(Swinfo -> '%(description)')
git
@(Swinfo -> '%(source)')
- $(ModId)
- $(Product)
- $(Version)
+ $(ModId)
+ $(Product)
+ $(Version)
-
+
\ No newline at end of file
diff --git a/SpaceWarp.sln b/SpaceWarp.sln
index c19f2bbb..69f805b4 100644
--- a/SpaceWarp.sln
+++ b/SpaceWarp.sln
@@ -8,16 +8,20 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Game", "src/Space
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Messaging", "src/SpaceWarp.Messaging/SpaceWarp.Messaging.csproj", "{66BA4E01-8521-42EB-9D7D-8EB653757177}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarpRestarter", "src\SpaceWarpRestarter\SpaceWarpRestarter.csproj", "{4B509D31-4C02-4D6E-8508-8417F0745776}"
+EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Sound", "src/SpaceWarp.Sound/SpaceWarp.Sound.csproj", "{BA439A24-7EA3-4E79-A44C-1FA303B9331C}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.UI", "src/SpaceWarp.UI/SpaceWarp.UI.csproj", "{CB131B63-51E6-4ED7-A47C-28B1EB65B8D7}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.VersionChecking", "src/SpaceWarp.VersionChecking/SpaceWarp.VersionChecking.csproj", "{6B76C415-5BC2-4AB0-8862-760D9DC8F485}"
EndProject
-Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarpPatcher", "src/SpaceWarpPatcher/SpaceWarpPatcher.csproj", "{2EF642D0-F66D-461C-A5B0-953E39307B76}"
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Preload", "src\SpaceWarp.Preload\SpaceWarp.Preload.csproj", "{2EF642D0-F66D-461C-A5B0-953E39307B76}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarpTest", "src/SpaceWarpTest/SpaceWarpTest.csproj", "{8DB42693-9177-40B9-AC6A-B6D7A4823FAD}"
EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SpaceWarp.Patches", "src\SpaceWarp.Patches\SpaceWarp.Patches.csproj", "{88F73A97-3D47-4ED3-8381-177EED4451AC}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -98,6 +102,22 @@ Global
{8DB42693-9177-40B9-AC6A-B6D7A4823FAD}.Deploy|Any CPU.Build.0 = Deploy|Any CPU
{8DB42693-9177-40B9-AC6A-B6D7A4823FAD}.DeployAndRun|Any CPU.ActiveCfg = DeployAndRun|Any CPU
{8DB42693-9177-40B9-AC6A-B6D7A4823FAD}.DeployAndRun|Any CPU.Build.0 = DeployAndRun|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.Release|Any CPU.Build.0 = Release|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.Deploy|Any CPU.ActiveCfg = Deploy|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.Deploy|Any CPU.Build.0 = Deploy|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.DeployAndRun|Any CPU.ActiveCfg = DeployAndRun|Any CPU
+ {4B509D31-4C02-4D6E-8508-8417F0745776}.DeployAndRun|Any CPU.Build.0 = DeployAndRun|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.Release|Any CPU.Build.0 = Release|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.Deploy|Any CPU.ActiveCfg = Deploy|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.Deploy|Any CPU.Build.0 = Deploy|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.DeployAndRun|Any CPU.ActiveCfg = DeployAndRun|Any CPU
+ {88F73A97-3D47-4ED3-8381-177EED4451AC}.DeployAndRun|Any CPU.Build.0 = DeployAndRun|Any CPU
EndGlobalSection
EndGlobal
diff --git a/plugin_template/BepInEx/plugins/ConfigurationManager/ConfigurationManager.dll b/plugin_template/BepInEx/plugins/ConfigurationManager/ConfigurationManager.dll
deleted file mode 100644
index ef1e7073..00000000
Binary files a/plugin_template/BepInEx/plugins/ConfigurationManager/ConfigurationManager.dll and /dev/null differ
diff --git a/plugin_template/BepInEx/plugins/ConfigurationManager/ConfigurationManager.xml b/plugin_template/BepInEx/plugins/ConfigurationManager/ConfigurationManager.xml
deleted file mode 100644
index fb742bb1..00000000
--- a/plugin_template/BepInEx/plugins/ConfigurationManager/ConfigurationManager.xml
+++ /dev/null
@@ -1,197 +0,0 @@
-
-
-
- ConfigurationManager
-
-
-
-
- Get entries for all core BepInEx settings
-
-
-
-
- Get entries for all settings of a plugin
-
-
-
-
- An easy way to let user configure how a plugin behaves without the need to make your own GUI. The user can change any of the settings you expose, even keyboard shortcuts.
- https://github.com/ManlyMarco/BepInEx.ConfigurationManager
-
-
-
-
- GUID of this plugin
-
-
-
-
- Version constant
-
-
-
-
- Event fired every time the manager window is shown or hidden.
-
-
-
-
- Disable the hotkey check used by config manager. If enabled you have to set to show the manager.
-
-
-
-
-
-
-
- Is the config manager main window displayed on screen
-
-
-
-
- Register a custom setting drawer for a given type. The action is ran in OnGui in a single setting slot.
- Do not use any Begin / End layout methods, and avoid raising height from standard.
-
-
-
-
- Rebuild the setting list. Use to update the config manager window if config settings were removed or added while it was open.
-
-
-
-
- String currently entered into the search box
-
-
-
-
- Class representing all data about a setting collected by ConfigurationManager.
-
-
-
-
- List of values this setting can take
-
-
-
-
- Range of the values this setting can take
-
-
-
-
- Should the setting be shown as a percentage (only applies to value range settings)
-
-
-
-
- Custom setting draw action
-
-
-
-
- Show this setting in the settings screen at all? If false, don't show.
-
-
-
-
- Category the setting is under. Null to be directly under the plugin.
-
-
-
-
- If set, a "Default" button will be shown next to the setting to allow resetting to default.
-
-
-
-
- Force the "Reset" button to not be displayed, even if a valid DefaultValue is available.
-
-
-
-
- Force the setting name to not be displayed. Should only be used with a to get more space.
- Can be used together with to gain even more space.
-
-
-
-
- Optional description shown when hovering over the setting
-
-
-
-
- Name of the setting
-
-
-
-
- Plugin this setting belongs to
-
-
-
-
- Only allow showing of the value. False whenever possible by default.
-
-
-
-
- Type of the variable
-
-
-
-
- Instance of the plugin that owns this setting
-
-
-
-
- Is this setting advanced
-
-
-
-
- Order of the setting on the settings list relative to other settings in a category. 0 by default, lower is higher on the list.
-
-
-
-
- Get the value of this setting
-
-
-
-
- Set the value of this setting
-
-
-
-
- Implementation of
-
-
-
-
- Custom converter from setting type to string for the textbox
-
-
-
-
- Custom converter from string to setting type for the textbox
-
-
-
-
- Arguments representing a change in value
-
-
-
-
-
-
-
- Newly assigned value
-
-
-
-
diff --git a/plugin_template/BepInEx/plugins/ConfigurationManager/LICENSE b/plugin_template/BepInEx/plugins/ConfigurationManager/LICENSE
deleted file mode 100644
index afdc2c38..00000000
--- a/plugin_template/BepInEx/plugins/ConfigurationManager/LICENSE
+++ /dev/null
@@ -1,167 +0,0 @@
-BepInEx.ConfigurationManager is licensed under the LGPL v3 license. The full text of the license is included below.
-
- GNU LESSER GENERAL PUBLIC LICENSE
- Version 3, 29 June 2007
-
- Copyright (C) 2007 Free Software Foundation, Inc.
- Everyone is permitted to copy and distribute verbatim copies
- of this license document, but changing it is not allowed.
-
-
- This version of the GNU Lesser General Public License incorporates
-the terms and conditions of version 3 of the GNU General Public
-License, supplemented by the additional permissions listed below.
-
- 0. Additional Definitions.
-
- As used herein, "this License" refers to version 3 of the GNU Lesser
-General Public License, and the "GNU GPL" refers to version 3 of the GNU
-General Public License.
-
- "The Library" refers to a covered work governed by this License,
-other than an Application or a Combined Work as defined below.
-
- An "Application" is any work that makes use of an interface provided
-by the Library, but which is not otherwise based on the Library.
-Defining a subclass of a class defined by the Library is deemed a mode
-of using an interface provided by the Library.
-
- A "Combined Work" is a work produced by combining or linking an
-Application with the Library. The particular version of the Library
-with which the Combined Work was made is also called the "Linked
-Version".
-
- The "Minimal Corresponding Source" for a Combined Work means the
-Corresponding Source for the Combined Work, excluding any source code
-for portions of the Combined Work that, considered in isolation, are
-based on the Application, and not on the Linked Version.
-
- The "Corresponding Application Code" for a Combined Work means the
-object code and/or source code for the Application, including any data
-and utility programs needed for reproducing the Combined Work from the
-Application, but excluding the System Libraries of the Combined Work.
-
- 1. Exception to Section 3 of the GNU GPL.
-
- You may convey a covered work under sections 3 and 4 of this License
-without being bound by section 3 of the GNU GPL.
-
- 2. Conveying Modified Versions.
-
- If you modify a copy of the Library, and, in your modifications, a
-facility refers to a function or data to be supplied by an Application
-that uses the facility (other than as an argument passed when the
-facility is invoked), then you may convey a copy of the modified
-version:
-
- a) under this License, provided that you make a good faith effort to
- ensure that, in the event an Application does not supply the
- function or data, the facility still operates, and performs
- whatever part of its purpose remains meaningful, or
-
- b) under the GNU GPL, with none of the additional permissions of
- this License applicable to that copy.
-
- 3. Object Code Incorporating Material from Library Header Files.
-
- The object code form of an Application may incorporate material from
-a header file that is part of the Library. You may convey such object
-code under terms of your choice, provided that, if the incorporated
-material is not limited to numerical parameters, data structure
-layouts and accessors, or small macros, inline functions and templates
-(ten or fewer lines in length), you do both of the following:
-
- a) Give prominent notice with each copy of the object code that the
- Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the object code with a copy of the GNU GPL and this license
- document.
-
- 4. Combined Works.
-
- You may convey a Combined Work under terms of your choice that,
-taken together, effectively do not restrict modification of the
-portions of the Library contained in the Combined Work and reverse
-engineering for debugging such modifications, if you also do each of
-the following:
-
- a) Give prominent notice with each copy of the Combined Work that
- the Library is used in it and that the Library and its use are
- covered by this License.
-
- b) Accompany the Combined Work with a copy of the GNU GPL and this license
- document.
-
- c) For a Combined Work that displays copyright notices during
- execution, include the copyright notice for the Library among
- these notices, as well as a reference directing the user to the
- copies of the GNU GPL and this license document.
-
- d) Do one of the following:
-
- 0) Convey the Minimal Corresponding Source under the terms of this
- License, and the Corresponding Application Code in a form
- suitable for, and under terms that permit, the user to
- recombine or relink the Application with a modified version of
- the Linked Version to produce a modified Combined Work, in the
- manner specified by section 6 of the GNU GPL for conveying
- Corresponding Source.
-
- 1) Use a suitable shared library mechanism for linking with the
- Library. A suitable mechanism is one that (a) uses at run time
- a copy of the Library already present on the user's computer
- system, and (b) will operate properly with a modified version
- of the Library that is interface-compatible with the Linked
- Version.
-
- e) Provide Installation Information, but only if you would otherwise
- be required to provide such information under section 6 of the
- GNU GPL, and only to the extent that such information is
- necessary to install and execute a modified version of the
- Combined Work produced by recombining or relinking the
- Application with a modified version of the Linked Version. (If
- you use option 4d0, the Installation Information must accompany
- the Minimal Corresponding Source and Corresponding Application
- Code. If you use option 4d1, you must provide the Installation
- Information in the manner specified by section 6 of the GNU GPL
- for conveying Corresponding Source.)
-
- 5. Combined Libraries.
-
- You may place library facilities that are a work based on the
-Library side by side in a single library together with other library
-facilities that are not Applications and are not covered by this
-License, and convey such a combined library under terms of your
-choice, if you do both of the following:
-
- a) Accompany the combined library with a copy of the same work based
- on the Library, uncombined with any other library facilities,
- conveyed under the terms of this License.
-
- b) Give prominent notice with the combined library that part of it
- is a work based on the Library, and explaining where to find the
- accompanying uncombined form of the same work.
-
- 6. Revised Versions of the GNU Lesser General Public License.
-
- The Free Software Foundation may publish revised and/or new versions
-of the GNU Lesser General Public License from time to time. Such new
-versions will be similar in spirit to the present version, but may
-differ in detail to address new problems or concerns.
-
- Each version is given a distinguishing version number. If the
-Library as you received it specifies that a certain numbered version
-of the GNU Lesser General Public License "or any later version"
-applies to it, you have the option of following the terms and
-conditions either of that published version or of any later version
-published by the Free Software Foundation. If the Library as you
-received it does not specify a version number of the GNU Lesser
-General Public License, you may choose any version of the GNU Lesser
-General Public License ever published by the Free Software Foundation.
-
- If the Library as you received it specifies that a proxy can decide
-whether future versions of the GNU Lesser General Public License shall
-apply, that proxy's public statement of acceptance of any version is
-permanent authorization for you to choose that version for the
-Library.
diff --git a/plugin_template/BepInEx/plugins/ConfigurationManager/README b/plugin_template/BepInEx/plugins/ConfigurationManager/README
deleted file mode 100644
index 019b6aef..00000000
--- a/plugin_template/BepInEx/plugins/ConfigurationManager/README
+++ /dev/null
@@ -1,2 +0,0 @@
-This contains binaries for BepInEx.ConfigurationManager, which is under the LGPL V3 license, copy of which is provided here.
-The source for these binaries can be found at https://github.com/BepInEx/BepInEx.ConfigurationManager
\ No newline at end of file
diff --git a/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/modlist.bundle b/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/modlist.bundle
index 54924792..259eb014 100644
Binary files a/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/modlist.bundle and b/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/modlist.bundle differ
diff --git a/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/swconsole.bundle b/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/swconsole.bundle
index cbce5b40..9ff413a1 100644
Binary files a/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/swconsole.bundle and b/plugin_template/BepInEx/plugins/SpaceWarp/assets/bundles/swconsole.bundle differ
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.CSharp.xml
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/Microsoft.CodeAnalysis.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/Microsoft.CodeAnalysis.xml
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Collections.Immutable.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Collections.Immutable.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Collections.Immutable.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Collections.Immutable.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Collections.Immutable.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Collections.Immutable.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Collections.Immutable.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Collections.Immutable.xml
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Memory.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Memory.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Memory.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Memory.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Memory.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Memory.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Memory.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Memory.xml
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Numerics.Vectors.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Numerics.Vectors.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Numerics.Vectors.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Numerics.Vectors.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Numerics.Vectors.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Numerics.Vectors.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Numerics.Vectors.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Numerics.Vectors.xml
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Reflection.Metadata.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Reflection.Metadata.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Reflection.Metadata.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Reflection.Metadata.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Reflection.Metadata.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Reflection.Metadata.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Reflection.Metadata.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Reflection.Metadata.xml
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Runtime.CompilerServices.Unsafe.xml
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Threading.Tasks.Extensions.dll b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Threading.Tasks.Extensions.dll
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Threading.Tasks.Extensions.dll
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Threading.Tasks.Extensions.dll
diff --git a/plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Threading.Tasks.Extensions.xml b/plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Threading.Tasks.Extensions.xml
similarity index 100%
rename from plugin_template/BepInEx/patchers/SpaceWarp/lib/System.Threading.Tasks.Extensions.xml
rename to plugin_template/BepInEx/plugins/SpaceWarp/lib/System.Threading.Tasks.Extensions.xml
diff --git a/plugin_template/BepInEx/plugins/SpaceWarp/localizations/space_warp_localizations.csv b/plugin_template/BepInEx/plugins/SpaceWarp/localizations/space_warp_localizations.csv
index 92936cf9..e335e0d1 100644
--- a/plugin_template/BepInEx/plugins/SpaceWarp/localizations/space_warp_localizations.csv
+++ b/plugin_template/BepInEx/plugins/SpaceWarp/localizations/space_warp_localizations.csv
@@ -1,46 +1,48 @@
-Key,Type,Description,English,Portuguese BR
-SpaceWarp/ModList/EnableAll,Text,,Enable All,Ativar todos
-SpaceWarp/ModList/DisableAll,Text,,Disable All,Desativar todos
-SpaceWarp/ModList/RevertChanges,Text,,Revert Changes,Reverter alterações
-SpaceWarp/ModList/multipleChangesDetected,Text,,"{0} changes detected, please restart to apply them","{0} alterações detetadas, porfavor reinicie o jogo"
-SpaceWarp/ModList/singleChangeDetected,Text,,"1 change detected, please restart to apply it","1 alteração detectada, reinicie para aplicá-la"
-SpaceWarp/ModList/Header,Text,,spacewarp.modlist,spacewarp.modlist
-SpaceWarp/ModList/EnabledMods,Text,,Enabled Mods,Mods ativos
-SpaceWarp/ModList/ErroredMods,Text,,Errored Mods,Mods com erros
-SpaceWarp/ModList/DisabledMods,Text,,Disabled Mods,Mods desativados
-SpaceWarp/ModList/Version,Text,,Version,Versão
-SpaceWarp/ModList/Author,Text,,Author,Autor
-SpaceWarp/ModList/Source,Text,,Source,Fonte
-SpaceWarp/ModList/Description,Text,,Description,Descrição
-SpaceWarp/ModList/KSP2Version,Text,,KSP2 Version,Versão do jogo
-SpaceWarp/ModList/Dependencies,Text,,Dependencies,Dependências
-SpaceWarp/ModList/outdated,Text,,outdated,desatualizado
-SpaceWarp/ModList/unsupported,Text,,unsupported,não suportado
-SpaceWarp/ModList/disabled,Text,,disabled,desativado
-SpaceWarp/ModList/OpenConfigurationManager,Text,,Open Configuration Manager,Abrir gestor de configurações
-SpaceWarp/ModList/OpenModsFolder,Text,,Open Mods Folder,Abrir pasta de mods
-SpaceWarp/ModList/mismatched,Text,,Mismatched,Não corresponde com o swinfo
-SpaceWarp/ModList/baddirectory,Text,,Bad Directory,Problemas no diretorio
-SpaceWarp/ModList/missingswinfo,Text,,Missing SW Info,Não possui um swinfo
-SpaceWarp/ModList/MissingDependency,Text,,Dependency is missing,Esta dependência não está presente
-SpaceWarp/ModList/ErroredDependency,Text,,Dependency had an error while loading,Esta dependência teve um erro durante o loading
-SpaceWarp/ModList/DisabledDependency,Text,,Dependency is disabled,Esta dependência esta desativada
-SpaceWarp/ModList/UnspecifiedDependency,Text,,Dependency was not specified in SW info,Esta dependência não está presente no swinfo
-SpaceWarp/ModList/UnsupportedDependency,Text,,Dependency is of an unsupported version,Esta dependência é de uma versão nao suportada
-SpaceWarp/ModList/Conflicts,Text,,Conflicts,Incompatibilidades
-SpaceWarp/ModList/Details,Text,,Details,Detalhes
-SpaceWarp/Mods,Text,,Mods,Mods
-SpaceWarp/Mods/Outdated,Text,,Mods ⚠ ,Mods ⚠
-SpaceWarp/Mods/Errored,Text,,Mods ⚠ ,Mods ⚠
-SpaceWarp,Text,,Space Warp,Space Warp
-SpaceWarp/VersionChecking,Text,,Allow Space Warp to check versions for mods over the network?,Deixar SpaceWarp verificar a versão dos mods na internet?
-SpaceWarp/Yes,Text,,Yes,Sim
-SpaceWarp/No,Text,,No,Não
-SpaceWarp/Console/Header,Text,,SPACE WARP - Console, SPACE WARP - Consola
-SpaceWarp/Console/Clear,Text,,Clear,Limpar
-SpaceWarp/Console/AutoScroll,Text,,Auto Scroll,Scroll automatico
-SpaceWarp/Console/On,Text,,On,On
-SpaceWarp/Console/Off,Text,,Off,Off
-SpaceWarp/AvcDialog/Title,Text,,spacewarp.avc,spacewarp.avc
-SpaceWarp/AvcDialog/MainText,Text,,Allow SpaceWarp to automatically check for mod updates online?,Allow SpaceWarp to automatically check for mod updates online?
-SpaceWarp/AvcDialog/MinorText,Text,,*You can change this later in the settings menu.,*You can change this later in the settings menu.
\ No newline at end of file
+Key,Type,Description,English,Portuguese BR,French
+SpaceWarp/ModList/EnableAll,Text,,Enable All,Ativar todos,Activer tous
+SpaceWarp/ModList/DisableAll,Text,,Disable All,Desativar todos,Désactiver tous
+SpaceWarp/ModList/RevertChanges,Text,,Revert Changes,Reverter alterações,Rétablir les changements
+SpaceWarp/ModList/ApplyChanges,Text,,Apply and restart,Aplicar e reiniciar,Appliquer et redémarrer
+SpaceWarp/ModList/multipleChangesDetected,Text,,"{0} changes detected, please restart to apply them","{0} alterações detetadas, porfavor reinicie o jogo","{0} changements détectés, veuillez redémarrer pour les appliquer"
+SpaceWarp/ModList/singleChangeDetected,Text,,"1 change detected, please restart to apply it","1 alteração detectada, reinicie para aplicá-la","1 changement détecté, veuillez redémarrer pour l'appliquer"
+SpaceWarp/ModList/Header,Text,,spacewarp.modlist,spacewarp.modlist,spacewarp.modlist
+SpaceWarp/ModList/CoreMods,Text,,Core Mods,Mods do jogo,Mods du jeu
+SpaceWarp/ModList/EnabledMods,Text,,Enabled Mods,Mods ativos,Mods activés
+SpaceWarp/ModList/ErroredMods,Text,,Errored Mods,Mods com erros,Mods avec des erreurs
+SpaceWarp/ModList/DisabledMods,Text,,Disabled Mods,Mods desativados,Mods désactivés
+SpaceWarp/ModList/Version,Text,,Version,Versão,Version
+SpaceWarp/ModList/Author,Text,,Author,Autor,Auteur
+SpaceWarp/ModList/Source,Text,,Source,Fonte,Source
+SpaceWarp/ModList/Description,Text,,Description,Descrição,Description
+SpaceWarp/ModList/KSP2Version,Text,,KSP2 Version,Versão do jogo,Version de KSP2
+SpaceWarp/ModList/Dependencies,Text,,Dependencies,Dependências,Dépendances
+SpaceWarp/ModList/outdated,Text,,(outdated),(desatualizado),(obsolète)
+SpaceWarp/ModList/unsupported,Text,,(unsupported),(não suportado),(non pris en charge)
+SpaceWarp/ModList/disabled,Text,,(disabled),(desativado),(désactivé)
+SpaceWarp/ModList/mismatched,Text,,(mismatched),(não corresponde com o swinfo),(non concordant)
+SpaceWarp/ModList/baddirectory,Text,,(bad directory),(problemas no diretorio),(mauvais dossier)
+SpaceWarp/ModList/missingswinfo,Text,,(missing SW Info),(não possui um swinfo),(SW Info manquant)
+SpaceWarp/ModList/OpenModSettings,Text,,Mod Settings,Configurações dos mods,Paramètres des mods
+SpaceWarp/ModList/OpenModsFolder,Text,,Open Mods Folder,Abrir pasta de mods,Ouvrir le dossier des mods
+SpaceWarp/ModList/MissingDependency,Text,,Dependency is missing,Esta dependência não está presente,Cette dépendance est manquante
+SpaceWarp/ModList/ErroredDependency,Text,,Dependency had an error while loading,Esta dependência teve um erro durante o loading,Une erreur s'est produite lors du chargement de cette dépendance
+SpaceWarp/ModList/DisabledDependency,Text,,Dependency is disabled,Esta dependência esta desativada,Cette dépendance est manquante
+SpaceWarp/ModList/UnspecifiedDependency,Text,,Dependency was not specified in SW info,Esta dependência não está presente no swinfo,Cette dépendance n'a pas été spécifiée dans SW Info
+SpaceWarp/ModList/UnsupportedDependency,Text,,Dependency is of an unsupported version,Esta dependência é de uma versão nao suportada,Cette dépendance est d'une version non supportée
+SpaceWarp/ModList/Conflicts,Text,,Conflicts,Incompatibilidades,Conflits
+SpaceWarp/ModList/Details,Text,,Details,Detalhes,Détails
+SpaceWarp/Mods,Text,,Mods,Mods,Mods
+SpaceWarp/Mods/Outdated,Text,,Mods ⚠ ,Mods ⚠ ,Mods ⚠
+SpaceWarp/Mods/Errored,Text,,Mods ⚠ ,Mods ⚠ ,Mods ⚠
+SpaceWarp,Text,,Space Warp,Space Warp,Space Warp
+SpaceWarp/VersionChecking,Text,,Allow Space Warp to check versions for mods over the network?,Deixar SpaceWarp verificar a versão dos mods na internet?,Autoriser Space Warp à vérifier les versions des mods sur le réseau ?
+SpaceWarp/Yes,Text,,Yes,Sim,Oui
+SpaceWarp/No,Text,,No,Não,Non
+SpaceWarp/Console/Header,Text,,SPACE WARP - Console,SPACE WARP - Consola,SPACE WARP - Console
+SpaceWarp/Console/Clear,Text,,Clear,Limpar,Effacer
+SpaceWarp/Console/AutoScroll,Text,,Auto Scroll,Scroll automatico,Défilement automatique
+SpaceWarp/Console/On,Text,,On,On,On
+SpaceWarp/Console/Off,Text,,Off,Off,Off
+SpaceWarp/AvcDialog/Title,Text,,spacewarp.avc,spacewarp.avc,spacewarp.avc
+SpaceWarp/AvcDialog/MainText,Text,,Allow SpaceWarp to automatically check for mod updates online?,Permitir que o SpaceWarp verifique automaticamente se há atualizações de mods online?,Autoriser SpaceWarp à vérifier automatiquement les mises à jour de mods en ligne ?
+SpaceWarp/AvcDialog/MinorText,Text,,*You can change this later in the settings menu.,*Pode alterá-lo mais tarde no menu de definições.,*Vous pouvez modifier plus tard dans le menu des réglages.
\ No newline at end of file
diff --git a/plugin_template/BepInEx/plugins/SpaceWarp/swinfo.json b/plugin_template/BepInEx/plugins/SpaceWarp/swinfo.json
index 67c244b5..6f560484 100644
--- a/plugin_template/BepInEx/plugins/SpaceWarp/swinfo.json
+++ b/plugin_template/BepInEx/plugins/SpaceWarp/swinfo.json
@@ -1,11 +1,11 @@
{
- "spec": "2.0",
+ "spec": "2.1",
"mod_id": "com.github.x606.spacewarp",
"author": "Space Warp Team",
"name": "Space Warp",
"description": "Space Warp is an API for KSP 2 mod developers.",
"source": "https://github.com/SpaceWarpDev/SpaceWarp",
- "version": "1.7.0",
+ "version": "1.8.0",
"version_check": "https://raw.githubusercontent.com/SpaceWarpDev/SpaceWarp/main/plugin_template/BepInEx/plugins/SpaceWarp/swinfo.json",
"ksp2_version": {
"min": "0.2.0",
@@ -18,13 +18,9 @@
"min": "2.4.0",
"max": "*"
}
- },
- {
- "id": "com.bepis.bepinex.configurationmanager",
- "version": {
- "min": "*",
- "max": "*"
- }
}
+ ],
+ "patchers": [
+ "SpaceWarpPatcher.dll"
]
}
diff --git a/plugin_template/doorstop_config.ini b/plugin_template/doorstop_config.ini
index a68f30f1..42991f24 100644
--- a/plugin_template/doorstop_config.ini
+++ b/plugin_template/doorstop_config.ini
@@ -7,7 +7,7 @@ targetAssembly=BepInEx\core\BepInEx.Preloader.dll
redirectOutputLog=false
# If enabled, DOORSTOP_DISABLE env var value is ignored
# USE THIS ONLY WHEN ASKED TO OR YOU KNOW WHAT THIS MEANS
-ignoreDisableSwitch=false
+ignoreDisableSwitch=true
# Overrides default Mono DLL search path
# Sometimes it is needed to instruct Mono to seek its assemblies from a different path
# (e.g. mscorlib is stripped in original game)
diff --git a/src/SpaceWarp.Core/API/Assets/AssetManager.cs b/src/SpaceWarp.Core/API/Assets/AssetManager.cs
index d1d956b2..fc578cb7 100644
--- a/src/SpaceWarp.Core/API/Assets/AssetManager.cs
+++ b/src/SpaceWarp.Core/API/Assets/AssetManager.cs
@@ -1,13 +1,14 @@
-using System;
-using System.Collections.Generic;
-using System.Threading.Tasks;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
+using SpaceWarp.API.Logging;
using SpaceWarp.API.Lua;
using UnityEngine;
using Logger = BepInEx.Logging.Logger;
namespace SpaceWarp.API.Assets;
+///
+/// Manages all mod assets loaded by SpaceWarp
+///
[SpaceWarpLuaAPI("Assets")]
[PublicAPI]
public static class AssetManager
@@ -17,7 +18,7 @@ public static class AssetManager
internal static async Task RegisterAssetBundle(string modId, string assetBundleName, AssetBundle assetBundle)
{
assetBundleName = assetBundleName.Replace(".bundle", "");
- var logger = Logger.CreateLogSource($"{modId}/{assetBundleName}");
+ var logger = BaseLogger.CreateDefault($"{modId}/{assetBundleName}");
var names = assetBundle.GetAllAssetNames();
diff --git a/src/SpaceWarp.Core/API/Configuration/BepInExConfigEntry.cs b/src/SpaceWarp.Core/API/Configuration/BepInExConfigEntry.cs
index 1901d908..d49ab909 100644
--- a/src/SpaceWarp.Core/API/Configuration/BepInExConfigEntry.cs
+++ b/src/SpaceWarp.Core/API/Configuration/BepInExConfigEntry.cs
@@ -1,20 +1,38 @@
-using System;
-using BepInEx.Configuration;
+using BepInEx.Configuration;
using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// A wrapper around a BepInEx to make it compatible with the
+/// interface.
+///
[PublicAPI]
public class BepInExConfigEntry : IConfigEntry
{
+ ///
+ /// The underlying that this class wraps.
+ ///
public readonly ConfigEntryBase EntryBase;
- public event Action Callbacks;
+
+ ///
+ /// The callbacks that are invoked when the value of this entry changes.
+ ///
+ public event Action Callbacks;
+
+ ///
+ /// Creates a new from the given and optional
+ /// .
+ ///
+ /// The to wrap.
+ /// The to use.
public BepInExConfigEntry(ConfigEntryBase entryBase, IValueConstraint constraint = null)
{
EntryBase = entryBase;
Constraint = constraint;
}
+ ///
public object Value
{
get => EntryBase.BoxedValue;
@@ -25,8 +43,10 @@ public object Value
}
}
+ ///
public Type ValueType => EntryBase.SettingType;
+ ///
public T Get() where T : class
{
if (!typeof(T).IsAssignableFrom(ValueType))
@@ -37,6 +57,7 @@ public T Get() where T : class
return Value as T;
}
+ ///
public void Set(T value)
{
if (!ValueType.IsAssignableFrom(typeof(T)))
@@ -48,12 +69,16 @@ public void Set(T value)
{
if (!Constraint.IsConstrained(value)) return;
}
- Callbacks?.Invoke(EntryBase.BoxedValue, value);
EntryBase.BoxedValue = Convert.ChangeType(value, ValueType);
}
+ ///
public string Description => EntryBase.Description.Description;
+
+ ///
public IValueConstraint Constraint { get; }
+
+ ///
public void RegisterCallback(Action valueChangedCallback)
{
Callbacks += valueChangedCallback;
diff --git a/src/SpaceWarp.Core/API/Configuration/BepInExConfigFile.cs b/src/SpaceWarp.Core/API/Configuration/BepInExConfigFile.cs
index a1a5c60f..f519af3c 100644
--- a/src/SpaceWarp.Core/API/Configuration/BepInExConfigFile.cs
+++ b/src/SpaceWarp.Core/API/Configuration/BepInExConfigFile.cs
@@ -1,40 +1,74 @@
-using System.Collections.Generic;
-using BepInEx.Configuration;
+using BepInEx.Configuration;
using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// A wrapper around BepInEx's to make it implement .
+///
[PublicAPI]
public class BepInExConfigFile : IConfigFile
{
-
+ ///
+ /// The underlying instance.
+ ///
public readonly ConfigFile AdaptedConfigFile;
+ ///
+ /// Creates a new instance.
+ ///
+ /// The instance to wrap.
public BepInExConfigFile(ConfigFile adaptedConfigFile)
{
AdaptedConfigFile = adaptedConfigFile;
}
+ ///
public void Save()
{
AdaptedConfigFile.Save();
}
- public IConfigEntry this[string section, string key] => new BepInExConfigEntry(AdaptedConfigFile[section, key]);
+ private Dictionary<(string section, string key), IConfigEntry> _storedEntries = new();
+
+ ///
+ public IConfigEntry this[string section, string key] => _storedEntries.TryGetValue((section, key), out var result)
+ ? result
+ : _storedEntries[(section, key)] = new BepInExConfigEntry(AdaptedConfigFile[section, key],
+ IValueConstraint.FromAcceptableValueBase(AdaptedConfigFile[section, key].Description.AcceptableValues));
+ ///
public IConfigEntry Bind(string section, string key, T defaultValue = default, string description = "")
{
return new BepInExConfigEntry(AdaptedConfigFile.Bind(section, key, defaultValue, description));
}
- public IConfigEntry Bind(string section, string key, T defaultValue, string description, IValueConstraint valueConstraint)
+ ///
+ /// Binds a new config entry to the given section and key with the given default value and description.
+ ///
+ /// Section to bind the entry to.
+ /// Key to bind the entry to.
+ /// Default value of the entry.
+ /// Description of the entry.
+ /// Value constraint of the entry.
+ /// Type of the entry.
+ /// The newly bound config entry.
+ public IConfigEntry Bind(
+ string section,
+ string key,
+ T defaultValue,
+ string description,
+ IValueConstraint valueConstraint
+ )
{
- return new BepInExConfigEntry(AdaptedConfigFile.Bind(new ConfigDefinition(section, key), defaultValue,
- new ConfigDescription(description, valueConstraint.ToAcceptableValueBase())));
+ return _storedEntries[(section, key)] = new BepInExConfigEntry(AdaptedConfigFile.Bind(new ConfigDefinition(section, key), defaultValue,
+ new ConfigDescription(description, valueConstraint.ToAcceptableValueBase())),valueConstraint);
}
+ ///
public IReadOnlyList Sections => AdaptedConfigFile.Keys.Select(x => x.Section).Distinct().ToList();
+ ///
public IReadOnlyList this[string section] => AdaptedConfigFile.Keys.Where(x => x.Section == section)
.Select(x => x.Key).ToList();
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Configuration/ConfigValue.cs b/src/SpaceWarp.Core/API/Configuration/ConfigValue.cs
index b4a54278..670b1977 100644
--- a/src/SpaceWarp.Core/API/Configuration/ConfigValue.cs
+++ b/src/SpaceWarp.Core/API/Configuration/ConfigValue.cs
@@ -1,13 +1,26 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// A wrapper around that provides type safety.
+///
+/// The type of the value.
[PublicAPI]
public class ConfigValue
{
+ ///
+ /// The underlying .
+ ///
public IConfigEntry Entry;
+ ///
+ /// Creates a new from an .
+ ///
+ /// The entry to wrap.
+ ///
+ /// If the type of does not match .
+ ///
public ConfigValue(IConfigEntry entry)
{
Entry = entry;
@@ -17,15 +30,19 @@ public ConfigValue(IConfigEntry entry)
}
}
+ ///
+ /// The value of the entry.
+ ///
public T Value
{
get => (T)Entry.Value;
- set
- {
- Entry.Value = value;
- }
+ set => Entry.Value = value;
}
+ ///
+ /// Registers a callback that will be invoked when the value changes.
+ ///
+ /// The callback to invoke.
public void RegisterCallback(Action callback)
{
// Callbacks += callback;
diff --git a/src/SpaceWarp.Core/API/Configuration/EmptyConfigFile.cs b/src/SpaceWarp.Core/API/Configuration/EmptyConfigFile.cs
index 503d8914..85cd3bbb 100644
--- a/src/SpaceWarp.Core/API/Configuration/EmptyConfigFile.cs
+++ b/src/SpaceWarp.Core/API/Configuration/EmptyConfigFile.cs
@@ -1,28 +1,52 @@
-using System.Collections.Generic;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// An empty config file that does not save anything.
+///
[PublicAPI]
public class EmptyConfigFile : IConfigFile
{
+ ///
public void Save()
{
}
+ ///
public IConfigEntry this[string section, string key] => throw new KeyNotFoundException($"{section}/{key}");
+ ///
public IConfigEntry Bind(string section, string key, T defaultValue = default, string description = "")
{
- throw new System.NotImplementedException();
+ throw new NotImplementedException();
}
- public IConfigEntry Bind(string section, string key, T defaultValue, string description, IValueConstraint valueConstraint)
+ ///
+ /// Binds a config entry to a section and key.
+ ///
+ /// Section to bind to.
+ /// Key to bind to.
+ /// Default value to use if no value is found.
+ /// Description of the config entry.
+ /// Constraint to use for the value.
+ /// Type of the value.
+ /// The config entry.
+ /// Always thrown.
+ public IConfigEntry Bind(
+ string section,
+ string key,
+ T defaultValue,
+ string description,
+ IValueConstraint valueConstraint
+ )
{
- throw new System.NotImplementedException();
+ throw new NotImplementedException();
}
+ ///
public IReadOnlyList Sections => new List();
+ ///
public IReadOnlyList this[string section] => throw new KeyNotFoundException($"{section}");
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Configuration/IConfigEntry.cs b/src/SpaceWarp.Core/API/Configuration/IConfigEntry.cs
index f5f062a9..0506edea 100644
--- a/src/SpaceWarp.Core/API/Configuration/IConfigEntry.cs
+++ b/src/SpaceWarp.Core/API/Configuration/IConfigEntry.cs
@@ -1,23 +1,52 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// Represents a config entry
+///
[PublicAPI]
public interface IConfigEntry
{
+ ///
+ /// The value of the config entry
+ ///
public object Value { get; set; }
+
+ ///
+ /// The type of the value of the config entry
+ ///
public Type ValueType { get; }
+
+ ///
+ /// Gets the value of the config entry as a specific type
+ ///
+ /// The type to cast to
+ /// The value as the specified type
public T Get() where T : class;
+
+ ///
+ /// Sets the value of the config entry
+ ///
+ /// The value to set
+ /// The type of the value
public void Set(T value);
+ ///
+ /// The description of the config entry
+ ///
public string Description { get; }
+ ///
+ /// The value constraint of the config entry
+ ///
public IValueConstraint Constraint { get; }
-
+
///
- /// Called when setting the value on a config file
+ /// Registers a callback to be called when setting the value on a config file
///
- /// An action that takes te old value and the new value and calls a callback
+ ///
+ /// An action that takes the old value and the new value and calls a callback
+ ///
public void RegisterCallback(Action valueChangedCallback);
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Configuration/IConfigFile.cs b/src/SpaceWarp.Core/API/Configuration/IConfigFile.cs
index 87aedf23..2b271e5d 100644
--- a/src/SpaceWarp.Core/API/Configuration/IConfigFile.cs
+++ b/src/SpaceWarp.Core/API/Configuration/IConfigFile.cs
@@ -1,18 +1,44 @@
-using System;
-using System.Collections.Generic;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// Represents a configuration file.
+///
[PublicAPI]
public interface IConfigFile
{
+ ///
+ /// Saves the configuration file.
+ ///
public void Save();
+ ///
+ /// Gets the with the specified section and key.
+ ///
+ /// Section of the entry.
+ /// Key of the entry.
public IConfigEntry this[string section, string key] { get; }
+ ///
+ /// Binds a new to the specified section and key.
+ ///
+ /// Section of the entry.
+ /// Key of the entry.
+ /// Default value of the entry.
+ /// Description of the entry.
+ /// Type of the entry.
+ /// The bound .
public IConfigEntry Bind(string section, string key, T defaultValue = default, string description = "");
-
+
+ ///
+ /// A list of all sections in the configuration file.
+ ///
public IReadOnlyList Sections { get; }
+
+ ///
+ /// A list of all keys in the specified section.
+ ///
+ ///
public IReadOnlyList this[string section] { get; }
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Configuration/IValueConstraint.cs b/src/SpaceWarp.Core/API/Configuration/IValueConstraint.cs
index 4256ceba..b6f78822 100644
--- a/src/SpaceWarp.Core/API/Configuration/IValueConstraint.cs
+++ b/src/SpaceWarp.Core/API/Configuration/IValueConstraint.cs
@@ -1,9 +1,56 @@
-using BepInEx.Configuration;
+using System.Reflection;
+using BepInEx.Configuration;
namespace SpaceWarp.API.Configuration;
+///
+/// A constraint that can be applied to a to limit the values it can take.
+///
public interface IValueConstraint
{
+ ///
+ /// Checks if the given object is constrained by this constraint.
+ ///
+ /// Object to check.
+ /// True if the object is constrained, false otherwise.
public bool IsConstrained(object o);
+
+ ///
+ /// Converts this constraint to an .
+ ///
+ /// An representing this constraint.
public AcceptableValueBase ToAcceptableValueBase();
+
+ ///
+ /// Converts an acceptable value base into an IValueConstraint
+ ///
+ /// The acceptable value base
+ /// The IValueConstraint
+ public static IValueConstraint FromAcceptableValueBase(AcceptableValueBase acceptableValueBase)
+ {
+ if (acceptableValueBase is null) return null;
+ if (acceptableValueBase.GetType().GetGenericTypeDefinition() == typeof(AcceptableValueList<>))
+ {
+ var type = acceptableValueBase.GetType().GetGenericArguments()[0];
+ var valuesMethod = acceptableValueBase.GetType()
+ .GetProperty("AcceptableValues", BindingFlags.Instance | BindingFlags.Public)
+ ?.GetMethod;
+ var values = valuesMethod?.Invoke(acceptableValueBase,[]);
+ return (IValueConstraint)Activator.CreateInstance(typeof(ListConstraint<>).MakeGenericType(type), [values]);
+ }
+
+ if (acceptableValueBase.GetType().GetGenericTypeDefinition() == typeof(AcceptableValueRange<>))
+ {
+ var type = acceptableValueBase.GetType().GetGenericArguments()[0];
+ var minMethod = acceptableValueBase.GetType()
+ .GetProperty("MinValue", BindingFlags.Instance | BindingFlags.Public)?.GetMethod;
+ var maxMethod = acceptableValueBase.GetType()
+ .GetProperty("MaxValue", BindingFlags.Instance | BindingFlags.Public)?.GetMethod;
+ var min = minMethod?.Invoke(acceptableValueBase, []);
+ var max = maxMethod?.Invoke(acceptableValueBase, []);
+ return (IValueConstraint)Activator.CreateInstance(typeof(RangeConstraint<>).MakeGenericType(type),[min,max]);
+ }
+
+ return null;
+ }
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Configuration/JsonConfigEntry.cs b/src/SpaceWarp.Core/API/Configuration/JsonConfigEntry.cs
index 977f910c..e43b17ab 100644
--- a/src/SpaceWarp.Core/API/Configuration/JsonConfigEntry.cs
+++ b/src/SpaceWarp.Core/API/Configuration/JsonConfigEntry.cs
@@ -1,17 +1,36 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// A config entry that is stored in a JSON file.
+///
[PublicAPI]
public class JsonConfigEntry : IConfigEntry
{
private readonly JsonConfigFile _configFile;
private object _value;
- public event Action Callbacks;
-
- public JsonConfigEntry(JsonConfigFile configFile, Type type, string description, object value, IValueConstraint constraint = null)
+ ///
+ /// The callbacks that are invoked when the value of this entry changes.
+ ///
+ public event Action Callbacks;
+
+ ///
+ /// Creates a new config entry.
+ ///
+ /// Config file that this entry belongs to.
+ /// Type of the value.
+ /// Description of the value.
+ /// Value of the entry.
+ /// Constraint of the value.
+ public JsonConfigEntry(
+ JsonConfigFile configFile,
+ Type type,
+ string description,
+ object value,
+ IValueConstraint constraint = null
+ )
{
_configFile = configFile;
_value = value;
@@ -20,7 +39,7 @@ public JsonConfigEntry(JsonConfigFile configFile, Type type, string description,
ValueType = type;
}
-
+ ///
public object Value
{
get => _value;
@@ -32,7 +51,10 @@ public object Value
}
}
+ ///
public Type ValueType { get; }
+
+ ///
public T Get() where T : class
{
if (!typeof(T).IsAssignableFrom(ValueType))
@@ -43,6 +65,7 @@ public T Get() where T : class
return Value as T;
}
+ ///
public void Set(T value)
{
if (!ValueType.IsAssignableFrom(typeof(T)))
@@ -56,8 +79,13 @@ public void Set(T value)
Value = Convert.ChangeType(value, ValueType);
}
+ ///
public string Description { get; }
+
+ ///
public IValueConstraint Constraint { get; }
+
+ ///
public void RegisterCallback(Action valueChangedCallback)
{
Callbacks += valueChangedCallback;
diff --git a/src/SpaceWarp.Core/API/Configuration/JsonConfigFile.cs b/src/SpaceWarp.Core/API/Configuration/JsonConfigFile.cs
index aafbfc8b..90d38866 100644
--- a/src/SpaceWarp.Core/API/Configuration/JsonConfigFile.cs
+++ b/src/SpaceWarp.Core/API/Configuration/JsonConfigFile.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text;
+using System.Text;
using JetBrains.Annotations;
using KSP.IO;
using Newtonsoft.Json;
@@ -11,6 +8,9 @@
namespace SpaceWarp.API.Configuration;
+///
+/// A config file that uses JSON to store its data.
+///
[PublicAPI]
public class JsonConfigFile : IConfigFile
{
@@ -19,6 +19,10 @@ public class JsonConfigFile : IConfigFile
internal Dictionary> CurrentEntries = new();
private readonly string _file;
+ ///
+ /// Creates a new JSON config file object.
+ ///
+ /// The file path to use.
public JsonConfigFile(string file)
{
// Use .cfg as this is going to have comments and that will be an issue
@@ -38,6 +42,7 @@ public JsonConfigFile(string file)
_file = file;
}
+ ///
public void Save()
{
if (!CurrentEntries.Any(value => value.Value.Count > 0)) return;
@@ -72,6 +77,9 @@ private static bool DumpSection(bool hadPreviousSection, StringBuilder result, K
private static List _defaultConverters;
+ ///
+ /// The default converters to use when serializing/deserializing JSON.
+ ///
public static List DefaultConverters
{
get
@@ -86,7 +94,11 @@ public static List DefaultConverters
}
}
- private static bool DumpEntry(StringBuilder result, bool hadPreviousKey, KeyValuePair entry)
+ private static bool DumpEntry(
+ StringBuilder result,
+ bool hadPreviousKey,
+ KeyValuePair entry
+ )
{
if (hadPreviousKey)
{
@@ -128,8 +140,10 @@ private static bool DumpEntry(StringBuilder result, bool hadPreviousKey, KeyValu
return true;
}
+ ///
public IConfigEntry this[string section, string key] => CurrentEntries[section][key];
+ ///
public IConfigEntry Bind(string section, string key, T defaultValue = default, string description = "")
{
// So now we have to check if its already bound, and/or if the previous config object has it
@@ -173,7 +187,9 @@ public IConfigEntry Bind(string section, string key, T defaultValue = default
return previousSection[key];
}
+ ///
public IReadOnlyList Sections => CurrentEntries.Keys.ToList();
+ ///
public IReadOnlyList this[string section] => CurrentEntries[section].Keys.ToList();
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Configuration/ListConstraint.cs b/src/SpaceWarp.Core/API/Configuration/ListConstraint.cs
index b9610ee4..af5dd4b8 100644
--- a/src/SpaceWarp.Core/API/Configuration/ListConstraint.cs
+++ b/src/SpaceWarp.Core/API/Configuration/ListConstraint.cs
@@ -1,32 +1,48 @@
-using System;
-using System.Collections.Generic;
-using System.Text;
+using System.Text;
using BepInEx.Configuration;
using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// A constraint that checks if the value is in a list of acceptable values.
+///
+/// The type of the value.
public class ListConstraint : ValueConstraint where T : IEquatable
{
- [PublicAPI]
- public List AcceptableValues;
-
+ ///
+ /// The list of acceptable values.
+ ///
+ [PublicAPI] public List AcceptableValues;
+
+ ///
+ /// Creates a new list constraint.
+ ///
+ /// The list of acceptable values.
public ListConstraint(IEnumerable acceptableValues)
{
AcceptableValues = acceptableValues.ToList();
}
+ ///
+ /// Creates a new list constraint.
+ ///
+ /// The array of acceptable values.
public ListConstraint(params T[] acceptableValues)
{
AcceptableValues = acceptableValues.ToList();
}
+ ///
public override bool IsValid(T o) => AcceptableValues.Any(x => x.Equals(o));
+
+ ///
public override AcceptableValueBase ToAcceptableValueBase()
{
return new AcceptableValueList(AcceptableValues.ToArray());
}
+ ///
public override string ToString()
{
StringBuilder sb = new();
diff --git a/src/SpaceWarp.Core/API/Configuration/RangeConstraint.cs b/src/SpaceWarp.Core/API/Configuration/RangeConstraint.cs
index 00fbc08d..18e0a4c5 100644
--- a/src/SpaceWarp.Core/API/Configuration/RangeConstraint.cs
+++ b/src/SpaceWarp.Core/API/Configuration/RangeConstraint.cs
@@ -1,28 +1,45 @@
-using System;
-using BepInEx.Configuration;
+using BepInEx.Configuration;
using JetBrains.Annotations;
namespace SpaceWarp.API.Configuration;
+///
+/// A constraint that checks if a value is within a range.
+///
+/// The type of the value.
public class RangeConstraint : ValueConstraint where T : IComparable, IComparable
{
- [PublicAPI]
- public T Minimum;
- [PublicAPI]
- public T Maximum;
+ ///
+ /// The minimum value.
+ ///
+ [PublicAPI] public T Minimum;
+ ///
+ /// The maximum value.
+ ///
+ [PublicAPI] public T Maximum;
+
+ ///
+ /// Creates a new range constraint.
+ ///
+ /// The minimum value.
+ /// The maximum value.
public RangeConstraint(T minimum, T maximum)
{
Minimum = minimum;
Maximum = maximum;
}
+ ///
public override bool IsValid(T o) => Minimum.CompareTo(o) <= 0 && Maximum.CompareTo(o) >= 0;
+
+ ///
public override AcceptableValueBase ToAcceptableValueBase()
{
return new AcceptableValueRange(Minimum, Maximum);
}
+ ///
public override string ToString()
{
return $"{Minimum} - {Maximum}";
diff --git a/src/SpaceWarp.Core/API/Configuration/ValueConstraint.cs b/src/SpaceWarp.Core/API/Configuration/ValueConstraint.cs
index ddabf763..4ba8da0e 100644
--- a/src/SpaceWarp.Core/API/Configuration/ValueConstraint.cs
+++ b/src/SpaceWarp.Core/API/Configuration/ValueConstraint.cs
@@ -2,18 +2,35 @@
namespace SpaceWarp.API.Configuration;
+///
+/// Base class for value constraints.
+///
+/// Type of the value.
public abstract class ValueConstraint : IValueConstraint
{
+ ///
+ /// Returns true if the given value is valid for this constraint.
+ ///
+ /// Value to check.
+ /// True if the value is valid, false otherwise.
public abstract bool IsValid(T o);
+
+ ///
+ /// Returns true if the given value is valid for this constraint.
+ ///
+ /// Value to check.
+ /// True if the value is valid, false otherwise.
public bool IsValid(object o)
{
return IsValid((T)o);
}
+ ///
public bool IsConstrained(object o)
{
return IsValid((T)o);
}
+ ///
public abstract AcceptableValueBase ToAcceptableValueBase();
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Loading/Loading.cs b/src/SpaceWarp.Core/API/Loading/Loading.cs
index e9a0a82d..d85b3b08 100644
--- a/src/SpaceWarp.Core/API/Loading/Loading.cs
+++ b/src/SpaceWarp.Core/API/Loading/Loading.cs
@@ -1,15 +1,17 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game.Flow;
using SpaceWarp.API.Assets;
using SpaceWarp.API.Mods;
using SpaceWarp.InternalUtilities;
using SpaceWarp.Patching.LoadingActions;
+#pragma warning disable CS0618 // Type or member is obsolete
+
namespace SpaceWarp.API.Loading;
+///
+/// API for mods to register their actions for the loading of assets.
+///
[PublicAPI]
public static class Loading
{
@@ -20,7 +22,7 @@ public static class Loading
internal static List> GeneralLoadingActions = new();
///
- /// Registers an asset loading function for space warp, will load assets from the subfolder. Should be added either on Awake() or Start().
+ /// Registers an asset loading function for SpaceWarp, will load assets from the subfolder. Should be added either on Awake() or Start().
///
/// The subfolder under "assets" that this loader matches
/// The name to be displayed for this loader, it gets displayed like the following "Mod Name: [name]"
@@ -98,7 +100,7 @@ private static Action CreateAssetLoadingActionWithExtension
}
catch (Exception e)
{
- plugin.ModLogger.LogError(e.ToString());
+ plugin.SWLogger.LogError(e.ToString());
}
}
}
@@ -127,7 +129,7 @@ private static Action CreateAssetLoadingActionWithExt
if (plugin.Plugin != null)
plugin.Plugin.SWLogger.LogError(e.ToString());
else
- SpaceWarpPlugin.Logger.LogError(plugin.SWInfo.Name + ": " + e);
+ SpaceWarpPlugin.Instance.SWLogger.LogError(plugin.SWInfo.Name + ": " + e);
}
}
}
@@ -195,7 +197,7 @@ private static Action CreateAssetLoadingActionWithoutExtens
}
catch (Exception e)
{
- plugin.ModLogger.LogError(e.ToString());
+ plugin.SWLogger.LogError(e.ToString());
}
}
};
@@ -221,7 +223,7 @@ private static Action CreateAssetLoadingActionWithout
if (plugin.Plugin != null)
plugin.Plugin.SWLogger.LogError(e.ToString());
else
- SpaceWarpPlugin.Logger.LogError(plugin.SWInfo.Name + ": " + e);
+ SpaceWarpPlugin.Instance.SWLogger.LogError(plugin.SWInfo.Name + ": " + e);
}
}
};
diff --git a/src/SpaceWarp.Core/API/Loading/SaveLoad.cs b/src/SpaceWarp.Core/API/Loading/SaveLoad.cs
index cd617ef5..8808ff96 100644
--- a/src/SpaceWarp.Core/API/Loading/SaveLoad.cs
+++ b/src/SpaceWarp.Core/API/Loading/SaveLoad.cs
@@ -1,17 +1,19 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game.Flow;
-using SpaceWarp.Patching;
+using SpaceWarp.Patching.Flow;
namespace SpaceWarp.API.Loading;
+///
+/// An API to register flow actions to be run during loading and saving.
+///
[PublicAPI]
public static class SaveLoad
{
///
/// Construct and add a FlowAction to the Game's load sequence.
///
- /// FlowActionType must have a public constructor that takes either no arguments,
+ /// TFlowActionType must have a public constructor that takes either no arguments,
/// or a single GameManager.
///
/// The action will be run after the first FlowAction with a name equal to referenceAction.
@@ -34,12 +36,12 @@ public static class SaveLoad
///
///
///
- /// The type of FlowAction to insert
- /// The name of the action to insert a FlowActionType after. Use null to insert it at the start.
- /// Thrown if FlowActionType does not have a valid Constructor
- public static void AddFlowActionToGameLoadAfter(string referenceAction) where FlowActionType : FlowAction
+ /// The type of FlowAction to insert
+ /// The name of the action to insert a TFlowActionType after. Use null to insert it at the start.
+ /// Thrown if TFlowActionType does not have a valid Constructor
+ public static void AddFlowActionToGameLoadAfter(string referenceAction) where TFlowActionType : FlowAction
{
- SequentialFlowLoadersPatcher.AddConstructor(referenceAction, typeof(FlowActionType), SequentialFlowLoadersPatcher.FlowMethodStartgame);
+ SequentialFlowLoadersPatcher.AddConstructor(referenceAction, typeof(TFlowActionType), SequentialFlowLoadersPatcher.FlowMethodStartgame);
}
///
@@ -66,17 +68,17 @@ public static void AddFlowActionToGameLoadAfter(string reference
///
///
/// The FlowAction to insert
- /// The name of the action to insert a FlowActionType after. Use null to insert it at the start.
+ /// The name of the action to insert a TFlowActionType after. Use null to insert it at the start.
public static void AddFlowActionToGameLoadAfter(FlowAction flowAction, string referenceAction)
{
SequentialFlowLoadersPatcher.AddFlowAction(referenceAction, flowAction, SequentialFlowLoadersPatcher.FlowMethodStartgame);
}
///
- /// Add a FlowAction to the save file loading sequence. A new FlowActionType is constructed every load.
+ /// Add a FlowAction to the save file loading sequence. A new TFlowActionType is constructed every load.
///
///
- /// FlowActionType must have a public constructor that at most one of each of the following types:
+ /// TFlowActionType must have a public constructor that at most one of each of the following types:
///
/// SaveLoadManager
/// LoadOrSaveCampaignTicket
@@ -145,12 +147,12 @@ public static void AddFlowActionToGameLoadAfter(FlowAction flowAction, string re
///
///
///
- /// The type of FlowAction to insert
- /// The name of the action to insert a FlowActionType after. Use null to insert it at the start.
- /// Thrown if FlowActionType does not have a valid Constructor
- public static void AddFlowActionToCampaignLoadAfter(string referenceAction) where FlowActionType : FlowAction
+ /// The type of FlowAction to insert
+ /// The name of the action to insert a TFlowActionType after. Use null to insert it at the start.
+ /// Thrown if TFlowActionType does not have a valid Constructor
+ public static void AddFlowActionToCampaignLoadAfter(string referenceAction) where TFlowActionType : FlowAction
{
- SequentialFlowLoadersPatcher.AddConstructor(referenceAction, typeof(FlowActionType), SequentialFlowLoadersPatcher.FlowMethodPrivateloadcommon);
+ SequentialFlowLoadersPatcher.AddConstructor(referenceAction, typeof(TFlowActionType), SequentialFlowLoadersPatcher.FlowMethodPrivateloadcommon);
}
///
@@ -225,10 +227,10 @@ public static void AddFlowActionToCampaignLoadAfter(FlowAction flowAction, strin
}
///
- /// Add a FlowAction to the save file writing sequence. A new FlowActionType is constructed every load.
+ /// Add a FlowAction to the save file writing sequence. A new TFlowActionType is constructed every load.
///
///
- /// FlowActionType must have a public constructor that at most one of each of the following types:
+ /// TFlowActionType must have a public constructor that at most one of each of the following types:
///
/// SaveLoadManager
/// LoadOrSaveCampaignTicket
@@ -258,12 +260,12 @@ public static void AddFlowActionToCampaignLoadAfter(FlowAction flowAction, strin
///
///
///
- /// The type of FlowAction to insert
- /// The name of the action to insert a FlowActionType after. Use null to insert it at the start.
- /// Thrown if FlowActionType does not have a valid Constructor
- public static void AddFlowActionToCampaignSaveAfter(string referenceAction) where FlowActionType : FlowAction
+ /// The type of FlowAction to insert
+ /// The name of the action to insert a TFlowActionType after. Use null to insert it at the start.
+ /// Thrown if TFlowActionType does not have a valid Constructor
+ public static void AddFlowActionToCampaignSaveAfter(string referenceAction) where TFlowActionType : FlowAction
{
- SequentialFlowLoadersPatcher.AddConstructor(referenceAction, typeof(FlowActionType), SequentialFlowLoadersPatcher.FlowMethodPrivatesavecommon);
+ SequentialFlowLoadersPatcher.AddConstructor(referenceAction, typeof(TFlowActionType), SequentialFlowLoadersPatcher.FlowMethodPrivatesavecommon);
}
///
diff --git a/src/SpaceWarp.Core/API/Logging/BaseLogger.cs b/src/SpaceWarp.Core/API/Logging/BaseLogger.cs
index 7835d5b4..1600c4c6 100644
--- a/src/SpaceWarp.Core/API/Logging/BaseLogger.cs
+++ b/src/SpaceWarp.Core/API/Logging/BaseLogger.cs
@@ -1,24 +1,39 @@
-using JetBrains.Annotations;
+using BepInEx.Logging;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Logging;
+///
+/// Base class for loggers.
+///
[PublicAPI]
public abstract class BaseLogger : ILogger
{
+ ///
public abstract void Log(LogLevel level, object x);
- public void LogNone(object x) => Log(LogLevel.None, x);
+ ///
public void LogFatal(object x) => Log(LogLevel.Fatal, x);
+ ///
public void LogError(object x) => Log(LogLevel.Error, x);
+ ///
public void LogWarning(object x) => Log(LogLevel.Warning, x);
+ ///
public void LogMessage(object x) => Log(LogLevel.Message, x);
+ ///
public void LogInfo(object x) => Log(LogLevel.Info, x);
+ ///
public void LogDebug(object x) => Log(LogLevel.Debug, x);
- public void LogAll(object x) => Log(LogLevel.All, x);
+ ///
+ /// Creates a logger of default type with the specified name.
+ ///
+ /// The name of the logger.
+ /// The created logger.
+ public static BaseLogger CreateDefault(string name) => new BepInExLogger(new ManualLogSource(name));
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Logging/BepInExLogger.cs b/src/SpaceWarp.Core/API/Logging/BepInExLogger.cs
index 662f73a3..07897907 100644
--- a/src/SpaceWarp.Core/API/Logging/BepInExLogger.cs
+++ b/src/SpaceWarp.Core/API/Logging/BepInExLogger.cs
@@ -3,20 +3,33 @@
namespace SpaceWarp.API.Logging;
+///
+/// A logger that uses BepInEx's logging system.
+///
[PublicAPI]
public class BepInExLogger : BaseLogger
{
private ManualLogSource _log;
+ ///
+ /// Creates a new instance of .
+ ///
+ /// The to use.
public BepInExLogger(ManualLogSource log)
{
_log = log;
}
+ ///
public override void Log(LogLevel level, object x)
{
_log.Log((BepInEx.Logging.LogLevel)level, x);
}
+ ///
+ /// Implicitly converts a to a .
+ ///
+ /// The to convert.
+ /// The converted .
public static implicit operator BepInExLogger(ManualLogSource log) => new(log);
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Logging/ILogger.cs b/src/SpaceWarp.Core/API/Logging/ILogger.cs
index a77e76e3..f84cfa9f 100644
--- a/src/SpaceWarp.Core/API/Logging/ILogger.cs
+++ b/src/SpaceWarp.Core/API/Logging/ILogger.cs
@@ -2,17 +2,52 @@
namespace SpaceWarp.API.Logging;
+///
+/// Interface for loggers.
+///
[PublicAPI]
public interface ILogger
{
+ ///
+ /// Logs the given object with the given log level.
+ ///
+ /// Log level.
+ /// Object to log.
public void Log(LogLevel level, object x);
- public void LogNone(object x);
+ ///
+ /// Logs the given object with the log level .
+ ///
+ /// Object to log.
public void LogFatal(object x);
+
+ ///
+ /// Logs the given object with the log level .
+ ///
+ /// Object to log.
public void LogError(object x);
+
+ ///
+ /// Logs the given object with the log level .
+ ///
+ /// Object to log.
public void LogWarning(object x);
+
+ ///
+ /// Logs the given object with the log level .
+ ///
+ /// Object to log.
public void LogMessage(object x);
+
+ ///
+ /// Logs the given object with the log level .
+ ///
+ /// Object to log.
public void LogInfo(object x);
+
+ ///
+ /// Logs the given object with the log level .
+ ///
+ /// Object to log.
public void LogDebug(object x);
- public void LogAll(object x);
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Logging/LogLevel.cs b/src/SpaceWarp.Core/API/Logging/LogLevel.cs
index 2ef7977f..2c26fdd5 100644
--- a/src/SpaceWarp.Core/API/Logging/LogLevel.cs
+++ b/src/SpaceWarp.Core/API/Logging/LogLevel.cs
@@ -2,15 +2,42 @@
namespace SpaceWarp.API.Logging;
+///
+/// The log level.
+///
[PublicAPI]
public enum LogLevel
{
+ ///
+ /// No logging.
+ ///
None = 0,
+ ///
+ /// Fatal errors.
+ ///
Fatal = 1,
+ ///
+ /// Errors.
+ ///
Error = 2,
+ ///
+ /// Warnings.
+ ///
Warning = 4,
+ ///
+ /// Messages.
+ ///
Message = 8,
+ ///
+ /// Information.
+ ///
Info = 16,
+ ///
+ /// Debug information.
+ ///
Debug = 32,
+ ///
+ /// All logging.
+ ///
All = Debug | Info | Message | Warning | Error | Fatal
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Logging/UnityLogSource.cs b/src/SpaceWarp.Core/API/Logging/UnityLogSource.cs
index 654cb060..8abbb90c 100644
--- a/src/SpaceWarp.Core/API/Logging/UnityLogSource.cs
+++ b/src/SpaceWarp.Core/API/Logging/UnityLogSource.cs
@@ -3,16 +3,27 @@
namespace SpaceWarp.API.Logging;
+///
+/// A logger that logs to Unity's built-in logging system.
+///
[PublicAPI]
public class UnityLogSource : BaseLogger
{
+ ///
+ /// The name of the logger.
+ ///
public string Name;
+ ///
+ /// Creates a new with the given name.
+ ///
+ /// The name of the logger.
public UnityLogSource(string name)
{
Name = name;
}
+ ///
public override void Log(LogLevel level, object x)
{
switch (level)
diff --git a/src/SpaceWarp.Core/API/Lua/LuaMod.cs b/src/SpaceWarp.Core/API/Lua/LuaMod.cs
index 14960196..9d5054fe 100644
--- a/src/SpaceWarp.Core/API/Lua/LuaMod.cs
+++ b/src/SpaceWarp.Core/API/Lua/LuaMod.cs
@@ -1,15 +1,20 @@
-using System;
-using BepInEx.Logging;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game;
using MoonSharp.Interpreter;
+using SpaceWarp.API.Logging;
namespace SpaceWarp.API.Lua;
+///
+/// A Lua mod, this is the base class for all mods that are written in Lua.
+///
[MoonSharpUserData]
[PublicAPI]
public class LuaMod : KerbalMonoBehaviour
{
+ ///
+ /// The table that contains the mod's functions.
+ ///
public Table ModTable;
// TODO: Add more than just this to the behaviour but for now
@@ -33,9 +38,15 @@ public class LuaMod : KerbalMonoBehaviour
private Closure _reset;
#endregion
- public ManualLogSource Logger;
+ ///
+ /// The logger for this mod.
+ ///
+ public ILogger Logger;
- // First a pass through to the wrapped table
+ ///
+ /// A pass through to the wrapped table
+ ///
+ /// The index of the name.
public DynValue this[DynValue idx]
{
get => ModTable.Get(idx);
@@ -55,17 +66,17 @@ private void TryCallMethod(Closure closure, params object[] args)
}
#region Message Handlers
- private void TryRegister(string name, out Closure method)
+ private void TryRegister(string methodName, out Closure method)
{
- if (ModTable.Get(name) != null && ModTable.Get(name).Type == DataType.Function)
+ if (ModTable.Get(methodName) != null && ModTable.Get(methodName).Type == DataType.Function)
{
- method = ModTable.Get(name).Function;
+ method = ModTable.Get(methodName).Function;
return;
}
method = null;
}
- public void Awake()
+ private void Awake()
{
if (ModTable.Get("Awake") != null && ModTable.Get("Awake").Type == DataType.Function)
{
@@ -92,7 +103,7 @@ public void Awake()
}
// Start
- public void Start()
+ private void Start()
{
if (_start != null)
{
@@ -102,7 +113,7 @@ public void Start()
// Update Functions
- public void Update()
+ private void Update()
{
if (_update != null)
{
@@ -110,7 +121,7 @@ public void Update()
}
}
- public void FixedUpdate()
+ private void FixedUpdate()
{
if (_fixedUpdate != null)
{
@@ -118,7 +129,7 @@ public void FixedUpdate()
}
}
- public void LateUpdate()
+ private void LateUpdate()
{
if (_lateUpdate != null)
{
@@ -128,7 +139,7 @@ public void LateUpdate()
// Enable/Disable
- public void OnEnable()
+ private void OnEnable()
{
if (_onEnable != null)
{
@@ -136,7 +147,7 @@ public void OnEnable()
}
}
- public void OnDisable()
+ private void OnDisable()
{
if (_onDisable != null)
{
@@ -146,7 +157,7 @@ public void OnDisable()
// Destruction
- public void OnDestroy()
+ private void OnDestroy()
{
if (_onDestroy != null)
{
@@ -155,7 +166,7 @@ public void OnDestroy()
}
// Reset
- public void Reset()
+ private void Reset()
{
if (_reset != null)
{
diff --git a/src/SpaceWarp.Core/API/Lua/SpaceWarpInterop.cs b/src/SpaceWarp.Core/API/Lua/SpaceWarpInterop.cs
index 96b762aa..6ae7663b 100644
--- a/src/SpaceWarp.Core/API/Lua/SpaceWarpInterop.cs
+++ b/src/SpaceWarp.Core/API/Lua/SpaceWarpInterop.cs
@@ -1,16 +1,26 @@
using BepInEx.Bootstrap;
using JetBrains.Annotations;
using MoonSharp.Interpreter;
+using SpaceWarp.API.Logging;
using SpaceWarp.InternalUtilities;
using UnityEngine;
using Logger = BepInEx.Logging.Logger;
namespace SpaceWarp.API.Lua;
+///
+/// SpaceWarp interop class for Lua API.
+///
[SpaceWarpLuaAPI("SpaceWarp")]
[PublicAPI]
public static class SpaceWarpInterop
{
+ ///
+ /// Registers a Lua mod.
+ ///
+ /// Name of the mod.
+ /// Table containing the mod's functions.
+ /// The created instance.
public static LuaMod RegisterMod(string name, Table modTable)
{
var go = new GameObject(name);
@@ -18,7 +28,7 @@ public static LuaMod RegisterMod(string name, Table modTable)
go.transform.SetParent(Chainloader.ManagerObject.transform);
go.SetActive(false);
var mod = go.AddComponent();
- mod.Logger = Logger.CreateLogSource(name);
+ mod.Logger = new BepInExLogger(Logger.CreateLogSource(name));
mod.ModTable = modTable;
go.SetActive(true);
return mod;
diff --git a/src/SpaceWarp.Core/API/Lua/SpaceWarpLuaAPIAttribute.cs b/src/SpaceWarp.Core/API/Lua/SpaceWarpLuaAPIAttribute.cs
index 91fc288f..7c346fa3 100644
--- a/src/SpaceWarp.Core/API/Lua/SpaceWarpLuaAPIAttribute.cs
+++ b/src/SpaceWarp.Core/API/Lua/SpaceWarpLuaAPIAttribute.cs
@@ -1,13 +1,23 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Lua;
+///
+/// Marks a class as a Lua API class, allowing it to be used in Lua.
+///
[AttributeUsage(AttributeTargets.Class)]
[MeansImplicitUse]
public class SpaceWarpLuaAPIAttribute : Attribute
{
+ ///
+ /// The name of the class in Lua.
+ ///
public string LuaName;
+
+ ///
+ /// Marks a class as a Lua API class, allowing it to be used in Lua.
+ ///
+ ///
public SpaceWarpLuaAPIAttribute(string luaName)
{
LuaName = luaName;
diff --git a/src/SpaceWarp.Core/API/Lua/UI/LuaUITK.cs b/src/SpaceWarp.Core/API/Lua/UI/LuaUITK.cs
index 34ae01f6..c8df04ae 100644
--- a/src/SpaceWarp.Core/API/Lua/UI/LuaUITK.cs
+++ b/src/SpaceWarp.Core/API/Lua/UI/LuaUITK.cs
@@ -1,50 +1,96 @@
using JetBrains.Annotations;
using MoonSharp.Interpreter;
using SpaceWarp.API.Assets;
+using UitkForKsp2.API;
using UnityEngine.UIElements;
namespace SpaceWarp.API.Lua.UI;
+///
+/// Lua API for UITK
+///
[SpaceWarpLuaAPI("UI")]
[PublicAPI]
+// ReSharper disable once InconsistentNaming
public static class LuaUITK
{
#region Creation
+ ///
+ /// Creates a new window from a UXML file.
+ ///
+ /// Mod to create the window for
+ /// ID of the window
+ /// Path to the UXML file
+ /// Created window
public static UIDocument Window(LuaMod mod, string id, string documentPath)
{
return Window(mod, id, AssetManager.GetAsset(documentPath));
}
+ ///
+ /// Creates a new window from a VisualTreeAsset.
+ ///
+ /// Mod to create the window for
+ /// ID of the window
+ /// VisualTreeAsset to create the window from
+ /// Created window
public static UIDocument Window(LuaMod mod, string id, VisualTreeAsset uxml)
{
- var parent = mod.transform;
- return UitkForKsp2.API.Window.CreateFromUxml(uxml, id, parent, true);
+ var windowOptions = WindowOptions.Default;
+ windowOptions.Parent = mod.transform;
+ windowOptions.WindowId = id;
+ return UitkForKsp2.API.Window.Create(windowOptions, uxml);
}
+ ///
+ /// Creates a new window with an empty root element.
+ ///
+ /// Mod to create the window for
+ /// ID of the window
+ /// Created window
public static UIDocument Window(LuaMod mod, string id)
{
- var parent = mod.transform;
- return UitkForKsp2.API.Window.Create(out _, id, parent, true);
+ var windowOptions = WindowOptions.Default;
+ windowOptions.Parent = mod.transform;
+ windowOptions.WindowId = id;
+ return UitkForKsp2.API.Window.Create(windowOptions);
}
#region Element Creation
+ ///
+ /// Creates a new VisualElement.
+ ///
+ /// Created VisualElement
public static VisualElement VisualElement()
{
return new VisualElement();
}
+ ///
+ /// Creates a new ScrollView.
+ ///
+ /// Created ScrollView
public static ScrollView ScrollView()
{
return new ScrollView();
}
+ ///
+ /// Creates a new ListView.
+ ///
+ /// Created ListView
public static ListView ListView()
{
return new ListView();
}
+ ///
+ /// Creates a new Toggle.
+ ///
+ /// Text of the Toggle
+ /// Created Toggle
public static Toggle Toggle(string text = "")
{
return new Toggle
@@ -53,6 +99,11 @@ public static Toggle Toggle(string text = "")
};
}
+ ///
+ /// Creates a new Label.
+ ///
+ /// Text of the Label
+ /// Created Label
public static Label Label(string text = "")
{
return new Label
@@ -61,6 +112,11 @@ public static Label Label(string text = "")
};
}
+ ///
+ /// Creates a new Button.
+ ///
+ /// Text of the Button
+ /// Created Button
public static Button Button(string text = "")
{
return new Button
@@ -69,11 +125,20 @@ public static Button Button(string text = "")
};
}
+ ///
+ /// Creates a new Scroller.
+ ///
+ /// Created Scroller
public static Scroller Scroller()
{
return new Scroller();
}
+ ///
+ /// Creates a new TextField.
+ ///
+ /// Text of the TextField
+ /// Created TextField
public static TextField TextField(string text = "")
{
return new TextField
@@ -82,11 +147,22 @@ public static TextField TextField(string text = "")
};
}
+ ///
+ /// Creates a new Foldout.
+ ///
+ /// Created Foldout
public static Foldout Foldout()
{
return new Foldout();
}
+ ///
+ /// Creates a new Slider.
+ ///
+ /// Value of the Slider
+ /// Minimum value of the Slider
+ /// Maximum value of the Slider
+ /// Created Slider
public static Slider Slider(float value = 0.0f, float minValue = 0.0f, float maxValue = 1.0f)
{
return new Slider
@@ -97,6 +173,13 @@ public static Slider Slider(float value = 0.0f, float minValue = 0.0f, float max
};
}
+ ///
+ /// Creates a new SliderInt.
+ ///
+ /// Value of the SliderInt
+ /// Minimum value of the SliderInt
+ /// Maximum value of the SliderInt
+ ///
public static SliderInt SliderInt(int value = 0, int minValue = 0, int maxValue = 100)
{
return new SliderInt
@@ -107,8 +190,20 @@ public static SliderInt SliderInt(int value = 0, int minValue = 0, int maxValue
};
}
- public static MinMaxSlider MinMaxSlider(float minValue = 0.0f, float maxValue = 1.0f, float minLimit = 0.0f,
- float maxLimit = 1.0f)
+ ///
+ /// Creates a new MinMaxSlider.
+ ///
+ /// Minimum value of the MinMaxSlider
+ /// Maximum value of the MinMaxSlider
+ /// Minimum limit of the MinMaxSlider
+ /// Maximum limit of the MinMaxSlider
+ ///
+ public static MinMaxSlider MinMaxSlider(
+ float minValue = 0.0f,
+ float maxValue = 1.0f,
+ float minLimit = 0.0f,
+ float maxLimit = 1.0f
+ )
{
return new MinMaxSlider
{
@@ -125,6 +220,12 @@ public static MinMaxSlider MinMaxSlider(float minValue = 0.0f, float maxValue =
#region Callbacks
+ ///
+ /// Adds a callback to a button from Lua
+ ///
+ /// Button to add the callback to
+ /// Callback to add
+ /// Self parameter for the callback
public static void AddCallback(Button button, Closure callback, [CanBeNull] DynValue self = null)
{
if (self != null)
@@ -138,13 +239,13 @@ public static void AddCallback(Button button, Closure callback, [CanBeNull] DynV
}
///
- /// Registers a value changed callback from lua
- /// The lua functions parameters should be like function(self?,previous,new)
+ /// Registers a value changed callback from Lua
+ /// The Lua functions parameters should be like function(self?,previous,new)
///
- ///
- ///
- ///
- ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Type of the value
public static void RegisterValueChangedCallback(
INotifyValueChanged element,
Closure callback,
@@ -170,19 +271,30 @@ private static void RegisterGenericCallback(
{
if (self != null)
{
- element.RegisterCallback(evt => callback.Call(self, evt),
- trickleDown ? TrickleDown.TrickleDown : TrickleDown.NoTrickleDown);
+ element.RegisterCallback(
+ evt => callback.Call(self, evt),
+ trickleDown ? TrickleDown.TrickleDown : TrickleDown.NoTrickleDown
+ );
}
else
{
- element.RegisterCallback(evt => callback.Call(evt),
- trickleDown ? TrickleDown.TrickleDown : TrickleDown.NoTrickleDown);
+ element.RegisterCallback(
+ evt => callback.Call(evt),
+ trickleDown ? TrickleDown.TrickleDown : TrickleDown.NoTrickleDown
+ );
}
}
#region Capture Events
+ ///
+ /// Registers a mouse capture callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseCaptureCallback(
VisualElement element,
Closure callback,
@@ -190,6 +302,13 @@ public static void RegisterMouseCaptureCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse capture out callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseCaptureOutCallback(
VisualElement element,
Closure callback,
@@ -197,6 +316,13 @@ public static void RegisterMouseCaptureOutCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer capture callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerCaptureCallback(
VisualElement element,
Closure callback,
@@ -204,6 +330,13 @@ public static void RegisterPointerCaptureCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer capture out callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerCaptureOutCallback(
VisualElement element,
Closure callback,
@@ -215,6 +348,13 @@ public static void RegisterPointerCaptureOutCallback(
#region Change Events
+ ///
+ /// Registers a boolean value change event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterChangeBoolCallback(
VisualElement element,
Closure callback,
@@ -222,6 +362,13 @@ public static void RegisterChangeBoolCallback(
bool trickleDown = false
) => RegisterGenericCallback>(element, callback, self, trickleDown);
+ ///
+ /// Registers an integer value change event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterChangeIntCallback(
VisualElement element,
Closure callback,
@@ -229,6 +376,13 @@ public static void RegisterChangeIntCallback(
bool trickleDown = false
) => RegisterGenericCallback>(element, callback, self, trickleDown);
+ ///
+ /// Registers a float value change event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterChangeFloatCallback(
VisualElement element,
Closure callback,
@@ -236,6 +390,13 @@ public static void RegisterChangeFloatCallback(
bool trickleDown = false
) => RegisterGenericCallback>(element, callback, self, trickleDown);
+ ///
+ /// Registers a string value change event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterChangeStringCallback(
VisualElement element,
Closure callback,
@@ -247,6 +408,13 @@ public static void RegisterChangeStringCallback(
#region Click Events
+ ///
+ /// Registers a click event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterClickCallback(
VisualElement element,
Closure callback,
@@ -258,6 +426,13 @@ public static void RegisterClickCallback(
#region Focus Events
+ ///
+ /// Registers a focus out event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterFocusOutCallback(
VisualElement element,
Closure callback,
@@ -265,6 +440,13 @@ public static void RegisterFocusOutCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a focus in event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterFocusInCallback(
VisualElement element,
Closure callback,
@@ -272,6 +454,13 @@ public static void RegisterFocusInCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a blur event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterBlurCallback(
VisualElement element,
Closure callback,
@@ -279,6 +468,13 @@ public static void RegisterBlurCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a focus event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterFocusCallback(
VisualElement element,
Closure callback,
@@ -290,6 +486,13 @@ public static void RegisterFocusCallback(
#region Input Events
+ ///
+ /// Registers an input event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterInputCallback(
VisualElement element,
Closure callback,
@@ -301,6 +504,13 @@ public static void RegisterInputCallback(
#region Layout Events
+ ///
+ /// Registers a geometry changed event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterGeometryChangedCallback(
VisualElement element,
Closure callback,
@@ -312,6 +522,13 @@ public static void RegisterGeometryChangedCallback(
#region Mouse Events
+ ///
+ /// Registers a mouse down event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseDownCallback(
VisualElement element,
Closure callback,
@@ -319,6 +536,14 @@ public static void RegisterMouseDownCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+
+ ///
+ /// Registers a mouse up event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseUpCallback(
VisualElement element,
Closure callback,
@@ -326,6 +551,13 @@ public static void RegisterMouseUpCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse move event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseMoveCallback(
VisualElement element,
Closure callback,
@@ -333,6 +565,13 @@ public static void RegisterMouseMoveCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse wheel event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterWheelCallback(
VisualElement element,
Closure callback,
@@ -340,6 +579,13 @@ public static void RegisterWheelCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse enter window event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseEnterWindowCallback(
VisualElement element,
Closure callback,
@@ -347,6 +593,13 @@ public static void RegisterMouseEnterWindowCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse leave window event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseLeaveWindowCallback(
VisualElement element,
Closure callback,
@@ -354,6 +607,13 @@ public static void RegisterMouseLeaveWindowCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse enter event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseEnterCallback(
VisualElement element,
Closure callback,
@@ -361,6 +621,13 @@ public static void RegisterMouseEnterCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse leave event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseLeaveCallback(
VisualElement element,
Closure callback,
@@ -368,6 +635,13 @@ public static void RegisterMouseLeaveCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse over event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseOverCallback(
VisualElement element,
Closure callback,
@@ -375,6 +649,13 @@ public static void RegisterMouseOverCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a mouse out event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterMouseOutCallback(
VisualElement element,
Closure callback,
@@ -386,6 +667,13 @@ public static void RegisterMouseOutCallback(
#region Pointer Events
+ ///
+ /// Registers a pointer down event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerDownCallback(
VisualElement element,
Closure callback,
@@ -393,6 +681,13 @@ public static void RegisterPointerDownCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer up event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerUpCallback(
VisualElement element,
Closure callback,
@@ -400,6 +695,13 @@ public static void RegisterPointerUpCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer move event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerMoveCallback(
VisualElement element,
Closure callback,
@@ -407,6 +709,13 @@ public static void RegisterPointerMoveCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer enter event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerEnterCallback(
VisualElement element,
Closure callback,
@@ -414,6 +723,13 @@ public static void RegisterPointerEnterCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer leave event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerLeaveCallback(
VisualElement element,
Closure callback,
@@ -421,6 +737,13 @@ public static void RegisterPointerLeaveCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer over event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerOverCallback(
VisualElement element,
Closure callback,
@@ -428,6 +751,13 @@ public static void RegisterPointerOverCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a pointer out event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterPointerOutCallback(
VisualElement element,
Closure callback,
@@ -439,6 +769,13 @@ public static void RegisterPointerOutCallback(
#region Panel Events
+ ///
+ /// Registers an attach to panel event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterAttachToPanelCallback(
VisualElement element,
Closure callback,
@@ -446,6 +783,13 @@ public static void RegisterAttachToPanelCallback(
bool trickleDown = false
) => RegisterGenericCallback(element, callback, self, trickleDown);
+ ///
+ /// Registers a detach from panel event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterDetachFromPanelCallback(
VisualElement element,
Closure callback,
@@ -457,6 +801,13 @@ public static void RegisterDetachFromPanelCallback(
#region Tooltip Events
+ ///
+ /// Registers a tooltip event callback from Lua
+ ///
+ /// Element to register the callback for
+ /// Callback to register
+ /// Self parameter for the callback
+ /// Whether the event should trickle down
public static void RegisterTooltipCallback(
VisualElement element,
Closure callback,
diff --git a/src/SpaceWarp.Core/API/Mods/BaseKspLoaderSpaceWarpMod.cs b/src/SpaceWarp.Core/API/Mods/BaseKspLoaderSpaceWarpMod.cs
index 0127632e..0cf5ecc2 100644
--- a/src/SpaceWarp.Core/API/Mods/BaseKspLoaderSpaceWarpMod.cs
+++ b/src/SpaceWarp.Core/API/Mods/BaseKspLoaderSpaceWarpMod.cs
@@ -5,31 +5,33 @@
namespace SpaceWarp.API.Mods;
+///
+/// Base class for mods that are loaded by the KSP2 internal loader
+///
[PublicAPI]
public abstract class BaseKspLoaderSpaceWarpMod : Mod, ISpaceWarpMod
{
+ ///
public virtual void OnPreInitialized()
{
-
}
+ ///
public virtual void OnInitialized()
{
}
+ ///
public virtual void OnPostInitialized()
{
}
- ///
- /// Gets set automatically, before awake is called
- ///
+ ///
public ILogger SWLogger { get; set; }
- public IConfigFile SWConfiguration {
- get;
- internal set;
- }
+ ///
+ public IConfigFile SWConfiguration { get; internal set; }
+ ///
public SpaceWarpPluginDescriptor SWMetadata { get; set; }
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/BaseSpaceWarpPlugin.cs b/src/SpaceWarp.Core/API/Mods/BaseSpaceWarpPlugin.cs
index 2f7551f8..6c22d6d4 100644
--- a/src/SpaceWarp.Core/API/Mods/BaseSpaceWarpPlugin.cs
+++ b/src/SpaceWarp.Core/API/Mods/BaseSpaceWarpPlugin.cs
@@ -1,5 +1,4 @@
using BepInEx;
-using BepInEx.Logging;
using JetBrains.Annotations;
using KSP.Game;
using KSP.Messages;
@@ -11,61 +10,83 @@
namespace SpaceWarp.API.Mods;
///
-/// Represents a KSP2 Mod, you should inherit from this and do your manager processing.
+/// Represents a SpaceWarp mod based on BepInEx.
///
[PublicAPI]
public abstract class BaseSpaceWarpPlugin : BaseUnityPlugin, ISpaceWarpMod
{
- #region KspBehaviour things
+ #region KerbalMonoBehaviour properties
+ ///
+ /// The current game instance, this is null if the game is not yet initialized or shutting down.
+ ///
protected static GameInstance Game => GameManager.Instance == null ? null : GameManager.Instance.Game;
+ ///
+ /// The message center for the current game instance.
+ ///
protected MessageCenter Messages => Game.Messages;
- // ReSharper disable Unity.NoNullPropagation
- // fine because its null checked by Game properly
+ ///
+ /// The current game instance, this is null if the game is not yet initialized or shutting down.
+ ///
+ // ReSharper disable Unity.NoNullPropagation - fine because it's null checked by Game properly
+ // ReSharper disable once InconsistentNaming
protected ContextualFxSystem CFXSystem => Game?.GraphicsManager?.ContextualFxSystem;
+ ///
+ /// Whether the game is shutting down.
+ ///
protected bool IsGameShuttingDown => Game == null;
#endregion
+ private BepInExLogger _logger;
+ private BepInExConfigFile _configFile;
+
+ ///
+ /// The mod info for this mod.
+ ///
+ [Obsolete("This will be removed in 2.0.0. Use SWMetadata instead.")]
public ModInfo SpaceWarpMetadata { get; internal set; }
- internal ManualLogSource ModLogger => Logger;
- public string PluginFolderPath { get; internal set; }
- public string IdBySpec => GetGuidBySpec(Info, SpaceWarpMetadata);
+ ///
+ /// The path to the folder containing the plugin.
+ ///
+ [Obsolete("This will be removed in 2.0.0. Use SWMetadata.Folder instead.")]
+ public string PluginFolderPath { get; internal set; }
///
- /// 1st stage initialization
- /// This is called before any of the game is actually loaded, it is called as early as possible in the games bootstrap
- /// process.
+ /// The correct ID of the mod based on its spec version.
///
+ [Obsolete("This will be removed in 2.0.0. Use SWMetadata.Guid instead.")]
+ public string IdBySpec => GetGuidBySpec(Info, SpaceWarpMetadata);
+
+ ///
+ public ILogger SWLogger => _logger ??= new BepInExLogger(Logger);
+
+ ///
+ public IConfigFile SWConfiguration => _configFile ??= new BepInExConfigFile(Config);
+
+ ///
+ public SpaceWarpPluginDescriptor SWMetadata { get; set; }
+
+ ///
public virtual void OnPreInitialized()
{
}
- ///
- /// 2nd stage initialization
- /// This is called after the game is loaded, and after your mods assets are loaded.
- ///
+ ///
public virtual void OnInitialized()
{
}
- ///
- /// 3rd stage initialization
- /// This is called after all mods have done first stage initialization
- ///
+ ///
public virtual void OnPostInitialized()
{
}
- private BepInExLogger _logger;
- public ILogger SWLogger => _logger ??= new BepInExLogger(Logger);
- private BepInExConfigFile _configFile;
- public IConfigFile SWConfiguration => _configFile ??= new BepInExConfigFile(Config);
- public SpaceWarpPluginDescriptor SWMetadata { get; set; }
+ [Obsolete("To be removed in 2.0.0.")]
internal static string GetGuidBySpec(PluginInfo pluginInfo, ModInfo modInfo)
{
return modInfo.Spec >= SpecVersion.V1_2
diff --git a/src/SpaceWarp.Core/API/Mods/GlobalModDefines.cs b/src/SpaceWarp.Core/API/Mods/GlobalModDefines.cs
index 4c36ad8e..fc1a8aa5 100644
--- a/src/SpaceWarp.Core/API/Mods/GlobalModDefines.cs
+++ b/src/SpaceWarp.Core/API/Mods/GlobalModDefines.cs
@@ -1,11 +1,19 @@
-using System.IO;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Mods;
+///
+/// Global definitions for all SpaceWarp mods.
+///
[PublicAPI]
public static class GlobalModDefines
{
+ ///
+ /// Relative path to the folder containing the mod's asset bundles.
+ ///
public static readonly string AssetBundlesFolder = Path.Combine("assets", "bundles");
+ ///
+ /// Relative path to the folder containing the mod's images.
+ ///
public static readonly string ImageAssetsFolder = Path.Combine("assets", "images");
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/ISpaceWarpMod.cs b/src/SpaceWarp.Core/API/Mods/ISpaceWarpMod.cs
index c2f9d446..73351897 100644
--- a/src/SpaceWarp.Core/API/Mods/ISpaceWarpMod.cs
+++ b/src/SpaceWarp.Core/API/Mods/ISpaceWarpMod.cs
@@ -4,18 +4,43 @@
namespace SpaceWarp.API.Mods;
+///
+/// Interface for all SpaceWarp mods
+///
[PublicAPI]
public interface ISpaceWarpMod
{
+ ///
+ /// 1st stage initialization.
+ /// This is called before any of the game is actually loaded, it is called as early as possible in the game's
+ /// bootstrap process.
+ ///
public void OnPreInitialized();
+ ///
+ /// 2nd stage initialization.
+ /// This is called after the game is loaded, and after your mods assets are loaded.
+ ///
public void OnInitialized();
+ ///
+ /// 3rd stage initialization.
+ /// This is called after all mods have done 2nd stage initialization.
+ ///
public void OnPostInitialized();
+ ///
+ /// Gets the logger for this mod
+ ///
public ILogger SWLogger { get; }
+ ///
+ /// Gets the configuration file for this mod
+ ///
public IConfigFile SWConfiguration { get; }
+ ///
+ /// Gets the metadata for this mod
+ ///
public SpaceWarpPluginDescriptor SWMetadata { get; set; }
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/JSON/Converters/SpecVersionConverter.cs b/src/SpaceWarp.Core/API/Mods/JSON/Converters/SpecVersionConverter.cs
index 0b742864..ac658668 100644
--- a/src/SpaceWarp.Core/API/Mods/JSON/Converters/SpecVersionConverter.cs
+++ b/src/SpaceWarp.Core/API/Mods/JSON/Converters/SpecVersionConverter.cs
@@ -1,5 +1,4 @@
-using System;
-using Newtonsoft.Json;
+using Newtonsoft.Json;
namespace SpaceWarp.API.Mods.JSON.Converters;
diff --git a/src/SpaceWarp.Core/API/Mods/JSON/DependencyInfo.cs b/src/SpaceWarp.Core/API/Mods/JSON/DependencyInfo.cs
index f862fcd1..dd4e5954 100644
--- a/src/SpaceWarp.Core/API/Mods/JSON/DependencyInfo.cs
+++ b/src/SpaceWarp.Core/API/Mods/JSON/DependencyInfo.cs
@@ -11,7 +11,13 @@ namespace SpaceWarp.API.Mods.JSON;
[PublicAPI]
public sealed class DependencyInfo
{
+ ///
+ /// The ID of the dependency.
+ ///
[JsonProperty("id")] public string ID { get; internal set; }
+ ///
+ /// The version of the dependency.
+ ///
[JsonProperty("version")] public SupportedVersionsInfo Version { get; internal set; }
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/JSON/ModInfo.cs b/src/SpaceWarp.Core/API/Mods/JSON/ModInfo.cs
index 9a971929..6be09bda 100644
--- a/src/SpaceWarp.Core/API/Mods/JSON/ModInfo.cs
+++ b/src/SpaceWarp.Core/API/Mods/JSON/ModInfo.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using Newtonsoft.Json;
namespace SpaceWarp.API.Mods.JSON;
@@ -12,10 +10,19 @@ namespace SpaceWarp.API.Mods.JSON;
[PublicAPI]
public sealed class ModInfo
{
- [JsonProperty("spec", Required = Required.DisallowNull)] public SpecVersion Spec { get; internal set; } = new();
+ ///
+ /// The spec version of the mod info file.
+ ///
+ [JsonProperty("spec", Required = Required.DisallowNull)]
+ public SpecVersion Spec { get; internal set; } = new();
- [JsonProperty("mod_id", Required = Required.DisallowNull)] private string _modID = "";
+ [JsonProperty("mod_id", Required = Required.DisallowNull)]
+ private string _modID = "";
+ ///
+ /// The mod ID of the mod.
+ ///
+ /// Thrown when the spec version is 1.2.
public string ModID
{
get
@@ -24,31 +31,57 @@ public string ModID
{
throw new DeprecatedSwinfoPropertyException(nameof(ModID), SpecVersion.V1_2);
}
+
return _modID;
}
internal set => _modID = value;
}
-
[JsonProperty("name")]
private string _name;
+
+ ///
+ /// The name of the mod.
+ ///
public string Name
{
get => _name ?? _modID;
internal set => _name = value;
}
+ ///
+ /// The author of the mod.
+ ///
[JsonProperty("author", Required = Required.DisallowNull)]
public string Author { get; internal set; } = "";
- [JsonProperty("description", Required = Required.DisallowNull)] public string Description { get; internal set; } = "";
+ ///
+ /// The description of the mod.
+ ///
+ [JsonProperty("description", Required = Required.DisallowNull)]
+ public string Description { get; internal set; } = "";
- [JsonProperty("source", Required = Required.DisallowNull)] public string Source { get; internal set; } = "";
+ ///
+ /// The URL of the source code of the mod.
+ ///
+ [JsonProperty("source", Required = Required.DisallowNull)]
+ public string Source { get; internal set; } = "";
- [JsonProperty("version", Required = Required.Always)] public string Version { get; internal set; }
+ ///
+ /// The version of the mod.
+ ///
+ [JsonProperty("version", Required = Required.Always)]
+ public string Version { get; internal set; }
- [JsonProperty("dependencies", Required = Required.DisallowNull)] public List Dependencies { get; internal set; } = new();
+ ///
+ /// The dependencies of the mod.
+ ///
+ [JsonProperty("dependencies", Required = Required.DisallowNull)]
+ public List Dependencies { get; internal set; } = new();
+ ///
+ /// The KSP2 versions supported by the mod.
+ ///
[JsonProperty("ksp2_version", Required = Required.DisallowNull)]
public SupportedVersionsInfo SupportedKsp2Versions { get; internal set; } = new()
{
@@ -56,14 +89,29 @@ public string Name
Max = "*"
};
+ ///
+ /// The URL for the version checking of the mod.
+ ///
[JsonProperty("version_check")]
[CanBeNull]
public string VersionCheck { get; internal set; }
+ ///
+ /// The type of version checking of the mod.
+ ///
[JsonProperty("version_check_type")]
[Obsolete("Only swinfo.json version checking will be allowed in 2.0.0.")]
public VersionCheckType VersionCheckType { get; internal set; } = VersionCheckType.SwInfo;
+ ///
+ /// The conflicts of the mod.
+ ///
[JsonProperty("conflicts", Required = Required.DisallowNull)]
public List Conflicts { get; internal set; } = new();
+
+ ///
+ /// The filenames of patcher assemblies of the mod.
+ ///
+ [JsonProperty("patchers", Required = Required.DisallowNull)]
+ public List Patchers { get; internal set; } = new();
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/JSON/SpecVersion.cs b/src/SpaceWarp.Core/API/Mods/JSON/SpecVersion.cs
index aa4c00dc..1c322806 100644
--- a/src/SpaceWarp.Core/API/Mods/JSON/SpecVersion.cs
+++ b/src/SpaceWarp.Core/API/Mods/JSON/SpecVersion.cs
@@ -1,5 +1,4 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using Newtonsoft.Json;
using SpaceWarp.API.Mods.JSON.Converters;
@@ -15,7 +14,14 @@ public sealed record SpecVersion
private const int DefaultMajor = 1;
private const int DefaultMinor = 0;
+ ///
+ /// Major version number.
+ ///
public int Major { get; } = DefaultMajor;
+
+ ///
+ /// Minor version number.
+ ///
public int Minor { get; } = DefaultMinor;
// ReSharper disable InconsistentNaming
@@ -39,11 +45,18 @@ public sealed record SpecVersion
public static SpecVersion V1_3 { get; } = new(1, 3);
///
- /// Specification version 2.0 (SpaceWarp 1.5.x and 2.0.x) - removes support for version checking from .csproj files,
- ///
+ /// Specification version 2.0 (SpaceWarp 1.5 - 1.7.x) - removes support for version checking from .csproj files,
+ /// adds support for specifying mod conflicts. Switched to semantic versioning.
///
public static SpecVersion V2_0 { get; } = new(2, 0);
+ ///
+ /// Specification version 2.1 (SpaceWarp 1.8.x) - requires that mods specify their preload patchers in the
+ /// swinfo.json file.
+ ///
+ public static SpecVersion V2_1 { get; } = new(2, 1);
+
+
// ReSharper restore InconsistentNaming
///
@@ -79,14 +92,44 @@ public SpecVersion(string version = null)
Minor = minor;
}
+ ///
+ /// Returns the string representation of the version in the format "major.minor".
+ ///
+ ///
public override string ToString() => $"{Major}.{Minor}";
+ ///
+ /// Returns true if the first version is less than the second version.
+ ///
+ /// First version
+ /// Second version
+ /// True if the first version is less than the second version
public static bool operator <(SpecVersion a, SpecVersion b) => Compare(a, b) < 0;
+
+ ///
+ /// Returns true if the first version is greater than the second version.
+ ///
+ /// First version
+ /// Second version
+ /// True if the first version is greater than the second version
public static bool operator >(SpecVersion a, SpecVersion b) => Compare(a, b) > 0;
+
+ ///
+ /// Returns true if the first version is less than or equal to the second version.
+ ///
+ /// First version
+ /// Second version
+ /// True if the first version is less than or equal to the second version
public static bool operator <=(SpecVersion a, SpecVersion b) => Compare(a, b) <= 0;
+
+ ///
+ /// Returns true if the first version is greater than or equal to the second version.
+ ///
+ /// First version
+ /// Second version
+ /// True if the first version is greater than or equal to the second version
public static bool operator >=(SpecVersion a, SpecVersion b) => Compare(a, b) >= 0;
-
private static int Compare(SpecVersion a, SpecVersion b)
{
if (a.Major != b.Major)
@@ -104,6 +147,10 @@ private static int Compare(SpecVersion a, SpecVersion b)
[PublicAPI]
public sealed class InvalidSpecVersionException : Exception
{
+ ///
+ /// Creates a new InvalidSpecVersionException.
+ ///
+ /// Invalid version string
public InvalidSpecVersionException(string version) :
base($"Invalid spec version: {version}. The correct format is \"major.minor\".")
{
@@ -116,8 +163,15 @@ public InvalidSpecVersionException(string version) :
[PublicAPI]
public sealed class DeprecatedSwinfoPropertyException : Exception
{
+ ///
+ /// Creates a new DeprecatedSwinfoPropertyException.
+ ///
+ /// Deprecated property name
+ /// Specification version in which the property was deprecated
public DeprecatedSwinfoPropertyException(string property, SpecVersion deprecationVersion) :
- base($"The swinfo.json property \"{property}\" is deprecated in the spec version {deprecationVersion} and will be removed completely in the future.")
+ base(
+ $"The swinfo.json property \"{property}\" is deprecated in the spec version {deprecationVersion} and will be removed completely in the future."
+ )
{
}
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/JSON/SupportedVersionsInfo.cs b/src/SpaceWarp.Core/API/Mods/JSON/SupportedVersionsInfo.cs
index fb4e3118..faca5784 100644
--- a/src/SpaceWarp.Core/API/Mods/JSON/SupportedVersionsInfo.cs
+++ b/src/SpaceWarp.Core/API/Mods/JSON/SupportedVersionsInfo.cs
@@ -11,18 +11,40 @@ namespace SpaceWarp.API.Mods.JSON;
[PublicAPI]
public sealed class SupportedVersionsInfo
{
+ ///
+ /// The default minimum version.
+ ///
public const string DefaultMin = "0.0.0";
+
+ ///
+ /// The default maximum version.
+ ///
public const string DefaultMax = "*";
+ ///
+ /// The minimum supported version of KSP2.
+ ///
[JsonProperty("min")] public string Min { get; internal set; } = DefaultMin;
+ ///
+ /// The maximum supported version of KSP2.
+ ///
[JsonProperty("max")] public string Max { get; internal set; } = DefaultMax;
+ ///
+ /// Checks if the given version is supported by this mod.
+ ///
+ /// The version to check.
+ ///
public bool IsSupported(string toCheck)
{
return VersionUtility.IsSupported(toCheck, Min, Max);
}
+ ///
+ /// Returns a string representation of the version range.
+ ///
+ /// The string representation of the version range.
public override string ToString()
{
return $"{Min} - {Max}";
diff --git a/src/SpaceWarp.Core/API/Mods/JSON/VersionCheckType.cs b/src/SpaceWarp.Core/API/Mods/JSON/VersionCheckType.cs
index bfa1b6db..521287f4 100644
--- a/src/SpaceWarp.Core/API/Mods/JSON/VersionCheckType.cs
+++ b/src/SpaceWarp.Core/API/Mods/JSON/VersionCheckType.cs
@@ -1,18 +1,26 @@
-using System;
-using System.Runtime.Serialization;
+using System.Runtime.Serialization;
using JetBrains.Annotations;
using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace SpaceWarp.API.Mods.JSON;
+///
+/// The type of version checking to use.
+///
[JsonConverter(typeof(StringEnumConverter))]
[Obsolete("Only swinfo.json version checking will be allowed in 2.0.0.")]
[PublicAPI]
public enum VersionCheckType
{
+ ///
+ /// Use the swinfo.json file to check for updates.
+ ///
[EnumMember(Value = "swinfo")]
SwInfo,
+ ///
+ /// Use the .csproj file to check for updates.
+ ///
[EnumMember(Value = "csproj")]
Csproj
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/PluginList.cs b/src/SpaceWarp.Core/API/Mods/PluginList.cs
index 73c7f22d..c8d2e84a 100644
--- a/src/SpaceWarp.Core/API/Mods/PluginList.cs
+++ b/src/SpaceWarp.Core/API/Mods/PluginList.cs
@@ -1,13 +1,9 @@
-using System;
-using System.Collections.Generic;
-using BepInEx;
+using BepInEx;
using BepInEx.Bootstrap;
using JetBrains.Annotations;
using SpaceWarp.API.Mods.JSON;
using SpaceWarp.API.Versions;
-using SpaceWarpPatcher;
-using UnityEngine.InputSystem;
-using UnityEngine.InputSystem.Switch.LowLevel;
+using SpaceWarp.Preload.API;
// Disable obsolete warning for Chainloader.Plugins
#pragma warning disable CS0618
@@ -26,7 +22,7 @@ public static class PluginList
/// Set if the plugin list is different in any way since last run (version differences, new mods, mods removed,
/// mods disabled, description differences, any different in any swinfo file and the disabled mod list).
///
- public static bool ModListChangedSinceLastRun => ChainloaderPatch.ModListChangedSinceLastRun;
+ public static bool ModListChangedSinceLastRun => ModList.ChangedSinceLastRun;
///
/// Contains information about all currently loaded plugins. The key is the BepInEx GUID of the plugin.
@@ -36,8 +32,8 @@ public static class PluginList
///
/// Contains information about all currently disabled plugins. The key is the BepInEx GUID of the plugin.
///
- public static Dictionary DisabledPluginInfos { get; } = ChainloaderPatch
- .DisabledPluginGuids.Zip(ChainloaderPatch.DisabledPlugins, (guid, info) => new { guid, info })
+ public static Dictionary DisabledPluginInfos { get; } = ModList.DisabledPluginGuids
+ .Zip(ModList.DisabledPlugins, (guid, info) => new { guid, info })
.ToDictionary(item => item.guid, item => item.info);
///
@@ -75,12 +71,9 @@ public static int CompareVersion(string guid, Version version)
/// of the plugin or null if not found
public static ModInfo TryGetSwinfo(string guid)
{
- var swModInfo = AllEnabledAndActivePlugins
- .FirstOrDefault(item => item.Guid == guid);
-
- if (swModInfo != null)
+ if (TryGetDescriptor(guid) is { SWInfo: var swInfo })
{
- return swModInfo.SWInfo;
+ return swInfo;
}
var disabledModInfo = AllDisabledPlugins
@@ -99,8 +92,7 @@ public static ModInfo TryGetSwinfo(string guid)
/// of the plugin or null if not found
public static SpaceWarpPluginDescriptor TryGetDescriptor(string guid)
{
- return AllEnabledAndActivePlugins
- .FirstOrDefault(item => item.Guid == guid);
+ return AllEnabledAndActivePlugins.FirstOrDefault(item => item.Guid == guid);
}
///
@@ -123,41 +115,53 @@ public static T TryGetPlugin(string guid) where T : BaseUnityPlugin =>
#region Registering Plugins
- private static List _allEnabledAndActivePlugins = new();
+ private static List _allEnabledAndActivePlugins = [];
+ private static List _allDisabledPlugins = [];
+ private static List _allErroredPlugins = [];
///
- /// All plugins that are enabled, and active (not errored)
+ /// All plugins that are enabled and active (not errored)
///
public static IReadOnlyList AllEnabledAndActivePlugins => _allEnabledAndActivePlugins;
- private static List _allDisabledPlugins = new();
-
///
/// All disabled plugins
///
public static IReadOnlyList AllDisabledPlugins => _allDisabledPlugins;
- private static List _allErroredPlugins = new();
+ ///
+ /// All errored plugins
+ ///
public static IReadOnlyList AllErroredPlugins => _allErroredPlugins;
+ ///
+ /// All plugins, including disabled and errored
+ ///
public static IEnumerable AllPlugins => _allEnabledAndActivePlugins
- .Concat(_allDisabledPlugins).Concat(_allErroredPlugins.Select(x => x.Plugin));
+ .Concat(_allDisabledPlugins)
+ .Concat(_allErroredPlugins.Select(x => x.Plugin));
- public static void RegisterPlugin(SpaceWarpPluginDescriptor plugin)
+ internal static void RegisterPlugin(SpaceWarpPluginDescriptor plugin)
{
if (AllPlugins.Any(x => x.Guid == plugin.Guid))
{
- SpaceWarpPlugin.Logger.LogError($"Attempting to register a mod with a duplicate GUID: {plugin.Guid}");
+ SpaceWarpPlugin.Instance.SWLogger.LogError($"Attempting to register a mod with a duplicate GUID: {plugin.Guid}");
}
- SpaceWarpPlugin.Logger.LogInfo($"Registered plugin: {plugin.Guid}");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Registered plugin: {plugin.Guid}");
_allEnabledAndActivePlugins.Add(plugin);
}
- public static void Disable(string guid)
+ internal static void Disable(string guid)
{
- var descriptor = _allEnabledAndActivePlugins.FirstOrDefault(x =>
- string.Equals(x.Guid, guid, StringComparison.InvariantCultureIgnoreCase));
+ var descriptor = _allEnabledAndActivePlugins.FirstOrDefault(
+ x => string.Equals(
+ x.Guid,
+ guid,
+ StringComparison.InvariantCultureIgnoreCase
+ )
+ );
+
if (descriptor != null)
{
_allEnabledAndActivePlugins.Remove(descriptor);
@@ -165,9 +169,8 @@ public static void Disable(string guid)
}
}
- public static SpaceWarpErrorDescription GetErrorDescriptor(SpaceWarpPluginDescriptor plugin)
+ internal static SpaceWarpErrorDescription GetErrorDescriptor(SpaceWarpPluginDescriptor plugin)
{
-
if (_allErroredPlugins.Any(x => x.Plugin == plugin))
{
return _allErroredPlugins.First(x => x.Plugin == plugin);
@@ -183,31 +186,31 @@ public static SpaceWarpErrorDescription GetErrorDescriptor(SpaceWarpPluginDescri
return newError;
}
- public static void NoteMissingSwinfoError(SpaceWarpPluginDescriptor plugin)
+ internal static void NoteMissingSwinfoError(SpaceWarpPluginDescriptor plugin)
{
var errorDescriptor = GetErrorDescriptor(plugin);
errorDescriptor.MissingSwinfo = true;
}
- public static void NoteBadDirectoryError(SpaceWarpPluginDescriptor plugin)
+ internal static void NoteBadDirectoryError(SpaceWarpPluginDescriptor plugin)
{
var errorDescriptor = GetErrorDescriptor(plugin);
errorDescriptor.BadDirectory = true;
}
- public static void NoteBadIDError(SpaceWarpPluginDescriptor plugin)
+ internal static void NoteBadIDError(SpaceWarpPluginDescriptor plugin)
{
var errorDescriptor = GetErrorDescriptor(plugin);
errorDescriptor.BadID = true;
}
- public static void NoteMismatchedVersionError(SpaceWarpPluginDescriptor plugin)
+ internal static void NoteMismatchedVersionError(SpaceWarpPluginDescriptor plugin)
{
var errorDescriptor = GetErrorDescriptor(plugin);
errorDescriptor.MismatchedVersion = true;
}
- public static void NoteUnspecifiedDependencyError(SpaceWarpPluginDescriptor plugin, string dependency)
+ internal static void NoteUnspecifiedDependencyError(SpaceWarpPluginDescriptor plugin, string dependency)
{
var errorDescriptor = GetErrorDescriptor(plugin);
errorDescriptor.UnspecifiedDependencies.Add(dependency);
@@ -216,7 +219,7 @@ public static void NoteUnspecifiedDependencyError(SpaceWarpPluginDescriptor plug
private static SemanticVersion PadVersion(string version)
{
var length = version.Split('.').Length;
- for (var i = 0; i < 3-length; i++)
+ for (var i = 0; i < 3 - length; i++)
{
version += ".0";
}
@@ -231,7 +234,7 @@ private static bool IsSupportedSemver(string version, string min, string max)
var maxVersion = PadVersion(max.Replace("*", $"{int.MaxValue}"));
return basicVersion >= minVersion && basicVersion <= maxVersion;
}
-
+
private static bool DependencyResolved(
SpaceWarpPluginDescriptor descriptor,
List resolvedPlugins
@@ -239,10 +242,12 @@ List resolvedPlugins
{
if (descriptor.SWInfo.Spec < SpecVersion.V1_3) return true;
return !(from dependency in descriptor.SWInfo.Dependencies
- let info = resolvedPlugins.FirstOrDefault(x => string.Equals(
- x.Guid,
- dependency.ID,
- StringComparison.InvariantCultureIgnoreCase)
+ let info = resolvedPlugins.FirstOrDefault(
+ x => string.Equals(
+ x.Guid,
+ dependency.ID,
+ StringComparison.InvariantCultureIgnoreCase
+ )
)
where info == null || !IsSupportedSemver(
info.SWInfo.Version,
@@ -271,10 +276,13 @@ private static void GetLoadOrder()
for (var i = _allEnabledAndActivePlugins.Count - 1; i >= 0; i--)
{
var info = _allEnabledAndActivePlugins[i];
- SpaceWarpPlugin.Logger.LogError($"Missing dependency for mod: {info.Name}, this mod will not be loaded");
+ SpaceWarpPlugin.Instance.SWLogger.LogError($"Missing dependency for mod: {info.Name}, this mod will not be loaded");
var error = GetErrorDescriptor(info);
- error.MissingDependencies = info.SWInfo.Dependencies.Select(x => x.ID).Where(x =>
- !newOrder.Any(y => string.Equals(x, y.Guid, StringComparison.InvariantCultureIgnoreCase))).ToList();
+ error.MissingDependencies = info.SWInfo
+ .Dependencies
+ .Select(x => x.ID)
+ .Where(x => !newOrder.Any(y => string.Equals(x, y.Guid, StringComparison.InvariantCultureIgnoreCase)))
+ .ToList();
}
_allEnabledAndActivePlugins = newOrder;
@@ -282,8 +290,9 @@ private static void GetLoadOrder()
private static void GetDependencyErrors()
{
- foreach (var erroredPlugin in _allErroredPlugins.Where(erroredPlugin =>
- erroredPlugin.MissingDependencies.Count != 0))
+ foreach (var erroredPlugin in _allErroredPlugins.Where(
+ erroredPlugin => erroredPlugin.MissingDependencies.Count != 0
+ ))
{
for (var i = erroredPlugin.MissingDependencies.Count - 1; i >= 0; i--)
{
@@ -312,19 +321,30 @@ private static void GetDependencyErrors()
private static void CheckCompatibility()
{
- var incompatibilities = _allEnabledAndActivePlugins.Select(x => (Key: x.Guid, Value: new HashSet()))
+ var incompatibilities = _allEnabledAndActivePlugins
+ .Select(x => (Key: x.Guid, Value: new HashSet()))
.ToDictionary(x => x.Key, x => x.Value);
- var versionLookup = _allEnabledAndActivePlugins.Select(x => (Key: x.Guid, Value: x.SWInfo.Version))
+ var versionLookup = _allEnabledAndActivePlugins
+ .Select(x => (Key: x.Guid, Value: x.SWInfo.Version))
.ToDictionary(x => x.Key, x => x.Value);
- var pluginDictionary = _allEnabledAndActivePlugins.ToDictionary(x => x.Guid, x => x);
+ var pluginDictionary = _allEnabledAndActivePlugins
+ .ToDictionary(x => x.Guid, x => x);
foreach (var mod in _allEnabledAndActivePlugins)
{
var swinfo = mod.SWInfo;
- if (swinfo.Spec < SpecVersion.V2_0) continue;
+ if (swinfo.Spec < SpecVersion.V2_0)
+ {
+ continue;
+ }
+
foreach (var conflict in swinfo.Conflicts)
{
if (!versionLookup.TryGetValue(conflict.ID, out var conflictingVersion) ||
- !IsSupportedSemver(conflictingVersion, conflict.Version.Min, conflict.Version.Max)) continue;
+ !IsSupportedSemver(conflictingVersion, conflict.Version.Min, conflict.Version.Max))
+ {
+ continue;
+ }
+
incompatibilities[mod.Guid].Add(conflict.ID);
incompatibilities[conflict.ID].Add(mod.Guid);
}
@@ -332,7 +352,11 @@ private static void CheckCompatibility()
foreach (var incompatibility in incompatibilities)
{
- if (incompatibility.Value.Count <= 0) continue;
+ if (incompatibility.Value.Count <= 0)
+ {
+ continue;
+ }
+
var descriptor = GetErrorDescriptor(pluginDictionary[incompatibility.Key]);
descriptor.Incompatibilities.AddRange(incompatibility.Value);
}
diff --git a/src/SpaceWarp.Core/API/Mods/SpaceWarpErrorDescription.cs b/src/SpaceWarp.Core/API/Mods/SpaceWarpErrorDescription.cs
index 22456c09..5670ff80 100644
--- a/src/SpaceWarp.Core/API/Mods/SpaceWarpErrorDescription.cs
+++ b/src/SpaceWarp.Core/API/Mods/SpaceWarpErrorDescription.cs
@@ -1,27 +1,74 @@
-using System.Collections.Generic;
-using BepInEx;
+using BepInEx;
using JetBrains.Annotations;
-using SpaceWarp.Patching;
-using UnityEngine;
+using SpaceWarp.Patching.Flow;
namespace SpaceWarp.API.Mods;
+///
+/// This class is used to describe the errors that occur when loading a plugin
+///
[PublicAPI]
public class SpaceWarpErrorDescription
{
+ ///
+ /// The plugin that errored
+ ///
public SpaceWarpPluginDescriptor Plugin;
+
+ ///
+ /// Whether the plugin is missing a swinfo file
+ ///
public bool MissingSwinfo;
+
+ ///
+ /// Whether the plugin is in the wrong directory
+ ///
public bool BadDirectory;
+
+ ///
+ /// Whether the plugin has a bad ID
+ ///
public bool BadID;
+
+ ///
+ /// Whether there's a version mismatch between the swinfo and the plugin
+ ///
public bool MismatchedVersion;
+ ///
+ /// List of dependencies that are disabled
+ ///
public List DisabledDependencies = new();
+
+ ///
+ /// List of dependencies that errored
+ ///
public List ErroredDependencies = new();
+
+ ///
+ /// List of dependencies that are missing
+ ///
public List MissingDependencies = new();
+
+ ///
+ /// List of dependencies that are unsupported
+ ///
public List UnsupportedDependencies = new();
+
+ ///
+ /// List of dependencies that are unspecified
+ ///
public List UnspecifiedDependencies = new();
+
+ ///
+ /// List of incompatibilities
+ ///
public List Incompatibilities = new();
+ ///
+ /// Creates a new error description for a plugin
+ ///
+ /// The plugin that errored
public SpaceWarpErrorDescription(SpaceWarpPluginDescriptor plugin)
{
Plugin = plugin;
@@ -43,5 +90,4 @@ public SpaceWarpErrorDescription(SpaceWarpPluginDescriptor plugin)
}
plugin.Plugin = null;
}
-
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Mods/SpaceWarpPluginDescriptor.cs b/src/SpaceWarp.Core/API/Mods/SpaceWarpPluginDescriptor.cs
index fdf7edfb..31e6b2e9 100644
--- a/src/SpaceWarp.Core/API/Mods/SpaceWarpPluginDescriptor.cs
+++ b/src/SpaceWarp.Core/API/Mods/SpaceWarpPluginDescriptor.cs
@@ -1,13 +1,25 @@
-using System.IO;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using SpaceWarp.API.Configuration;
using SpaceWarp.API.Mods.JSON;
namespace SpaceWarp.API.Mods;
+///
+/// A descriptor for a SpaceWarp plugin.
+///
[PublicAPI]
public class SpaceWarpPluginDescriptor
{
+ ///
+ /// Creates a new plugin descriptor.
+ ///
+ /// The plugin instance.
+ /// The plugin's GUID.
+ /// The plugin's name.
+ /// The plugin's swinfo.
+ /// The plugin's folder.
+ /// Whether or not to do loading actions.
+ /// The plugin's config file.
public SpaceWarpPluginDescriptor(
[CanBeNull] ISpaceWarpMod plugin,
string guid,
@@ -27,19 +39,53 @@ public SpaceWarpPluginDescriptor(
ConfigFile = configFile;
}
+ ///
+ /// The plugin instance.
+ ///
[CanBeNull] public ISpaceWarpMod Plugin;
+
+ ///
+ /// The plugin's GUID.
+ ///
public readonly string Guid;
+
+ ///
+ /// The plugin's name.
+ ///
public readonly string Name;
+
+ ///
+ /// The plugin's swinfo.
+ ///
public readonly ModInfo SWInfo;
+
+ ///
+ /// The plugin's folder.
+ ///
public readonly DirectoryInfo Folder;
+
+ ///
+ /// Whether or not to do loading actions.
+ ///
public bool DoLoadingActions;
+
+ ///
+ /// The plugin's config file.
+ ///
[CanBeNull] public IConfigFile ConfigFile;
- // Set by the version checking system
+ ///
+ /// Whether or not the plugin is outdated. Set by the version checking system.
+ ///
public bool Outdated;
- public bool Unsupported = false;
+ ///
+ /// Whether or not the plugin is unsupported.
+ ///
+ public bool Unsupported;
- // Used to check for mods that have not been pre-initialized
+ ///
+ /// Whether or not the plugin has been pre-initialized yet.
+ ///
public bool LatePreInitialize;
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Parts/Colors.cs b/src/SpaceWarp.Core/API/Parts/Colors.cs
index 752bb847..6ef376ae 100644
--- a/src/SpaceWarp.Core/API/Parts/Colors.cs
+++ b/src/SpaceWarp.Core/API/Parts/Colors.cs
@@ -1,51 +1,52 @@
-using System;
-using System.Collections.Generic;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using SpaceWarp.API.Lua;
-using SpaceWarp.Patching;
+using SpaceWarp.Patching.Parts;
using UnityEngine;
namespace SpaceWarp.API.Parts;
+///
+/// API for allowing modded parts to be colored.
+///
[SpaceWarpLuaAPI("Colors")]
[PublicAPI]
public static class Colors
{
///
- /// Key is ModGUID.
- /// Value is list of strings containing the partNames.
- /// Only parts in this list will be modified.
+ /// Key is ModGUID.
+ /// Value is list of strings containing the partNames.
+ /// Only parts in this list will be modified.
///
- [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead")]
+ [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead. Will be removed in 2.0.0.")]
public static Dictionary DeclaredParts => new();
///
- /// Adds to internal parts list under
- /// allowing them to have the patch applied.
+ /// Adds to internal parts list under
+ /// allowing them to have the patch applied.
///
/// guid of the mod that owns the parts.
///
- /// Collection of partNames. Names that end in XS, S, M, L or XL will be counted as the same
- /// part,
- /// Example: partNameS, partNameM, partNameL, partNameXL are all treated as partName
+ /// Collection of partNames. Names that end in XS, S, M, L or XL will be counted as the same
+ /// part,
+ /// Example: partNameS, partNameM, partNameL, partNameXL are all treated as partName
///
- [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead")]
+ [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead. Will be removed in 2.0.0.")]
public static void DeclareParts(string modGuid, params string[] partNameList)
{
ColorsPatch.DeclareParts(modGuid, partNameList);
}
///
- /// Adds to internal parts list under
- /// allowing them to have the patch applied.
+ /// Adds to internal parts list under
+ /// allowing them to have the patch applied.
///
/// guid of the mod that owns the parts.
///
- /// Collection of partNames. Names that end in XS, S, M, L or XL will be counted as the same
- /// part.
- /// Example: partNameS, partNameM, partNameL, partNameXL are all treated as partName
+ /// Collection of partNames. Names that end in XS, S, M, L or XL will be counted as the same
+ /// part.
+ /// Example: partNameS, partNameM, partNameL, partNameXL are all treated as partName
///
- [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead")]
+ [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead. Will be removed in 2.0.0.")]
public static void DeclareParts(string modGuid, IEnumerable partNameList)
{
ColorsPatch.DeclareParts(modGuid, partNameList);
@@ -54,7 +55,7 @@ public static void DeclareParts(string modGuid, IEnumerable partNameList
/// Retrieves all the texture list from your part. Textures not set will be null.
///
/// Name of the part as described in the .json.
- ///
- [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead")]
+ /// Array of textures.
+ [Obsolete("Use the shader \"KSP2/Parts/Paintable\" or \"Parts Replace\" instead. Will be removed in 2.0.0.")]
public static Texture[] GetTextures(string partName) => Array.Empty();
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs b/src/SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs
index 5cfb02d6..e32bbaf2 100644
--- a/src/SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs
+++ b/src/SpaceWarp.Core/API/Parts/PartComponentModuleOverride.cs
@@ -1,14 +1,14 @@
using JetBrains.Annotations;
using KSP.Sim.impl;
-using SpaceWarp.API.Logging;
namespace SpaceWarp.API.Parts;
+///
+/// This class allows you to register your custom PartComponentModule for background resource processing.
+///
[PublicAPI]
public static class PartComponentModuleOverride
{
- private static readonly ILogger _LOGGER = new UnityLogSource("SpaceWarp.PartComponentModuleOverride");
-
internal static List RegisteredPartComponentOverrides = new();
///
@@ -22,11 +22,14 @@ public static void RegisterModuleForBackgroundResourceProcessing() where T :
// Check if this Module is already registered
if (RegisteredPartComponentOverrides.Contains(typeof(T)))
{
- throw new ArgumentException($"Module '{moduleName}' is already registered. Skipping.", nameof(T));
+ throw new ArgumentException(
+ $"Background resource processing for module '{moduleName}' is already registered. Skipping.",
+ nameof(T)
+ );
}
RegisteredPartComponentOverrides.Add(typeof(T));
- _LOGGER.LogInfo($"Registered '{moduleName}' for background resources processing.");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Registered '{moduleName}' for background resources processing.");
}
///
@@ -35,9 +38,12 @@ public static void RegisterModuleForBackgroundResourceProcessing() where T :
/// Your Custom Module class that inherits from PartComponentModule
public static void UnRegisterModuleForBackgroundResourceProcessing() where T : PartComponentModule
{
- if (!RegisteredPartComponentOverrides.Contains(typeof(T))) return;
+ if (!RegisteredPartComponentOverrides.Contains(typeof(T)))
+ {
+ return;
+ }
RegisteredPartComponentOverrides.Remove(typeof(T));
- _LOGGER.LogInfo($"Unregistered '{typeof(T).Name}' from background resources processing.");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Unregistered '{typeof(T).Name}' from background resources processing.");
}
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/SaveGameManager/ModSaves.cs b/src/SpaceWarp.Core/API/SaveGameManager/ModSaves.cs
index 792d0ee1..baae6cbc 100644
--- a/src/SpaceWarp.Core/API/SaveGameManager/ModSaves.cs
+++ b/src/SpaceWarp.Core/API/SaveGameManager/ModSaves.cs
@@ -1,28 +1,43 @@
using JetBrains.Annotations;
using SpaceWarp.Backend.SaveGameManager;
-using System;
-using System.Collections.Generic;
-using SpaceWarp.API.Logging;
namespace SpaceWarp.API.SaveGameManager;
+///
+/// This class allows you to register your mod data for the game's save file system .
+///
[PublicAPI]
public static class ModSaves
{
- private static readonly ILogger Logger = new UnityLogSource("SpaceWarp.ModSaves");
-
internal static List InternalPluginSaveData = new();
///
/// Registers your mod data for saving and loading events.
///
/// Any object
- /// Your mod GUID. Or, technically, any kind of string can be passed here, but what is mandatory is that it's unique compared to what other mods will use.
- /// Function that will execute when a SAVE event is triggered. Defaults to null or no callback.
- /// Function that will execute when a LOAD event is triggered. Defaults to null or no callback.
- /// Your object that will be saved to a save file during a save event and that will be updated when a load event pulls new data. Ensure that a new instance of this object is NOT created after registration.
- /// T saveData object you passed as a parameter, or a default instance of object T if you didn't pass anything
- public static T RegisterSaveLoadGameData(string modGuid, Action onSave = null, Action onLoad = null, T saveData = default)
+ ///
+ /// Your mod GUID. Or, technically, any kind of string can be passed here, but what is mandatory is that it's unique
+ /// compared to what other mods will use.
+ ///
+ ///
+ /// Function that will execute when a SAVE event is triggered. Defaults to null or no callback.
+ ///
+ ///
+ /// Function that will execute when a LOAD event is triggered. Defaults to null or no callback.
+ ///
+ ///
+ /// Your object that will be saved to a save file during a save event and that will be updated when a load event
+ /// pulls new data. Ensure that a new instance of this object is NOT created after registration.
+ ///
+ ///
+ /// T saveData object you passed as a parameter, or a default instance of object T if you didn't pass anything
+ ///
+ public static T RegisterSaveLoadGameData(
+ string modGuid,
+ Action onSave = null,
+ Action onLoad = null,
+ T saveData = default
+ ) where T : class
{
// Check if this GUID is already registered
if (InternalPluginSaveData.Find(p => p.ModGuid == modGuid) != null)
@@ -32,10 +47,18 @@ public static T RegisterSaveLoadGameData(string modGuid, Action onSave = n
saveData ??= Activator.CreateInstance();
- InternalPluginSaveData.Add(new PluginSaveData { ModGuid = modGuid, SaveEventCallback = SaveCallbackAdapter, LoadEventCallback = LoadCallbackAdapter, SaveData = saveData });
- Logger.LogInfo($"Registered '{modGuid}' for save/load events.");
+ InternalPluginSaveData.Add(new PluginSaveData
+ {
+ ModGuid = modGuid,
+ SaveEventCallback = SaveCallbackAdapter,
+ LoadEventCallback = LoadCallbackAdapter,
+ SaveData = saveData
+ });
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Registered '{modGuid}' for save/load events.");
return saveData;
+ // Create adapter functions to convert Action to CallbackFunctionDelegate
+
void LoadCallbackAdapter(object dataToBeLoaded)
{
if (onLoad != null && dataToBeLoaded is T data)
@@ -44,7 +67,6 @@ void LoadCallbackAdapter(object dataToBeLoaded)
}
}
- // Create adapter functions to convert Action to CallbackFunctionDelegate
void SaveCallbackAdapter(object dataToBeSaved)
{
if (onSave != null && dataToBeSaved is T data)
@@ -55,7 +77,8 @@ void SaveCallbackAdapter(object dataToBeSaved)
}
///
- /// Unregister your previously registered mod data for saving and loading. Use this if you no longer need your data to be saved and loaded.
+ /// Unregister your previously registered mod data for saving and loading. Use this if you no longer need your data
+ /// to be saved and loaded.
///
/// Your mod GUID you used when registering.
public static void UnRegisterSaveLoadGameData(string modGuid)
@@ -63,21 +86,39 @@ public static void UnRegisterSaveLoadGameData(string modGuid)
var toRemove = InternalPluginSaveData.Find(p => p.ModGuid == modGuid);
if (toRemove == null) return;
InternalPluginSaveData.Remove(toRemove);
- Logger.LogInfo($"Unregistered '{modGuid}' for save/load events.");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Unregistered '{modGuid}' for save/load events.");
}
///
/// Unregisters then again registers your mod data for saving and loading events
///
- /// Any object
- /// Your mod GUID. Or, technically, any kind of string can be passed here, but what is mandatory is that it's unique compared to what other mods will use.
- /// Function that will execute when a SAVE event is triggered. Defaults to null or no callback.
- /// Function that will execute when a LOAD event is triggered. Defaults to null or no callback.
- /// Your object that will be saved to a save file during a save event and that will be updated when a load event pulls new data. Ensure that a new instance of this object is NOT created after registration.
- /// T saveData object you passed as a parameter, or a default instance of object T if you didn't pass anything
- public static T ReregisterSaveLoadGameData(string modGuid, Action onSave = null, Action onLoad = null, T saveData = default(T))
+ /// The type of your save data
+ ///
+ /// Your mod GUID. Or, technically, any kind of string can be passed here, but what is mandatory is that it's unique
+ /// compared to what other mods will use.
+ ///
+ ///
+ /// Function that will execute when a SAVE event is triggered. Defaults to null or no callback.
+ ///
+ ///
+ /// Function that will execute when a LOAD event is triggered. Defaults to null or no callback.
+ ///
+ ///
+ /// Your object that will be saved to a save file during a save event and that will be
+ /// updated when a load event pulls new data. Ensure that a new instance of this object is NOT created after
+ /// registration.
+ ///
+ ///
+ /// T saveData object you passed as a parameter, or a default instance of object T if you didn't pass anything
+ ///
+ public static T ReregisterSaveLoadGameData(
+ string modGuid,
+ Action onSave = null,
+ Action onLoad = null,
+ T saveData = default
+ ) where T : class
{
UnRegisterSaveLoadGameData(modGuid);
return RegisterSaveLoadGameData(modGuid, onSave, onLoad, saveData);
}
-}
+}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/API/Versions/SemanticVersion.cs b/src/SpaceWarp.Core/API/Versions/SemanticVersion.cs
index ea45be74..bb51a7e9 100644
--- a/src/SpaceWarp.Core/API/Versions/SemanticVersion.cs
+++ b/src/SpaceWarp.Core/API/Versions/SemanticVersion.cs
@@ -1,5 +1,4 @@
-using System;
-using System.Collections.Generic;
+
// Disable warnings for missing Equals and GetHashCode implementations
#pragma warning disable CS0660, CS0661
diff --git a/src/SpaceWarp.Core/API/Versions/VersionUtility.cs b/src/SpaceWarp.Core/API/Versions/VersionUtility.cs
index b6f9b2a3..dfe0e777 100644
--- a/src/SpaceWarp.Core/API/Versions/VersionUtility.cs
+++ b/src/SpaceWarp.Core/API/Versions/VersionUtility.cs
@@ -1,9 +1,11 @@
-using System;
-using System.Text.RegularExpressions;
+using System.Text.RegularExpressions;
using JetBrains.Annotations;
namespace SpaceWarp.API.Versions;
+///
+/// Utility class for comparing semantic versions
+///
[PublicAPI]
public static class VersionUtility
{
@@ -29,6 +31,13 @@ public static bool IsOlderThan(string version1, string version2)
return CompareSemanticVersionStrings(version1, version2) < 0;
}
+ ///
+ /// Checks if a semantic version is supported by a range of versions
+ ///
+ /// The version to check
+ /// The minimum version
+ /// The maximum version
+ ///
public static bool IsSupported(string version, string min, string max)
{
return !IsOlderThan(version, min) && !IsNewerThan(version, max);
@@ -120,7 +129,7 @@ private static int ComparePrereleaseSemanticVersions(string version1, string ver
alphaVersionNumber1 = int.Parse(number.Value);
alphaVersionName1 = name.Value;
}
-
+
if (_prereleaseVersion.IsMatch(alphaVersion2))
{
var match = _prereleaseVersion.Match(alphaVersion2);
@@ -131,20 +140,21 @@ private static int ComparePrereleaseSemanticVersions(string version1, string ver
}
var comparison = string.CompareOrdinal(alphaVersionName1, alphaVersionName2);
- if (comparison == 0)
+ if (comparison != 0)
{
- if (alphaVersionNumber1 > alphaVersionNumber2)
- {
- return 1;
- } else if (alphaVersionNumber1 == alphaVersionNumber2)
- {
- return 0;
- }
- else
- {
- return -1;
- }
+ return comparison;
}
- return comparison;
+
+ if (alphaVersionNumber1 > alphaVersionNumber2)
+ {
+ return 1;
+ }
+
+ if (alphaVersionNumber1 == alphaVersionNumber2)
+ {
+ return 0;
+ }
+
+ return -1;
}
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Backend/Modding/BepInExModAdapter.cs b/src/SpaceWarp.Core/Backend/Modding/BepInExModAdapter.cs
index 84f61bda..44117635 100644
--- a/src/SpaceWarp.Core/Backend/Modding/BepInExModAdapter.cs
+++ b/src/SpaceWarp.Core/Backend/Modding/BepInExModAdapter.cs
@@ -5,14 +5,16 @@
namespace SpaceWarp.Backend.Modding;
-public class BepInExModAdapter : ISpaceWarpMod
+internal class BepInExModAdapter : ISpaceWarpMod
{
public readonly BaseUnityPlugin Plugin;
+ ///
public void OnPreInitialized()
{
}
+ ///
public void OnInitialized()
{
}
diff --git a/src/SpaceWarp.Core/Backend/Modding/Ksp2ModInfo.cs b/src/SpaceWarp.Core/Backend/Modding/Ksp2ModInfo.cs
index d8615dd9..25610c2d 100644
--- a/src/SpaceWarp.Core/Backend/Modding/Ksp2ModInfo.cs
+++ b/src/SpaceWarp.Core/Backend/Modding/Ksp2ModInfo.cs
@@ -1,43 +1,48 @@
-using System;
-using Newtonsoft.Json;
+using Newtonsoft.Json;
using Newtonsoft.Json.Converters;
namespace SpaceWarp.Backend.Modding;
+///
+/// Represents the KSP2 mod info file used by the internal loader.
+///
public class Ksp2ModInfo
{
+ ///
+ /// The API version of the mod.
+ ///
[JsonConverter(typeof(VersionConverter))]
[JsonProperty]
public Version APIVersion { get; private set; }
- // Token: 0x17001C93 RID: 7315
- // (get) Token: 0x06008070 RID: 32880 RVA: 0x001EE0B9 File Offset: 0x001EC2B9
- // (set) Token: 0x06008071 RID: 32881 RVA: 0x001EE0C1 File Offset: 0x001EC2C1
+ ///
+ /// The version of the mod.
+ ///
[JsonConverter(typeof(VersionConverter))]
[JsonProperty]
public Version ModVersion { get; private set; }
- // Token: 0x17001C94 RID: 7316
- // (get) Token: 0x06008072 RID: 32882 RVA: 0x001EE0CA File Offset: 0x001EC2CA
- // (set) Token: 0x06008073 RID: 32883 RVA: 0x001EE0D2 File Offset: 0x001EC2D2
+ ///
+ /// The name of the mod.
+ ///
[JsonProperty]
public string ModName { get; private set; }
- // Token: 0x17001C95 RID: 7317
- // (get) Token: 0x06008074 RID: 32884 RVA: 0x001EE0DB File Offset: 0x001EC2DB
- // (set) Token: 0x06008075 RID: 32885 RVA: 0x001EE0E3 File Offset: 0x001EC2E3
+ ///
+ /// The author of the mod.
+ ///
[JsonProperty]
public string ModAuthor { get; private set; }
- // Token: 0x17001C96 RID: 7318
- // (get) Token: 0x06008076 RID: 32886 RVA: 0x001EE0EC File Offset: 0x001EC2EC
- // (set) Token: 0x06008077 RID: 32887 RVA: 0x001EE0F4 File Offset: 0x001EC2F4
+ ///
+ /// The description of the mod.
+ ///
[JsonProperty]
public string ModDescription { get; private set; }
- // Token: 0x17001C97 RID: 7319
- // (get) Token: 0x06008078 RID: 32888 RVA: 0x001EE0FD File Offset: 0x001EC2FD
- // (set) Token: 0x06008079 RID: 32889 RVA: 0x001EE105 File Offset: 0x001EC305
+ ///
+ /// The addressables catalog file of the mod.
+ ///
[JsonProperty]
public string Catalog { get; private set; }
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Backend/Modding/PluginRegister.cs b/src/SpaceWarp.Core/Backend/Modding/PluginRegister.cs
index 88d24c1c..1bde7b06 100644
--- a/src/SpaceWarp.Core/Backend/Modding/PluginRegister.cs
+++ b/src/SpaceWarp.Core/Backend/Modding/PluginRegister.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Text.RegularExpressions;
-using BepInEx;
+using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using Newtonsoft.Json;
@@ -11,7 +7,7 @@
using SpaceWarp.API.Mods;
using SpaceWarp.API.Mods.JSON;
using SpaceWarp.API.Versions;
-using SpaceWarpPatcher;
+using SpaceWarp.Preload.API;
namespace SpaceWarp.Backend.Modding;
@@ -27,7 +23,7 @@ public static void RegisterAllMods()
DisableMods();
}
- private static ILogger Logger = (BepInExLogger)SpaceWarpPlugin.Logger;
+ private static readonly ILogger Logger = SpaceWarpPlugin.Instance.SWLogger;
private static ModInfo BepInExToSWInfo(PluginInfo plugin)
{
@@ -55,7 +51,6 @@ private static ModInfo BepInExToSWInfo(PluginInfo plugin)
Max = "*"
},
VersionCheck = null,
- VersionCheckType = VersionCheckType.SwInfo,
Conflicts = plugin.Incompatibilities.Select(x => new DependencyInfo
{
ID = x.IncompatibilityGUID,
@@ -74,7 +69,9 @@ private static bool AssertFolderPath(BaseSpaceWarpPlugin plugin, string folderPa
if (Path.GetFileName(folderPath) != "plugins") return true;
Logger.LogError(
- $"Found Space Warp mod {plugin.Info.Metadata.Name} in the BepInEx/plugins directory. This mod will not be initialized.");
+ $"Found Space Warp mod {plugin.Info.Metadata.Name} in the BepInEx/plugins directory. This mod will " +
+ $"not be initialized."
+ );
var descriptor = new SpaceWarpPluginDescriptor(
plugin,
@@ -86,25 +83,38 @@ private static bool AssertFolderPath(BaseSpaceWarpPlugin plugin, string folderPa
new BepInExConfigFile(plugin.Config)
);
PluginList.NoteBadDirectoryError(descriptor);
+
return false;
}
private static bool AssertModInfoExistence(BaseSpaceWarpPlugin plugin, string modInfoPath, string folderPath)
{
- if (File.Exists(modInfoPath)) return true;
+ if (File.Exists(modInfoPath))
+ {
+ return true;
+ }
Logger.LogError(
- $"Found Space Warp plugin {plugin.Info.Metadata.Name} without a swinfo.json next to it. This mod will not be initialized.");
+ $"Found Space Warp plugin {plugin.Info.Metadata.Name} without a swinfo.json in its folder. This mod " +
+ $"will not be initialized."
+ );
+
PluginList.NoteMissingSwinfoError(new SpaceWarpPluginDescriptor(plugin,
plugin.Info.Metadata.GUID,
plugin.Info.Metadata.Name,
BepInExToSWInfo(plugin.Info),
- new DirectoryInfo(folderPath)));
+ new DirectoryInfo(folderPath))
+ );
+
return false;
}
- private static bool TryReadModInfo(BaseUnityPlugin plugin,
- string modInfoPath, string folderPath, out ModInfo metadata)
+ private static bool TryReadModInfo(
+ BaseUnityPlugin plugin,
+ string modInfoPath,
+ string folderPath,
+ out ModInfo metadata
+ )
{
try
{
@@ -131,22 +141,19 @@ private static bool TryReadModInfo(BaseUnityPlugin plugin,
private static bool AssertSpecificationCompliance(
SpaceWarpPluginDescriptor descriptor,
BaseUnityPlugin plugin,
- ModInfo metadata,
- string folderPath
+ ModInfo metadata
) => metadata.Spec < SpecVersion.V1_3 || AssertSpecVersion13Compliance(
descriptor,
plugin,
- metadata,
- folderPath
+ metadata
);
private static bool AssertSpecVersion13Compliance(
SpaceWarpPluginDescriptor descriptor,
BaseUnityPlugin plugin,
- ModInfo metadata,
- string folderPath
- ) => AssertMatchingModID(descriptor, plugin, metadata, folderPath) &&
- AssertMatchingVersions(descriptor, plugin, metadata, folderPath) &&
+ ModInfo metadata
+ ) => AssertMatchingModID(descriptor, plugin, metadata) &&
+ AssertMatchingVersions(descriptor, plugin, metadata) &&
AssertAllDependenciesAreSpecified(descriptor, plugin, metadata);
private static bool AssertAllDependenciesAreSpecified(
@@ -165,12 +172,19 @@ private static bool AssertDependencyIsSpecified(
ModInfo metadata
)
{
- if (metadata.Dependencies.Any(
- x => string.Equals(x.ID, dep.DependencyGUID, StringComparison.InvariantCultureIgnoreCase))
- ) return true;
+ if (metadata.Dependencies.Any(x => string.Equals(
+ x.ID,
+ dep.DependencyGUID,
+ StringComparison.InvariantCultureIgnoreCase
+ )))
+ {
+ return true;
+ }
Logger.LogError(
- $"Found Space Warp Plugin {plugin.Info.Metadata.Name} that has an unspecified swinfo dependency found in its BepInDependencies: {dep.DependencyGUID}");
+ $"Found Space Warp Plugin {plugin.Info.Metadata.Name} that has an unspecified swinfo dependency found " +
+ $"in its BepInDependencies: {dep.DependencyGUID}"
+ );
PluginList.NoteUnspecifiedDependencyError(descriptor, dep.DependencyGUID);
metadata.Dependencies.Add(new DependencyInfo
{
@@ -187,21 +201,22 @@ ModInfo metadata
private static string ClearPrerelease(string version)
{
var semver = new SemanticVersion(version);
- return
- $"{semver.Major}.{semver.Minor}.{semver.Patch}{(semver.VersionNumbers.Count > 3 ? $".{semver.VersionNumbers[3]}" : "")}";
+ return $"{semver.Major}.{semver.Minor}.{semver.Patch}" +
+ $"{(semver.VersionNumbers.Count > 3 ? $".{semver.VersionNumbers[3]}" : "")}";
}
private static bool AssertMatchingVersions(
SpaceWarpPluginDescriptor descriptor,
BaseUnityPlugin plugin,
- ModInfo metadata,
- string folderPath
+ ModInfo metadata
)
{
if (new Version(ClearPrerelease(metadata.Version)) == plugin.Info.Metadata.Version) return true;
Logger.LogError(
- $"Found Space Warp plugin {plugin.Info.Metadata.Name} that's swinfo version ({metadata.Version}) does not match the plugin version ({plugin.Info.Metadata.Version}), this mod will not be initialized");
+ $"Found Space Warp plugin {plugin.Info.Metadata.Name} that's swinfo version ({metadata.Version}) does " +
+ $"not match the plugin version ({plugin.Info.Metadata.Version}), this mod will not be initialized"
+ );
PluginList.NoteMismatchedVersionError(descriptor);
return false;
}
@@ -209,15 +224,16 @@ string folderPath
private static bool AssertMatchingModID(
SpaceWarpPluginDescriptor descriptor,
BaseUnityPlugin plugin,
- ModInfo metadata,
- string folderPath
+ ModInfo metadata
)
{
var modID = metadata.ModID;
if (modID == plugin.Info.Metadata.GUID) return true;
Logger.LogError(
- $"Found Space Warp plugin {plugin.Info.Metadata.Name} that has an swinfo.json w/ spec version >= 1.3 that's ModID is not the same as the plugins GUID, This mod will not be initialized.");
+ $"Found SpaceWarp plugin {plugin.Info.Metadata.Name} that has a swinfo.json file with spec version >=" +
+ $" 1.3 whose ModID is not the same as the plugin's GUID. This mod will not be initialized."
+ );
PluginList.NoteBadIDError(descriptor);
return false;
}
@@ -225,16 +241,34 @@ string folderPath
private static void RegisterSingleSpaceWarpPlugin(BaseSpaceWarpPlugin plugin)
{
var folderPath = Path.GetDirectoryName(plugin.Info.Location);
+
+#pragma warning disable CS0618 // Type or member is obsolete
+ // TODO: Remove this in 2.0
plugin.PluginFolderPath = folderPath;
- if (!AssertFolderPath(plugin, folderPath)) return;
+#pragma warning restore CS0618 // Type or member is obsolete
+
+ if (!AssertFolderPath(plugin, folderPath))
+ {
+ return;
+ }
var modInfoPath = Path.Combine(folderPath!, "swinfo.json");
- if (!AssertModInfoExistence(plugin, modInfoPath, folderPath)) return;
+ if (!AssertModInfoExistence(plugin, modInfoPath, folderPath))
+ {
+ return;
+ }
- if (!TryReadModInfo(plugin, modInfoPath, folderPath, out var metadata)) return;
+ if (!TryReadModInfo(plugin, modInfoPath, folderPath, out var metadata))
+ {
+ return;
+ }
+#pragma warning disable CS0618 // Type or member is obsolete
+ // TODO: Remove this in 2.0
plugin.SpaceWarpMetadata = metadata;
+#pragma warning restore CS0618 // Type or member is obsolete
+
var directoryInfo = new FileInfo(modInfoPath).Directory;
var descriptor = new SpaceWarpPluginDescriptor(
plugin,
@@ -246,7 +280,10 @@ private static void RegisterSingleSpaceWarpPlugin(BaseSpaceWarpPlugin plugin)
new BepInExConfigFile(plugin.Config)
);
descriptor.Plugin!.SWMetadata = descriptor;
- if (!AssertSpecificationCompliance(descriptor, plugin, metadata, folderPath)) return;
+ if (!AssertSpecificationCompliance(descriptor, plugin, metadata))
+ {
+ return;
+ }
PluginList.RegisterPlugin(descriptor);
}
@@ -263,7 +300,11 @@ private static void RegisterSingleBepInExPlugin(BaseUnityPlugin plugin)
var directoryInfo = new DirectoryInfo(Path.GetDirectoryName(plugin.Info.Location)!);
if (File.Exists(modInfoPath))
{
- if (!TryReadModInfo(plugin, modInfoPath, folderPath, out var metadata)) return;
+ if (!TryReadModInfo(plugin, modInfoPath, folderPath, out var metadata))
+ {
+ return;
+ }
+
var descriptor = new SpaceWarpPluginDescriptor(
new BepInExModAdapter(plugin),
metadata.Spec != SpecVersion.V1_2 ? metadata.ModID : plugin.Info.Metadata.GUID,
@@ -274,8 +315,11 @@ private static void RegisterSingleBepInExPlugin(BaseUnityPlugin plugin)
new BepInExConfigFile(plugin.Config)
);
descriptor.Plugin!.SWMetadata = descriptor;
- if (!AssertSpecificationCompliance(descriptor, plugin, metadata, folderPath))
+ if (!AssertSpecificationCompliance(descriptor, plugin, metadata))
+ {
return;
+ }
+
PluginList.RegisterPlugin(descriptor);
}
else
@@ -297,6 +341,7 @@ private static SpaceWarpPluginDescriptor GetBepInExDescriptor(BaseUnityPlugin pl
new BepInExConfigFile(plugin.Config)
);
pluginAdapter.SWMetadata = descriptor;
+
return descriptor;
}
@@ -346,7 +391,9 @@ private static void RegisterAllCodelessMods()
if (swinfoData.Spec < SpecVersion.V1_3)
{
Logger.LogWarning(
- $"Found swinfo information for: {swinfoData.Name}, but its spec is less than v1.3, if this describes a \"codeless\" mod, it will be ignored");
+ $"Found swinfo information for: {swinfoData.Name}, but its spec is less than 1.3, if this " +
+ $"describes a \"codeless\" mod, it will be ignored"
+ );
continue;
}
@@ -364,7 +411,10 @@ private static void RegisterAllCodelessMods()
if (PluginList.AllPlugins.Any(
x => string.Equals(x.Guid, swinfoData.ModID, StringComparison.InvariantCultureIgnoreCase)
- )) continue;
+ ))
+ {
+ continue;
+ }
// Now we can just add it to our plugin list
PluginList.RegisterPlugin(descriptor);
@@ -394,8 +444,7 @@ private static ModInfo KspToSwinfo(Ksp2ModInfo mod)
Min = "*",
Max = "*"
},
- VersionCheck = null,
- VersionCheckType = VersionCheckType.SwInfo
+ VersionCheck = null
};
return newInfo;
}
@@ -416,7 +465,10 @@ private static void RegisterSingleKspMod(DirectoryInfo folder)
);
metadata = KspToSwinfo(modinfo);
}
- else return;
+ else
+ {
+ return;
+ }
// This descriptor *will* be modified later
var descriptor = new SpaceWarpPluginDescriptor(
@@ -436,9 +488,14 @@ private static void RegisterSingleKspMod(DirectoryInfo folder)
private static void RegisterAllKspMods()
{
var pluginPath = new DirectoryInfo(Path.Combine(Paths.GameRootPath, "GameData", "Mods"));
- if (!pluginPath.Exists) return;
+ if (!pluginPath.Exists)
+ {
+ return;
+ }
+
Logger.LogInfo($"KSP Loaded mods path: {pluginPath.FullName}");
- // Lets quickly register every KSP loader loaded mod into the load order before anything, with late pre-initialize
+ // Let's quickly register every mod loaded with the internal loader into the load order before anything else,
+ // with late pre-initialize
foreach (var plugin in pluginPath.EnumerateDirectories())
{
Logger.LogInfo($"Attempting to register KSP loaded mod at {pluginPath.FullName}");
@@ -465,7 +522,10 @@ private static void RegisterAllErroredMods()
(x.Plugin is BaseUnityPlugin baseUnityPlugin && string.Equals(
baseUnityPlugin.Info.Metadata.GUID, info.Metadata.GUID,
StringComparison.InvariantCultureIgnoreCase))
- )) continue;
+ ))
+ {
+ continue;
+ }
var descriptor = new SpaceWarpPluginDescriptor(
null,
@@ -484,7 +544,7 @@ private static void RegisterAllErroredMods()
private static void GetDisabledPlugins()
{
- foreach (var plugin in ChainloaderPatch.DisabledPlugins)
+ foreach (var plugin in ModList.DisabledPlugins)
{
GetSingleDisabledPlugin(plugin);
}
@@ -526,7 +586,7 @@ private static void GetSingleDisabledPlugin(PluginInfo plugin)
private static void DisableMods()
{
- foreach (var mod in ChainloaderPatch.DisabledPluginGuids)
+ foreach (var mod in ModList.DisabledPluginGuids)
{
PluginList.Disable(mod);
}
diff --git a/src/SpaceWarp.Core/Backend/SaveGameManager/PluginSaveData.cs b/src/SpaceWarp.Core/Backend/SaveGameManager/PluginSaveData.cs
index 768e5bf3..42796b31 100644
--- a/src/SpaceWarp.Core/Backend/SaveGameManager/PluginSaveData.cs
+++ b/src/SpaceWarp.Core/Backend/SaveGameManager/PluginSaveData.cs
@@ -1,13 +1,24 @@
-using System;
+namespace SpaceWarp.Backend.SaveGameManager;
-namespace SpaceWarp.Backend.SaveGameManager;
-
-internal delegate void SaveGameCallbackFunctionDelegate(object data);
+///
+/// The delegate type that will be called when a save or load event is triggered.
+///
+public delegate void SaveGameCallbackFunctionDelegate(object data);
+///
+/// This class is used to store your mod data for saving and loading.
+///
[Serializable]
public class PluginSaveData
{
+ ///
+ /// The GUID of your mod
+ ///
public string ModGuid { get; set; }
+
+ ///
+ /// The data that will be saved
+ ///
public object SaveData { get; set; }
[NonSerialized]
diff --git a/src/SpaceWarp.Core/Backend/SaveGameManager/SpaceWarpSerializedSavedGame.cs b/src/SpaceWarp.Core/Backend/SaveGameManager/SpaceWarpSerializedSavedGame.cs
index a777997c..5315f775 100644
--- a/src/SpaceWarp.Core/Backend/SaveGameManager/SpaceWarpSerializedSavedGame.cs
+++ b/src/SpaceWarp.Core/Backend/SaveGameManager/SpaceWarpSerializedSavedGame.cs
@@ -1,8 +1,4 @@
-using System;
-using System.Collections.Generic;
-using UnityEngine.Serialization;
-
-namespace SpaceWarp.Backend.SaveGameManager;
+namespace SpaceWarp.Backend.SaveGameManager;
///
/// Extension of game's save/load data class
@@ -10,5 +6,9 @@ namespace SpaceWarp.Backend.SaveGameManager;
[Serializable]
public class SpaceWarpSerializedSavedGame : KSP.Sim.SerializedSavedGame
{
+ ///
+ /// List of serialized plugin save data
+ ///
+ // ReSharper disable once InconsistentNaming
public List serializedPluginSaveData = new();
}
diff --git a/src/SpaceWarp.Core/InternalUtilities/AssetHelpers.cs b/src/SpaceWarp.Core/InternalUtilities/AssetHelpers.cs
index 5eeeaac3..1565e81c 100644
--- a/src/SpaceWarp.Core/InternalUtilities/AssetHelpers.cs
+++ b/src/SpaceWarp.Core/InternalUtilities/AssetHelpers.cs
@@ -1,4 +1,3 @@
-using System.IO;
using I2.Loc;
using KSP.Game;
using UnityEngine.AddressableAssets;
@@ -22,44 +21,42 @@ public static void LoadAddressable(string catalog)
SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Loaded addressables catalog {catalog}");
var locator = operation.Result;
SpaceWarpPlugin.Instance.SWLogger.LogInfo($"{catalog} ----- {locator.LocatorId}");
- GameManager.Instance.Assets.RegisterResourceLocator(locator);
+ // GameManager.Instance.Assets.RegisterResourceLocator(locator);
}
}
internal static void LoadLocalizationFromFolder(string folder)
{
SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Attempting to load localizations from {folder}");
- LanguageSourceData languageSourceData = null;
if (!Directory.Exists(folder))
{
SpaceWarpPlugin.Instance.SWLogger.LogInfo($"{folder} does not exist, not loading localizations.");
return;
}
+ int loadedCount = 0;
+
var info = new DirectoryInfo(folder);
- foreach (var csvFile in info.GetFiles("*.csv"))
+ foreach (var csvFile in info.GetFiles("*.csv", SearchOption.AllDirectories))
{
- languageSourceData ??= new LanguageSourceData();
+ var csvSource = new LanguageSourceData();
var csvData = File.ReadAllText(csvFile.FullName).Replace("\r\n", "\n");
- languageSourceData.Import_CSV("", csvData, eSpreadsheetUpdateMode.AddNewTerms);
+ csvSource.Import_CSV("", csvData, eSpreadsheetUpdateMode.AddNewTerms);
+ loadedCount++;
+ LocalizationHelpers.AddSource(csvSource);
}
- foreach (var i2CsvFile in info.GetFiles("*.i2csv"))
+ foreach (var i2CsvFile in info.GetFiles("*.i2csv", SearchOption.AllDirectories))
{
- languageSourceData ??= new LanguageSourceData();
+ var i2CsvSource = new LanguageSourceData();
var i2CsvData = File.ReadAllText(i2CsvFile.FullName).Replace("\r\n", "\n");
- languageSourceData.Import_I2CSV("", i2CsvData, eSpreadsheetUpdateMode.AddNewTerms);
+ i2CsvSource.Import_I2CSV("", i2CsvData, eSpreadsheetUpdateMode.AddNewTerms);
+ loadedCount++;
+ LocalizationHelpers.AddSource(i2CsvSource);
}
- if (languageSourceData != null)
- {
- languageSourceData.OnMissingTranslation = LanguageSourceData.MissingTranslationAction.Fallback;
- SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Loaded localizations from {folder}");
- LocalizationManager.AddSource(languageSourceData);
- }
- else
- {
- SpaceWarpPlugin.Instance.SWLogger.LogInfo($"No localizations found in {folder}");
- }
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo(
+ loadedCount > 0 ? $"Loaded localizations from {folder}" : $"No localizations found in {folder}"
+ );
}
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/InternalUtilities/InternalExtensions.cs b/src/SpaceWarp.Core/InternalUtilities/InternalExtensions.cs
index 55accc73..e6aeb81d 100644
--- a/src/SpaceWarp.Core/InternalUtilities/InternalExtensions.cs
+++ b/src/SpaceWarp.Core/InternalUtilities/InternalExtensions.cs
@@ -1,5 +1,4 @@
using System.Reflection;
-using System;
using UnityEngine;
using System.Collections;
diff --git a/src/SpaceWarp.Core/InternalUtilities/LocalizationHelpers.cs b/src/SpaceWarp.Core/InternalUtilities/LocalizationHelpers.cs
new file mode 100644
index 00000000..db51997b
--- /dev/null
+++ b/src/SpaceWarp.Core/InternalUtilities/LocalizationHelpers.cs
@@ -0,0 +1,29 @@
+using I2.Loc;
+
+namespace SpaceWarp.InternalUtilities;
+
+internal static class LocalizationHelpers
+{
+ public static void AddSource(LanguageSourceData source)
+ {
+ if (LocalizationManager.Sources.Contains(source))
+ {
+ return;
+ }
+
+ source.OnMissingTranslation = LanguageSourceData.MissingTranslationAction.Fallback;
+
+ LocalizationManager.Sources.Insert(0, source);
+ foreach (var language in source.mLanguages)
+ {
+ language.SetLoaded(true);
+ }
+
+ if (source.mDictionary.Count != 0)
+ {
+ return;
+ }
+
+ source.UpdateDictionary(true);
+ }
+}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/InternalUtilities/PathHelpers.cs b/src/SpaceWarp.Core/InternalUtilities/PathHelpers.cs
index 49eb5e80..1f69801d 100644
--- a/src/SpaceWarp.Core/InternalUtilities/PathHelpers.cs
+++ b/src/SpaceWarp.Core/InternalUtilities/PathHelpers.cs
@@ -1,7 +1,4 @@
-using System;
-using System.IO;
-
-namespace SpaceWarp.InternalUtilities;
+namespace SpaceWarp.InternalUtilities;
internal static class PathHelpers
{
diff --git a/src/SpaceWarp.Core/Modules/ModuleManager.cs b/src/SpaceWarp.Core/Modules/ModuleManager.cs
index 29876ccd..c980f3ba 100644
--- a/src/SpaceWarp.Core/Modules/ModuleManager.cs
+++ b/src/SpaceWarp.Core/Modules/ModuleManager.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
+using System.Reflection;
using HarmonyLib;
using SpaceWarp.API.Configuration;
using SpaceWarp.API.Logging;
@@ -9,11 +6,20 @@
namespace SpaceWarp.Modules;
+///
+/// Manager of SpaceWarp modules.
+///
public static class ModuleManager
{
internal static List AllSpaceWarpModules = new();
private static readonly ILogger ModuleManagerLogSource = new UnityLogSource("SpaceWarp.ModuleManager");
+ ///
+ /// Gets a SpaceWarp module instance by name.
+ ///
+ /// Name of the module.
+ /// The module instance.
+ /// True if the module was found, false otherwise.
public static bool TryGetModule(string name, out SpaceWarpModule module)
{
module = AllSpaceWarpModules.FirstOrDefault(x => x.Name == name);
@@ -43,7 +49,7 @@ internal static void LoadAllModules()
AllSpaceWarpModules.Add(mod);
}
- Harmony.CreateAndPatchAll(assembly);
+ // Harmony.CreateAndPatchAll(assembly);
}
catch (Exception e)
{
diff --git a/src/SpaceWarp.Core/Modules/SpaceWarpModule.cs b/src/SpaceWarp.Core/Modules/SpaceWarpModule.cs
index d2f89bd0..9e72094f 100644
--- a/src/SpaceWarp.Core/Modules/SpaceWarpModule.cs
+++ b/src/SpaceWarp.Core/Modules/SpaceWarpModule.cs
@@ -1,23 +1,50 @@
-using System.Collections.Generic;
-using SpaceWarp.API.Configuration;
+using SpaceWarp.API.Configuration;
using SpaceWarp.API.Logging;
namespace SpaceWarp.Modules;
+///
+/// Base class for SpaceWarp modules.
+///
public abstract class SpaceWarpModule
{
+ ///
+ /// The logger for the module.
+ ///
public ILogger ModuleLogger;
+
+ ///
+ /// The configuration file for the module.
+ ///
public IConfigFile ModuleConfiguration;
+ ///
+ /// The name of the module.
+ ///
public abstract string Name { get; }
- public abstract void LoadModule();
-
- public abstract void PreInitializeModule();
-
- public abstract void InitializeModule();
-
- public abstract void PostInitializeModule();
-
+ ///
+ /// Loads the module. Called in plugin's Awake method.
+ ///
+ public virtual void LoadModule() {}
+
+ ///
+ /// 1st stage of module initialization. Called in plugin's OnPreInitialized method.
+ ///
+ public virtual void PreInitializeModule() {}
+
+ ///
+ /// 2nd stage of module initialization. Called in plugin's OnInitialized method.
+ ///
+ public virtual void InitializeModule() {}
+
+ ///
+ /// 3rd stage of module initialization. Called in plugin's OnPostInitialized method.
+ ///
+ public virtual void PostInitializeModule() {}
+
+ ///
+ /// Names of modules that this module depends on.
+ ///
public virtual List Prerequisites => new();
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/CodeGenerationUtilities.cs b/src/SpaceWarp.Core/Patching/CodeGenerationUtilities.cs
index 60fcee96..b67bc18e 100644
--- a/src/SpaceWarp.Core/Patching/CodeGenerationUtilities.cs
+++ b/src/SpaceWarp.Core/Patching/CodeGenerationUtilities.cs
@@ -6,7 +6,7 @@ namespace SpaceWarp.Patching;
internal static class CodeGenerationUtilities
{
///
- /// Creates a CodeInstruction that pushed an integer to the stack.
+ /// Creates a CodeInstruction that pushed an integer to the stack.
///
/// The integer to push
/// An new CodeInstruction to push i
diff --git a/src/SpaceWarp.Core/Patching/BootstrapPatch.cs b/src/SpaceWarp.Core/Patching/Flow/BootstrapPatch.cs
similarity index 94%
rename from src/SpaceWarp.Core/Patching/BootstrapPatch.cs
rename to src/SpaceWarp.Core/Patching/Flow/BootstrapPatch.cs
index 29a080fa..b10b1c23 100644
--- a/src/SpaceWarp.Core/Patching/BootstrapPatch.cs
+++ b/src/SpaceWarp.Core/Patching/Flow/BootstrapPatch.cs
@@ -1,4 +1,3 @@
-using System.Collections.Generic;
using HarmonyLib;
using KSP.Game;
using KSP.Game.Flow;
@@ -8,7 +7,7 @@
using SpaceWarp.Backend.Modding;
using SpaceWarp.Patching.LoadingActions;
-namespace SpaceWarp.Patching;
+namespace SpaceWarp.Patching.Flow;
[HarmonyPatch]
internal static class BootstrapPatch
@@ -24,8 +23,8 @@ private static void GetAllMods()
PluginList.ResolveDependenciesAndLoadOrder();
}
- [HarmonyILManipulator]
[HarmonyPatch(typeof(GameManager), nameof(GameManager.StartBootstrap))]
+ [HarmonyILManipulator]
private static void PatchInitializationsIL(ILContext ilContext, ILLabel endLabel)
{
ILCursor ilCursor = new(ilContext);
@@ -109,9 +108,9 @@ private static IList GetAllPlugins()
IList allPlugins;
if (ForceSpaceWarpLoadDueToError)
{
- var l = new List { ErroredSWPluginDescriptor };
- l.AddRange(PluginList.AllEnabledAndActivePlugins);
- allPlugins = l;
+ var list = new List { ErroredSWPluginDescriptor };
+ list.AddRange(PluginList.AllEnabledAndActivePlugins);
+ allPlugins = list;
}
else
{
@@ -131,7 +130,9 @@ private static void InjectBeforeGameLoadMethods()
foreach (var plugin in PluginList.AllEnabledAndActivePlugins)
{
if (plugin.Plugin != null && !plugin.LatePreInitialize)
+ {
GameManager.Instance.LoadingFlow.AddAction(new PreInitializeModAction(plugin));
+ }
}
}
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/SequentialFlowLoadersPatcher.cs b/src/SpaceWarp.Core/Patching/Flow/SequentialFlowLoadersPatcher.cs
similarity index 71%
rename from src/SpaceWarp.Core/Patching/SequentialFlowLoadersPatcher.cs
rename to src/SpaceWarp.Core/Patching/Flow/SequentialFlowLoadersPatcher.cs
index e84a7067..1fdfb79f 100644
--- a/src/SpaceWarp.Core/Patching/SequentialFlowLoadersPatcher.cs
+++ b/src/SpaceWarp.Core/Patching/Flow/SequentialFlowLoadersPatcher.cs
@@ -1,13 +1,11 @@
-using System;
-using System.Collections.Generic;
-using System.Reflection;
+using System.Reflection;
using System.Reflection.Emit;
-using BepInEx.Logging;
using HarmonyLib;
using KSP.Game;
using KSP.Game.Flow;
+using SpaceWarp.API.Logging;
-namespace SpaceWarp.Patching;
+namespace SpaceWarp.Patching.Flow;
[HarmonyPatch]
internal static class SequentialFlowLoadersPatcher
@@ -16,28 +14,29 @@ internal static class SequentialFlowLoadersPatcher
internal const int FlowMethodPrivateloadcommon = 1;
internal const int FlowMethodPrivatesavecommon = 2;
- private static SequentialFlowAdditions[] _sequentialFlowAdditions =
+ private static readonly SequentialFlowAdditions[] SequentialFlowAdditionMethods =
{
- new(typeof(GameManager).GetMethod("StartGame")), // Must be index FLOW_METHOD_STARTGAME
- new(AccessTools.Method(
- "KSP.Game.SaveLoadManager:PrivateLoadCommon")), // Must be index FLOW_METHOD_PRIVATELOADCOMMON
- new(AccessTools.Method(
- "KSP.Game.SaveLoadManager:PrivateSaveCommon")), // Must be index FLOW_METHOD_PRIVATESAVECOMMON
+ // Must be index FlowMethodStartgame
+ new(typeof(GameManager).GetMethod("StartGame")),
+ // Must be index FlowMethodPrivateloadcommon
+ new(AccessTools.Method("KSP.Game.SaveLoadManager:PrivateLoadCommon")),
+ // Must be index FlowMethodPrivatesavecommon
+ new(AccessTools.Method("KSP.Game.SaveLoadManager:PrivateSaveCommon"))
};
internal static void AddConstructor(string after, Type flowAction, int methodIndex)
{
- _sequentialFlowAdditions[methodIndex].AddConstructor(after, flowAction);
+ SequentialFlowAdditionMethods[methodIndex].AddConstructor(after, flowAction);
}
internal static void AddFlowAction(string after, FlowAction flowAction, int methodIndex)
{
- _sequentialFlowAdditions[methodIndex].AddAction(after, flowAction);
+ SequentialFlowAdditionMethods[methodIndex].AddAction(after, flowAction);
}
public static SequentialFlow Apply(SequentialFlow flow, object[] methodArguments, int methodIndex)
{
- _sequentialFlowAdditions[methodIndex].ApplyTo(flow, methodArguments);
+ SequentialFlowAdditionMethods[methodIndex].ApplyTo(flow, methodArguments);
return flow;
}
@@ -57,8 +56,9 @@ int methodIndex
// Get list of relevant arguments to pass to FlowAction constructors.
// `parameterCount` has a `+ 1` because `GetParameters()` doesn't include the instance parameter (this).
- var parameters = _sequentialFlowAdditions[methodIndex].method.GetParameters()
- .Where(parameter => !parameter.ParameterType.IsValueType).ToArray();
+ var parameters = SequentialFlowAdditionMethods[methodIndex].Method.GetParameters()
+ .Where(parameter => !parameter.ParameterType.IsValueType)
+ .ToArray();
var parameterCount = parameters.Length + 1;
// Creation of argument `methodArguments` to `Apply()`:
@@ -99,19 +99,18 @@ int methodIndex
}
}
- [HarmonyPatch(typeof(GameManager))]
- [HarmonyPatch("StartGame")]
+ [HarmonyPatch(typeof(GameManager), nameof(GameManager.StartGame))]
[HarmonyPrefix]
+ // ReSharper disable once InconsistentNaming
public static void PrefixGameManagerStartGame(GameManager __instance)
{
- _sequentialFlowAdditions[FlowMethodStartgame].ApplyTo(
+ SequentialFlowAdditionMethods[FlowMethodStartgame].ApplyTo(
__instance.LoadingFlow,
new object[] { __instance }
);
}
- [HarmonyPatch(typeof(SaveLoadManager))]
- [HarmonyPatch("PrivateLoadCommon")]
+ [HarmonyPatch(typeof(SaveLoadManager), nameof(SaveLoadManager.PrivateLoadCommon))]
[HarmonyTranspiler]
public static IEnumerable TranspileSaveLoadManagerPrivateLoadCommon(
IEnumerable instructions)
@@ -119,8 +118,7 @@ public static IEnumerable TranspileSaveLoadManagerPrivateLoadCo
return TranspileSequentialFlowBuilderMethod(instructions, FlowMethodPrivateloadcommon);
}
- [HarmonyPatch(typeof(SaveLoadManager))]
- [HarmonyPatch("PrivateSaveCommon")]
+ [HarmonyPatch(typeof(SaveLoadManager), nameof(SaveLoadManager.PrivateSaveCommon))]
[HarmonyTranspiler]
public static IEnumerable TranspileSaveLoadManagerPrivateSaveCommon(
IEnumerable instructions)
@@ -130,29 +128,35 @@ public static IEnumerable TranspileSaveLoadManagerPrivateSaveCo
private class SequentialFlowAdditions
{
- private readonly HashSet availableTypes;
- private readonly List> insertAfter = new();
- internal readonly MethodInfo method;
+ private readonly HashSet _availableTypes;
+ private readonly List> _insertAfter = new();
+
+ internal readonly MethodInfo Method;
internal SequentialFlowAdditions(MethodInfo method)
{
- availableTypes =
- new HashSet(method.GetParameters().Select(parameter => parameter.ParameterType)
- .Where(type => !type.IsValueType)) { method.DeclaringType };
- this.method = method;
+ _availableTypes =
+ [
+ ..method.GetParameters()
+ .Select(parameter => parameter.ParameterType)
+ .Where(type => !type.IsValueType),
+ method.DeclaringType
+ ];
+ Method = method;
}
internal void AddConstructor(string after, Type flowAction)
{
// Determine the correct constructor to use.
var constructor = flowAction.GetConstructors()
- .OrderByDescending(constructor => constructor.GetParameters().Length).Where(constructor =>
+ .OrderByDescending(constructor => constructor.GetParameters().Length)
+ .Where(constructor =>
{
HashSet seen = new();
foreach (var parameter in constructor.GetParameters())
{
- if (!availableTypes.Contains(parameter.ParameterType))
+ if (!_availableTypes.Contains(parameter.ParameterType))
return false;
if (!seen.Add(parameter.GetType()))
@@ -160,15 +164,18 @@ internal void AddConstructor(string after, Type flowAction)
}
return true;
- }).FirstOrDefault() ?? throw new InvalidOperationException(
- $"Flow action type {flowAction.Name} does not have a public constructor that has parameters compatible with {method.DeclaringType.Name}.{method.Name}");
+ })
+ .FirstOrDefault() ?? throw new InvalidOperationException(
+ $"Flow action type {flowAction.Name} does not have a public constructor that has " +
+ $"parameters compatible with {Method.DeclaringType!.Name}.{Method.Name}"
+ );
- insertAfter.Add(new KeyValuePair(after, constructor));
+ _insertAfter.Add(new KeyValuePair(after, constructor));
}
internal void AddAction(string after, FlowAction action)
{
- insertAfter.Add(new KeyValuePair(after, action));
+ _insertAfter.Add(new KeyValuePair(after, action));
}
private static FlowAction Construct(ConstructorInfo constructor, object[] methodArguments)
@@ -201,11 +208,11 @@ private void AddActionsAfter(string name, List actions, bool[] added
if (added[i])
continue;
- if (insertAfter[i].Key != name) continue;
+ if (_insertAfter[i].Key != name) continue;
added[i] = true;
- var action = insertAfter[i].Value switch
+ var action = _insertAfter[i].Value switch
{
ConstructorInfo constructor => Construct(constructor, methodArguments),
FlowAction flowAction => flowAction,
@@ -216,7 +223,7 @@ private void AddActionsAfter(string name, List actions, bool[] added
// There could be actions set to run after the newly inserted action,
// so this needs to be called again.
- AddActionsAfter(action.Name, actions, added, methodArguments);
+ AddActionsAfter(action!.Name, actions, added, methodArguments);
}
}
@@ -242,7 +249,7 @@ internal void ApplyTo(SequentialFlow flow, object[] methodArguments)
// Has each action been added already?
// Used to prevent duplicates, and warn about unused actions.
- var added = new bool[insertAfter.Count()];
+ var added = new bool[_insertAfter.Count()];
// `null` is sued to signify the start of the action list.
AddActionsAfter(null, actions, added, methodArguments);
@@ -261,20 +268,27 @@ internal void ApplyTo(SequentialFlow flow, object[] methodArguments)
// Warn about any actions that were not used.
for (int i = 0; i < added.Length; i++)
{
- if (added[i]) continue;
+ if (added[i])
+ {
+ continue;
+ }
- if (insertAfter[i].Value is ConstructorInfo constructor)
+ if (_insertAfter[i].Value is ConstructorInfo constructor)
{
var actionType = constructor.DeclaringType;
- var logger = Logger.CreateLogSource($"{actionType.Assembly.GetName().Name}/{actionType.Name}");
+ var logger = BaseLogger.CreateDefault($"{actionType!.Assembly.GetName().Name}/{actionType.Name}");
logger.LogWarning(
- $"Flow action {actionType.Name} was set to be inserted after \"{insertAfter[i].Key}\" in {method.Name}, however that action does not exist in that flow");
+ $"Flow action {actionType.Name} was set to be inserted after \"{_insertAfter[i].Key}\" " +
+ $"in {Method.Name}, however that action does not exist in that flow"
+ );
}
- else if (insertAfter[i].Value is FlowAction action)
+ else if (_insertAfter[i].Value is FlowAction action)
{
- var logger = Logger.CreateLogSource("SequentialFlow");
+ var logger = BaseLogger.CreateDefault("SequentialFlow");
logger.LogWarning(
- $"Flow action \"{action.Name}\" was set to be inserted after \"{insertAfter[i].Key}\" in {method.Name}, however that action does not exist in that flow");
+ $"Flow action \"{action.Name}\" was set to be inserted after \"{_insertAfter[i].Key}\" " +
+ $"in {Method.Name}, however that action does not exist in that flow"
+ );
}
}
}
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/AddressableAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/AddressableAction.cs
index cfb2dbce..6f1b6cfc 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/AddressableAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/AddressableAction.cs
@@ -1,6 +1,4 @@
-using System;
-using System.Collections.Generic;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game;
using KSP.Game.Flow;
using UnityEngine;
@@ -8,17 +6,29 @@
namespace SpaceWarp.Patching.LoadingActions;
+// TODO: Move this to SpaceWarp.API.Loading in 2.0.0
+
+///
+/// A loading action that loads addressable assets by label.
+///
+/// The type of assets to load.
[Obsolete("This will be moved to SpaceWarp.API.Loading in 2.0.0")]
[PublicAPI]
public class AddressableAction : FlowAction where T : UnityObject
{
- private string Label;
- private Action Action;
+ private string _label;
+ private Action _action;
+ ///
+ /// Creates a new addressable loading action.
+ ///
+ /// Name of the action.
+ /// Label of the asset to load.
+ /// Action to perform on the loaded asset.
public AddressableAction(string name, string label, Action action) : base(name)
{
- Label = label;
- Action = action;
+ _label = label;
+ _action = action;
}
private bool DoesLabelExist(object label)
@@ -27,18 +37,23 @@ private bool DoesLabelExist(object label)
|| Addressables.ResourceLocators.Any(locator => locator.Keys.Contains(label));
}
+ ///
+ /// Performs the loading action.
+ ///
+ /// Callback to call when the action is resolved.
+ /// Callback to call when the action is rejected.
public override void DoAction(Action resolve, Action reject)
{
- if (!DoesLabelExist(Label))
+ if (!DoesLabelExist(_label))
{
- Debug.Log($"[Space Warp] Skipping loading addressables for {Label} which does not exist.");
+ Debug.Log($"[Space Warp] Skipping loading addressables for {_label} which does not exist.");
resolve();
return;
}
try
{
- GameManager.Instance.Assets.LoadByLabel(Label,Action,delegate(IList assetLocations)
+ GameManager.Instance.Assets.LoadByLabel(_label,_action,delegate(IList assetLocations)
{
if (assetLocations != null)
{
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/DescriptorLoadingAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/DescriptorLoadingAction.cs
index b1ab21d0..53ffb54d 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/DescriptorLoadingAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/DescriptorLoadingAction.cs
@@ -1,10 +1,14 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game.Flow;
using SpaceWarp.API.Mods;
namespace SpaceWarp.Patching.LoadingActions;
+// TODO: Move this to SpaceWarp.API.Loading in 2.0.0
+
+///
+/// A general loading action for a mod descriptor.
+///
[Obsolete("This will be moved to SpaceWarp.API.Loading in 2.0.0")]
[PublicAPI]
public class DescriptorLoadingAction : FlowAction
@@ -12,6 +16,12 @@ public class DescriptorLoadingAction : FlowAction
private readonly Action _action;
private readonly SpaceWarpPluginDescriptor _plugin;
+ ///
+ /// Creates a new descriptor loading action.
+ ///
+ /// Name of the loading action.
+ /// Callback to perform the loading action.
+ /// The plugin descriptor to create the action for.
public DescriptorLoadingAction(
string actionName,
Action action,
@@ -22,21 +32,32 @@ SpaceWarpPluginDescriptor plugin
_plugin = plugin;
}
+ ///
+ /// Performs the loading action.
+ ///
+ /// Callback to call when the action is resolved.
+ /// Callback to call when the action is rejected.
public override void DoAction(Action resolve, Action reject)
{
try
{
if (_plugin.DoLoadingActions)
+ {
_action(_plugin);
+ }
resolve();
}
catch (Exception e)
{
if (_plugin.Plugin != null)
+ {
_plugin.Plugin.SWLogger.LogError(e.ToString());
+ }
else
- SpaceWarpPlugin.Logger.LogError(_plugin.SWInfo.Name + ": " + e);
+ {
+ SpaceWarpPlugin.Instance.SWLogger.LogError(_plugin.SWInfo.Name + ": " + e);
+ }
reject(null);
}
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/FunctionalLoadingActions.cs b/src/SpaceWarp.Core/Patching/LoadingActions/FunctionalLoadingActions.cs
index 59e68969..4e9cec47 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/FunctionalLoadingActions.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/FunctionalLoadingActions.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using UnityEngine;
+using UnityEngine;
namespace SpaceWarp.Patching.LoadingActions;
@@ -15,8 +12,7 @@ string filename
var assetBundle = AssetBundle.LoadFromFile(filename);
if (assetBundle == null)
{
- throw new Exception(
- $"Failed to load AssetBundle {internalPath} ({filename})");
+ throw new Exception($"Failed to load AssetBundle {internalPath} ({filename})");
}
internalPath = internalPath.Replace(".bundle", "");
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/InitializeModAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/InitializeModAction.cs
index 04ad68eb..8c49c2d2 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/InitializeModAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/InitializeModAction.cs
@@ -1,4 +1,3 @@
-using System;
using KSP.Game.Flow;
using SpaceWarp.API.Mods;
@@ -8,8 +7,7 @@ internal sealed class InitializeModAction : FlowAction
{
private readonly SpaceWarpPluginDescriptor _plugin;
- public InitializeModAction(SpaceWarpPluginDescriptor plugin) : base(
- $"Initialization for plugin {plugin.Name}")
+ public InitializeModAction(SpaceWarpPluginDescriptor plugin) : base($"Initialization for plugin {plugin.Name}")
{
_plugin = plugin;
}
@@ -19,7 +17,10 @@ public override void DoAction(Action resolve, Action reject)
try
{
if (_plugin.DoLoadingActions)
+ {
_plugin.Plugin.OnInitialized();
+ }
+
resolve();
}
catch (Exception e)
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/LoadAddressablesAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/LoadAddressablesAction.cs
index 3e7376b3..956e9f71 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/LoadAddressablesAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/LoadAddressablesAction.cs
@@ -1,7 +1,5 @@
-using System;
-using System.IO;
-using BepInEx.Logging;
-using KSP.Game.Flow;
+using KSP.Game.Flow;
+using SpaceWarp.API.Logging;
using SpaceWarp.API.Mods;
using SpaceWarp.InternalUtilities;
@@ -9,7 +7,7 @@ namespace SpaceWarp.Patching.LoadingActions;
internal sealed class LoadAddressablesAction : FlowAction
{
- private static readonly ManualLogSource Logger = BepInEx.Logging.Logger.CreateLogSource("Addressables Loader");
+ private static readonly ILogger Logger = BaseLogger.CreateDefault("Addressables Loader");
private readonly SpaceWarpPluginDescriptor _plugin;
public LoadAddressablesAction(SpaceWarpPluginDescriptor plugin) : base(
@@ -40,9 +38,14 @@ public override void DoAction(Action resolve, Action reject)
catch (Exception e)
{
if (_plugin.Plugin != null)
+ {
_plugin.Plugin.SWLogger.LogError(e.ToString());
+ }
else
- SpaceWarpPlugin.Logger.LogError(_plugin.SWInfo.Name + ": " + e);
+ {
+ SpaceWarpPlugin.Instance.SWLogger.LogError(_plugin.SWInfo.Name + ": " + e);
+ }
+
reject(null);
}
}
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/LoadLocalizationAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/LoadLocalizationAction.cs
index 69646912..9ba4aac1 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/LoadLocalizationAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/LoadLocalizationAction.cs
@@ -1,6 +1,4 @@
-using System;
-using System.IO;
-using KSP.Game.Flow;
+using KSP.Game.Flow;
using SpaceWarp.API.Mods;
using SpaceWarp.InternalUtilities;
@@ -27,9 +25,14 @@ public override void DoAction(Action resolve, Action reject)
catch (Exception e)
{
if (_plugin.Plugin != null)
+ {
_plugin.Plugin.SWLogger.LogError(e.ToString());
+ }
else
- SpaceWarpPlugin.Logger.LogError(_plugin.SWInfo.Name + ": " + e);
+ {
+ SpaceWarpPlugin.Instance.SWLogger.LogError(_plugin.SWInfo.Name + ": " + e);
+ }
+
reject(null);
}
}
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/LoadLuaAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/LoadLuaAction.cs
index 0403bc07..5128baac 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/LoadLuaAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/LoadLuaAction.cs
@@ -1,6 +1,4 @@
-using System;
-using System.IO;
-using KSP.Game.Flow;
+using KSP.Game.Flow;
using SpaceWarp.API.Mods;
namespace SpaceWarp.Patching.LoadingActions;
@@ -32,9 +30,13 @@ public override void DoAction(Action resolve, Action reject)
catch (Exception e)
{
if (_plugin.Plugin != null)
+ {
_plugin.Plugin.SWLogger.LogError(e.ToString());
+ }
else
- SpaceWarpPlugin.Logger.LogError(_plugin.SWInfo.Name + ": " + e);
+ {
+ SpaceWarpPlugin.Instance.SWLogger.LogError(_plugin.SWInfo.Name + ": " + e);
+ }
}
}
@@ -43,9 +45,14 @@ public override void DoAction(Action resolve, Action reject)
catch (Exception e)
{
if (_plugin.Plugin != null)
+ {
_plugin.Plugin.SWLogger.LogError(e.ToString());
+ }
else
- SpaceWarpPlugin.Logger.LogError(_plugin.SWInfo.Name + ": " + e);
+ {
+ SpaceWarpPlugin.Instance.SWLogger.LogError(_plugin.SWInfo.Name + ": " + e);
+ }
+
reject(null);
}
}
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/LoadingAddressablesLocalizationsAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/LoadingAddressablesLocalizationsAction.cs
deleted file mode 100644
index dc0e075b..00000000
--- a/src/SpaceWarp.Core/Patching/LoadingActions/LoadingAddressablesLocalizationsAction.cs
+++ /dev/null
@@ -1,52 +0,0 @@
-using System;
-using System.Collections.Generic;
-using I2.Loc;
-using KSP.Game;
-using KSP.Game.Flow;
-using UnityEngine;
-using UnityEngine.AddressableAssets;
-
-namespace SpaceWarp.Patching.LoadingActions;
-
-internal sealed class LoadAddressablesLocalizationsAction : FlowAction
-{
- public LoadAddressablesLocalizationsAction() : base("Loading localizations from Addressables")
- {
- }
-
- public override void DoAction(Action resolve, Action reject)
- {
- try
- {
- GameManager.Instance.Assets.LoadByLabel(
- "language_source",
- OnLanguageSourceAssetLoaded,
- delegate(IList languageAssetLocations)
- {
- if (languageAssetLocations != null)
- {
- Addressables.Release(languageAssetLocations);
- }
-
- resolve();
- }
- );
- }
- catch (Exception e)
- {
- Debug.LogError(e.ToString());
- reject(null);
- }
- }
-
- private static void OnLanguageSourceAssetLoaded(LanguageSourceAsset asset)
- {
- if (!asset || LocalizationManager.Sources.Contains(asset.mSource))
- {
- return;
- }
-
- asset.mSource.owner = asset;
- LocalizationManager.AddSource(asset.mSource);
- }
-}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/ModLoadingAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/ModLoadingAction.cs
index e595db71..f54c7c69 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/ModLoadingAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/ModLoadingAction.cs
@@ -1,38 +1,52 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game.Flow;
using SpaceWarp.API.Mods;
namespace SpaceWarp.Patching.LoadingActions;
+// TODO: Move this to SpaceWarp.API.Loading in 2.0.0
+
+///
+/// A general loading action for a SpaceWarp mod plugin.
+///
[Obsolete("This will be moved to SpaceWarp.API.Loading in 2.0.0")]
[PublicAPI]
public class ModLoadingAction : FlowAction
{
- private Action Action;
- private BaseSpaceWarpPlugin Plugin;
-
+ private Action _action;
+ private BaseSpaceWarpPlugin _plugin;
+ ///
+ /// Creates a new mod plugin loading action.
+ ///
+ /// Name of the loading action.
+ /// Callback to perform the loading action.
+ /// The mod plugin to create the action for.
public ModLoadingAction(
string actionName,
Action action,
BaseSpaceWarpPlugin plugin
) : base($"{plugin.SpaceWarpMetadata.Name}:{actionName}")
{
- Action = action;
- Plugin = plugin;
+ _action = action;
+ _plugin = plugin;
}
+ ///
+ /// Performs the loading action.
+ ///
+ /// Callback to call when the action is resolved.
+ /// Callback to call when the action is rejected.
public override void DoAction(Action resolve, Action reject)
{
try
{
- Action(Plugin);
+ _action(_plugin);
resolve();
}
catch (Exception e)
{
- Plugin.ModLogger.LogError(e.ToString());
+ _plugin.SWLogger.LogError(e.ToString());
reject(null);
}
}
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/PostInitializeModAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/PostInitializeModAction.cs
index e8c5894d..80831b50 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/PostInitializeModAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/PostInitializeModAction.cs
@@ -1,5 +1,4 @@
-using System;
-using KSP.Game.Flow;
+using KSP.Game.Flow;
using SpaceWarp.API.Mods;
namespace SpaceWarp.Patching.LoadingActions;
@@ -19,7 +18,10 @@ public override void DoAction(Action resolve, Action reject)
try
{
if (_plugin.DoLoadingActions)
- _plugin.Plugin.OnPostInitialized();
+ {
+ _plugin.Plugin!.OnPostInitialized();
+ }
+
resolve();
}
catch (Exception e)
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/PreInitializeModAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/PreInitializeModAction.cs
index a8aac19c..8dea48e8 100644
--- a/src/SpaceWarp.Core/Patching/LoadingActions/PreInitializeModAction.cs
+++ b/src/SpaceWarp.Core/Patching/LoadingActions/PreInitializeModAction.cs
@@ -1,4 +1,3 @@
-using System;
using KSP.Game.Flow;
using SpaceWarp.API.Mods;
@@ -16,18 +15,19 @@ public PreInitializeModAction(SpaceWarpPluginDescriptor plugin)
public override void DoAction(Action resolve, Action reject)
{
- SpaceWarpPlugin.Logger.LogInfo($"Pre-initializing: {_plugin.Name}?");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Pre-initializing: {_plugin.Name}?");
try
{
if (_plugin.DoLoadingActions)
{
- SpaceWarpPlugin.Logger.LogInfo($"YES! {_plugin.Plugin}");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"YES! {_plugin.Plugin}");
_plugin.Plugin.OnPreInitialized();
}
else
{
- SpaceWarpPlugin.Logger.LogInfo("NO!!");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo("NO!!");
}
+
resolve();
}
catch (Exception e)
diff --git a/src/SpaceWarp.Core/Patching/LoadingActions/ResolvingPatchOrderAction.cs b/src/SpaceWarp.Core/Patching/LoadingActions/ResolvingPatchOrderAction.cs
deleted file mode 100644
index 76926cd3..00000000
--- a/src/SpaceWarp.Core/Patching/LoadingActions/ResolvingPatchOrderAction.cs
+++ /dev/null
@@ -1,16 +0,0 @@
-using System;
-using KSP.Game.Flow;
-
-namespace SpaceWarp.Patching.LoadingActions;
-
-internal class ResolvingPatchOrderAction : FlowAction
-{
- public ResolvingPatchOrderAction(string name) : base(name)
- {
- }
-
- public override void DoAction(Action resolve, Action reject)
- {
- throw new NotImplementedException();
- }
-}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/Localization/LocalizationPatch.cs b/src/SpaceWarp.Core/Patching/Localization/LocalizationPatch.cs
new file mode 100644
index 00000000..37330d9e
--- /dev/null
+++ b/src/SpaceWarp.Core/Patching/Localization/LocalizationPatch.cs
@@ -0,0 +1,250 @@
+using HarmonyLib;
+using I2.Loc;
+using UnityEngine;
+
+namespace SpaceWarp.Patching.Localization;
+
+///
+/// Patches the localization system to properly find fallback translations.
+///
+[HarmonyPatch]
+internal static class LocalizationPatch
+{
+ [HarmonyPatch(
+ typeof(LocalizationManager),
+ nameof(LocalizationManager.TryGetTranslation),
+ [
+ typeof(string), typeof(string), typeof(bool), typeof(int), typeof(bool), typeof(bool),
+ typeof(GameObject), typeof(string), typeof(bool), typeof(string)
+ ],
+ [
+ ArgumentType.Normal, ArgumentType.Out, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal,
+ ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal, ArgumentType.Normal
+ ]
+ )]
+ [HarmonyPrefix]
+ // ReSharper disable InconsistentNaming
+ private static bool LocalizationManagerTryGetTranslationPrefix(
+ ref bool __result,
+ string Term,
+ out string Translation,
+ bool FixForRTL = true,
+ int maxLineLengthForRTL = 0,
+ bool ignoreRTLnumbers = true,
+ bool applyParameters = false,
+ GameObject localParametersRoot = null,
+ string overrideLanguage = null,
+ bool allowLocalizedParameters = true,
+ string overrideSpecialization = null
+ )
+ {
+ // ReSharper restore InconsistentNaming
+ __result = TryGetTranslation(
+ Term,
+ out Translation,
+ FixForRTL,
+ maxLineLengthForRTL,
+ ignoreRTLnumbers,
+ applyParameters,
+ localParametersRoot,
+ overrideLanguage,
+ allowLocalizedParameters,
+ overrideSpecialization
+ );
+
+ return false;
+ }
+
+ private static bool TryGetTranslation(
+ string term,
+ out string translation,
+ bool fixForRtl,
+ int maxLineLengthForRtl,
+ bool ignoreRtlNumbers,
+ bool applyParameters,
+ GameObject localParametersRoot,
+ string overrideLanguage,
+ bool allowLocalizedParameters,
+ string overrideSpecialization
+ )
+ {
+ translation = null;
+ if (string.IsNullOrEmpty(term))
+ {
+ return false;
+ }
+
+ if (LocalizationManager.DebugLocalizationIsOn)
+ {
+ translation = term;
+ return true;
+ }
+
+ LocalizationManager.InitializeIfNeeded();
+
+ foreach (var source in LocalizationManager.Sources)
+ {
+ if (!TryGetTranslationFromSource(
+ source,
+ term,
+ out translation,
+ overrideLanguage,
+ overrideSpecialization
+ ))
+ {
+ continue;
+ }
+
+ if (applyParameters)
+ {
+ LocalizationManager.ApplyLocalizationParams(
+ ref translation,
+ localParametersRoot,
+ allowLocalizedParameters
+ );
+ }
+
+ if (LocalizationManager.IsRight2Left & fixForRtl)
+ {
+ translation = LocalizationManager.ApplyRTLfix(translation, maxLineLengthForRtl, ignoreRtlNumbers);
+ }
+
+ return true;
+ }
+
+ return TryGetFallback(
+ term,
+ ref translation,
+ fixForRtl,
+ maxLineLengthForRtl,
+ ignoreRtlNumbers,
+ applyParameters,
+ localParametersRoot,
+ allowLocalizedParameters,
+ overrideSpecialization
+ );
+ }
+
+ private static bool TryGetTranslationFromSource(
+ LanguageSourceData source,
+ string term,
+ out string translation,
+ string overrideLanguage = null,
+ string overrideSpecialization = null,
+ bool skipDisabled = false,
+ bool allowCategoryMistmatch = false
+ )
+ {
+ var languageIndex = source.GetLanguageIndex(
+ overrideLanguage ?? LocalizationManager.CurrentLanguage,
+ SkipDisabled: false
+ );
+
+ if (languageIndex >= 0 && (!skipDisabled || source.mLanguages[languageIndex].IsEnabled()))
+ {
+ var termData = source.GetTermData(term, allowCategoryMistmatch);
+ if (termData != null)
+ {
+ translation = termData.GetTranslation(languageIndex, overrideSpecialization, true);
+ if (translation == "---")
+ {
+ translation = string.Empty;
+ return true;
+ }
+
+ if (!string.IsNullOrEmpty(translation))
+ {
+ return true;
+ }
+ }
+ }
+
+ translation = null;
+ return false;
+ }
+
+ private static bool TryGetFallback(
+ string term,
+ ref string translation,
+ bool fixForRtl,
+ int maxLineLengthForRtl,
+ bool ignoreRtlNumbers,
+ bool applyParameters,
+ GameObject localParametersRoot,
+ bool allowLocalizedParameters,
+ string overrideSpecialization
+ )
+ {
+ if (!string.IsNullOrEmpty(translation) && !translation.Equals(term))
+ {
+ return true;
+ }
+
+ foreach (var source in LocalizationManager.Sources)
+ {
+ switch (source.OnMissingTranslation)
+ {
+ case LanguageSourceData.MissingTranslationAction.ShowWarning:
+ translation = "";
+ return true;
+ case LanguageSourceData.MissingTranslationAction.Empty:
+ translation = string.Empty;
+ return true;
+ case LanguageSourceData.MissingTranslationAction.ShowTerm:
+ translation = term;
+ return true;
+ }
+
+ if (!TryGetFallbackFromSource(source, term, out var fallback, overrideSpecialization))
+ {
+ continue;
+ }
+
+ if (applyParameters)
+ {
+ LocalizationManager.ApplyLocalizationParams(
+ ref fallback,
+ localParametersRoot,
+ allowLocalizedParameters
+ );
+ }
+
+ if (LocalizationManager.IsRight2Left & fixForRtl)
+ {
+ fallback = LocalizationManager.ApplyRTLfix(fallback, maxLineLengthForRtl, ignoreRtlNumbers);
+ }
+
+ translation = fallback;
+ return true;
+ }
+
+ return false;
+ }
+
+ private static bool TryGetFallbackFromSource(
+ LanguageSourceData source,
+ string term,
+ out string translation,
+ string overrideSpecialization
+ )
+ {
+ translation = null;
+
+ for (var index = 0; index < source.mLanguages.Count; ++index)
+ {
+ var termData = source.GetTermData(term);
+ if (termData == null)
+ {
+ continue;
+ }
+
+ translation = termData.GetTranslation(index, overrideSpecialization, true);
+ if (!string.IsNullOrEmpty(translation))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/ModLoaderPatch.cs b/src/SpaceWarp.Core/Patching/Mods/ModLoaderPatch.cs
similarity index 58%
rename from src/SpaceWarp.Core/Patching/ModLoaderPatch.cs
rename to src/SpaceWarp.Core/Patching/Mods/ModLoaderPatch.cs
index 98d10a64..b7462921 100644
--- a/src/SpaceWarp.Core/Patching/ModLoaderPatch.cs
+++ b/src/SpaceWarp.Core/Patching/Mods/ModLoaderPatch.cs
@@ -1,7 +1,4 @@
-using System;
-using System.Collections.Generic;
-using System.IO;
-using System.Reflection;
+using System.Reflection;
using HarmonyLib;
using KSP.Modding;
using Newtonsoft.Json;
@@ -11,16 +8,16 @@
using SpaceWarp.API.Mods.JSON;
using SpaceWarp.Backend.Modding;
using SpaceWarp.InternalUtilities;
-using SpaceWarpPatcher;
+using SpaceWarp.Preload.API;
using UnityEngine;
using File = System.IO.File;
-namespace SpaceWarp.Patching;
+namespace SpaceWarp.Patching.Mods;
[HarmonyPatch(typeof(KSP2Mod))]
-public static class ModLoaderPatch
+internal static class ModLoaderPatch
{
- private static ModInfo KSPToSwinfo(KSP2Mod mod)
+ private static ModInfo KspToSwinfo(KSP2Mod mod)
{
var newInfo = new ModInfo
{
@@ -37,36 +34,40 @@ private static ModInfo KSPToSwinfo(KSP2Mod mod)
Min = "*",
Max = "*"
},
- VersionCheck = null,
- VersionCheckType = VersionCheckType.SwInfo
+ VersionCheck = null
};
return newInfo;
}
- [HarmonyPrefix]
+
[HarmonyPatch(nameof(KSP2Mod.Load))]
+ [HarmonyPrefix]
+ // ReSharper disable InconsistentNaming
private static bool LoadPre(KSP2Mod __instance, ref bool __result, out bool __state)
{
- SpaceWarpPlugin.Logger.LogInfo($"KSP2Mod.Load (Pre): {__instance.ModName}");
+ // ReSharper restore InconsistentNaming
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"KSP2Mod.Load (Pre): {__instance.ModName}");
var path = __instance.ModRootPath;
var info = File.Exists(Path.Combine(path, "swinfo.json"))
? JsonConvert.DeserializeObject(File.ReadAllText(path))
- : KSPToSwinfo(__instance);
- var disabled = ChainloaderPatch.DisabledPluginGuids.Contains(info.ModID);
+ : KspToSwinfo(__instance);
+ var disabled = ModList.DisabledPluginGuids.Contains(info.ModID);
__state = disabled;
return !disabled;
}
- [HarmonyPostfix]
[HarmonyPatch(nameof(KSP2Mod.Load))]
+ [HarmonyPostfix]
+ // ReSharper disable InconsistentNaming
private static void LoadPost(KSP2Mod __instance, ref bool __result, ref bool __state)
{
- SpaceWarpPlugin.Logger.LogInfo($"KSP2Mod.Load (Post): {__instance.ModName}");
+ // ReSharper restore InconsistentNaming
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"KSP2Mod.Load (Post): {__instance.ModName}");
if (__state) return;
var path = __instance.ModRootPath;
var info = File.Exists(Path.Combine(path, "swinfo.json"))
? JsonConvert.DeserializeObject(File.ReadAllText(path))
- : KSPToSwinfo(__instance);
+ : KspToSwinfo(__instance);
var descriptor =
PluginList.AllPlugins.FirstOrDefault(x =>
string.Equals(x.Guid, info.ModID, StringComparison.InvariantCultureIgnoreCase));
@@ -77,14 +78,17 @@ private static void LoadPost(KSP2Mod __instance, ref bool __result, ref bool __s
if (__instance.EntryPoint != null)
{
if (LoadCodeBasedMod(__instance, ref __result, go, ref descriptor.Plugin, ref addAdapter,
- ref descriptor.ConfigFile, ref descriptor.DoLoadingActions)) return;
+ ref descriptor.ConfigFile, ref descriptor.DoLoadingActions))
+ {
+ return;
+ }
}
else
{
__instance.modType = KSP2ModType.ContentOnly;
}
- SpaceWarpPlugin.Logger.LogInfo($"KSP2Mod.Load (Loaded stuff): {__instance.ModName}");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"KSP2Mod.Load (Loaded stuff): {__instance.ModName}");
if (addAdapter)
{
@@ -100,8 +104,8 @@ private static void LoadPost(KSP2Mod __instance, ref bool __result, ref bool __s
}
private static bool LoadCodeBasedMod(
- KSP2Mod __instance,
- ref bool __result,
+ KSP2Mod instance,
+ ref bool result,
GameObject go,
ref ISpaceWarpMod swMod,
ref bool addAdapter,
@@ -110,46 +114,59 @@ ref bool isSWMod
)
{
// Lets take a simple guess at what needs to be done.
- if (File.Exists(Path.Combine(__instance.ModRootPath, __instance.EntryPoint)))
+ if (File.Exists(Path.Combine(instance.ModRootPath, instance.EntryPoint)))
{
- if (__instance.EntryPoint.EndsWith(".dll"))
+ if (instance.EntryPoint.EndsWith(".dll"))
{
- if (LoadModWithDLLEntryPoint(__instance, ref __result, go, ref swMod, ref addAdapter, ref configFile,
- ref isSWMod)) return true;
+ if (LoadModWithDLLEntryPoint(
+ instance,
+ ref result,
+ go,
+ ref swMod,
+ ref addAdapter,
+ ref configFile,
+ ref isSWMod
+ ))
+ {
+ return true;
+ }
}
- else if (__instance.EntryPoint.EndsWith(".lua"))
+ else if (instance.EntryPoint.EndsWith(".lua"))
{
- if (LoadModWithLuaEntryPoint(__instance, ref __result)) return true;
+ if (LoadModWithLuaEntryPoint(instance, ref result))
+ {
+ return true;
+ }
}
}
else
{
- __instance.modType = KSP2ModType.Error;
- __result = false;
+ instance.modType = KSP2ModType.Error;
+ result = false;
return true;
}
return false;
}
- private static bool LoadModWithLuaEntryPoint(KSP2Mod __instance, ref bool __result)
+ private static bool LoadModWithLuaEntryPoint(KSP2Mod instance, ref bool result)
{
try
{
- __instance.modCore = new KSP2LuaModCore(
- __instance.APIVersion,
- __instance.ModName,
- __instance.EntryPoint,
- __instance.ModRootPath
+ instance.modCore = new KSP2LuaModCore(
+ instance.APIVersion,
+ instance.ModName,
+ instance.EntryPoint,
+ instance.ModRootPath
);
- __instance.modType = KSP2ModType.Lua;
- __instance.currentState = KSP2ModState.Active;
+ instance.modType = KSP2ModType.Lua;
+ instance.currentState = KSP2ModState.Active;
}
catch (Exception e)
{
- SpaceWarpPlugin.Logger.LogError(e);
- __instance.modType = KSP2ModType.Error;
- __result = false;
+ SpaceWarpPlugin.Instance.SWLogger.LogError(e);
+ instance.modType = KSP2ModType.Error;
+ result = false;
return true;
}
@@ -157,8 +174,8 @@ private static bool LoadModWithLuaEntryPoint(KSP2Mod __instance, ref bool __resu
}
private static bool LoadModWithDLLEntryPoint(
- KSP2Mod __instance,
- ref bool __result,
+ KSP2Mod instance,
+ ref bool result,
GameObject go,
ref ISpaceWarpMod swMod,
ref bool addAdapter,
@@ -168,32 +185,39 @@ ref bool isSWMod
{
try
{
- var asm = Assembly.LoadFile(Path.Combine(__instance.ModRootPath, __instance.EntryPoint));
- __instance.modType = KSP2ModType.CSharp;
+ var asm = Assembly.LoadFile(Path.Combine(instance.ModRootPath, instance.EntryPoint));
+ instance.modType = KSP2ModType.CSharp;
foreach (var type in asm.GetTypes())
{
- if (!typeof(Mod).IsAssignableFrom(type) || type.IsAbstract) continue;
+ if (!typeof(Mod).IsAssignableFrom(type) || type.IsAbstract)
+ {
+ continue;
+ }
+
var comp = go.AddComponent(type);
- if (comp is not BaseKspLoaderSpaceWarpMod baseKspLoaderSpaceWarpMod) continue;
+ if (comp is not BaseKspLoaderSpaceWarpMod baseKspLoaderSpaceWarpMod)
+ {
+ continue;
+ }
- SpaceWarpPlugin.Logger.LogInfo($"Loading mod: {comp}");
+ SpaceWarpPlugin.Instance.SWLogger.LogInfo($"Loading mod: {comp}");
isSWMod = true;
- baseKspLoaderSpaceWarpMod.SWLogger = new UnityLogSource(__instance.ModName);
+ baseKspLoaderSpaceWarpMod.SWLogger = new UnityLogSource(instance.ModName);
// baseKspLoaderSpaceWarpMod.modFolder = __instance.ModRootPath;
configFile = baseKspLoaderSpaceWarpMod.SWConfiguration = new JsonConfigFile(
- Path.Combine(__instance.ModRootPath, "config.cfg")
+ Path.Combine(instance.ModRootPath, "config.cfg")
);
swMod = baseKspLoaderSpaceWarpMod;
addAdapter = false;
}
- __instance.currentState = KSP2ModState.Active;
+ instance.currentState = KSP2ModState.Active;
}
catch (Exception e)
{
- SpaceWarpPlugin.Logger.LogError(e);
- __instance.modType = KSP2ModType.Error;
- __result = false;
+ SpaceWarpPlugin.Instance.SWLogger.LogError(e);
+ instance.modType = KSP2ModType.Error;
+ result = false;
return true;
}
diff --git a/src/SpaceWarp.Core/Patching/PartOwnerComponentConstructor.cs b/src/SpaceWarp.Core/Patching/PartOwnerComponentConstructor.cs
deleted file mode 100644
index f9c7da1f..00000000
--- a/src/SpaceWarp.Core/Patching/PartOwnerComponentConstructor.cs
+++ /dev/null
@@ -1,32 +0,0 @@
-using System.Reflection;
-using HarmonyLib;
-using JetBrains.Annotations;
-using KSP.Sim.impl;
-using SpaceWarp.API.Parts;
-
-namespace SpaceWarp.Patching;
-
-
-[HarmonyPatch(typeof(PartOwnerComponent))]
-public static class PartOwnerComponentConstructor
-{
- private static FieldInfo AddedField =
- typeof(PartOwnerComponent).GetField("HasRegisteredPartComponentsForFixedUpdate");
-
- [HarmonyPatch(MethodType.Constructor)]
- public static void SetFalse(PartOwnerComponent __instance)
- {
-
- AddedField.SetValue(__instance, false);
- }
-
- [HarmonyPatch(nameof(PartOwnerComponent.Add)), HarmonyPrefix, UsedImplicitly]
- public static void CheckForModule(PartOwnerComponent __instance, PartComponent part)
- {
- var currentValue = (Boolean)AddedField.GetValue(__instance);
- if (currentValue) return;
- var hasModule = PartComponentModuleOverride.RegisteredPartComponentOverrides.Any(type => part.TryGetModule(type, out _));
-
- AddedField.SetValue(__instance, hasModule);
- }
-}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/ColorsPatch.cs b/src/SpaceWarp.Core/Patching/Parts/ColorsPatch.cs
similarity index 94%
rename from src/SpaceWarp.Core/Patching/ColorsPatch.cs
rename to src/SpaceWarp.Core/Patching/Parts/ColorsPatch.cs
index c2d8b52e..77db677a 100644
--- a/src/SpaceWarp.Core/Patching/ColorsPatch.cs
+++ b/src/SpaceWarp.Core/Patching/Parts/ColorsPatch.cs
@@ -1,16 +1,15 @@
-using System.Collections.Generic;
-using System.Reflection;
-using BepInEx.Logging;
-using Castle.Core.Internal;
+using System.Reflection;
using HarmonyLib;
using KSP.Game;
using KSP.Modules;
using KSP.OAB;
using KSP.Sim.impl;
using SpaceWarp.API.Assets;
+using SpaceWarp.API.Logging;
using UnityEngine;
+using ILogger = SpaceWarp.API.Logging.ILogger;
-namespace SpaceWarp.Patching;
+namespace SpaceWarp.Patching.Parts;
///
/// This patch is meant to give modders a way to use the new colors system on KSP2.
@@ -22,9 +21,9 @@ namespace SpaceWarp.Patching;
[HarmonyPatch]
internal class ColorsPatch
{
+ #region Colors patch
+
private const string Ksp2OpaquePath = "KSP2/Scenery/Standard (Opaque)";
- private const string Ksp2TransparentPath = "KSP2/Scenery/Standard (Transparent)";
- private const string UnityStandard = "Standard";
[HarmonyPatch(typeof(ObjectAssemblyPartTracker), nameof(ObjectAssemblyPartTracker.OnPartPrefabLoaded))]
public static void Prefix(IObjectAssemblyAvailablePart obj, ref GameObject prefab)
@@ -32,7 +31,11 @@ public static void Prefix(IObjectAssemblyAvailablePart obj, ref GameObject prefa
foreach (var renderer in prefab.GetComponentsInChildren())
{
var shaderName = renderer.material.shader.name;
- if (shaderName is not ("Parts Replace" or "KSP2/Parts/Paintable")) continue;
+ if (shaderName is not ("Parts Replace" or "KSP2/Parts/Paintable"))
+ {
+ continue;
+ }
+
Material material;
var mat = new Material(Shader.Find(Ksp2OpaquePath))
{
@@ -50,7 +53,11 @@ public static void UpdateColorsInFlight(GameObject instance)
foreach (var renderer in instance.GetComponentsInChildren())
{
var shaderName = renderer.material.shader.name;
- if (shaderName is not ("Parts Replace" or "KSP2/Parts/Paintable")) continue;
+ if (shaderName is not ("Parts Replace" or "KSP2/Parts/Paintable"))
+ {
+ continue;
+ }
+
Material material;
var mat = new Material(Shader.Find(Ksp2OpaquePath))
{
@@ -61,7 +68,17 @@ public static void UpdateColorsInFlight(GameObject instance)
}
}
- //Everything below this point will be removed in the next patch
+ #endregion
+
+ // TODO: Remove everything below this comment in 2.0.
+
+ #region To be removed
+
+ // ReSharper disable all
+
+ private const string Ksp2TransparentPath = "KSP2/Scenery/Standard (Transparent)";
+ private const string UnityStandard = "Standard";
+
private const int Diffuse = 0;
private const int Metallic = 1;
private const int Bump = 2;
@@ -100,9 +117,8 @@ public static void UpdateColorsInFlight(GameObject instance)
private static Shader _ksp2Opaque;
private static Shader _ksp2Transparent;
private static Shader _unityStandard;
- internal static ManualLogSource Logger;
+ internal static ILogger Logger = BaseLogger.CreateDefault(DisplayName);
- ///TODO: Implement false behaviour
public static Dictionary DeclaredParts { get; } = new();
[HarmonyPrepare]
@@ -128,9 +144,7 @@ private static bool Init(MethodBase original)
_ksp2Transparent = Shader.Find(Ksp2TransparentPath);
_unityStandard = Shader.Find(UnityStandard);
- Logger = BepInEx.Logging.Logger.CreateLogSource(DisplayName);
-
- return true; // TODO: add config to enable/disable this patch, if disabled return false.
+ return true;
}
///
@@ -314,7 +328,7 @@ private static string TrimPartName(string partName)
nameof(GameManager.OnLoadingFinished))]
internal static void Prefix()
{
- LoadDeclaredParts(); // TODO: Move this to a more apropriate call, like the one loading parts or something like that.
+ LoadDeclaredParts();
}
[HarmonyPatch(typeof(Module_Color),
@@ -322,7 +336,7 @@ internal static void Prefix()
internal static void Postfix(Module_Color __instance)
{
var partName = __instance.OABPart is not null ? __instance.OABPart.PartName : __instance.part.Name;
- if (partName.IsNullOrEmpty()) return;
+ if (string.IsNullOrEmpty(partName)) return;
var trimmedPartName = TrimPartName(partName);
if (DeclaredParts.Count <= 0 || !_allParts.Contains(trimmedPartName)) return;
@@ -365,4 +379,6 @@ private static void LogError(object data)
{
Logger.LogError($"{data}");
}
+
+ #endregion
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/Parts/PartOwnerComponentConstructor.cs b/src/SpaceWarp.Core/Patching/Parts/PartOwnerComponentConstructor.cs
new file mode 100644
index 00000000..4eea15cc
--- /dev/null
+++ b/src/SpaceWarp.Core/Patching/Parts/PartOwnerComponentConstructor.cs
@@ -0,0 +1,38 @@
+using System.Reflection;
+using HarmonyLib;
+using KSP.Sim.impl;
+using SpaceWarp.API.Parts;
+
+namespace SpaceWarp.Patching.Parts;
+
+[HarmonyPatch(typeof(PartOwnerComponent))]
+internal static class PartOwnerComponentConstructor
+{
+ private static readonly FieldInfo AddedField =
+ typeof(PartOwnerComponent).GetField("HasRegisteredPartComponentsForFixedUpdate");
+
+ [HarmonyPatch(MethodType.Constructor)]
+ // ReSharper disable once InconsistentNaming
+ private static void SetFalse(PartOwnerComponent __instance)
+ {
+ AddedField.SetValue(__instance, false);
+ }
+
+ [HarmonyPatch(nameof(PartOwnerComponent.Add))]
+ [HarmonyPrefix]
+ // ReSharper disable once InconsistentNaming
+ private static void CheckForModule(PartOwnerComponent __instance, PartComponent part)
+ {
+ var currentValue = (bool)AddedField.GetValue(__instance);
+ if (currentValue)
+ {
+ return;
+ }
+
+ var hasModule = PartComponentModuleOverride.RegisteredPartComponentOverrides.Any(
+ type => part.TryGetModule(type, out _)
+ );
+
+ AddedField.SetValue(__instance, hasModule);
+ }
+}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/SaveGameManager/SaveGamePatches.cs b/src/SpaceWarp.Core/Patching/SaveGameManager/SaveGamePatches.cs
index 5dad1816..a77deaec 100644
--- a/src/SpaceWarp.Core/Patching/SaveGameManager/SaveGamePatches.cs
+++ b/src/SpaceWarp.Core/Patching/SaveGameManager/SaveGamePatches.cs
@@ -1,28 +1,31 @@
using HarmonyLib;
using KSP.Game.Load;
using KSP.IO;
-using SpaceWarp.API.Logging;
using SpaceWarp.API.SaveGameManager;
using SpaceWarp.Backend.SaveGameManager;
using SpaceWarp.InternalUtilities;
-using System;
namespace SpaceWarp.Patching.SaveGameManager;
[HarmonyPatch]
internal class SaveLoadPatches
{
- private static readonly ILogger _logger = new UnityLogSource("SpaceWarp.SaveLoadPatches");
+ #region Saving
- /// SAVING ///
-
- [HarmonyPatch(typeof(SerializeGameDataFlowAction), MethodType.Constructor), HarmonyPostfix]
- [HarmonyPatch(new Type[] { typeof(string), typeof(LoadGameData) })]
- private static void InjectPluginSaveGameData(string filename, LoadGameData data, SerializeGameDataFlowAction __instance)
+ [HarmonyPatch(typeof(SerializeGameDataFlowAction), MethodType.Constructor, [typeof(string), typeof(LoadGameData)])]
+ [HarmonyPostfix]
+ private static void InjectPluginSaveGameData(
+ string filename,
+ LoadGameData data,
+ // ReSharper disable once InconsistentNaming
+ SerializeGameDataFlowAction __instance
+ )
{
// Skip plugin data injection if there are no mods that have registered for save/load actions
if (ModSaves.InternalPluginSaveData.Count == 0)
+ {
return;
+ }
// Take the game's LoadGameData, extend it with our own class and copy plugin save data to it
SpaceWarpSerializedSavedGame modSaveData = new();
@@ -37,21 +40,30 @@ private static void InjectPluginSaveGameData(string filename, LoadGameData data,
}
}
- /// LOADING ///
+ #endregion
+
+ #region Loading
- [HarmonyPatch(typeof(DeserializeContentsFlowAction), "DoAction"), HarmonyPrefix]
- private static bool DeserializeLoadedPluginData(Action resolve, Action reject, DeserializeContentsFlowAction __instance)
+ [HarmonyPatch(typeof(DeserializeContentsFlowAction), "DoAction")]
+ [HarmonyPrefix]
+ private static bool DeserializeLoadedPluginData(
+ Action resolve,
+ Action reject,
+ // ReSharper disable once InconsistentNaming
+ DeserializeContentsFlowAction __instance
+ )
{
// Skip plugin deserialization if there are no mods that have registered for save/load actions
if (ModSaves.InternalPluginSaveData.Count == 0)
+ {
return true;
+ }
__instance._game.UI.SetLoadingBarText(__instance.Description);
try
{
// Deserialize save data to our own class that extends game's SerializedSavedGame
- SpaceWarpSerializedSavedGame serializedSavedGame = new();
- IOProvider.FromJsonFile(__instance._filename, out serializedSavedGame);
+ IOProvider.FromJsonFile(__instance._filename, out var serializedSavedGame);
__instance._data.SavedGame = serializedSavedGame;
__instance._data.DataLength = IOProvider.GetFileSize(__instance._filename);
@@ -62,18 +74,27 @@ private static bool DeserializeLoadedPluginData(Action resolve, Action r
foreach (var loadedData in serializedSavedGame.serializedPluginSaveData)
{
// Match registered plugin GUID with the GUID found in the save file
- var existingData = ModSaves.InternalPluginSaveData.Find(p => p.ModGuid == loadedData.ModGuid);
+ var existingData = ModSaves.InternalPluginSaveData.Find(
+ p => p.ModGuid == loadedData.ModGuid
+ );
if (existingData == null)
{
- _logger.LogWarning($"Saved data for plugin '{loadedData.ModGuid}' found during a load event, however that plugin isn't registered for save/load events. Skipping load for this plugin.");
+ SpaceWarpPlugin.Instance.SWLogger.LogWarning(
+ $"Saved data for plugin '{loadedData.ModGuid}' found during a load event, however " +
+ $"that plugin isn't registered for save/load events. Skipping load for this plugin."
+ );
continue;
}
- // Perform a callback if plugin specified a callback function. This is done before plugin data is actually updated.
+ // Perform a callback if plugin specified a callback function. This is done before plugin data is
+ // actually updated.
existingData.LoadEventCallback(loadedData.SaveData);
// Copy loaded data to the SaveData object plugin registered
- InternalExtensions.CopyFieldAndPropertyDataFromSourceToTargetObject(loadedData.SaveData, existingData.SaveData);
+ InternalExtensions.CopyFieldAndPropertyDataFromSourceToTargetObject(
+ loadedData.SaveData,
+ existingData.SaveData
+ );
}
}
}
@@ -82,8 +103,11 @@ private static bool DeserializeLoadedPluginData(Action resolve, Action r
UnityEngine.Debug.LogException(ex);
reject(ex.Message);
}
+
resolve();
return false;
}
-}
+
+ #endregion
+}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/Patching/SettingsManagerPatcher.cs b/src/SpaceWarp.Core/Patching/Settings/SettingsManagerPatcher.cs
similarity index 50%
rename from src/SpaceWarp.Core/Patching/SettingsManagerPatcher.cs
rename to src/SpaceWarp.Core/Patching/Settings/SettingsManagerPatcher.cs
index 93864fe9..3196c04e 100644
--- a/src/SpaceWarp.Core/Patching/SettingsManagerPatcher.cs
+++ b/src/SpaceWarp.Core/Patching/Settings/SettingsManagerPatcher.cs
@@ -1,16 +1,14 @@
-using System.Collections.Generic;
-using HarmonyLib;
+using HarmonyLib;
using KSP.UI;
-namespace SpaceWarp.Patching;
+namespace SpaceWarp.Patching.Settings;
[HarmonyPatch]
internal static class SettingsManagerPatcher
{
- internal static List AllExtrasSettingsMenus = new();
-
+ internal static readonly List AllExtrasSettingsMenus = new();
+
+ [HarmonyPatch(typeof(SettingsMenuManager), nameof(SettingsMenuManager.ResetAllSettings))]
[HarmonyPostfix]
- [HarmonyPatch(typeof(SettingsMenuManager))]
- [HarmonyPatch(nameof(SettingsMenuManager.ResetAllSettings))]
internal static void ResetModsMenu()
{
foreach (var menu in AllExtrasSettingsMenus.Where(menu => menu != null))
diff --git a/src/SpaceWarp.Core/Patching/FixGetTypes.cs b/src/SpaceWarp.Core/Patching/System/FixGetTypes.cs
similarity index 76%
rename from src/SpaceWarp.Core/Patching/FixGetTypes.cs
rename to src/SpaceWarp.Core/Patching/System/FixGetTypes.cs
index 19ddcf90..b592666c 100644
--- a/src/SpaceWarp.Core/Patching/FixGetTypes.cs
+++ b/src/SpaceWarp.Core/Patching/System/FixGetTypes.cs
@@ -1,27 +1,29 @@
-using System;
using System.Reflection;
-using BepInEx.Logging;
using HarmonyLib;
+using SpaceWarp.API.Logging;
-namespace SpaceWarp.Patching;
+namespace SpaceWarp.Patching.System;
[HarmonyPatch]
internal static class FixGetTypes
{
- [HarmonyFinalizer]
[HarmonyPatch(typeof(Assembly), nameof(Assembly.GetTypes), new Type[0])]
[HarmonyPatch(typeof(Assembly), nameof(Assembly.GetExportedTypes))]
+ [HarmonyFinalizer]
+ // ReSharper disable InconsistentNaming
private static Exception GetTypesFix(Exception __exception, Assembly __instance, ref Type[] __result)
{
+ // ReSharper restore InconsistentNaming
if (__exception is not ReflectionTypeLoadException reflectionTypeLoadException)
{
return __exception;
}
- var logger = new ManualLogSource("FixGetTypes");
+ var logger = BaseLogger.CreateDefault("FixGetTypes");
logger.LogWarning(
- $"Types failed to load from assembly {__instance.FullName} due to the reasons below, continuing anyway.");
+ $"Types failed to load from assembly {__instance.FullName} due to the reasons below, continuing anyway."
+ );
logger.LogWarning($"Exception: {__exception}");
foreach (var exception in reflectionTypeLoadException.LoaderExceptions)
@@ -31,6 +33,5 @@ private static Exception GetTypesFix(Exception __exception, Assembly __instance,
__result = reflectionTypeLoadException.Types.Where(type => type != null).ToArray();
return null;
-
}
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Core/AssemblyInfo.cs b/src/SpaceWarp.Core/Properties/AssemblyInfo.cs
similarity index 100%
rename from src/SpaceWarp.Core/AssemblyInfo.cs
rename to src/SpaceWarp.Core/Properties/AssemblyInfo.cs
diff --git a/src/SpaceWarp.Core/SpaceWarp.Core.csproj b/src/SpaceWarp.Core/SpaceWarp.Core.csproj
index b3662049..9819d2a0 100644
--- a/src/SpaceWarp.Core/SpaceWarp.Core.csproj
+++ b/src/SpaceWarp.Core/SpaceWarp.Core.csproj
@@ -21,6 +21,9 @@
-
+
+ false
+ all
+
diff --git a/src/SpaceWarp.Core/SpaceWarpPlugin.cs b/src/SpaceWarp.Core/SpaceWarpPlugin.cs
index 87186335..db943ad6 100644
--- a/src/SpaceWarp.Core/SpaceWarpPlugin.cs
+++ b/src/SpaceWarp.Core/SpaceWarpPlugin.cs
@@ -1,7 +1,5 @@
global using UnityObject = UnityEngine.Object;
global using System.Linq;
-using System;
-using System.IO;
using System.Reflection;
using BepInEx;
using BepInEx.Logging;
@@ -21,28 +19,47 @@
namespace SpaceWarp;
-[BepInDependency("com.bepis.bepinex.configurationmanager", "17.1")]
+///
+/// The main SpaceWarp plugin class.
+///
[BepInDependency(UitkForKsp2Plugin.ModGuid, UitkForKsp2Plugin.ModVer)]
[BepInIncompatibility("com.shadow.quantum")]
[BepInPlugin(ModGuid, ModName, ModVer)]
public sealed class SpaceWarpPlugin : BaseSpaceWarpPlugin
{
+ ///
+ /// SpaceWarp plugin instance.
+ ///
public static SpaceWarpPlugin Instance;
- [PublicAPI] public const string ModGuid = "com.github.x606.spacewarp";
- [PublicAPI] public const string ModName = "Space Warp";
- [PublicAPI] public const string ModVer = MyPluginInfo.PLUGIN_VERSION; // TODO: Don't hard code this, but I don't know much msbuild stuff so @munix wil have to do that,
- // and @munix is really lazy to do it right now but he definitely will at some point :P
-
+ ///
+ /// The GUID of the SpaceWarp plugin.
+ ///
+ [PublicAPI] public const string ModGuid = MyPluginInfo.PLUGIN_GUID;
+
+ ///
+ /// The name of the SpaceWarp plugin.
+ ///
+ [PublicAPI] public const string ModName = MyPluginInfo.PLUGIN_NAME;
+
+ ///
+ /// The version of the SpaceWarp plugin.
+ ///
+ [PublicAPI] public const string ModVer = MyPluginInfo.PLUGIN_VERSION;
+
internal ScriptEnvironment GlobalLuaState;
internal new static ManualLogSource Logger;
+ ///
+ /// Initializes a new instance of the class.
+ ///
public SpaceWarpPlugin()
{
// Load the type forwarders
Assembly.LoadFile(
- $"{new FileInfo(Assembly.GetExecutingAssembly().Location).Directory.FullName}\\SpaceWarp.dll");
+ $"{new FileInfo(Assembly.GetExecutingAssembly().Location).Directory!.FullName}\\SpaceWarp.dll"
+ );
Logger = base.Logger;
Instance = this;
}
@@ -55,9 +72,10 @@ private static void OnLanguageSourceAssetLoaded(LanguageSourceAsset asset)
}
asset.mSource.owner = asset;
- LocalizationManager.AddSource(asset.mSource);
+ LocalizationHelpers.AddSource(asset.mSource);
}
- public void Awake()
+
+ private void Awake()
{
BepInEx.Bootstrap.Chainloader.ManagerObject.Persist();
// IOProvider.Init();
@@ -65,9 +83,22 @@ public void Awake()
Harmony.CreateAndPatchAll(typeof(SpaceWarpPlugin).Assembly, ModGuid);
ModuleManager.LoadAllModules();
- Loading.AddAssetLoadingAction("bundles", "loading asset bundles", FunctionalLoadingActions.AssetBundleLoadingAction, "bundle");
- Loading.AddAssetLoadingAction("images", "loading images", FunctionalLoadingActions.ImageLoadingAction);
- Loading.AddAddressablesLoadingAction("localization","language_source",OnLanguageSourceAssetLoaded);
+ Loading.AddAssetLoadingAction(
+ "bundles",
+ "loading asset bundles",
+ FunctionalLoadingActions.AssetBundleLoadingAction,
+ "bundle"
+ );
+ Loading.AddAssetLoadingAction(
+ "images",
+ "loading images",
+ FunctionalLoadingActions.ImageLoadingAction
+ );
+ Loading.AddAddressablesLoadingAction(
+ "localization",
+ "language_source",
+ OnLanguageSourceAssetLoaded
+ );
}
private void SetupLuaState()
@@ -96,18 +127,27 @@ private void SetupLuaState()
}
}
+ private void UpdateLanguagesDropdown()
+ {
+ Game.SettingsMenuManager._generalSettings.InitializeLanguageDropdown();
+ }
+
+ ///
public override void OnPreInitialized()
{
// Persist all game objects so I don't need to stomp on config
ModuleManager.PreInitializeAllModules();
}
+ ///
public override void OnInitialized()
{
ModuleManager.InitializeAllModules();
SetupLuaState();
+ UpdateLanguagesDropdown();
}
+ ///
public override void OnPostInitialized()
{
ModuleManager.PostInitializeAllModules();
diff --git a/src/SpaceWarp.Game/API/Game/Extensions/PartProviderExtensions.cs b/src/SpaceWarp.Game/API/Game/Extensions/PartProviderExtensions.cs
index d77af419..353a7643 100644
--- a/src/SpaceWarp.Game/API/Game/Extensions/PartProviderExtensions.cs
+++ b/src/SpaceWarp.Game/API/Game/Extensions/PartProviderExtensions.cs
@@ -1,14 +1,21 @@
-using System.Collections.Generic;
-using System.Linq;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game;
using KSP.Sim.Definitions;
namespace SpaceWarp.API.Game.Extensions;
+///
+/// Extensions for .
+///
[PublicAPI]
public static class PartProviderExtensions
{
+ ///
+ /// Gets all parts with a module of type .
+ ///
+ /// The part provider.
+ /// The module type.
+ /// All parts with a module of type .
public static IEnumerable WithModule(this PartProvider provider) where T : ModuleData
{
return provider._partData.Values.Where(part => part.modules.OfType().Any());
diff --git a/src/SpaceWarp.Game/API/Game/Extensions/VesselVehicleExtensions.cs b/src/SpaceWarp.Game/API/Game/Extensions/VesselVehicleExtensions.cs
index e8b4df65..b7553b2c 100644
--- a/src/SpaceWarp.Game/API/Game/Extensions/VesselVehicleExtensions.cs
+++ b/src/SpaceWarp.Game/API/Game/Extensions/VesselVehicleExtensions.cs
@@ -5,9 +5,17 @@
namespace SpaceWarp.API.Game.Extensions;
+///
+/// Extensions for .
+///
[PublicAPI]
public static class VesselVehicleExtensions
{
+ ///
+ /// Sets the throttle of the vessel.
+ ///
+ /// The vessel.
+ /// The throttle value.
public static void SetMainThrottle(this VesselVehicle vehicle, float throttle)
{
var incremental = new FlightCtrlStateIncremental
@@ -17,6 +25,11 @@ public static void SetMainThrottle(this VesselVehicle vehicle, float throttle)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the roll of the vessel.
+ ///
+ /// The vessel.
+ /// The roll value.
public static void SetRoll(this VesselVehicle vehicle, float roll)
{
var incremental = new FlightCtrlStateIncremental
@@ -26,6 +39,11 @@ public static void SetRoll(this VesselVehicle vehicle, float roll)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the yaw of the vessel.
+ ///
+ /// The vessel.
+ /// The yaw value.
public static void SetYaw(this VesselVehicle vehicle, float yaw)
{
var incremental = new FlightCtrlStateIncremental
@@ -35,6 +53,11 @@ public static void SetYaw(this VesselVehicle vehicle, float yaw)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the pitch of the vessel.
+ ///
+ /// The vessel.
+ /// The pitch value.
public static void SetPitch(this VesselVehicle vehicle, float pitch)
{
var incremental = new FlightCtrlStateIncremental
@@ -44,6 +67,13 @@ public static void SetPitch(this VesselVehicle vehicle, float pitch)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the roll, yaw and pitch of the vessel.
+ ///
+ /// The vessel.
+ /// The roll value.
+ /// The yaw value.
+ /// The pitch value.
public static void SetRollYawPitch(this VesselVehicle vehicle, float roll, float yaw, float pitch)
{
var incremental = new FlightCtrlStateIncremental
@@ -55,6 +85,11 @@ public static void SetRollYawPitch(this VesselVehicle vehicle, float roll, float
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the roll trim of the vessel.
+ ///
+ /// The vessel.
+ /// The roll trim value.
public static void SetRollTrim(this VesselVehicle vehicle, float rollTrim)
{
var incremental = new FlightCtrlStateIncremental
@@ -64,6 +99,11 @@ public static void SetRollTrim(this VesselVehicle vehicle, float rollTrim)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the yaw trim of the vessel.
+ ///
+ /// The vessel.
+ /// The yaw trim value.
public static void SetYawTrim(this VesselVehicle vehicle, float yawTrim)
{
var incremental = new FlightCtrlStateIncremental
@@ -73,6 +113,11 @@ public static void SetYawTrim(this VesselVehicle vehicle, float yawTrim)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the pitch trim of the vessel.
+ ///
+ /// The vessel.
+ /// The pitch trim value.
public static void SetPitchTrim(this VesselVehicle vehicle, float pitchTrim)
{
var incremental = new FlightCtrlStateIncremental
@@ -83,6 +128,13 @@ public static void SetPitchTrim(this VesselVehicle vehicle, float pitchTrim)
}
+ ///
+ /// Sets the roll, yaw and pitch trim of the vessel.
+ ///
+ /// The vessel.
+ /// The roll trim value.
+ /// The yaw trim value.
+ /// The pitch trim value.
public static void SetRollYawPitchTrim(this VesselVehicle vehicle, float rollTrim, float yawTrim, float pitchTrim)
{
var incremental = new FlightCtrlStateIncremental
@@ -94,6 +146,11 @@ public static void SetRollYawPitchTrim(this VesselVehicle vehicle, float rollTri
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the input roll of the vessel.
+ ///
+ /// The vessel.
+ /// The input roll value.
public static void SetInputRoll(this VesselVehicle vehicle, float roll)
{
var incremental = new FlightCtrlStateIncremental
@@ -103,6 +160,11 @@ public static void SetInputRoll(this VesselVehicle vehicle, float roll)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the input yaw of the vessel.
+ ///
+ /// The vessel.
+ /// The input yaw value.
public static void SetInputYaw(this VesselVehicle vehicle, float yaw)
{
var incremental = new FlightCtrlStateIncremental
@@ -112,6 +174,11 @@ public static void SetInputYaw(this VesselVehicle vehicle, float yaw)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the input pitch of the vessel.
+ ///
+ /// The vessel.
+ /// The input pitch value.
public static void SetInputPitch(this VesselVehicle vehicle, float pitch)
{
var incremental = new FlightCtrlStateIncremental
@@ -121,6 +188,13 @@ public static void SetInputPitch(this VesselVehicle vehicle, float pitch)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the input roll, yaw and pitch of the vessel.
+ ///
+ /// The vessel.
+ /// The input roll value.
+ /// The input yaw value.
+ /// The input pitch value.
public static void SetInputRollYawPitch(this VesselVehicle vehicle, float roll, float yaw, float pitch)
{
var incremental = new FlightCtrlStateIncremental
@@ -132,6 +206,12 @@ public static void SetInputRollYawPitch(this VesselVehicle vehicle, float roll,
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the wheel steer and wheel steer trim of the vessel.
+ ///
+ /// The vessel.
+ /// The wheel steer value.
+ /// The wheel steer trim value.
public static void SetWheelSteer(this VesselVehicle vehicle, float wheelSteer, float? wheelSteerTrim = null)
{
var incremental = new FlightCtrlStateIncremental
@@ -142,6 +222,12 @@ public static void SetWheelSteer(this VesselVehicle vehicle, float wheelSteer, f
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the wheel throttle and wheel throttle trim of the vessel.
+ ///
+ /// The vessel.
+ /// The wheel throttle value.
+ /// The wheel throttle trim value.
public static void SetWheelThrottle(this VesselVehicle vehicle, float wheelThrottle,
float? wheelThrottleTrim = null)
{
@@ -153,6 +239,13 @@ public static void SetWheelThrottle(this VesselVehicle vehicle, float wheelThrot
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the X, Y and Z values of the vessel.
+ ///
+ /// The vessel.
+ /// The X orientation value.
+ /// The Y orientation value.
+ /// The Z orientation value.
public static void SetXYZ(this VesselVehicle vehicle, float? x = null, float? y = null, float? z = null)
{
var incremental = new FlightCtrlStateIncremental
@@ -164,6 +257,11 @@ public static void SetXYZ(this VesselVehicle vehicle, float? x = null, float? y
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the X, Y and Z values of the vessel.
+ ///
+ /// The vessel.
+ /// The X, Y and Z vector.
public static void SetXYZ(this VesselVehicle vehicle, Vector3 xyz)
{
var incremental = new FlightCtrlStateIncremental
@@ -175,6 +273,11 @@ public static void SetXYZ(this VesselVehicle vehicle, Vector3 xyz)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the kill rotation value of the vessel.
+ ///
+ ///
+ ///
public static void SetKillRot(this VesselVehicle vehicle, bool killRot)
{
var incremental = new FlightCtrlStateIncremental
@@ -184,6 +287,11 @@ public static void SetKillRot(this VesselVehicle vehicle, bool killRot)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the gear state of the vessel.
+ ///
+ /// The vessel.
+ /// Whether the gear is up.
public static void SetGearState(this VesselVehicle vehicle, bool up)
{
var incremental = new FlightCtrlStateIncremental
@@ -194,7 +302,11 @@ public static void SetGearState(this VesselVehicle vehicle, bool up)
vehicle.AtomicSet(incremental);
}
-
+ ///
+ /// Sets the headlight state of the vessel.
+ ///
+ /// The vessel.
+ /// Whether the headlight is on.
public static void SetHeadlight(this VesselVehicle vehicle, bool on)
{
var incremental = new FlightCtrlStateIncremental
@@ -204,7 +316,11 @@ public static void SetHeadlight(this VesselVehicle vehicle, bool on)
vehicle.AtomicSet(incremental);
}
-
+ ///
+ /// Sets the brake state of the vessel.
+ ///
+ /// The vessel.
+ /// Whether the brakes are on.
public static void SetBrake(this VesselVehicle vehicle, bool on)
{
var incremental = new FlightCtrlStateIncremental
@@ -214,6 +330,11 @@ public static void SetBrake(this VesselVehicle vehicle, bool on)
vehicle.AtomicSet(incremental);
}
+ ///
+ /// Sets the staging state of the vessel.
+ ///
+ /// The vessel.
+ /// Whether to stage.
public static void SetStage(this VesselVehicle vehicle, bool stage)
{
var incremental = new FlightCtrlStateIncremental
diff --git a/src/SpaceWarp.Game/API/Game/Messages/StateChanges.cs b/src/SpaceWarp.Game/API/Game/Messages/StateChanges.cs
index c0f5768f..91693698 100644
--- a/src/SpaceWarp.Game/API/Game/Messages/StateChanges.cs
+++ b/src/SpaceWarp.Game/API/Game/Messages/StateChanges.cs
@@ -1,5 +1,4 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Game;
using KSP.Messages;
@@ -23,50 +22,208 @@ public static class StateChanges
#region Entering States
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action InvalidStateEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action WarmUpLoadingStateEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action MainMenuStateEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action KerbalSpaceCenterStateEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action VehicleAssemblyBuilderEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action BaseAssemblyEditorEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action FlightViewEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action ColonyViewEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action Map3DViewEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action PhotoModeEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action MetricsModeEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action PlanetViewerEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action LoadingEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action TrainingCenterEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action MissionControlEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action TrackingStationEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action ResearchAndDevelopmentEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action LaunchpadEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action RunwayEntered;
+
+ ///
+ /// Invoked when the game state is changed to
+ ///
public static event Action FlagEntered;
#endregion
#region Leaving States
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action InvalidStateLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action WarmUpLoadingStateLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action MainMenuStateLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action KerbalSpaceCenterStateLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action VehicleAssemblyBuilderLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action BaseAssemblyEditorLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action FlightViewLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action ColonyViewLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action PhotoModeLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action Map3DViewLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action MetricsModeLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action PlanetViewerLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action LoadingLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action TrainingCenterLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action MissionControlLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action TrackingStationLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action ResearchAndDevelopmentLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action LaunchpadLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action RunwayLeft;
+
+ ///
+ /// Invoked when the game state is changed from
+ ///
public static event Action FlagLeft;
#endregion
diff --git a/src/SpaceWarp.Game/API/Game/Messages/StateLoadings.cs b/src/SpaceWarp.Game/API/Game/Messages/StateLoadings.cs
index 94df110c..df232a49 100644
--- a/src/SpaceWarp.Game/API/Game/Messages/StateLoadings.cs
+++ b/src/SpaceWarp.Game/API/Game/Messages/StateLoadings.cs
@@ -1,24 +1,49 @@
-using System;
-using JetBrains.Annotations;
+using JetBrains.Annotations;
using KSP.Messages;
namespace SpaceWarp.API.Game.Messages;
+///
+/// Messages related to the loading of game states.
+///
[PublicAPI]
public class StateLoadings
{
+ ///
+ /// Invoked when the training center is loaded.
+ ///
public static event Action TrainingCenterLoaded;
+ ///
+ /// Invoked when the tracking station is loaded.
+ ///
public static event Action TrackingStationLoaded;
+ ///
+ /// Invoked when the tracking station is unloaded.
+ ///
public static event Action TrackingStationUnloaded;
+
+ ///
+ /// Handler for the evenr.
+ ///
+ /// The associated message.
public static void TrainingCenterLoadedHandler(MessageCenterMessage message)
{
TrainingCenterLoaded?.Invoke(message as TrainingCenterLoadedMessage);
}
+
+ ///
+ /// Handler for the event.
+ ///
+ /// The associated message.
public static void TrackingStationLoadedHandler(MessageCenterMessage message)
{
TrackingStationLoaded?.Invoke(message as TrackingStationLoadedMessage);
}
+ ///
+ /// Handler for the event.
+ ///
+ /// The associated message.
public static void TrackingStationUnloadedHandler(MessageCenterMessage message)
{
TrackingStationUnloaded?.Invoke(message as TrackingStationUnloadedMessage);
diff --git a/src/SpaceWarp.Game/API/Game/Vehicle.cs b/src/SpaceWarp.Game/API/Game/Vehicle.cs
index 68902970..9372bdf5 100644
--- a/src/SpaceWarp.Game/API/Game/Vehicle.cs
+++ b/src/SpaceWarp.Game/API/Game/Vehicle.cs
@@ -5,10 +5,20 @@
namespace SpaceWarp.API.Game;
+///
+/// Vehicle related API.
+///
[SpaceWarpLuaAPI("Vehicle")]
[PublicAPI]
public static class Vehicle
{
+ ///
+ /// Gets the active vessel.
+ ///
public static VesselVehicle ActiveVesselVehicle => GameManager.Instance.Game.ViewController._activeVesselVehicle;
+
+ ///
+ /// Gets the active vessel component.
+ ///
public static VesselComponent ActiveSimVessel => GameManager.Instance.Game.ViewController.GetActiveSimVessel();
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Game/Modules/Game.cs b/src/SpaceWarp.Game/Modules/Game.cs
index 461156ff..c9db2432 100644
--- a/src/SpaceWarp.Game/Modules/Game.cs
+++ b/src/SpaceWarp.Game/Modules/Game.cs
@@ -5,19 +5,16 @@
namespace SpaceWarp.Modules;
+///
+/// The module for game-related APIs.
+///
[UsedImplicitly]
public class Game : SpaceWarpModule
{
+ ///
public override string Name => "SpaceWarp.Game";
- public override void LoadModule()
- {
- }
-
- public override void PreInitializeModule()
- {
- }
-
+ ///
public override void InitializeModule()
{
var game = GameManager.Instance.Game;
@@ -28,8 +25,4 @@ public override void InitializeModule()
game.Messages.Subscribe(typeof(TrackingStationUnloadedMessage), StateLoadings.TrackingStationUnloadedHandler, false, true);
game.Messages.Subscribe(typeof(TrainingCenterLoadedMessage), StateLoadings.TrainingCenterLoadedHandler, false, true);
}
-
- public override void PostInitializeModule()
- {
- }
}
\ No newline at end of file
diff --git a/src/SpaceWarp.Messaging/API/Messaging/MessageBus.cs b/src/SpaceWarp.Messaging/API/Messaging/MessageBus.cs
index dc220ba3..36590251 100644
--- a/src/SpaceWarp.Messaging/API/Messaging/MessageBus.cs
+++ b/src/SpaceWarp.Messaging/API/Messaging/MessageBus.cs
@@ -1,10 +1,10 @@
-using System;
-using System.Collections.Generic;
-using JetBrains.Annotations;
-using UnityEngine;
+using JetBrains.Annotations;
namespace SpaceWarp.API.Messaging;
+///
+/// MessageBus that can be used to publish messages with no arguments to subscribers.
+///
[PublicAPI]
public class MessageBus : MessageBusBase
{
@@ -12,21 +12,42 @@ public class MessageBus : MessageBusBase
internal override IReadOnlyList Handlers => _handlers;
internal override void RemoveHandlerAt(int index) => _handlers.RemoveAt(index);
+ ///
+ /// Subscribes a handler to the MessageBus.
+ ///
+ /// The handler to subscribe.
+ /// Thrown when the handler is null.
public void Subscribe(Action handler)
{
if (handler == null)
+ {
throw new ArgumentNullException();
+ }
_handlers.Add(handler);
}
+ ///
+ /// Unsubscribes a handler from the MessageBus.
+ ///
+ /// The handler to unsubscribe.
public void Unsubscribe(Action handler)
{
for (var i = _handlers.Count; i-- > 0;)
+ {
if (_handlers[i] == handler)
+ {
_handlers.RemoveAt(i);
+ }
+ }
}
+ ///
+ /// Publishes a message to all subscribers.
+ ///
+ ///
+ /// Publishes a message to all subscribers.
+ ///
public void Publish()
{
for (var i = _handlers.Count; i-- > 0;)
@@ -43,6 +64,9 @@ public void Publish()
}
}
+///
+/// MessageBus that can be used to publish messages with 1 argument to subscribers.
+///
[PublicAPI]
public class MessageBus : MessageBusBase
{
@@ -50,21 +74,39 @@ public class MessageBus : MessageBusBase
internal override IReadOnlyList Handlers => _handlers;
internal override void RemoveHandlerAt(int index) => _handlers.RemoveAt(index);
+ ///
+ /// Subscribes a handler to the MessageBus.
+ ///
+ /// The handler to subscribe.
+ /// Thrown when the handler is null.
public void Subscribe(Action handler)
{
if (handler == null)
+ {
throw new ArgumentNullException();
+ }
_handlers.Add(handler);
}
+ ///
+ /// Unsubscribes a handler from the MessageBus.
+ ///
+ /// The handler to unsubscribe.
public void Unsubscribe(Action handler)
{
for (var i = _handlers.Count; i-- > 0;)
+ {
if (_handlers[i] == handler)
+ {
_handlers.RemoveAt(i);
+ }
+ }
}
+ ///