diff --git a/.gitignore b/.gitignore index 93d42729..f6362e97 100644 --- a/.gitignore +++ b/.gitignore @@ -1,113 +1,12 @@ -# Build Folders (you can keep bin if you'd like, to store dlls and pdbs) -[Oo]bj/ - -# mstest test results -TestResults - -## Ignore Visual Studio temporary files, build results, and -## files generated by popular Visual Studio add-ons. - -# User-specific files -*.suo -*.user* -*.sln.docstates - -# Build results -[Dd]ebug/ -[Rr]elease/ -x64/ -*_i.c -*_p.c -*.ilk -*.meta -*.obj -*.pch -*.pdb -*.pgc -*.pgd -*.rsp -*.sbr -*.tlb -*.tli -*.tlh -*.tmp -*.log -*.vspscc -*.vssscc -.builds - -# Visual C++ cache files -ipch/ -*.aps -*.ncb -*.opensdf -*.sdf - -# Visual Studio profiler -*.psess -*.vsp -*.vspx - -# Guidance Automation Toolkit -*.gpState - -# ReSharper is a .NET coding add-in -_ReSharper* - -# NCrunch -*.ncrunch* -.*crunch*.local.xml - -# Installshield output folder -[Ee]xpress - -# DocProject is a documentation generator add-in -DocProject/buildhelp/ -DocProject/Help/*.HxT -DocProject/Help/*.HxC -DocProject/Help/*.hhc -DocProject/Help/*.hhk -DocProject/Help/*.hhp -DocProject/Help/Html2 -DocProject/Help/html - -# Click-Once directory -publish - -# Publish Web Output -*.Publish.xml - -# NuGet Packages Directory +.vs +bin +obj +GameData/**/LICENSE* +GameData/**/NOTICE* +GameData/**/README.md +GameData/**/*.version +GameData/**/*.dll +GameData/**/CHANGE_LOG.md +Source/**/Properties/Version.cs packages - -# Windows Azure Build Output -csx -*.build.csdef - -# Windows Store app package directory -AppPackages/ - -# Others -[Bb]in -[Oo]bj -sql -TestResults -[Tt]est[Rr]esult* -*.Cache -ClientBin -[Ss]tyle[Cc]op.* -~$* -*.dbmdl -Generated_Code #added for RIA/Silverlight projects - -# Backup & report files from converting an old project file to a newer -# Visual Studio version. Backup files are not needed, because we have git ;-) -_UpgradeReport_Files/ -Backup*/ -UpgradeLog*.XML - -ModuleManager.csproj.user - -ModuleManager.*.dll - -.vs* +Archive diff --git a/CHANGES.md b/CHANGES.md new file mode 100644 index 00000000..a7018073 --- /dev/null +++ b/CHANGES.md @@ -0,0 +1,107 @@ +# Module Manager /L :: Changes +*Lasciate ogne speranza, voi ch'intrate* +- - - + +* 2026-0329: 4.2.3.7 (Lisias) for KSP >= 1.2.2 + + Some pretty lame mistake I let pass through when reporting errors. + - Yet another one of my not that bright moments... +* 2025-0209: 4.2.3.6 (Lisias) for KSP >= 1.2.2 + + More sensible warnings about the `:FOR[foo]:NEEDS[foo]` problem, avoiding flagging the occurrences where the problems are not triggered. + + Reworks issues: + - [#31](https://github.com/KSP-ModularManagement/ModuleManager/issues/31) Warn when :FOR is used with :NEEDS using the same modName on the patch +* 2025-0207: 4.2.3.5 (Lisias) for KSP >= 1.2.2 + + Fixes a pretty nasty Log Spam I let pass trough + + Log a warning when `:FOR` and `:NEEDS` on the same patch uses the same identifier, as this will not work exactly as one would expect. +* 2024-0415: 4.2.3.4 (Lisias) for KSP >= 1.2.2 + + Fix some long due "Reload Database" on the Module Manager Menu (Alt-F11) + - Nope, the Full Reload is still broken, and it was hidden. Sorry! + + We had moved! + - The Official Repository is now on https://github.com/KSP-ModularManagement/ModuleManager +* 2024-0330: 4.2.3.3 (Lisias) for KSP >= 1.2 + + Slightly less spammy on spamming logs. +* 2024-0311: 4.2.3.2 (Lisias) for KSP >= 1.2 + + Logging revamp/refactoring + - Saner code + - MOAR LOGS + - Previous `LOGSPAM` conditional compiling is now pushed into the mainstream as TRACE messages. + - Edit the relevant ModuleManager section on `/PluginData/KSPe.cfg` file to set the desired log level. +* 2023-0716: 4.2.3.1 (Lisias) for KSP >= 1.2 + + Bumps versioning, catching up with upstream and formalising he fixes already implemented - ome for ages... :) + + Removes yet some more deprecated calls from `KSPe`. +* 2023-0521: 4.2.2.6 (Lisias) for KSP >= 1.2 + + (Hopefully) mitigates a pretty weird problem happening on some new Intel CPU's with asymmetric cores (and on a less extent, faster Intel and probably AMD with symmetric ones). + - Initially discovered by [LinuxGuruGamer](https://github.com/sarbian/ModuleManager/pull/180), then (pretty badly) misdiagnosed by me until I got in my senses and did some testings. + + Removes some deprecated calls from `KSPe`. +* 2023-0316: 4.2.2.5 (Lisias) for KSP >= 1.2 + + Drops the Experimental status + + Relicense the whole shebang to GPL-3.0 + + Make the thing properly distributable. + + **Needs** KSPe 2.5 or higher. +* 2022-0918: 4.2.2.4b (Lisias) for KSP >= 1.2 + + Updates the [`INSTALL.md`](https://github.com/KSP-ModularManagement/ModuleManager/blob/master/INSTALL.md) file to reflect the new deployment model. + - A new `MM/L` release wasn't really **needed**, but since I failed to update the install instructions and there're people using this, I choose to be conservative on the matter. + - There're no changes on the DLL, so I choose to shove a "b" on the same release number. +* 2022-0809: 4.2.2.4 (Lisias) for KSP >= 1.2 + + Fixed a pretty lame mistake on the 1.2.2 port. + - And, yeah. I should had tested this thing on KSP 1.2.2 recently... #facePalm +* 2022-0719: 4.2.2.3 (Lisias) for KSP >= 1.2 + + More resilient handling of a potentially corrupted (or old) cache. +* 2022-0716: 4.2.2.2 (Lisias) for KSP >= 1.2 + + Removes a memory leak, and promotes some key functions reusability. + + Mitigates false positives while checking the ConfigCache, aiming to avoid the need of "deleting the cache when something weird happens" after load. + - It's pretty rare, but not that much, that a change on a file ends up getting the same SHA256. + - Checking also the file size now, as it's **way more** improbable that we would had a hash collision on a file with the same size. +* 2022-0620: 4.2.2.1 (Lisias) for KSP >= 1.2 + + Catch up with upstream: + - v4.2.2 + - Support wildcards in nodetype matching so you can do @*,* {} + - Support # in value names since loc names start with # + - Tell Localizer to reload the language after MM finishes + + More orthodoxous deploy model + - **COMPLETELY REMOVE ALL OLDER FILES FROM `GameData`** before updating !! +* 2022-0306: 4.2.1.3 (Lisias) for KSP >= 1.2 + + More sensible performance logging. +* 2021-0927: 4.2.1.2 (Lisias) for KSP >= 1.2 + + Code base updated to the newest KSPe 2.4 series + + **ATTENTION** + - This release will only work on the new KSPe 2.4 series! +* 2021-0907: 4.2.1.1 (Lisias) for KSP >= 1.2 + + Catch up with upstream: + - 4.2.1 + - Fix off-by-one string indexing in constraint checking Also change string + - comparison type to `StringComparison.Ordinal`, which should be the correct type according to [best-practices-strings](https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings). + - Undo string comparison change. + - 4.2.0 + - Set modded physics and reload earlier + - Ensure string comparison is culture invariant + - Always replace physics +* 2021-0822: 4.1.4.8 (Lisias) for KSP >= 1.2 + + Fix a performance issue on KSP >= 1.8, due a change on when the GameSettings were being applied (that ended you screwing my fork's restoring point) +* 2021-0227: 4.1.4.7 (Lisias) for KSP >= 1.2 + + Resurrects the Patch Logger on file +* 2020-1216: 4.1.4.6 (Lisias) for KSP >= 1.2 + + Fixing a regression I introduced on 4.1.4.3 when I refactored MM to allow suporting KSP 1.2.2 again. + - Yep... Pretty stupid... #facePalm +* 2020-0922: 4.1.4.5 (Lisias) for KSP >= 1.2 + + Making sure that eventual Database reloading borks don't screw up the KSP Performance Settings. + + The performance gain claimed by 4.1.4.4 may be inaccurate - the measures on my rig enhanced a bit, but a closer inspection of the original code revealed that (obviously) it was already doing (almost) the same. + - Until I have more (and better) information about what exactly is happening, I suggest to take any measurement improvement with a huge grain of salt. + + The support for KSP 1.2 is still beta! + - Some less used features are still Work In Progress. +* 2020-0921: 4.1.4.4 (Lisias) for KSP >= 1.2 + + Squeezing the last possible second from the Loading Scene by pumping up Unity's FPS settings (and restoring user's settings on finish) + - Your mileage will vary, but I got about 10% faster loading times on my rig when using the MM cache, and even a bit more while rebuilding it on heavily modded instalments. + + Beta support for KSP 1.2 is on the wild! + - Some less used features are still Work In Progress. +* 2020-0825: 4.1.4.3 (Lisias) for KSP >= 1.3.1 + + Preventing KSPe to use Thread Safe logging. + - MM doesn't need it (yet), and it's somewhat verbose on the logging. + - KSPe thread safe logging will also mangle a bit the timestamps (as the writings are delayed until the next frame), what may be undesirable on MM. + + Needs KSPe 2.2.1 or newer. +* 2020-0711: 4.1.4.1 (Lisias) for KSP >= 1.3.1 + + Merging upstream updates: + - Fix a bug with LAST[modx] when modx is not present + - some code cleanups +* 2020-0707: 4.1.4.0 (sarbian) for KSP >= 1.8 + + Fix a bug with LAST[modx] when modx is not present + + some code cleanups diff --git a/CHANGE_LOG.md b/CHANGE_LOG.md new file mode 100644 index 00000000..badaafcd --- /dev/null +++ b/CHANGE_LOG.md @@ -0,0 +1,852 @@ +# Module Manager /L :: Change Log +*Lasciate ogne speranza, voi ch'intrate* +- - - + +* 2026-0329: 4.2.3.7 (Lisias) for KSP >= 1.2.2 + + Some pretty lame mistake I let pass through when reporting errors. + - Yet another one of my not that bright moments... +* 2025-0209: 4.2.3.6 (Lisias) for KSP >= 1.2.2 + + More sensible warnings about the `:FOR[foo]:NEEDS[foo]` problem, avoiding flagging the occurrences where the problems are not triggered. + + Reworks issues: + - [#31](https://github.com/KSP-ModularManagement/ModuleManager/issues/31) Warn when :FOR is used with :NEEDS using the same modName on the patch +* 2025-0207: 4.2.3.5 (Lisias) for KSP >= 1.2.2 + + Fixes a pretty nasty Log Spam I let pass trough + + Log a warning when `:FOR` and `:NEEDS` on the same patch uses the same identifier, as this will not work exactly as one would expect. +* 2024-0415: 4.2.3.4 (Lisias) for KSP >= 1.2.2 + + Fix some long due "Reload Database" on the Module Manager Menu (Alt-F11) + - Nope, the Full Reload is still broken, and it was hidden. Sorry! + + We had moved! + - The Official Repository is now on https://github.com/KSP-ModularManagement/ModuleManager +* 2024-0330: 4.2.3.3 (Lisias) for KSP >= 1.2 + + Slightly less spammy on spamming logs. +* 2024-0311: 4.2.3.2 (Lisias) for KSP >= 1.2 + + Logging revamp/refactoring + - Saner code + - MOAR LOGS + - Previous `LOGSPAM` conditional compiling is now pushed into the mainstream as TRACE messages. + - Edit the relevant ModuleManager section on `/PluginData/KSPe.cfg` file to set the desired log level. +* 2023-0716: 4.2.3.1 (Lisias) for KSP >= 1.2 + + Bumps versioning, catching up with upstream and formalising the fixes already implemented - some for ages... :) + + Removes yet some more deprecated calls from `KSPe`. +* 2023-0703: 4.2.3.0 (Sarbian) for KSP >= 1.9 + + Fix the dll hashing when the dll is already opened. by @linuxgurugamer + + Fix for MM loading the wrong physics file when when when using the faulty PDLauncher workaround +* 2023-0521: 4.2.2.6 (Lisias) for KSP >= 1.2 + + (Hopefully) mitigates a pretty weird problem happening on some new Intel CPU's with asymmetric cores (and on a less extent, faster Intel and probably AMD with symmetric ones). + - Initially discovered by [LinuxGuruGamer](https://github.com/sarbian/ModuleManager/pull/180), then (pretty badly) misdiagnosed by me until I got in my senses and did some testings. + + Removes some deprecated calls from `KSPe`. +* 2023-0316: 4.2.2.5 (Lisias) for KSP >= 1.2 + + Drops the Experimental status + + Relicense the whole shebang to GPL-3.0 + + Make the thing properly distributable. + + **Needs** KSPe 2.5 or higher. +* 2022-0918: 4.2.2.4b (Lisias) for KSP >= 1.2 + + Updates the [`INSTALL.md`](https://github.com/KSP-ModularManagement/ModuleManager/blob/master/INSTALL.md) file to reflect the new deployment model. + - A new `MM/L` release wasn't really **needed**, but since I failed to update the install instructions and there're people using this, I choose to be conservative on the matter. + - There're no changes on the DLL, so I choose to shove a "b" on the same release number. +* 2022-0809: 4.2.2.4 (Lisias) for KSP >= 1.2 + + Fixed a pretty lame mistake on the 1.2.2 port. + - And, yeah. I should had tested this thing on KSP 1.2.2 recently... #facePalm +* 2022-0719: 4.2.2.3 (Lisias) for KSP >= 1.2 + + More resilient handling of a potentially corrupted (or old) cache. +* 2022-0716: 4.2.2.2 (Lisias) for KSP >= 1.2 + + Removes a memory leak, and promotes some key functions reusability. + + Mitigates false positives while checking the ConfigCache, aiming to avoid the need of "deleting the cache when something weird happens" after load. + - It's pretty rare, but not that much, that a change on a file ends up getting the same SHA256. + - Checking also the file size now, as it's **way more** improbable that we would had a hash collision on a file with the same size. +* 2022-0620: 4.2.2.1 (Lisias) for KSP >= 1.2 + + Catch up with upstream: + - v4.2.2 + - Support wildcards in nodetype matching so you can do @*,* {} + - Support # in value names since loc names start with # + - Tell Localizer to reload the language after MM finishes + + More orthodoxous deploy model + - **COMPLETELY REMOVE ALL OLDER FILES FROM `GameData`** before updating !! +* 2022-0306: 4.2.1.3 (Lisias) for KSP >= 1.2 + + More sensible performance logging. +* 2021-0927: 4.2.1.2 (Lisias) for KSP >= 1.2 + + Code base updated to the newest KSPe 2.4 series + + **ATTENTION** + - This release will only work on the new KSPe 2.4 series! +* 2021-0907: 4.2.1.1 (Lisias) for KSP >= 1.2 + + Catch up with upstream: + - 4.2.1 + - Fix off-by-one string indexing in constraint checking Also change string + - comparison type to `StringComparison.Ordinal`, which should be the correct type according to [best-practices-strings](https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings). + - Undo string comparison change. + - 4.2.0 + - Set modded physics and reload earlier + - Ensure string comparison is culture invariant + - Always replace physics +* 2021-0822: 4.1.4.8 (Lisias) for KSP >= 1.2 + + Fix a performance issue on KSP >= 1.8, due a change on when the GameSettings were being applied (that ended you screwing my fork's restoring point) +* 2021-0801: 4.2.1 (Sarbian) for KSP 1.8.0 + + Fix off-by-one string indexing in constraint checking Also change string + + comparison type to `StringComparison.Ordinal`, which should be the + + correct type according to + + https://docs.microsoft.com/en-us/dotnet/standard/base-types/best-practices-strings. + + Undo string comparison change. +* 2021-0801: 4.2.0 (Sarbian) for KSP 1.8.0 + + Normalize KSP root path + + KSP makes it weird + + Addresses confusion in #164 + + Set modded physics and reload earlier + + Do it in post patch, this allows the part loader to pick up changes + + (e.g. rigidbody min mass) + + mark dependencies as copy local false + + prevents them from showing up in the target directory + + fix remaining .NET 3.5 nuget packages + + upgrade visual studio runner + + Update remaining NuGet packages + + Add specific language markers to all project files + + seems to get confused otherwise + + Ensure string comparison is culture invariant + + And get rid of message suppresions related to it + + Always replace physics + + On a database reload this will already be true but we still want physics + + reloading to happen +* 2021-0227: 4.1.4.7 (Lisias) for KSP >= 1.2 + + Resurrects the Patch Logger on file +* 2020-1216: 4.1.4.6 (Lisias) for KSP >= 1.2 + + Fixing a regression I introduced on 4.1.4.3 when I refactored MM to allow suporting KSP 1.2.2 again. + - Yep... Pretty stupid... #facePalm +* 2020-0922: 4.1.4.5 (Lisias) for KSP >= 1.2 + + Making sure that eventual Database reloading borks don't screw up the KSP Performance Settings. + + The performance gain claimed by 4.1.4.4 may be inaccurate - the measures on my rig enhanced a bit, but a closer inspection of the original code revealed that (obviously) it was already doing (almost) the same. + - Until I have more (and better) information about what exactly is happening, I suggest to take any measurement improvement with a huge grain of salt. + + The support for KSP 1.2 is still beta! + - Some less used features are still Work In Progress. +* 2020-0921: 4.1.4.4 (Lisias) for KSP >= 1.2 + + Squeezing the last possible second from the Loading Scene by pumping up Unity's FPS settings (and restoring user's settings on finish) + - Your mileage will vary, but I got about 10% faster loading times on my rig when using the MM cache, and even a bit more while rebuilding it on heavily modded instalments. + + Beta support for KSP 1.2 is on the wild! + - Some less used features are still Work In Progress. +* 2020-0825: 4.1.4.3 (Lisias) for KSP >= 1.3.1 + + Preventing KSPe to use Thread Safe logging. + - MM doesn't need it (yet), and it's somewhat verbose on the logging. + - KSPe thread safe logging will also mangle a bit the timestamps (as the writings are delayed until the next frame), what may be undesirable on MM. + + Needs KSPe 2.2.1 or newer. +* 2020-0822: 4.1.4.2 (Lisias) for KSP >= 1.3.1 + + **Withdrawn** due a KSPe bork. +* 2020-0711: 4.1.4.1 (Lisias) for KSP >= 1.3.1 + + Merging upstream updates: + - Fix a bug with LAST[modx] when modx is not present + - some code cleanups +* 2020-0707: 4.1.4.0 (sarbian) for KSP >= 1.8 + + Fix a bug with LAST[modx] when modx is not present + + some code cleanups +* 2020-0616: 4.1.3.2 (Lisias) for KSP >= 1.3.1 + + A nasty mishap from an old merge (dated 2018-11) was detected and fixed. + - See Issue [#4](https://github.com/KSP-ModularManagement/ModuleManager/issues/4). +* 2020-0526: 4.1.3.1 (Lisias) for KSP >= 1.3.1 + + Adding a nice 'Houston' GUI message + + Merging upstream updates: + - Adding an Exception interceptor to catch `ReflectionTypeLoadException` and properly blame DLLs + - Cleanup the InterceptLogHandler, remove double logging and avoid any risk of throwing more + + These things were reworked to keep them compatible with previous KSP versions. +* 2019-1130: 4.1.3.0 (sarbian) for KSP 1.8 + + Cleanup the InterceptLogHandler, remove double logging and avoid any risk of throwing more and improve the badly worded warning + + Start the Handler earlier +* 2019-1115: 4.1.2.0 (sarbian) for KSP 1.8 + + Add an Exception interceptor to catch ReflectionTypeLoadException and properly blame broken DLLs +* 2019-1027: 4.1.1.0 (sarbian) for KSP 1.8 + + Outdated Firespitter warning +* 2019-1016: 4.1.0.0 (sarbian) for KSP 1.8 + + Extract escaping/unescaping of node values + + Fix dump database to files + + Fix reload dialog showing 100% when it shouldn't + + KSP 1.8 ! With less cat bugs +* 2019-0807: 4.0.3.1 (Lisias) for KSP >= 1.3.1 + + Updating code to the latest KSPe API + - Getting rid of deprecated warnings + + Getting rid of the overcomplicated logging code + - Relying on KSPe to that + - Logging into a file will be implemented later on KSPe itself. Place holders were kept. + + Merging upstream updates: + - Improvements on thread safety + - Small improvements on performance (regex caching and preserving config cache when just whitespaces were changed) + - Better handling of Escape Chars, SHAs and URLs + - Some code cleaning and better test cases +* 2019-0807: 4.0.3.0 (sarbian) for 1.4 <= KSP <= 1.7.3 + + add thread-safe KeyValueCache + + use new KeyValueCache class as regex cache + + add test for ProtoUrlConfig + + Add name value to applying patch messages + + Fix StreamLogger ignoring messages + + Redo logging interface + + Initialize LogMessage from old LogMessage + + Don't put date on every log message + + Initialize timestamp with log message + + ModLogger -> PrefixLogger + + Unnecessary using + + Use better assertion + + Mark disposables as sealed + + Another unnecessary using + + Use custom code to lookup file by url + + Put extension on cache URLs + + Alphabetize .csproj files + + improve file sha generator + + Convert UrlBuilder cfg test to theory + + Set FileType based on common types + + unnecessary using + + make StreamLoggerTest.TestLog work on \n platforms + + Improve TestConfigNodeTest + + Remove redundant parent class + + Fix TestConfigNode's handling of escaped chars + + Clean up test a bit + + Fix DeepCopy handling of escaped values + + Fix ModifyNode handling of escaped characters + + Ensure tabs and newlines don't break cache +* 2019-0405: 4.0.2.1 (Lisias) for KSP >= 1.3.1 + + Reverting change on MMPatchLoader to allow it to be findable by `UnityEngine.Object.FindObjectOfType` + + Merging upstream updates: + - Allow assemblies to add to mod list (Fix for Kerbalism compatibility) + - Add -mm-dont-copy-logs command line flag if you do not want to copy MM log back into the game log + - Fix for KSP runs in debug mode. +* 2019-0203: 4.0.2.0 (sarbian) for KSP 1.3 & 1.4 + + Fix datetime format + + Use KSP's directory listing rather than file system + + Better status updates in post patch + + Add -mm-dont-copy-logs command line flag + + Allow assemblies to add to mod list + + wait another frame for plugins to finish initializing + + Don't use Unity's time since startup in thread +* 2019-0125: 4.0.1.0 (sarbian) for KSP 1.3 & 1.4 + + Delete unnecessary space + + Fix modded physics and tech treegithubweb) + + Make physics and tech tree node names constant +* 2019-0125: 4.0.0.2 (Lisias) for KSP >= 1.3.1 + + Merging upstream updates: + - [blowfish](https://forum.kerbalspaceprogram.com/index.php?/profile/119688-blowfish/) worked his magic once more and now MM does the patching while the game loads the models and textures. + - Fix tech tree and modded physics + + (my) Fixes to the upstream: + - Fixing the Logging system, restoring the (sane) previous behaviour. The new logs were preserved, and can be found on `/Logs/ModuleManager` + - Allowing "stock" compatibility to 1.3.1 by avoiding >= 1.4 specifics #hurray :) + - Monitoring changes to TechTree and Physics + - Preventing hijacking them when another Add'On changes them. + - They are set up only **one** at first time Space Center is loaded. From there, it only logs if they were changed. + + Stating **Official** support for KSP 1.3.1 :) +* 2019-0124: 4.0.0.0 (sarbian) for KSP 1.3 & 1.4 + + Update NuGet packages where available + + Accessory projects on .NET 4.7.1 + + Update NSubstitute to latest + + Update Xunit + + Fix Xunit warnings + + implement stream logger + + Unnecessary using + + These are already run by MMPatchLoader + + Extract post patch + + Operate on a copy of the game database then apply + + Move path initialization to static initializer + + Make sure cache also uses copy of game db + + Extract paths to their own class + + patch in background + + Remove PurgeUnused + + Put log paths in path repository + + Rename file to reflect class name + + Dump ModuleManager log to main log after patching + + Don't count insert nodes as patches + + Only display whole percentages + + Add subdir under Logs + + Replace reloading screen messages with dialog + + add LogSplitter + + Save patch log and dump when loading from cache + + Get rid of stream logger's exception logger + + Get rid of trailing whitespace + + use international date format + + extract common parts of reading logs from queue to its own class +* 2019-0110: 3.1.3.1 (Lisias) for KSP >= 1.4.1 + + Merging 1.6.0 DragCube workaround from uptream + + Certifying for use on 1.5.x and 1.6.x series + + Bumping up version to catch upstream's +* 2019-0108: 3.1.3.0 (sarbian) for KSP 1.4 + + Implement :LAST[mod] pass + + return iterator rather than array + + Workaround for 1.6.0 PartDatabase rebuild +* 2018-1125: 3.1.2.0 (sarbian) for KSP 1.4 + + Fix color tag + + Clear filesSha before generating sha + + Move election check up + + Make MM a once addon + + Get rid of unnecessary using +* 2018-1112: 3.1.1.1 (Lisias) for KSP 1.4; 1.5 + + Adding KSPe logging facilities + + Syncing source with upstream latest fixes. + - more Internal code improvement by @blowfish +* 2018-1112: 3.1.1.0 (sarbian) for KSP 1.4 + + Make patch stopwatch local + + Make useCache local + + Make Patch an object + + Simplify a bit + + Extra semicolon + + Extract interface for PatchList, modify PatchExtractor + + Allow null value in wildcard match + + Extract node matcher + + Extract IPatch interface, split up root patches + + Fix tests depending on line endings + + Whitespace + + Allow warnings + + Make ArrayEnumerator more versatile + + Tag, TagList, TagListParser + + Restructure patch building + + Make extra colons a warning rather than an error +* 2018-1019: 3.1.0.1 (Lisias) for KSP 1.4 + + Declaring this thing **EXPERIMENTAL**. + - I will properly maintain it, but it still Experimental (and non Standard) + + Syncing source with upstream latest fixes. +* 2018-1015: 3.1.0.0 (sarbian) for KSP 1.4 + + Stupid typo + + Remove unused variable + + Make const stuff const + + Fix typo in test +* 2018-1011: 3.0.7.4 (Lisias) for KSP 1.4 + + We have moved to the properly maintained /L Division! :) + + No code changes from the last release. +* 2018-1010: 3.0.7.3 (Lisias) for KSP 1.4 + + Moving the datafiles to /PluginData , where God intended it to be. + + Using KSPe facilities + - (some) Logging + - File System and Data Files + + Some small glitches and what appears to be a behavior inconsistency fixed. + + Doing things the right way this time. +* 2018-1010: 3.0.7.2 (Lisias) for KSP 1.4 -- WITHDRAWN +* 2018-0930: 3.0.7.1 (Lisias) for KSP 1.4 + + fixing MissingMethodException: Method not found: 'UnityEngine.Texture2D.LoadImage'. +* 2018-0505: 3.0.7 (sarbian) for KSP 1.4 + + Fix deprecation + + Turn some semi-redundant methods into extensions + + Keeps having to reimplement them for every IBasicLogger implementation + + Split up prefixing and translating logs for unity + + Should be separate classes. + + Allow parentheses in value name + + Allow spaces in value names + + Addresses #107 + + Fix operators + + Addresses #110 + + Operators are now parsed like commands, removed from the regex. + + Fix value assignment with * indexer + + Broken in #111 - probably an unusual case but it would have worked + + before. + + Added tests to ensure that this fixes it. Tests are not and will + + probably never cover all of MMPatchLoader.ModifyNode but useful to add + + bugfix cases here as they occur. + + Reflection fields should be readonly + + Create special GameData subdirectory + + It's special + + Allow checking needs against directories + + If the needs string contains a / it will check for a directory with that + + path in GameData. Notes: + - PluginData folders are excluded + - Leading and trailing slashes are allowed + - Multiple slashes together will be treated as a single slash + - Comaprison is case sensitive + + Require at least one space before the operator (#119) + + Fixes wildcards in value names. If * appears in at the end of value + + name without a space it should be interpreted as a wildcard rather than + + the multiplication operator + + Fix SHA generation for DLL - Fix #120 + + Make sure TransformFinalBlock is called *after* the last block +* 2018-0313: 3.0.6 (sarbian) for KSP 1.4 + + Cats trails fix and better text position +* 2018-0307: 3.0.5 (sarbian) for KSP 1.4 + + Fix :NEEDS clause sometimes not getting removed + + Fixes #94 + + remove ModuleManager.csproj from .gitignore + + It was under version control anyway + + Make post build into a shell script, allowing cross-platform + + compatibility + + Just requires sh to be installed on Windows. Relies on $PDB2MDB to find + + the pdb2mdb executable, and $KSPDIR to find where to copy to. If either + + of these are absent, it will be ignored (but the build will still work) +* 2018-0211: 3.0.4 (sarbian) for KSP 1.3 + + Allow operator-like character in value name + + Means that the operator needs a space before it in most cases + + Already was the case with - and * but now also the case for other + + operator-like characters + / ^ ! +* 2018-0209: 3.0.3 (sarbian) for KSP 1.3 + + Fix for #92 - non-US Linux decimal separator fix +* 2018-0208: 3.0.2 (sarbian) for KSP 1.3 + + No changelog provided +* 2017-1206: 3.0.1 (sarbian) for KSP 1.3 + + Add a -mm-dump cmd line option and redo the export + + Now uses the same directory sub tree as GameData + + Fix NEEDS checking for inner nodes/values + + Didn't work if you had both top level NEEDS and NEEDS on a subnode/value + + since it was checking NEEDS on the wrong node in that case +* 2017-1202: 3.0.0 (sarbian) for KSP 1.3 + + Begin splitting files up (#76) + - rename file + - most of it is MMPatchLoader so that's what it'll be + - Remove corrupt #region + - It starts in one class and ends in another, I can't tell where it's + + really supposed to go + - Move addon to its own file + - Put cats in a box + - Can has namespace + - Promote business cat to manager + - Unnecessary now + - Old stuff + + Change debug C# version to default + + VS, why u do dis? + + Add ImmutableStack class + + Add PatchContext struct + + Use ImmutableStack and PatchContext in MM + + Remove unused code + + Apparently had to do with texture replacer corruption, but not called + + anywhere + + Implement IEnumerable + + Add Depth property + + Use immutability in CheckNeeds + + Forgot a using directive + + Ged rid of Win64 specific code + + Doesn't matter anymore + + Needs to be included in the project too + + Add logging interface + + Extract progress into its own object + + Use logger and progress + + Make some things static that no longer depend on the patch loader's + + state + + Remove blocking option + + It's no longer used + + Use inline variable declaration + + Make log messages consistent + + Make deletes and copies count toward patch count + + Make names more accurate + + These are called before the patch is applied + + Simplify null check + + move main project to its own directory + + Allows more to be added + + Better output dir for debug + + Do not copy local + + Add test project + + Add MM, Assembly-CSharp, UnityEngine refs + + Add console runner + + Will be needed eventually + + Yo dawg, I heard you like tests + + Add TestConfigNode class + + Makes testing with ConfigNodes by simplifying creating them + + Reference TestUtils + + Don't reference a specific version of System + + Add test for ImmutableStack + + Add test for GetPath + + Add NSubstitute + + Add tests for ModLogger + + Fix an error + + Add UrlBuilder + + Hackily creates UrlDir, UrlFile, UrlConfig for testing purposes + + Progress shouldn't depend on deleted subnodes + + The number of needs unsatisfied nodes it should be counting is the + + number of root nodes that have been removed, not subnodes as well + + These should use actual URLs + + Since all the calls were just using .url anyway + + These too + + Minor logging tweak + + Add tests for PatchProgress + + Replace DeepCopy with ConfigNode.CreateCopy + + It does 100% the same thing (and is recursive) + + Inline out variable declarations + + Yay C#7 + + Obey naming conventions + + Pull Command and ParseCommand out of MMPatchLoader + + Would be nice if enums allowed static methods + + Extract ShallowCopy + - this" is the node you're copying to so that the extension method is + + only modifying "its" node + + Don't create duplicates in UrlBuilder + + Add ArrayEnumerator + + Enumerates arrays in a garbage-free way + + PatchList + + list of patches, 'nuff said + + Add PatchExtractor + + Extracts patches from the game database and sorts them + + Add SafeUrl extension method for UrlConfig + + Makes sure logging doesn't mess up, and fixes the weird quirk where a + + node with a name value ends up displaying that instead of its actual + + name + + Use SafeUrl in logging + + Remove unused + + Doesn't really have any benefit + + Log when BEFORE or AFTER patch deleted + + This is pretty much equivalent to unsatisfied NEEDS, so it should be + + noted as such. Also log on an unsatisfied FOR, although this shouldn't + + happen (make it a warning) + + Fix case issues + + Mods may not be lowercase to begin with, need to handle this + + Extract IsBracketBalanced + + Remove bracket unbalanced nodes when sorting + + Unused method + + Bring back DeepCopy + + Apparently KSP's default implementation fails on badly formed nodes + + Fix bad region + + Make sure badly formed mod passes are an error + + That's a bug + + Add some explanatory comments + + Unnecessary using directives + + Use sorted patches when applying + + Improves performance somewhat + + Verified that sorting patches takes almost no time even for a fairly + + large number of patches + + Remove now-unnecessary try-catch + + There's already one around it and we no longer care about removing + + patches from the database at this stage + + Replace big if with guard clause + + Reduces indentation. Insert nodes shouldn't exist here anyway + + Simplify this + + It no longer has to look in actual passes here, so we can just use the + + name we want it to display. + + It does change the way it displays in the loading screen but that seems + + fine. + + Invalid command = error on the patch extractor + + This seems like the right place to check it + + Extract RemoveWS + + Fix logging + + Extract PrettyPrint + + Get rid of unnecesary using directives + + Don't run PrePatchInit if cache is being used + + Mod list is not necessary + + Eliminate mods instance variable + + Use method param rather than instance var + + Makes things easier to disentagle + + Eliminate Update + + Status will be updated when necessary anyway + + Eliminate redundant logging + + MMPatchLoader logs this info itself + + Keep track of progress fraction independently + + Make StatusUpdate less general + + If cache is used, status only needs to be set once, no need to check it + + every time + + Move this + + What I get for trying to make a bunch of changes and then split them + + into small commits + + Eliminate Progress instance variable + + Make it local, inject where needed + + Make more methods static + + All their instance variable dependencies have been eliminated + + This is no longer necessary + + And will probably result in an error anyway + + Move exception handling outside of PrettyConfig + + Callers really shouldn't be trying to print the result if it resulted in + + an exception anyway + + Tweak test + + This isn't the case it was trying to test + + Allow adding a ConfigNode.Value in initializer + + Not useful yet but maybe at some point + + Extract PrettyConfig (for UrlConfig) + + Add one more test + + Make CheckNeeds static + + Can now be extracted + + This can already be static + + Remove unnecessary Using + + Improve url and node printing + - Handle null name explicitly + - Include url when printing a UrlConfig + + Extract CheckNeeds + + Equality vs sameness mostly not tested for now, need to determine + + desired behavior + + Ensure that final string printed to the screen is the actual status + + Fix up mod list logging + - Use a string builder + - Print assemblies in a nicer format (table) + + Use Path.Combine + + It's more concise then concatenating with the separator char + + Unnecessary now + + Improve assembly list + - Get rid of unused code + - Include KSPAssembly version + + Accidentally removed + + Move tracking number of patches + + from mod list to sorting patches + + Put progress counts in their own object + + Allows the same counts to be used with a different logger. Also remove + + unused setter for NeedsUnsatisfiedRootCount + + Move exception handling out of FIleSHA + + Callers should be aware of exceptions anyway + + Extract FileSHA + + Interacts with the file system so difficult to test unfortunately + + Fix unassigned variable + + Make this extractable + + Extract GenerateModList + + Unfortunately interacts with AssemblyLoader and the file system so not + + really testable + + Add MessageQueue + + Add QueueLogger and supporting classes + + Allows logging to a queue + + Don't keep track of non-root needs unsatisfied + + Isn't used anywhere + + Add FatalErrorHandler + + Allows us to display a message to the user and quit when an + + unrecoverable error occurs. + + Can't really be tested unfortunately. + + Add background task support + + Allows a background task to be run and monitored, including if it exits + + due to an exception + + Begin creating Progress namespace + + Finish creating Progress namespace + + Unnecessary directives + + Add needs test for and/or and capitalization + + Separate out progress counter + + Make it so that all the values can be incremented but not otherwise + + messed with. + + Allow a new progress tracker to be initialized that shares a counter + + with another but uses a different logger + + Ensure Counter behaves like an int + + More unnecessary using + + Add test for ! (not) in :NEEDS + + More unnecessary using directives + + Extract application of patches to its own thread + + Allows it to not be bound by logging which can be slow + + Test and fix PatchProgress.ProgressFraction + + Patches are now only counted after needs are checked, so this shouldn't + + consider needs unsatisfied nodes + + Tweak + + Only convert to array once per pass + + This is expensive + + Make node matching its own method + + Saves a level of indentation + + Loop only applies to edit patches + + Saves another indentation level. Also remove MM_PATCH_LOOP {} after + + done + + Don't convert to an array at all + + It's not necessary. Also don't use switch - makes things cleaner. It's + + only 3 cases anyway + + Ensure that user gets updates during long passes + + The patcher can potentially generate log messages faster than the main + + thread can log them, causing frames that are noticeably long with no + + updates. This ensures that yields still happen then. + + Verified that this does not meaningfully affect performance. Previous + + tests suggest that the time wasted by waiting until the next frame is + + relatively small. + + Without switch, i is valid here + + Ensure time between each check of the log queue + + This prevents the queue from being locked too often, slowing down the + + patching thread + + Convert to an array initially + + Apparently it saves a bit of time, and this won't be changed while + + patches run + + Having an actual array here no longer necessary + + Apparently Linq slows things down + + I guess it matters at scale + + Improve access of name a bit + + Looks like GetValue("name") has a bit of overhead, instead we can check + + if the UrlConfig's type == name + + Move loop out of loop + + This is all a bit loopy + + case should match filename + + matters on some filesystems +* 2017-0629: 2.8.1 (Sarbian) for KSP 1.3 + + Improve some cat related code and add -ncats cmd line option + + Improve logging related to some exceptions + + Update project file +* 2017-0526: 2.8.0 (Sarbian) for KSP 1.3 + + Revert "Temp revert of 1.3 changes to release a 1.2 patch" + + This reverts commit 29df624348391373485a82fec75e273ceed30648. +* 2017-0506: 2.7.6 (sarbian) for KSP 1.3 + + KSP 1.3 changes (#66) + - Add names to dialog windows + - Now required + - Adjust MMPatchLoaderIndex + - A new LoadingSystem was added at the beginning (FontLoader). This + + change ensures that MM will always be after the GameDatabase regardless. + - Fix position of MM info in loading screen + - Things seem to have moved + - Remove unused field + - Press Alt+F11 again to dismiss the menu + - Apparently this wasn't a feature before (at least not recently) but + + pretty simple to implement + + Reload PartUpgrade System after patching (#70) + + As the part-upgrade data is initially populated prior to ModuleManager + + patching, this fix allows for the patches that are applied to the + + PARTUPGRADE nodes to be reloaded for use by the PartUpgrade system. + + With this fix in place the tech-nodes, names, descriptions, etc, for the + + part-upgrade parts located on the tech tree will use the proper + + post-patching config data. + - This solution has been tested to work properly when used directly from + + a ModuleManagerPostLoad callback. + - Fix for problems discovered in KSP-RO/RealismOverhaul/#1628 + + Temp revert of 1.3 changes to release a 1.2 patch +* 2016-1129: 2.7.5 (sarbian) for KSP 1.2.1 + + No changelog provided +* 2016-1114: 2.7.4 (sarbian) for KSP 1.2.1 + + Fix typos (#63) + + Fix #64 - Targeting all values applied the operation more than it should +* 2016-1105: 2.7.3 (sarbian) for KSP 1.2.1 + + No changelog provided +* 2016-1011: 2.7.2 (sarbian) for KSP 1.2 + + No changelog provided +* 2016-1008: 2.7.1 (sarbian) for KSP 1.2 + + Fix the problem with setting value name that include comma (unless the + + comma is followed by a number) + + Dispaly how many exception were encountered + + Remove some debug spam + + Lower garbage by removing implicit allocation in CheckConstraints + + Disable some warning that I am getting tired of seeing + + Prevent garbage generated by debug string that we do not display or + + print + + Prevent cache genration when there are exception and display the files + + that generated them + + Improved feedback on what is going on + + Minor cleanup +* 2016-1005: 2.7.0 (sarbian) for KSP 1.1.3 + + No changelog provided +* 2016-0519: 2.6.25 (sarbian) for KSP 1.1.2 + + Fix Exception for variable searching a value that does not exist +* 2016-0430: 2.6.24 (sarbian) for KSP 1.1.2 + + 2.6.64 - Rebuild for 1.1.2 +* 2016-0424: 2.6.23 (sarbian) for KSP 1.1.1 + + No point of updating the status outside the loading screen + + Add & operator: insert only if it doesn't already exist + + Doesn't work with root nodes right now, same as insert (%) + + Make the game always load in background + + Fix the insert NODE at position that blowfish found + + Fix nested node constraints only checking the first set + + Test for HAS +* 2016-0419: 2.6.22 (sarbian) for KSP 1.1 + + Fix for #50 +* 2016-0330: 2.6.21 (sarbian) for KSP 1.0.5 + + No changelog provided +* 2016-0218: 2.6.20 (sarbian) for KSP 1.0.5 + + Remove the debug spam of the out of node value edit + + Prevents the creation of a cache if there were errors while patching +* 2016-0216: 2.6.19 (sarbian) for KSP 1.0.5 + + Add a special "*MM_PATCH_LOOP" node that when found tries to apply the + + patch once more on the same NODE + + Fix the patch loop id to "MM_PATCH_LOOP" + + Allow for out of node editing of values Like : *@TEST[Test]/copy -= 1 +* 2016-0214: 2.6.18 (sarbian) for KSP 1.0.5 + + Update README.md +* 2016-0110: 2.6.17 (sarbian) for KSP 1.0.5 + + Prevents nightingale from trying to breaking some stuff. Fix #44 + + Add a warning for KSP build 1.0.5.1024 + + Logging the Exception may be smarter + + Store SHA for each cfg and log added/changed/removed cfg +* 2016-0101: 2.6.16 (sarbian) for KSP 1.0.5 + + Added code for !key,* = DEL and fixed group nr. 5 + + Bumped Assembly Version +* 2015-1231: 2.6.15 (sarbian) for KSP 1.0.5 + + Fix a bug with #34 + + remove some tabs + + Comments are nice, let s update them +* 2015-1231: 2.6.14 (sarbian) for KSP 1.0.5 + + Implemented @key,* = something to resolve #37 + + Implemented Vector Editing, using @key,*[0] + + There are options for editing all keys [*] and specifing a seperator + + (defaults to ,): [0, ] (here we use a space as the seperator). Math also + + works. + + Fixed the Regex + + Bumped AssemblyVersion +* 2015-1109: 2.6.13 (sarbian) for KSP 1.0.5 + + 2.6.13 - let's just change the number and pretend all is fine for 1.0.5 +* 2015-1104: 2.6.12 (sarbian) for KSP 1.0.4 + + No changelog provided +* 2015-0917: 2.6.11 (sarbian) for KSP 1.0.4 + + Added try/catch to FileSHA. +* 2015-0914: 2.6.10 (sarbian) for KSP 1.0.4 + + Return empty string if a character-separated list has fewer than the + + requested number of elements. + + Update version so sarbian can merge. +* 2015-0905: 2.6.9 (sarbian) for KSP 1.0.4 + + Prevents NullReferenceException when saving the cache to pause the + + loading + + 30 FPS patching +* 2015-0829: 2.6.8 (sarbian) for KSP 1.0.4 + + Fix a bug with nested :NEEDS when the top node also used a :NEEDS +* 2015-0804: 2.6.7 (sarbian) for KSP 1.0.4 + + No changelog provided +* 2015-0625: 2.6.6 (sarbian) for KSP 1.0.4 + + Add a Quick Reload for ALT F11 menu (skip PartDatabase.cfg generation) + + Ignore the cache (and force a PartDatabase.cfg generation) on KSP +* 2015-0523: 2.6.5 (sarbian) for KSP 1.0.3 + + KSP "-nyan-nyan" option detection for the true believers + + Clear the partDatabase if the cache is expired + + Display the useful log info even if we use the cache + + Do not use the cache if the techtree cache is not present + + Format and cleanup +* 2015-0514: 2.6.4 (sarbian) for KSP 1.0.2 + + Improve the loaded mod listing + + Do not change the Tech & physic file patch if they are already OK + + Make the error messages more consistent +* 2015-0504: 2.6.3 (sarbian) for KSP 1.0.2 + + Count the error for math operations +* 2015-0429: 2.6.2 (sarbian) for KSP 1.0.2 + + No changelog provided +* 2015-0427: 2.6.1 (sarbian) for KSP 1.0.2 + + No changelog provided +* 2015-0401: 2.6.0 (sarbian) for KSP 1.0.2 + + No changelog provided +* 2015-0325: 2.5.13 (sarbian) for KSP 1.0.1 + + DB Corruption check code kept in case of need + + Change for #28 + + Bullet proof PrettyPrint + + Remove debug stuff + + Forgot 2 lines + + Reformat + + < and > for value HAS check ( #mass[<100] ~mass[>100] ) + + operator for nodes to copy-paste whole nodes +* 2015-0223: 2.5.12 (sarbian) for KSP 1.0.1 + + No changelog provided +* 2015-0217: 2.5.10 (sarbian) for KSP 1.0.1 + + Fix the NODE,*:HAS[xxxx] reported by NathanKell + + More exception hunting and poor man debuging +* 2015-0427: 2.2.0 (sarbian) for KSP 1.0.1 + + No changelog provided +* 2014-0522: 2.1.5 (sarbian) for KSP 0.23.5 + + Fix a bug when inserting a name less node +* 2014-0518: 2.1.4 (Swamp-Ig) for KSP 0.23.5 + + Allow GameData subdir in NEEDS / BEFORE / AFTER +* 2014-0517: 2.1.3 (Swamp-Ig) for KSP 0.23.5 + + Removed non-essential backups + + Improvements for if multiple copies of the same version are installed. +* 2014-0510: 2.1.2 (Swamp-Ig) for KSP 0.23.5 + + Lots of improvements and bug fixes in this release. + + [Full details here](http://forum.kerbalspaceprogram.com/threads/55219-Module-Manager-2-1-0-%28May-04%29-please-read-the-orange-text-in-first-post?p=1149933&viewfull=1#post1149933) +* 2014-0504: 2.0.9 (Swamp-Ig) for KSP 0.23.5 + + So I've done my own enhancements to module manager. + + They seem to work pretty nice! I'd really appreciate ppl testing it out on their various MM files prior to me pushing it back to the MM repo. + + Any issues you have - take them up with me not with sarbian + + Features: + + Order Preserving + - now preserves the original order, both for nodes and for values. + + Use of NEEDS +``` +PART:NEEDS[RealFuels] { + name = dummyPartIgnore + module = Part + DOG { + name = First + key1:NEEDS[ProceduralParts|StretchySRB] = Original Value + key2:NEEDS[!RealFuels] = Some other value + } +} +``` + + In the above, the part will only be defined if you have RealFuels loaded. You can do this on keys, values, patches, anywhere. + + key1 will be defined if (ProceduralParts OR StretchySRB are loaded) and RealFuels is NOT loaded. You can still use , and it is treated like &. Not has highest precedence, then or, then and. + + Define an insertion point for any nodes or values +``` +@PART[dummyPartIgnore] +{ + DOG { + name = AddLast + string = Will insert at the end + } + DOG,0 { + name = AddFirst + string = Will insert at the beginning + } + @DOG,0 { // Edits node zero as before, but ends up editing the above node + string,0 = Insert before the string already at the beginning + } +} +``` + + The index after the comma is where it will be inserted, this is relative to other nodes or values with the same name. + + Regexp replaces +``` +@PART[dummyPartIgnore] +{ + @DOG[First] + { + @string ^= :^.*$:First dog edit $& in place + } +} +``` + + Breaking this down, the first character defines the separator, the section between the first : and the second : is the match string, and the section following the second : is the replacement. + + For details on how to use regexp [see the documentation here](http://msdn.microsoft.com/en-us/library/hs600312%28v=vs.110%29.aspx) diff --git a/CONFIG.inc b/CONFIG.inc new file mode 100644 index 00000000..ceea7d74 --- /dev/null +++ b/CONFIG.inc @@ -0,0 +1,38 @@ +source ../CONFIG.inc + +PACKAGE=ModuleManager +TARGETDIR="$PACKAGE" +TARGETBINDIR="$TARGETDIR" +PROJECTSDIR="Source/$PACKAGE/" +VERSIONFILE="$PACKAGE.version" + +DLLS="$PACKAGE" +# PluginData DLLs +PD_DLLS="$PACKAGE" +# Rule oriented deployoment for PluginData +#declare -A PD_SUB_RULES=( ["KSPe.UI.12"]="./12x/KSPe.UI" ["KSPe.UI.14"]="./14x/KSPe.UI" ["KSPe.UI.18"]="./18x/KSPe.UI" ) +declare -A PD_SUB_RULES=( ) +PD_SUB_DLLS=`{ for K in "${!PD_SUB_RULES[@]}"; do echo $(basename ${PD_SUB_RULES[$K]}); done } | sort -u | tr '\n' ' '` +PD_SUB_DIRS=`{ for K in "${!PD_SUB_RULES[@]}"; do echo $(dirname ${PD_SUB_RULES[$K]}); done } | sort -u | tr '\n' ' '` + +# GameData deployed DLLs +GD_DLLS="KSPe" +GD_PRIORITY="000" + +# Dev LIB deployed DLLs +LIB_DLLS="${DLLS}" + +# External Libs from the LIB directory +EXT_DLLS="" + + +PROJECT_BRANCH=`git branch | grep \* | cut -d ' ' -f2` +if [ "$PROJECT_BRANCH" == "master" ] ; then + # Release mode + PROJECT_STATE="" +else + # Note: Add a leading dash when this value is present! + PROJECT_STATE="" +fi + +VERSION=$( cat $VERSIONFILE | tr '\n' ' ' | sed -n -E 's/^.*?"VERSION\":\{.*"MAJOR":([0-9]+?),.*?"MINOR":([0-9]+?),.*?"PATCH":([0-9]+?),.*?"BUILD":([0-9]+?).*?\}.*$/\1.\2.\3.\4/p' ) diff --git a/Docs/LMJ/CC BY-SA 4.0 now one-way compatible with GPLv3 - Creative Commons.pdf b/Docs/LMJ/CC BY-SA 4.0 now one-way compatible with GPLv3 - Creative Commons.pdf new file mode 100644 index 00000000..955fae28 Binary files /dev/null and b/Docs/LMJ/CC BY-SA 4.0 now one-way compatible with GPLv3 - Creative Commons.pdf differ diff --git a/Docs/LMJ/CC BY-SA 4.0 now one-way compatible with GPLv3 - Creative Commons.webarchive b/Docs/LMJ/CC BY-SA 4.0 now one-way compatible with GPLv3 - Creative Commons.webarchive new file mode 100644 index 00000000..944082bd Binary files /dev/null and b/Docs/LMJ/CC BY-SA 4.0 now one-way compatible with GPLv3 - Creative Commons.webarchive differ diff --git a/Docs/LMJ/[0.20] ModuleManager 1.3 - for all your stock-modding needs - Add-on Releases - Kerbal Space Program.pdf b/Docs/LMJ/[0.20] ModuleManager 1.3 - for all your stock-modding needs - Add-on Releases - Kerbal Space Program.pdf new file mode 100644 index 00000000..c7829bbe Binary files /dev/null and b/Docs/LMJ/[0.20] ModuleManager 1.3 - for all your stock-modding needs - Add-on Releases - Kerbal Space Program.pdf differ diff --git a/Docs/LMJ/[0.20] ModuleManager 1.3 - for all your stock-modding needs - Add-on Releases - Kerbal Space Program.webarchive b/Docs/LMJ/[0.20] ModuleManager 1.3 - for all your stock-modding needs - Add-on Releases - Kerbal Space Program.webarchive new file mode 100644 index 00000000..0637a19c Binary files /dev/null and b/Docs/LMJ/[0.20] ModuleManager 1.3 - for all your stock-modding needs - Add-on Releases - Kerbal Space Program.webarchive differ diff --git a/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Add-on Releases.pdf b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Add-on Releases.pdf new file mode 100644 index 00000000..a5f8727e Binary files /dev/null and b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Add-on Releases.pdf differ diff --git a/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Add-on Releases.webarchive b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Add-on Releases.webarchive new file mode 100644 index 00000000..5da49441 Binary files /dev/null and b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Add-on Releases.webarchive differ diff --git a/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Page 55 - Add-o.LICENSE.pdf b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Page 55 - Add-o.LICENSE.pdf new file mode 100644 index 00000000..9d2d0ba1 Binary files /dev/null and b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Page 55 - Add-o.LICENSE.pdf differ diff --git a/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Page 55 - Add-o.LICENSE.webarchive b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Page 55 - Add-o.LICENSE.webarchive new file mode 100644 index 00000000..f8a2e920 Binary files /dev/null and b/Docs/LMJ/[1.8.x-1.9.x] Module Manager 4.1.3 (November 30th 2019) - Right To Ludicrous Speed - Page 55 - Add-o.LICENSE.webarchive differ diff --git a/INSTALL.md b/INSTALL.md new file mode 100644 index 00000000..e22f53ee --- /dev/null +++ b/INSTALL.md @@ -0,0 +1,57 @@ +# Module Manager /L Experimental +*Lasciate ogne speranza, voi ch'intrate* +- - - + +ModuleManager is mod that let you write patch file that edit other part at load time. + +This is Lisias' Experimental fork for Module Mamager. + + +## Installation Instructions + +To install, place the GameData folder inside your Kerbal Space Program folder. Optionally, you can also do the same for the PluginData (be careful to do not overwrite your custom settings): + +* **REMOVE ANY OLD VERSIONS OF THE PRODUCT BEFORE INSTALLING**, including any other fork: + + Delete `/ModuleManager*` + - Yes. Every single file that starts with this name. + - Older MM/L versions used to shove all files on `GameData`. This changed on 4.2.2.4. + + Delete the directory`/ModuleManager/` if existant + - This is the new deployment model as 4.2.2.4 +* Extract the package's `GameData` folder into your KSP's root: + + `/GameData` --> `/GameData` + +The following file layout must be present after installation: + +``` + + [GameData] + [ModuleManager] + [PluginData] + ... + CHANGE_LOG.md + LICENSE + ModuleManager.version + NOTICE + README.md + 000_KSPe.dll + ModuleManager.dll + ... + [PluginData] + [ModuleManager] + ... + KSP.log + PartDatabase.cfg + ... +``` + +Note: the `/PluginData/ModuleManager` folder will be automatically created and populated after the first run. + +Additionally, don't mangle with `/ModuleManager/PluginData` as it contents is used by `ModuleManagerWatchDog` to keep `MM/L` healthy. + +### Dependencies + +* [KSP API Extensions/L](https://github.com/net-lisias-ksp/KSPAPIExtensions) + + Hard dependency, it will not work without it. +* [Module Manager Watch Dog](https://github.com/net-lisias-ksp/ModuleManagerWatchDog) + + Soft Dependency. It's possible to run `MM/L` without `MMWD`, but it's highly recommended to install it and let it care about the `MM` (being it my fork or not) healthiness. + diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..067c5298 --- /dev/null +++ b/LICENSE @@ -0,0 +1,674 @@ + GNU 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. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is intended to guarantee your freedom to +share and change all versions of a program--to make sure it remains free +software for all its users. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + When we speak of free software, we are referring to freedom, not +price. Our General Public Licenses are designed to make sure that you +have the freedom to distribute copies of free software (and charge for +them if you wish), that you receive source code or can get it if you +want it, that you can change the software or use pieces of it in new +free programs, and that you know you can do these things. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + The precise terms and conditions for copying, distribution and +modification follow. + + TERMS AND CONDITIONS + + 0. Definitions. + + "This License" refers to version 3 of the GNU General Public License. + + "Copyright" also means copyright-like laws that apply to other kinds of +works, such as semiconductor masks. + + "The Program" refers to any copyrightable work licensed under this +License. Each licensee is addressed as "you". "Licensees" and +"recipients" may be individuals or organizations. + + To "modify" a work means to copy from or adapt all or part of the work +in a fashion requiring copyright permission, other than the making of an +exact copy. The resulting work is called a "modified version" of the +earlier work or a work "based on" the earlier work. + + A "covered work" means either the unmodified Program or a work based +on the Program. + + To "propagate" a work means to do anything with it that, without +permission, would make you directly or secondarily liable for +infringement under applicable copyright law, except executing it on a +computer or modifying a private copy. Propagation includes copying, +distribution (with or without modification), making available to the +public, and in some countries other activities as well. + + To "convey" a work means any kind of propagation that enables other +parties to make or receive copies. Mere interaction with a user through +a computer network, with no transfer of a copy, is not conveying. + + An interactive user interface displays "Appropriate Legal Notices" +to the extent that it includes a convenient and prominently visible +feature that (1) displays an appropriate copyright notice, and (2) +tells the user that there is no warranty for the work (except to the +extent that warranties are provided), that licensees may convey the +work under this License, and how to view a copy of this License. If +the interface presents a list of user commands or options, such as a +menu, a prominent item in the list meets this criterion. + + 1. Source Code. + + The "source code" for a work means the preferred form of the work +for making modifications to it. "Object code" means any non-source +form of a work. + + A "Standard Interface" means an interface that either is an official +standard defined by a recognized standards body, or, in the case of +interfaces specified for a particular programming language, one that +is widely used among developers working in that language. + + The "System Libraries" of an executable work include anything, other +than the work as a whole, that (a) is included in the normal form of +packaging a Major Component, but which is not part of that Major +Component, and (b) serves only to enable use of the work with that +Major Component, or to implement a Standard Interface for which an +implementation is available to the public in source code form. A +"Major Component", in this context, means a major essential component +(kernel, window system, and so on) of the specific operating system +(if any) on which the executable work runs, or a compiler used to +produce the work, or an object code interpreter used to run it. + + The "Corresponding Source" for a work in object code form means all +the source code needed to generate, install, and (for an executable +work) run the object code and to modify the work, including scripts to +control those activities. However, it does not include the work's +System Libraries, or general-purpose tools or generally available free +programs which are used unmodified in performing those activities but +which are not part of the work. For example, Corresponding Source +includes interface definition files associated with source files for +the work, and the source code for shared libraries and dynamically +linked subprograms that the work is specifically designed to require, +such as by intimate data communication or control flow between those +subprograms and other parts of the work. + + The Corresponding Source need not include anything that users +can regenerate automatically from other parts of the Corresponding +Source. + + The Corresponding Source for a work in source code form is that +same work. + + 2. Basic Permissions. + + All rights granted under this License are granted for the term of +copyright on the Program, and are irrevocable provided the stated +conditions are met. This License explicitly affirms your unlimited +permission to run the unmodified Program. The output from running a +covered work is covered by this License only if the output, given its +content, constitutes a covered work. This License acknowledges your +rights of fair use or other equivalent, as provided by copyright law. + + You may make, run and propagate covered works that you do not +convey, without conditions so long as your license otherwise remains +in force. You may convey covered works to others for the sole purpose +of having them make modifications exclusively for you, or provide you +with facilities for running those works, provided that you comply with +the terms of this License in conveying all material for which you do +not control copyright. Those thus making or running the covered works +for you must do so exclusively on your behalf, under your direction +and control, on terms that prohibit them from making any copies of +your copyrighted material outside their relationship with you. + + Conveying under any other circumstances is permitted solely under +the conditions stated below. Sublicensing is not allowed; section 10 +makes it unnecessary. + + 3. Protecting Users' Legal Rights From Anti-Circumvention Law. + + No covered work shall be deemed part of an effective technological +measure under any applicable law fulfilling obligations under article +11 of the WIPO copyright treaty adopted on 20 December 1996, or +similar laws prohibiting or restricting circumvention of such +measures. + + When you convey a covered work, you waive any legal power to forbid +circumvention of technological measures to the extent such circumvention +is effected by exercising rights under this License with respect to +the covered work, and you disclaim any intention to limit operation or +modification of the work as a means of enforcing, against the work's +users, your or third parties' legal rights to forbid circumvention of +technological measures. + + 4. Conveying Verbatim Copies. + + You may convey verbatim copies of the Program's source code as you +receive it, in any medium, provided that you conspicuously and +appropriately publish on each copy an appropriate copyright notice; +keep intact all notices stating that this License and any +non-permissive terms added in accord with section 7 apply to the code; +keep intact all notices of the absence of any warranty; and give all +recipients a copy of this License along with the Program. + + You may charge any price or no price for each copy that you convey, +and you may offer support or warranty protection for a fee. + + 5. Conveying Modified Source Versions. + + You may convey a work based on the Program, or the modifications to +produce it from the Program, in the form of source code under the +terms of section 4, provided that you also meet all of these conditions: + + a) The work must carry prominent notices stating that you modified + it, and giving a relevant date. + + b) The work must carry prominent notices stating that it is + released under this License and any conditions added under section + 7. This requirement modifies the requirement in section 4 to + "keep intact all notices". + + c) You must license the entire work, as a whole, under this + License to anyone who comes into possession of a copy. This + License will therefore apply, along with any applicable section 7 + additional terms, to the whole of the work, and all its parts, + regardless of how they are packaged. This License gives no + permission to license the work in any other way, but it does not + invalidate such permission if you have separately received it. + + d) If the work has interactive user interfaces, each must display + Appropriate Legal Notices; however, if the Program has interactive + interfaces that do not display Appropriate Legal Notices, your + work need not make them do so. + + A compilation of a covered work with other separate and independent +works, which are not by their nature extensions of the covered work, +and which are not combined with it such as to form a larger program, +in or on a volume of a storage or distribution medium, is called an +"aggregate" if the compilation and its resulting copyright are not +used to limit the access or legal rights of the compilation's users +beyond what the individual works permit. Inclusion of a covered work +in an aggregate does not cause this License to apply to the other +parts of the aggregate. + + 6. Conveying Non-Source Forms. + + You may convey a covered work in object code form under the terms +of sections 4 and 5, provided that you also convey the +machine-readable Corresponding Source under the terms of this License, +in one of these ways: + + a) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by the + Corresponding Source fixed on a durable physical medium + customarily used for software interchange. + + b) Convey the object code in, or embodied in, a physical product + (including a physical distribution medium), accompanied by a + written offer, valid for at least three years and valid for as + long as you offer spare parts or customer support for that product + model, to give anyone who possesses the object code either (1) a + copy of the Corresponding Source for all the software in the + product that is covered by this License, on a durable physical + medium customarily used for software interchange, for a price no + more than your reasonable cost of physically performing this + conveying of source, or (2) access to copy the + Corresponding Source from a network server at no charge. + + c) Convey individual copies of the object code with a copy of the + written offer to provide the Corresponding Source. This + alternative is allowed only occasionally and noncommercially, and + only if you received the object code with such an offer, in accord + with subsection 6b. + + d) Convey the object code by offering access from a designated + place (gratis or for a charge), and offer equivalent access to the + Corresponding Source in the same way through the same place at no + further charge. You need not require recipients to copy the + Corresponding Source along with the object code. If the place to + copy the object code is a network server, the Corresponding Source + may be on a different server (operated by you or a third party) + that supports equivalent copying facilities, provided you maintain + clear directions next to the object code saying where to find the + Corresponding Source. Regardless of what server hosts the + Corresponding Source, you remain obligated to ensure that it is + available for as long as needed to satisfy these requirements. + + e) Convey the object code using peer-to-peer transmission, provided + you inform other peers where the object code and Corresponding + Source of the work are being offered to the general public at no + charge under subsection 6d. + + A separable portion of the object code, whose source code is excluded +from the Corresponding Source as a System Library, need not be +included in conveying the object code work. + + A "User Product" is either (1) a "consumer product", which means any +tangible personal property which is normally used for personal, family, +or household purposes, or (2) anything designed or sold for incorporation +into a dwelling. In determining whether a product is a consumer product, +doubtful cases shall be resolved in favor of coverage. For a particular +product received by a particular user, "normally used" refers to a +typical or common use of that class of product, regardless of the status +of the particular user or of the way in which the particular user +actually uses, or expects or is expected to use, the product. A product +is a consumer product regardless of whether the product has substantial +commercial, industrial or non-consumer uses, unless such uses represent +the only significant mode of use of the product. + + "Installation Information" for a User Product means any methods, +procedures, authorization keys, or other information required to install +and execute modified versions of a covered work in that User Product from +a modified version of its Corresponding Source. The information must +suffice to ensure that the continued functioning of the modified object +code is in no case prevented or interfered with solely because +modification has been made. + + If you convey an object code work under this section in, or with, or +specifically for use in, a User Product, and the conveying occurs as +part of a transaction in which the right of possession and use of the +User Product is transferred to the recipient in perpetuity or for a +fixed term (regardless of how the transaction is characterized), the +Corresponding Source conveyed under this section must be accompanied +by the Installation Information. But this requirement does not apply +if neither you nor any third party retains the ability to install +modified object code on the User Product (for example, the work has +been installed in ROM). + + The requirement to provide Installation Information does not include a +requirement to continue to provide support service, warranty, or updates +for a work that has been modified or installed by the recipient, or for +the User Product in which it has been modified or installed. Access to a +network may be denied when the modification itself materially and +adversely affects the operation of the network or violates the rules and +protocols for communication across the network. + + Corresponding Source conveyed, and Installation Information provided, +in accord with this section must be in a format that is publicly +documented (and with an implementation available to the public in +source code form), and must require no special password or key for +unpacking, reading or copying. + + 7. Additional Terms. + + "Additional permissions" are terms that supplement the terms of this +License by making exceptions from one or more of its conditions. +Additional permissions that are applicable to the entire Program shall +be treated as though they were included in this License, to the extent +that they are valid under applicable law. If additional permissions +apply only to part of the Program, that part may be used separately +under those permissions, but the entire Program remains governed by +this License without regard to the additional permissions. + + When you convey a copy of a covered work, you may at your option +remove any additional permissions from that copy, or from any part of +it. (Additional permissions may be written to require their own +removal in certain cases when you modify the work.) You may place +additional permissions on material, added by you to a covered work, +for which you have or can give appropriate copyright permission. + + Notwithstanding any other provision of this License, for material you +add to a covered work, you may (if authorized by the copyright holders of +that material) supplement the terms of this License with terms: + + a) Disclaiming warranty or limiting liability differently from the + terms of sections 15 and 16 of this License; or + + b) Requiring preservation of specified reasonable legal notices or + author attributions in that material or in the Appropriate Legal + Notices displayed by works containing it; or + + c) Prohibiting misrepresentation of the origin of that material, or + requiring that modified versions of such material be marked in + reasonable ways as different from the original version; or + + d) Limiting the use for publicity purposes of names of licensors or + authors of the material; or + + e) Declining to grant rights under trademark law for use of some + trade names, trademarks, or service marks; or + + f) Requiring indemnification of licensors and authors of that + material by anyone who conveys the material (or modified versions of + it) with contractual assumptions of liability to the recipient, for + any liability that these contractual assumptions directly impose on + those licensors and authors. + + All other non-permissive additional terms are considered "further +restrictions" within the meaning of section 10. If the Program as you +received it, or any part of it, contains a notice stating that it is +governed by this License along with a term that is a further +restriction, you may remove that term. If a license document contains +a further restriction but permits relicensing or conveying under this +License, you may add to a covered work material governed by the terms +of that license document, provided that the further restriction does +not survive such relicensing or conveying. + + If you add terms to a covered work in accord with this section, you +must place, in the relevant source files, a statement of the +additional terms that apply to those files, or a notice indicating +where to find the applicable terms. + + Additional terms, permissive or non-permissive, may be stated in the +form of a separately written license, or stated as exceptions; +the above requirements apply either way. + + 8. Termination. + + You may not propagate or modify a covered work except as expressly +provided under this License. Any attempt otherwise to propagate or +modify it is void, and will automatically terminate your rights under +this License (including any patent licenses granted under the third +paragraph of section 11). + + However, if you cease all violation of this License, then your +license from a particular copyright holder is reinstated (a) +provisionally, unless and until the copyright holder explicitly and +finally terminates your license, and (b) permanently, if the copyright +holder fails to notify you of the violation by some reasonable means +prior to 60 days after the cessation. + + Moreover, your license from a particular copyright holder is +reinstated permanently if the copyright holder notifies you of the +violation by some reasonable means, this is the first time you have +received notice of violation of this License (for any work) from that +copyright holder, and you cure the violation prior to 30 days after +your receipt of the notice. + + Termination of your rights under this section does not terminate the +licenses of parties who have received copies or rights from you under +this License. If your rights have been terminated and not permanently +reinstated, you do not qualify to receive new licenses for the same +material under section 10. + + 9. Acceptance Not Required for Having Copies. + + You are not required to accept this License in order to receive or +run a copy of the Program. Ancillary propagation of a covered work +occurring solely as a consequence of using peer-to-peer transmission +to receive a copy likewise does not require acceptance. However, +nothing other than this License grants you permission to propagate or +modify any covered work. These actions infringe copyright if you do +not accept this License. Therefore, by modifying or propagating a +covered work, you indicate your acceptance of this License to do so. + + 10. Automatic Licensing of Downstream Recipients. + + Each time you convey a covered work, the recipient automatically +receives a license from the original licensors, to run, modify and +propagate that work, subject to this License. You are not responsible +for enforcing compliance by third parties with this License. + + An "entity transaction" is a transaction transferring control of an +organization, or substantially all assets of one, or subdividing an +organization, or merging organizations. If propagation of a covered +work results from an entity transaction, each party to that +transaction who receives a copy of the work also receives whatever +licenses to the work the party's predecessor in interest had or could +give under the previous paragraph, plus a right to possession of the +Corresponding Source of the work from the predecessor in interest, if +the predecessor has it or can get it with reasonable efforts. + + You may not impose any further restrictions on the exercise of the +rights granted or affirmed under this License. For example, you may +not impose a license fee, royalty, or other charge for exercise of +rights granted under this License, and you may not initiate litigation +(including a cross-claim or counterclaim in a lawsuit) alleging that +any patent claim is infringed by making, using, selling, offering for +sale, or importing the Program or any portion of it. + + 11. Patents. + + A "contributor" is a copyright holder who authorizes use under this +License of the Program or a work on which the Program is based. The +work thus licensed is called the contributor's "contributor version". + + A contributor's "essential patent claims" are all patent claims +owned or controlled by the contributor, whether already acquired or +hereafter acquired, that would be infringed by some manner, permitted +by this License, of making, using, or selling its contributor version, +but do not include claims that would be infringed only as a +consequence of further modification of the contributor version. For +purposes of this definition, "control" includes the right to grant +patent sublicenses in a manner consistent with the requirements of +this License. + + Each contributor grants you a non-exclusive, worldwide, royalty-free +patent license under the contributor's essential patent claims, to +make, use, sell, offer for sale, import and otherwise run, modify and +propagate the contents of its contributor version. + + In the following three paragraphs, a "patent license" is any express +agreement or commitment, however denominated, not to enforce a patent +(such as an express permission to practice a patent or covenant not to +sue for patent infringement). To "grant" such a patent license to a +party means to make such an agreement or commitment not to enforce a +patent against the party. + + If you convey a covered work, knowingly relying on a patent license, +and the Corresponding Source of the work is not available for anyone +to copy, free of charge and under the terms of this License, through a +publicly available network server or other readily accessible means, +then you must either (1) cause the Corresponding Source to be so +available, or (2) arrange to deprive yourself of the benefit of the +patent license for this particular work, or (3) arrange, in a manner +consistent with the requirements of this License, to extend the patent +license to downstream recipients. "Knowingly relying" means you have +actual knowledge that, but for the patent license, your conveying the +covered work in a country, or your recipient's use of the covered work +in a country, would infringe one or more identifiable patents in that +country that you have reason to believe are valid. + + If, pursuant to or in connection with a single transaction or +arrangement, you convey, or propagate by procuring conveyance of, a +covered work, and grant a patent license to some of the parties +receiving the covered work authorizing them to use, propagate, modify +or convey a specific copy of the covered work, then the patent license +you grant is automatically extended to all recipients of the covered +work and works based on it. + + A patent license is "discriminatory" if it does not include within +the scope of its coverage, prohibits the exercise of, or is +conditioned on the non-exercise of one or more of the rights that are +specifically granted under this License. You may not convey a covered +work if you are a party to an arrangement with a third party that is +in the business of distributing software, under which you make payment +to the third party based on the extent of your activity of conveying +the work, and under which the third party grants, to any of the +parties who would receive the covered work from you, a discriminatory +patent license (a) in connection with copies of the covered work +conveyed by you (or copies made from those copies), or (b) primarily +for and in connection with specific products or compilations that +contain the covered work, unless you entered into that arrangement, +or that patent license was granted, prior to 28 March 2007. + + Nothing in this License shall be construed as excluding or limiting +any implied license or other defenses to infringement that may +otherwise be available to you under applicable patent law. + + 12. No Surrender of Others' Freedom. + + If conditions are imposed on you (whether by court order, agreement or +otherwise) that contradict the conditions of this License, they do not +excuse you from the conditions of this License. If you cannot convey a +covered work so as to satisfy simultaneously your obligations under this +License and any other pertinent obligations, then as a consequence you may +not convey it at all. For example, if you agree to terms that obligate you +to collect a royalty for further conveying from those to whom you convey +the Program, the only way you could satisfy both those terms and this +License would be to refrain entirely from conveying the Program. + + 13. Use with the GNU Affero General Public License. + + Notwithstanding any other provision of this License, you have +permission to link or combine any covered work with a work licensed +under version 3 of the GNU Affero General Public License into a single +combined work, and to convey the resulting work. The terms of this +License will continue to apply to the part which is the covered work, +but the special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 +Program specifies that a certain numbered version of the GNU General +Public License "or any later version" applies to it, you have the +option of following the terms and conditions either of that numbered +version or of any later version published by the Free Software +Foundation. If the Program does not specify a version number of the +GNU General Public License, you may choose any version ever published +by the Free Software Foundation. + + If the Program specifies that a proxy can decide which future +versions of the GNU General Public License can be used, that proxy's +public statement of acceptance of a version permanently authorizes you +to choose that version for the Program. + + Later license versions may give you additional or different +permissions. However, no additional obligations are imposed on any +author or copyright holder as a result of your choosing to follow a +later version. + + 15. Disclaimer of Warranty. + + THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY +APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT +HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY +OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, +THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR +PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM +IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF +ALL NECESSARY SERVICING, REPAIR OR CORRECTION. + + 16. Limitation of Liability. + + IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS +THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY +GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE +USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF +DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD +PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), +EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF +SUCH DAMAGES. + + 17. Interpretation of Sections 15 and 16. + + If the disclaimer of warranty and limitation of liability provided +above cannot be given local legal effect according to their terms, +reviewing courts shall apply local law that most closely approximates +an absolute waiver of all civil liability in connection with the +Program, unless a warranty or assumption of liability accompanies a +copy of the Program in return for a fee. + + END OF TERMS AND CONDITIONS + + How to Apply These Terms to Your New Programs + + If you develop a new program, and you want it to be of the greatest +possible use to the public, the best way to achieve this is to make it +free software which everyone can redistribute and change under these terms. + + To do so, attach the following notices to the program. It is safest +to attach them to the start of each source file to most effectively +state the exclusion of warranty; and each file should have at least +the "copyright" line and a pointer to where the full notice is found. + + {one line to give the program's name and a brief idea of what it does.} + Copyright (C) {year} {name of author} + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + {project} Copyright (C) {year} {fullname} + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + You should also get your employer (if you work as a programmer) or school, +if any, to sign a "copyright disclaimer" for the program, if necessary. +For more information on this, and how to apply and follow the GNU GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/ModuleManager.122.version b/ModuleManager.122.version new file mode 100644 index 00000000..3b3f5117 --- /dev/null +++ b/ModuleManager.122.version @@ -0,0 +1,18 @@ +{ + "NAME" : "Module Manager /L Beta", + "URL" : "https://raw.githubusercontent.com/KSP-ModularManagement/ModuleManager/master/ModuleManager.122.version", + "DOWNLOAD" : "https://github.com/KSP-ModularManagement/ModuleManager/releases", + "CHANGE_LOG" : "https://raw.githubusercontent.com/KSP-ModularManagement/ModuleManager/master/CHANGE_LOG.md", + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/KSP-ModularManagement/ModuleManager/master/CHANGES.md", + "VERSION":{ + "MAJOR":4, + "MINOR":2, + "PATCH":3, + "BUILD":7 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":2, + "PATCH":2 + } +} diff --git a/ModuleManager.sln b/ModuleManager.sln index ac8200bc..d2df68eb 100644 --- a/ModuleManager.sln +++ b/ModuleManager.sln @@ -3,18 +3,22 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio 15 VisualStudioVersion = 15.0.26730.12 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModuleManager", "ModuleManager\ModuleManager.csproj", "{02C8E3AF-69F9-4102-AB60-DD6DE60662D3}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModuleManager.12", "Source\ModuleManager\ModuleManager.12.csproj", "{02C8E3AF-69F9-4102-AB60-DD6DE60662D4}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModuleManagerTests", "ModuleManagerTests\ModuleManagerTests.csproj", "{BC2A08C8-64EF-4823-A40B-8889C1CCFD75}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModuleManagerTests", "Source\ModuleManagerTests\ModuleManagerTests.csproj", "{BC2A08C8-64EF-4823-A40B-8889C1CCFD75}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtils", "TestUtils\TestUtils.csproj", "{20EAAFE6-510D-4374-8D2F-6B52D0178E85}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtils", "Source\TestUtils\TestUtils.csproj", "{20EAAFE6-510D-4374-8D2F-6B52D0178E85}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilsTests", "TestUtilsTests\TestUtilsTests.csproj", "{E695C11F-4217-4014-9B51-7232A654C205}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ModuleManager", "Source\ModuleManager\ModuleManager.csproj", "{02C8E3AF-69F9-4102-AB60-DD6DE60662D3}" +EndProject +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestUtilsTests", "Source\TestUtilsTests\TestUtilsTests.csproj", "{E695C11F-4217-4014-9B51-7232A654C205}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU Release|Any CPU = Release|Any CPU + 122.Release|Any CPU = 122.Release|Any CPU + 122.Debug|Any CPU = 122.Debug|Any CPU EndGlobalSection GlobalSection(ProjectConfigurationPlatforms) = postSolution {02C8E3AF-69F9-4102-AB60-DD6DE60662D3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU @@ -24,15 +28,16 @@ Global {BC2A08C8-64EF-4823-A40B-8889C1CCFD75}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {BC2A08C8-64EF-4823-A40B-8889C1CCFD75}.Debug|Any CPU.Build.0 = Debug|Any CPU {BC2A08C8-64EF-4823-A40B-8889C1CCFD75}.Release|Any CPU.ActiveCfg = Release|Any CPU - {BC2A08C8-64EF-4823-A40B-8889C1CCFD75}.Release|Any CPU.Build.0 = Release|Any CPU {20EAAFE6-510D-4374-8D2F-6B52D0178E85}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {20EAAFE6-510D-4374-8D2F-6B52D0178E85}.Debug|Any CPU.Build.0 = Debug|Any CPU {20EAAFE6-510D-4374-8D2F-6B52D0178E85}.Release|Any CPU.ActiveCfg = Release|Any CPU - {20EAAFE6-510D-4374-8D2F-6B52D0178E85}.Release|Any CPU.Build.0 = Release|Any CPU + {02C8E3AF-69F9-4102-AB60-DD6DE60662D4}.Release|Any CPU.ActiveCfg = Release|Any CPU + {02C8E3AF-69F9-4102-AB60-DD6DE60662D4}.Release|Any CPU.Build.0 = Release|Any CPU + {02C8E3AF-69F9-4102-AB60-DD6DE60662D4}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {02C8E3AF-69F9-4102-AB60-DD6DE60662D4}.Debug|Any CPU.Build.0 = Debug|Any CPU {E695C11F-4217-4014-9B51-7232A654C205}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {E695C11F-4217-4014-9B51-7232A654C205}.Debug|Any CPU.Build.0 = Debug|Any CPU {E695C11F-4217-4014-9B51-7232A654C205}.Release|Any CPU.ActiveCfg = Release|Any CPU - {E695C11F-4217-4014-9B51-7232A654C205}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -43,5 +48,37 @@ Global GlobalSection(MonoDevelopProperties) = preSolution StartupItem = ModuleManager.csproj outputpath = ..\..\Plugins + Policies = $0 + $0.TextStylePolicy = $1 + $1.inheritsSet = null + $1.scope = text/x-csharp + $0.CSharpFormattingPolicy = $2 + $2.scope = text/x-csharp + $0.TextStylePolicy = $3 + $3.FileWidth = 132 + $3.EolMarker = Unix + $3.scope = text/plain + $0.TextStylePolicy = $4 + $4.inheritsSet = null + $4.scope = text/microsoft-resx + $0.XmlFormattingPolicy = $5 + $5.inheritsSet = null + $5.scope = text/microsoft-resx + $0.TextStylePolicy = $6 + $6.inheritsSet = null + $6.scope = application/xml + $0.XmlFormattingPolicy = $7 + $7.scope = application/xml + $0.TextStylePolicy = $8 + $8.inheritsSet = null + $8.scope = application/config+xml + $0.XmlFormattingPolicy = $9 + $9.inheritsSet = null + $9.scope = application/config+xml + $0.TextStylePolicy = $10 + $10.inheritsSet = null + $10.scope = application/t4-template + $0.DotNetNamingPolicy = $11 + $11.DirectoryNamespaceAssociation = PrefixedHierarchical EndGlobalSection EndGlobal diff --git a/ModuleManager.sln.DotSettings b/ModuleManager.sln.DotSettings deleted file mode 100644 index 5858365e..00000000 --- a/ModuleManager.sln.DotSettings +++ /dev/null @@ -1,31 +0,0 @@ - - True - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - DO_NOT_SHOW - FAR - ISP - KSP - ME - SFS - UI - <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> - <Policy Inspect="True" Prefix="_" Suffix="" Style="aaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> - <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb"><ExtraRule Prefix="" Suffix="" Style="aaBb" /></Policy> - GUI - ID - UV - XZU - KL - SRB - TS - SPH - VAB - \ No newline at end of file diff --git a/ModuleManager.userprefs b/ModuleManager.userprefs deleted file mode 100644 index ab535b21..00000000 --- a/ModuleManager.userprefs +++ /dev/null @@ -1,29 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - diff --git a/ModuleManager.version b/ModuleManager.version new file mode 100644 index 00000000..0d4df5ce --- /dev/null +++ b/ModuleManager.version @@ -0,0 +1,18 @@ +{ + "NAME" : "Module Manager /L", + "URL" : "https://raw.githubusercontent.com/KSP-ModularManagement/ModuleManager/master/ModuleManager.version", + "DOWNLOAD" : "https://github.com/KSP-ModularManagement/ModuleManager/releases", + "CHANGE_LOG" : "https://raw.githubusercontent.com/KSP-ModularManagement/ModuleManager/master/CHANGE_LOG.md", + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/KSP-ModularManagement/ModuleManager/master/CHANGES.md", + "VERSION":{ + "MAJOR":4, + "MINOR":2, + "PATCH":3, + "BUILD":7 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":3, + "PATCH":1 + } +} diff --git a/ModuleManager/Command.cs b/ModuleManager/Command.cs deleted file mode 100644 index 5e7dde49..00000000 --- a/ModuleManager/Command.cs +++ /dev/null @@ -1,25 +0,0 @@ -using System; - -namespace ModuleManager -{ - public enum Command - { - Insert, - - Delete, - - Edit, - - Replace, - - Copy, - - Rename, - - Paste, - - Special, - - Create - } -} diff --git a/ModuleManager/CustomConfigsManager.cs b/ModuleManager/CustomConfigsManager.cs deleted file mode 100644 index d7444363..00000000 --- a/ModuleManager/CustomConfigsManager.cs +++ /dev/null @@ -1,27 +0,0 @@ -using System; -using System.IO; -using UnityEngine; - -using static ModuleManager.FilePathRepository; - -namespace ModuleManager -{ - [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] - public class CustomConfigsManager : MonoBehaviour - { - internal void Start() - { - if (HighLogic.CurrentGame.Parameters.Career.TechTreeUrl != techTreeFile && File.Exists(techTreePath)) - { - Log("Setting modded tech tree as the active one"); - HighLogic.CurrentGame.Parameters.Career.TechTreeUrl = techTreeFile; - } - } - - public static void Log(String s) - { - print("[CustomConfigsManager] " + s); - } - - } -} diff --git a/ModuleManager/Extensions/IBasicLoggerExtensions.cs b/ModuleManager/Extensions/IBasicLoggerExtensions.cs deleted file mode 100644 index 9fd29be3..00000000 --- a/ModuleManager/Extensions/IBasicLoggerExtensions.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using UnityEngine; -using ModuleManager.Logging; - -namespace ModuleManager.Extensions -{ - public static class IBasicLoggerExtensions - { - public static void Info(this IBasicLogger logger, string message) => logger.Log(new LogMessage(LogType.Log, message)); - public static void Warning(this IBasicLogger logger, string message) => logger.Log(new LogMessage(LogType.Warning, message)); - public static void Error(this IBasicLogger logger, string message) => logger.Log(new LogMessage(LogType.Error, message)); - - public static void Exception(this IBasicLogger logger, Exception exception) - { - if (exception == null) throw new ArgumentNullException(nameof(exception)); - logger.Log(new LogMessage(LogType.Exception, exception.ToString())); - } - - public static void Exception(this IBasicLogger logger, string message, Exception exception) - { - if (message == null) throw new ArgumentNullException(nameof(message)); - if (exception == null) throw new ArgumentNullException(nameof(exception)); - logger.Log(new LogMessage(LogType.Exception, message + ": " + exception.ToString())); - } - } -} diff --git a/ModuleManager/Extensions/UrlFileExtensions.cs b/ModuleManager/Extensions/UrlFileExtensions.cs deleted file mode 100644 index 3d203b24..00000000 --- a/ModuleManager/Extensions/UrlFileExtensions.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; - -namespace ModuleManager.Extensions -{ - public static class UrlFileExtensions - { - public static string GetUrlWithExtension(this UrlDir.UrlFile urlFile) - { - return $"{urlFile.url}.{urlFile.fileExtension}"; - } - public static string GetNameWithExtension(this UrlDir.UrlFile urlFile) - { - return $"{urlFile.name}.{urlFile.fileExtension}"; - } - } -} diff --git a/ModuleManager/FilePathRepository.cs b/ModuleManager/FilePathRepository.cs deleted file mode 100644 index 0d1448d7..00000000 --- a/ModuleManager/FilePathRepository.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; -using System.IO; - -namespace ModuleManager -{ - internal static class FilePathRepository - { - internal static readonly string normalizedRootPath = Path.GetFullPath(KSPUtil.ApplicationRootPath); - internal static readonly string cachePath = Path.Combine(normalizedRootPath, "GameData", "ModuleManager.ConfigCache"); - - internal static readonly string techTreeFile = Path.Combine("GameData", "ModuleManager.TechTree"); - internal static readonly string techTreePath = Path.Combine(normalizedRootPath, techTreeFile); - - internal static readonly string physicsFile = Path.Combine("GameData", "ModuleManager.Physics"); - internal static readonly string physicsPath = Path.Combine(normalizedRootPath, physicsFile); - internal static readonly string defaultPhysicsPath = Path.Combine(normalizedRootPath, "Physics.cfg"); - - internal static readonly string partDatabasePath = Path.Combine(normalizedRootPath, "PartDatabase.cfg"); - - internal static readonly string shaPath = Path.Combine(normalizedRootPath, "GameData", "ModuleManager.ConfigSHA"); - - internal static readonly string logsDirPath = Path.Combine(normalizedRootPath, "Logs", "ModuleManager"); - internal static readonly string logPath = Path.Combine(logsDirPath, "ModuleManager.log"); - internal static readonly string patchLogPath = Path.Combine(logsDirPath, "MMPatch.log"); - } -} diff --git a/ModuleManager/Logging/IBasicLogger.cs b/ModuleManager/Logging/IBasicLogger.cs deleted file mode 100644 index 25cd9367..00000000 --- a/ModuleManager/Logging/IBasicLogger.cs +++ /dev/null @@ -1,10 +0,0 @@ -using System; - -namespace ModuleManager.Logging -{ - // Stripped down version of UnityEngine.ILogger - public interface IBasicLogger - { - void Log(ILogMessage message); - } -} diff --git a/ModuleManager/Logging/ILogMessage.cs b/ModuleManager/Logging/ILogMessage.cs deleted file mode 100644 index bf85f488..00000000 --- a/ModuleManager/Logging/ILogMessage.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using UnityEngine; - -namespace ModuleManager.Logging -{ - public interface ILogMessage - { - LogType LogType { get; } - DateTime Timestamp { get; } - string Message { get; } - string ToLogString(); - } -} diff --git a/ModuleManager/Logging/LogMessage.cs b/ModuleManager/Logging/LogMessage.cs deleted file mode 100644 index c6554aaf..00000000 --- a/ModuleManager/Logging/LogMessage.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System; -using UnityEngine; - -namespace ModuleManager.Logging -{ - public class LogMessage : ILogMessage - { - private const string DATETIME_FORMAT_STRING = "HH:mm:ss.fff"; - - public LogType LogType { get; } - public DateTime Timestamp { get; } - public string Message { get; } - - public LogMessage(LogType logType, string message) - { - LogType = logType; - Timestamp = DateTime.Now; - Message = message ?? throw new ArgumentNullException(nameof(message)); - } - - public LogMessage(ILogMessage logMessage, string newMessage) - { - if (logMessage == null) throw new ArgumentNullException(nameof(logMessage)); - LogType = logMessage.LogType; - Timestamp = logMessage.Timestamp; - Message = newMessage ?? throw new ArgumentNullException(nameof(newMessage)); - } - - public string ToLogString() - { - string prefix; - if (LogType == LogType.Log) - prefix = "LOG"; - else if (LogType == LogType.Warning) - prefix = "WRN"; - else if (LogType == LogType.Error) - prefix = "ERR"; - else if (LogType == LogType.Assert) - prefix = "AST"; - else if (LogType == LogType.Exception) - prefix = "EXC"; - else - prefix = "???"; - - return $"[{prefix} {Timestamp.ToString(DATETIME_FORMAT_STRING)}] {Message}"; - } - - public override string ToString() - { - return $"[{GetType().FullName} LogType={LogType} Message={Message}]"; - } - } -} diff --git a/ModuleManager/Logging/LogSplitter.cs b/ModuleManager/Logging/LogSplitter.cs deleted file mode 100644 index b1d2c89f..00000000 --- a/ModuleManager/Logging/LogSplitter.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace ModuleManager.Logging -{ - public class LogSplitter : IBasicLogger - { - private readonly IBasicLogger logger1; - private readonly IBasicLogger logger2; - - public LogSplitter(IBasicLogger logger1, IBasicLogger logger2) - { - this.logger1 = logger1 ?? throw new ArgumentNullException(nameof(logger1)); - this.logger2 = logger2 ?? throw new ArgumentNullException(nameof(logger2)); - } - - public void Log(ILogMessage message) - { - if (message == null) throw new ArgumentNullException(nameof(message)); - logger1.Log(message); - logger2.Log(message); - } - } -} diff --git a/ModuleManager/Logging/PrefixLogger.cs b/ModuleManager/Logging/PrefixLogger.cs deleted file mode 100644 index 410473fa..00000000 --- a/ModuleManager/Logging/PrefixLogger.cs +++ /dev/null @@ -1,23 +0,0 @@ -using System; - -namespace ModuleManager.Logging -{ - public class PrefixLogger : IBasicLogger - { - private readonly string prefix; - private readonly IBasicLogger logger; - - public PrefixLogger(string prefix, IBasicLogger logger) - { - if (string.IsNullOrEmpty(prefix)) throw new ArgumentNullException(nameof(prefix)); - this.prefix = $"[{prefix}] "; - this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - - public void Log(ILogMessage message) - { - if (message == null) throw new ArgumentNullException(nameof(message)); - logger.Log(new LogMessage(message, prefix + message.Message)); - } - } -} diff --git a/ModuleManager/Logging/QueueLogRunner.cs b/ModuleManager/Logging/QueueLogRunner.cs deleted file mode 100644 index f78cf611..00000000 --- a/ModuleManager/Logging/QueueLogRunner.cs +++ /dev/null @@ -1,68 +0,0 @@ -using System; -using System.IO; - -using ModuleManager.Collections; - -namespace ModuleManager.Logging -{ - public class QueueLogRunner - { - private enum State - { - Initialized, - Running, - StopRequested, - Stopped, - } - - private State state = State.Initialized; - private readonly IMessageQueue logQueue; - private readonly long timeToWaitForLogsMs; - - public QueueLogRunner(IMessageQueue logQueue, long timeToWaitForLogsMs = 50) - { - this.logQueue = logQueue ?? throw new ArgumentNullException(nameof(logQueue)); - if (timeToWaitForLogsMs < 0) throw new ArgumentException("must be non-negative", nameof(timeToWaitForLogsMs)); - this.timeToWaitForLogsMs = timeToWaitForLogsMs; - } - - public void RequestStop() - { - if (state == State.StopRequested || state == State.Stopped) return; - if (state != State.Running) throw new InvalidOperationException($"Cannot request stop from {state} state"); - state = State.StopRequested; - } - - public void Run(IBasicLogger logger) - { - if (state != State.Initialized) throw new InvalidOperationException($"Cannot run from {state} state"); - if (logger == null) throw new ArgumentNullException(nameof(logger)); - state = State.Running; - - System.Diagnostics.Stopwatch stopwatch = new System.Diagnostics.Stopwatch(); - - while (state == State.Running) - { - stopwatch.Start(); - - foreach (ILogMessage message in logQueue.TakeAll()) - { - logger.Log(message); - } - - long timeRemaining = timeToWaitForLogsMs - stopwatch.ElapsedMilliseconds; - if (timeRemaining > 0) - System.Threading.Thread.Sleep((int)timeRemaining); - - stopwatch.Reset(); - } - - foreach (ILogMessage message in logQueue.TakeAll()) - { - logger.Log(message); - } - - state = State.Stopped; - } - } -} diff --git a/ModuleManager/Logging/QueueLogger.cs b/ModuleManager/Logging/QueueLogger.cs deleted file mode 100644 index b7cd288a..00000000 --- a/ModuleManager/Logging/QueueLogger.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using ModuleManager.Collections; - -namespace ModuleManager.Logging -{ - public class QueueLogger : IBasicLogger - { - private readonly IMessageQueue queue; - - public QueueLogger(IMessageQueue queue) - { - this.queue = queue ?? throw new ArgumentNullException(nameof(queue)); - } - - public void Log(ILogMessage message) - { - if (message == null) throw new ArgumentNullException(nameof(message)); - queue.Add(message); - } - } -} diff --git a/ModuleManager/Logging/StreamLogger.cs b/ModuleManager/Logging/StreamLogger.cs deleted file mode 100644 index d020f64c..00000000 --- a/ModuleManager/Logging/StreamLogger.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; -using System.IO; - -namespace ModuleManager.Logging -{ - public sealed class StreamLogger : IBasicLogger, IDisposable - { - private readonly StreamWriter streamWriter; - private bool disposed = false; - - public StreamLogger(Stream stream) - { - streamWriter = new StreamWriter(stream); - } - - public void Log(ILogMessage message) - { - if (disposed) throw new InvalidOperationException("Object has already been disposed"); - if (message == null) throw new ArgumentNullException(nameof(message)); - - streamWriter.WriteLine(message.ToLogString()); - } - - public void Dispose() - { - // Flushes and closes the StreamWriter and the underlying stream - streamWriter.Close(); - - disposed = true; - } - } -} diff --git a/ModuleManager/Logging/UnityLogger.cs b/ModuleManager/Logging/UnityLogger.cs deleted file mode 100644 index d51063c4..00000000 --- a/ModuleManager/Logging/UnityLogger.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using UnityEngine; - -namespace ModuleManager.Logging -{ - public class UnityLogger : IBasicLogger - { - private readonly ILogger logger; - - public UnityLogger(ILogger logger) - { - this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); - } - - public void Log(ILogMessage message) - { - if (message == null) throw new ArgumentNullException(nameof(message)); - logger.Log(message.LogType, message.Message); - } - } -} diff --git a/ModuleManager/Operator.cs b/ModuleManager/Operator.cs deleted file mode 100644 index 2846efa6..00000000 --- a/ModuleManager/Operator.cs +++ /dev/null @@ -1,15 +0,0 @@ -using System; - -namespace ModuleManager -{ - public enum Operator - { - Assign, - Add, - Subtract, - Multiply, - Divide, - Exponentiate, - RegexReplace, - } -} diff --git a/ModuleManager/Patches/IPatch.cs b/ModuleManager/Patches/IPatch.cs deleted file mode 100644 index a877ea80..00000000 --- a/ModuleManager/Patches/IPatch.cs +++ /dev/null @@ -1,16 +0,0 @@ -using System; -using System.Collections.Generic; -using ModuleManager.Logging; -using ModuleManager.Patches.PassSpecifiers; -using ModuleManager.Progress; - -namespace ModuleManager.Patches -{ - public interface IPatch - { - UrlDir.UrlConfig UrlConfig { get; } - IPassSpecifier PassSpecifier { get; } - bool CountsAsPatch { get; } - void Apply(LinkedList configs, IPatchProgress progress, IBasicLogger logger); - } -} diff --git a/ModuleManager/Patches/PassSpecifiers/FinalPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/FinalPassSpecifier.cs deleted file mode 100644 index 7567f344..00000000 --- a/ModuleManager/Patches/PassSpecifiers/FinalPassSpecifier.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using ModuleManager.Progress; - -namespace ModuleManager.Patches.PassSpecifiers -{ - public class FinalPassSpecifier : IPassSpecifier - { - public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) - { - if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); - if (progress == null) throw new ArgumentNullException(nameof(progress)); - return true; - } - - public string Descriptor => ":FINAL"; - } -} diff --git a/ModuleManager/Patches/PassSpecifiers/FirstPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/FirstPassSpecifier.cs deleted file mode 100644 index 7d32bbbd..00000000 --- a/ModuleManager/Patches/PassSpecifiers/FirstPassSpecifier.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using ModuleManager.Progress; - -namespace ModuleManager.Patches.PassSpecifiers -{ - public class FirstPassSpecifier : IPassSpecifier - { - public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) - { - if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); - if (progress == null) throw new ArgumentNullException(nameof(progress)); - return true; - } - - public string Descriptor => ":FIRST"; - } -} diff --git a/ModuleManager/Patches/PassSpecifiers/IPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/IPassSpecifier.cs deleted file mode 100644 index 384e52d5..00000000 --- a/ModuleManager/Patches/PassSpecifiers/IPassSpecifier.cs +++ /dev/null @@ -1,11 +0,0 @@ -using System; -using ModuleManager.Progress; - -namespace ModuleManager.Patches.PassSpecifiers -{ - public interface IPassSpecifier - { - bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress); - string Descriptor { get; } - } -} diff --git a/ModuleManager/Patches/PassSpecifiers/InsertPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/InsertPassSpecifier.cs deleted file mode 100644 index 244f9c5c..00000000 --- a/ModuleManager/Patches/PassSpecifiers/InsertPassSpecifier.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using ModuleManager.Progress; - -namespace ModuleManager.Patches.PassSpecifiers -{ - public class InsertPassSpecifier : IPassSpecifier - { - public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) - { - if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); - if (progress == null) throw new ArgumentNullException(nameof(progress)); - return true; - } - - public string Descriptor => ":INSERT (initial)"; - } -} diff --git a/ModuleManager/Patches/PassSpecifiers/LegacyPassSpecifier.cs b/ModuleManager/Patches/PassSpecifiers/LegacyPassSpecifier.cs deleted file mode 100644 index ddbee929..00000000 --- a/ModuleManager/Patches/PassSpecifiers/LegacyPassSpecifier.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using ModuleManager.Progress; - -namespace ModuleManager.Patches.PassSpecifiers -{ - public class LegacyPassSpecifier : IPassSpecifier - { - public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) - { - if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); - if (progress == null) throw new ArgumentNullException(nameof(progress)); - return true; - } - - public string Descriptor => ":LEGACY (default)"; - } -} diff --git a/ModuleManager/Patches/PatchCompiler.cs b/ModuleManager/Patches/PatchCompiler.cs deleted file mode 100644 index 6c7e7f30..00000000 --- a/ModuleManager/Patches/PatchCompiler.cs +++ /dev/null @@ -1,26 +0,0 @@ -using System; - -namespace ModuleManager.Patches -{ - public interface IPatchCompiler - { - IPatch CompilePatch(ProtoPatch protoPatch); - } - - public class PatchCompiler : IPatchCompiler - { - public IPatch CompilePatch(ProtoPatch protoPatch) - { - if (protoPatch == null) throw new ArgumentNullException(nameof(protoPatch)); - - return protoPatch.command switch - { - Command.Insert => new InsertPatch(protoPatch.urlConfig, protoPatch.nodeType, protoPatch.passSpecifier), - Command.Edit => new EditPatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier), - Command.Copy => new CopyPatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier), - Command.Delete => new DeletePatch(protoPatch.urlConfig, new NodeMatcher(protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier), - _ => throw new ArgumentException("has an invalid command for a root node: " + protoPatch.command, nameof(protoPatch)), - }; - } - } -} diff --git a/ModuleManager/Progress/IPatchProgress.cs b/ModuleManager/Progress/IPatchProgress.cs deleted file mode 100644 index 46bcb2ad..00000000 --- a/ModuleManager/Progress/IPatchProgress.cs +++ /dev/null @@ -1,32 +0,0 @@ -using System; - -namespace ModuleManager.Progress -{ - public interface IPatchProgress - { - ProgressCounter Counter { get; } - - float ProgressFraction { get; } - - EventVoid OnPatchApplied { get; } - EventData OnPassStarted { get; } - - void Warning(UrlDir.UrlConfig url, string message); - void Error(UrlDir.UrlConfig url, string message); - void Error(string message); - void Exception(string message, Exception exception); - void Exception(UrlDir.UrlConfig url, string message, Exception exception); - void NeedsUnsatisfiedRoot(UrlDir.UrlConfig url); - void NeedsUnsatisfiedNode(UrlDir.UrlConfig url, string path); - void NeedsUnsatisfiedValue(UrlDir.UrlConfig url, string path); - void NeedsUnsatisfiedBefore(UrlDir.UrlConfig url); - void NeedsUnsatisfiedFor(UrlDir.UrlConfig url); - void NeedsUnsatisfiedAfter(UrlDir.UrlConfig url); - void ApplyingCopy(IUrlConfigIdentifier original, UrlDir.UrlConfig patch); - void ApplyingDelete(IUrlConfigIdentifier original, UrlDir.UrlConfig patch); - void ApplyingUpdate(IUrlConfigIdentifier original, UrlDir.UrlConfig patch); - void PatchAdded(); - void PatchApplied(); - void PassStarted(IPass pass); - } -} diff --git a/ModuleManager/Progress/ProgressCounter.cs b/ModuleManager/Progress/ProgressCounter.cs deleted file mode 100644 index 7fc16627..00000000 --- a/ModuleManager/Progress/ProgressCounter.cs +++ /dev/null @@ -1,20 +0,0 @@ -using System; -using System.Collections.Generic; -using ModuleManager.Utils; - -namespace ModuleManager.Progress -{ - public class ProgressCounter - { - public readonly Counter totalPatches = new Counter(); - public readonly Counter appliedPatches = new Counter(); - public readonly Counter patchedNodes = new Counter(); - public readonly Counter warnings = new Counter(); - public readonly Counter errors = new Counter(); - public readonly Counter exceptions = new Counter(); - public readonly Counter needsUnsatisfied = new Counter(); - - public readonly Dictionary warningFiles = new Dictionary(); - public readonly Dictionary errorFiles = new Dictionary(); - } -} diff --git a/ModuleManager/Properties/AssemblyInfo.cs b/ModuleManager/Properties/AssemblyInfo.cs deleted file mode 100644 index e4e038f0..00000000 --- a/ModuleManager/Properties/AssemblyInfo.cs +++ /dev/null @@ -1,28 +0,0 @@ -using System.Reflection; -using System.Runtime.CompilerServices; - -// Information about this assembly is defined by the following attributes. -// Change them to the values specific to your project. - -[assembly: AssemblyTitle("ModuleManager")] -[assembly: AssemblyDescription("")] -[assembly: AssemblyConfiguration("")] -[assembly: AssemblyCompany("")] -[assembly: AssemblyProduct("")] -[assembly: AssemblyCopyright("")] -[assembly: AssemblyTrademark("")] -[assembly: AssemblyCulture("")] - -// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". -// The form "{Major}.{Minor}.*" will automatically update the build and revision, -// and "{Major}.{Minor}.{Build}.*" will update just the revision. - -[assembly: AssemblyVersion("4.2.2")] -[assembly: KSPAssembly("ModuleManager", 2, 5)] - -// The following attributes are used to specify the signing key for the assembly, -// if desired. See the Mono documentation for more information about signing. - -//[assembly: AssemblyDelaySign(false)] -//[assembly: AssemblyKeyFile("")] - diff --git a/ModuleManager/Threading/ITaskStatus.cs b/ModuleManager/Threading/ITaskStatus.cs deleted file mode 100644 index e60c76bd..00000000 --- a/ModuleManager/Threading/ITaskStatus.cs +++ /dev/null @@ -1,12 +0,0 @@ -using System; - -namespace ModuleManager.Threading -{ - public interface ITaskStatus - { - bool IsRunning { get; } - bool IsFinished { get; } - bool IsExitedWithError { get; } - Exception Exception { get; } - } -} diff --git a/ModuleManager/Threading/TaskStatusWrapper.cs b/ModuleManager/Threading/TaskStatusWrapper.cs deleted file mode 100644 index 1750633c..00000000 --- a/ModuleManager/Threading/TaskStatusWrapper.cs +++ /dev/null @@ -1,19 +0,0 @@ -using System; - -namespace ModuleManager.Threading -{ - public class TaskStatusWrapper : ITaskStatus - { - private readonly ITaskStatus inner; - - public TaskStatusWrapper(ITaskStatus inner) - { - this.inner = inner; - } - - public bool IsRunning => inner.IsRunning; - public bool IsFinished => inner.IsFinished; - public bool IsExitedWithError => inner.IsExitedWithError; - public Exception Exception => inner.Exception; - } -} diff --git a/ModuleManager/Utils/Counter.cs b/ModuleManager/Utils/Counter.cs deleted file mode 100644 index dcafce53..00000000 --- a/ModuleManager/Utils/Counter.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; - -namespace ModuleManager.Utils -{ - public class Counter - { - public int Value { get; private set; } = 0; - - public void Increment() - { - Value++; - } - - public override string ToString() - { - return Value.ToString(); - } - - public static implicit operator int(Counter counter) => counter.Value; - } -} diff --git a/ModuleManager/Utils/FileUtils.cs b/ModuleManager/Utils/FileUtils.cs deleted file mode 100644 index 818d3cc6..00000000 --- a/ModuleManager/Utils/FileUtils.cs +++ /dev/null @@ -1,21 +0,0 @@ -using System; -using System.IO; -using System.Security.Cryptography; -using ModuleManager.Extensions; - -namespace ModuleManager.Utils -{ - public static class FileUtils - { - public static string FileSHA(string filename) - { - if (!File.Exists(filename)) throw new FileNotFoundException("File does not exist", filename); - - using SHA256 sha = SHA256.Create(); - using FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read); - byte[] data = sha.ComputeHash(fs); - - return data.ToHex(); - } - } -} diff --git a/ModuleManager/copy_build.sh b/ModuleManager/copy_build.sh deleted file mode 100644 index 8d9f1ad5..00000000 --- a/ModuleManager/copy_build.sh +++ /dev/null @@ -1,45 +0,0 @@ -if [ -z "${TARGET_PATH}" ] ; then - echo 'Expected $TARGET_PATH to be defined but it is not' >&2 - exit 1 -elif ! [ -f "${TARGET_PATH}" ] ; then - echo 'Expected $TARGET_PATH to be a file but it is not' >&2 - exit 1 -fi - -if [ -z "${TARGET_DIR}" ] ; then - echo 'Expected $TARGET_DIR to be defined but it is not' >&2 - exit 1 -elif ! [ -d "${TARGET_DIR}" ] ; then - echo 'Expected $TARGET_DIR to be a directory but it is not' >&2 - exit 1 -fi - -if [ -z "${TARGET_NAME}" ] ; then - echo 'Expected $TARGET_NAME to be defined but it is not' >&2 - exit 1 -fi - -if [ -z "${PDB2MDB}" ] ; then - echo '$PDB2MDB not found' -else - echo "Running '${PDB2MDB}'" - "${PDB2MDB}" "${TARGET_PATH}" -fi - -if [ -z "${KSPDIR}" ] ; then - echo '$KSPDIR not found' -else - if ! [ -d "${KSPDIR}" ] ; then - echo 'Expected $KSPDIR to point to a directory but it is not' >&2 - exit 1 - fi - if ! [ -d "${KSPDIR}/GameData" ] ; then - echo 'Expected $KSPDIR to contain a GameData subdirectory but it does not' >&2 - exit 1 - fi - echo "Copying to '${KSPDIR}'" - cp "${TARGET_PATH}" "${KSPDIR}/GameData/" - test -f "${TARGET_DIR}/${TARGET_NAME}.pdb" && cp "${TARGET_DIR}/${TARGET_NAME}.pdb" "${KSPDIR}/GameData/" - test -f "${TARGET_DIR}/${TARGET_NAME}.dll.mdb" && cp "${TARGET_DIR}/${TARGET_NAME}.dll.mdb" "${KSPDIR}/GameData/" - rm -f "${KSPDIR}/GameData/ModuleManager.ConfigCache" -fi diff --git a/ModuleManagerTests/DummyTest.cs b/ModuleManagerTests/DummyTest.cs deleted file mode 100644 index 50783efd..00000000 --- a/ModuleManagerTests/DummyTest.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Xunit; - -namespace ModuleManagerTests -{ - public class DummyTest - { - [Fact] - public void PassingTest() - { - Assert.True(true); - } - } -} diff --git a/ModuleManagerTests/Extensions/UrlFileExtensionsTest.cs b/ModuleManagerTests/Extensions/UrlFileExtensionsTest.cs deleted file mode 100644 index 147e603e..00000000 --- a/ModuleManagerTests/Extensions/UrlFileExtensionsTest.cs +++ /dev/null @@ -1,17 +0,0 @@ -using System; -using Xunit; -using TestUtils; -using ModuleManager.Extensions; - -namespace ModuleManagerTests.Extensions -{ - public static class UrlFileExtensionsTest - { - [Fact] - public static void TestGetUrlWithExtension() - { - UrlDir.UrlFile urlFile = UrlBuilder.CreateFile("abc/def/ghi.cfg"); - Assert.Equal("abc/def/ghi.cfg", urlFile.GetUrlWithExtension()); - } - } -} diff --git a/NOTICE b/NOTICE new file mode 100644 index 00000000..355fed51 --- /dev/null +++ b/NOTICE @@ -0,0 +1,13 @@ +"Module Manager" is trademark of ialdabaoth, Sarbian & Blowfish +"/L" is trademark of LisiasT +"Module Manager /L" is trademark of LisiasT + +"/L Aerospace" is a fictitious entity created for entertainment purposes. It is in no way meant to represent a real entity. Any similarity to a real entity is purely coincidental. + +"Kerbal Space Program" is © 2011-2019 Private Division LLC. Developed by Squad. This project is in no way associated with nor endorsed by Squad or Private Division. + +Other trademarks and registered trademarks are the property of the respective trademark holders. + +© 2018-2026 LisiasT +© 2013-2018 Sarbian & Blowfish +© 2013 ialdabaoth diff --git a/README.md b/README.md index 4e1f154c..84fc9825 100644 --- a/README.md +++ b/README.md @@ -1,32 +1,82 @@ -ModuleManager -============= +# Module Manager /L +*Lasciate ogne speranza, voi ch'intrate* +- - - +ModuleManager is a mod that let you write patches that edit other parts at load time. -Original (c) from Ialdabaoth ( https://github.com/Ialdabaoth ) +This is Lisias' fork for Module Manager, and it's intended to bring functionality and performant improvements to ModuleManager - with great to moderate success being achieved toward these goals (most of the time!), as well others not mentioned here. -Modified by // Modifications by // Maintained by sarbian ( https://github.com/sarbian ) +Backwards compatibility is guaranteed - including functional bugs on `Module Manager - Forum`. `MM/L`'s patching output will be always the same as `Module Manager - Forum`, salvo new (and optional) features when not present on `Module Manager - Forum`. +Development for this fork is ongoing and, as such, subject to some screw ups now and then. **AVOID** Pre Releases unless you are willing to help me debug this thing (check for `Pre Release` markings before downloading). -The original licence requirement was: +Please, **DO NOT** submit bug reports/issues to the [References](#references) (see the bottom of this document), as this is an EXPERIMENTAL/WIP version of `ModuleManger - Forum` being developed in parallel and separately from the Forum version. ---- +Necessarily, `MM/L` will receive **no support** from the maintainers of `ModuleManger - Forum`, as well from some 3rd parties that may choose to support `ModuleManger - Forum` only. Some others (and myself), on the other hand, **will** actively support `MM/L`. Check your add'ons documentation (or politely ask us directly) for more information. -under a CC share-alike license. Anyone is free to do anything they like with ModuleManager's source, with two caveats: +Please, **DO** submit bug reports/issues to the links depicted on the next section of this document disregarding if you think it's a problem on this fork or not. If the bug is on the upstream's releases, the report will be applied to it as well with any fixes - but I can't guarantee the pull requests will be accepted! -1. You credit me as the original creator that your code is based on -2. You make it ABSOLUTELY CLEAR that your code is not the original ModuleManager, and that any problems that people have with your fork should be taken up with YOU, not me. ---- +## In a Hurry +* [Releases](https://github.com/KSP-ModularManagement/ModuleManager/Archive) +* [Latest Release](https://github.com/KSP-ModularManagement/ModuleManager/releases) +* [Source](https://github.com/KSP-ModularManagement/ModuleManager) +* [Issue Tracker](https://github.com/KSP-ModularManagement/ModuleManager/issues) +* Documentation + + [Homepage](http://ksp.lisias.net/add-ons/ModuleManager) on L Aerospace KSP Division + + [Project's README](https://github.com/KSP-ModularManagement/ModuleManager/blob/master/README.md) + + [Install Instructions](https://github.com/KSP-ModularManagement/ModuleManager/blob/master/INSTALL.md) + + [Change Log](./CHANGE_LOG.md) + + [TODO](./TODO.md) list +* Official Distribution Sites: + + [Homepage](http://ksp.lisias.net/add-ons/ModuleManager) on L Aerospace + + [Source and Binaries](https://github.com/KSP-ModularManagement/ModuleManager) on GitHub. -THIS IS NOT THE ORIGINAL MODULEMANAGER CODE. -Do not bother Ialdabaoth about any problems with it. +## Description -## Dependencies +ModuleManager is mod that let you write patch file that edit other part at load time. With is you can edit squad (and other mod) part without overwriting their file. -- mono resgen2 - - Fedora: `sudo dnf install mono-devel` -- Mono C# Compiler - - Fedora: `sudo ln -s /usr/bin/mcs /usr/bin/gmcs` +## Installation +To install, place the GameData folder inside your Kerbal Space Program folder. If asked to overwrite files, please do so. + +**REMOVE ANY OLD VERSIONS OF THE DLL BEFORE INSTALLING**. + +### Dependencies + +* Hard Depencies: + * [KSP API Extensions/L](https://github.com/KSP-ModularManagement/KSPAPIExtensions) V 2.0 or above. + +### Licensing + +This work is licensed as follows: + +* [GPL 3.0](https://www.gnu.org/licenses/gpl-3.0.en.html). See [here](./LICENSE) + + You are free to: + - Use : unpack and use the material in any computer or device + - Redistribute : redistribute the original package in any medium + - Adapt : Reuse, modify or incorporate source code into your works (and redistribute it!) + + Under the following terms: + - You retain any copyright notices + - You recognise and respect any trademarks + - You don't impersonate the authors, neither redistribute a derivative that could be misrepresented as theirs. + - You credit the author and republish the copyright notices on your works where the code is used. + - You relicense (and fully comply) your works using GPL 3.0 + - Please note that upgrading the license to any posterior GPL **IS NOT ALLOWED** for this work, as the author **DID NOT** added the "or (at your option) any later version" on the license. + - You don't mix your work with GPL incompatible works. + +[Previous releases](https://github.com/KSP-ModularManagement/ModuleManager/tree/upstream/master) remain licensed under the [CC-BY-SA 4.0](https://creativecommons.org/licenses/by-sa/4.0/). Additionally, [check this statement](https://creativecommons.org/2015/10/08/cc-by-sa-4-0-now-one-way-compatible-with-gplv3/) from CC. + +Please note the copyrights and trademarks in [NOTICE](./NOTICE) + + +## References + +* [Sarbian](https://forum.kerbalspaceprogram.com/index.php?/profile/57146-sarbian/) UPSTREAM / Current Maintainer + + [Forum](https://forum.kerbalspaceprogram.com/index.php?/topic/50533-141-module-manager-307-may-5th-2018-its-dangerous-to-go-alone-take-those-cats-with-you) + + [GitHub](https://github.com/sarbian/ModuleManager) +* [Ialdabaoth](https://forum.kerbalspaceprogram.com/index.php?/profile/57270-ialdabaoth/) ROOT + + [Forum](https://forum.kerbalspaceprogram.com/index.php?/topic/28844-020-modulemanager-13-for-all-your-stock-modding-needs) + + [GitHub](https://github.com/Ialdabaoth/ModuleManager) diff --git a/ModuleManager/Cats/CatAnimator.cs b/Source/ModuleManager/Cats/CatAnimator.cs similarity index 57% rename from ModuleManager/Cats/CatAnimator.cs rename to Source/ModuleManager/Cats/CatAnimator.cs index 7806d4aa..f54868a8 100644 --- a/ModuleManager/Cats/CatAnimator.cs +++ b/Source/ModuleManager/Cats/CatAnimator.cs @@ -1,7 +1,24 @@ -using System.Collections; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System.Collections; using System.Diagnostics.CodeAnalysis; using UnityEngine; +#if CATS namespace ModuleManager.Cats { class CatAnimator : MonoBehaviour @@ -16,7 +33,7 @@ class CatAnimator : MonoBehaviour [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] void Start() { - spriteRenderer = GetComponent(); + spriteRenderer = this.GetComponent(); spriteRenderer.sortingOrder = 3; StartCoroutine(Animate()); } @@ -38,3 +55,4 @@ IEnumerator Animate() } } } +#endif \ No newline at end of file diff --git a/ModuleManager/Cats/CatManager.cs b/Source/ModuleManager/Cats/CatManager.cs similarity index 63% rename from ModuleManager/Cats/CatManager.cs rename to Source/ModuleManager/Cats/CatManager.cs index 05f671d6..c7d7a351 100644 --- a/ModuleManager/Cats/CatManager.cs +++ b/Source/ModuleManager/Cats/CatManager.cs @@ -1,6 +1,24 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using UnityEngine; +using K = KSPe.Util.Log; +#if CATS namespace ModuleManager.Cats { public static class CatManager @@ -49,22 +67,24 @@ private static void InitCats() for (int i = 0; i < tex.Length; i++) { tex[i] = new Texture2D(70, 42, TextureFormat.ARGB32, false); - } - tex[0].LoadImage(Properties.Resources.cat1); - tex[1].LoadImage(Properties.Resources.cat2); - tex[2].LoadImage(Properties.Resources.cat3); - tex[3].LoadImage(Properties.Resources.cat4); - tex[4].LoadImage(Properties.Resources.cat5); - tex[5].LoadImage(Properties.Resources.cat6); - tex[6].LoadImage(Properties.Resources.cat7); - tex[7].LoadImage(Properties.Resources.cat8); - tex[8].LoadImage(Properties.Resources.cat9); - tex[9].LoadImage(Properties.Resources.cat10); - tex[10].LoadImage(Properties.Resources.cat11); - tex[11].LoadImage(Properties.Resources.cat12); - + } + { + int i = 0; + tex[i++].LoadRawTextureData(Properties.Resources.cat1); + tex[i++].LoadRawTextureData(Properties.Resources.cat2); + tex[i++].LoadRawTextureData(Properties.Resources.cat3); + tex[i++].LoadRawTextureData(Properties.Resources.cat4); + tex[i++].LoadRawTextureData(Properties.Resources.cat5); + tex[i++].LoadRawTextureData(Properties.Resources.cat6); + tex[i++].LoadRawTextureData(Properties.Resources.cat7); + tex[i++].LoadRawTextureData(Properties.Resources.cat8); + tex[i++].LoadRawTextureData(Properties.Resources.cat9); + tex[i++].LoadRawTextureData(Properties.Resources.cat10); + tex[i++].LoadRawTextureData(Properties.Resources.cat11); + tex[i++].LoadRawTextureData(Properties.Resources.cat12); + } rainbow = new Texture2D(39, 36, TextureFormat.ARGB32, false); - rainbow.LoadImage(Properties.Resources.rainbow); + rainbow.LoadRawTextureData(Properties.Resources.rainbow); rainbow.Apply(); catFrames = new Sprite[12]; @@ -94,9 +114,13 @@ private static GameObject LaunchCat(int scale) sr.sprite = catFrames[0]; - trail.material = new Material(Shader.Find("Legacy Shaders/Particles/Alpha Blended")); + trail.material = new Material(Shader.Find( + 2019 == KSPe.Util.UnityTools.UnityVersion + ? "Legacy Shaders/Particles/Alpha Blended" + : "Particles/Alpha Blended" + )); - Debug.Log("material = " + trail.material); + LOG.info("material = {0}", trail.material); trail.material.mainTexture = rainbow; trail.time = 1.5f; trail.startWidth = 0.6f * scale * rainbow.height; @@ -111,5 +135,8 @@ private static GameObject LaunchCat(int scale) cat.transform.localScale = 70 * scale * Vector3.one; return cat; } - } + + internal static readonly K.Logger LOG = K.Logger.CreateForType(true); + } } +#endif \ No newline at end of file diff --git a/ModuleManager/Cats/CatMover.cs b/Source/ModuleManager/Cats/CatMover.cs similarity index 74% rename from ModuleManager/Cats/CatMover.cs rename to Source/ModuleManager/Cats/CatMover.cs index d97a3f7c..a4efd89f 100644 --- a/ModuleManager/Cats/CatMover.cs +++ b/Source/ModuleManager/Cats/CatMover.cs @@ -1,6 +1,23 @@ -using System.Diagnostics.CodeAnalysis; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System.Diagnostics.CodeAnalysis; using UnityEngine; +#if CATS namespace ModuleManager.Cats { public class CatMover : MonoBehaviour @@ -27,10 +44,10 @@ public class CatMover : MonoBehaviour [SuppressMessage("CodeQuality", "IDE0051", Justification = "Called by Unity")] void Start() { - trail = GetComponent(); + trail = this.GetComponent(); trail.sortingOrder = 2; - spriteRenderer = GetComponent(); + spriteRenderer = this.GetComponent(); offsetY = Mathf.FloorToInt(0.2f * Screen.height); @@ -79,3 +96,4 @@ void Update() } } +#endif \ No newline at end of file diff --git a/ModuleManager/Cats/CatOrbiter.cs b/Source/ModuleManager/Cats/CatOrbiter.cs similarity index 86% rename from ModuleManager/Cats/CatOrbiter.cs rename to Source/ModuleManager/Cats/CatOrbiter.cs index 34b1f6e8..12cbbf68 100644 --- a/ModuleManager/Cats/CatOrbiter.cs +++ b/Source/ModuleManager/Cats/CatOrbiter.cs @@ -1,10 +1,27 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using KSP.UI; using UnityEngine; using Random = UnityEngine.Random; +#if CATS namespace ModuleManager.Cats { class CatOrbiter : MonoBehaviour @@ -86,8 +103,7 @@ public void Init(CatOrbiter parent, float soi) double circularVel = Math.Sqrt(G * (Mass + parent.Mass) / dist.magnitude); if (parent == sun) circularVel *= Random.Range(0.9f, 1.1f); - Debug.Log("CatOrbiter " + circularVel.ToString("F3") + " " + Mass.ToString("F2") + " " + orbiters[0].Mass.ToString("F2") + " " + - dist.magnitude.ToString("F2")); + CatManager.LOG.info("CatOrbiter {0} {1} {2} {3}", circularVel.ToString("F3"), Mass.ToString("F2"), orbiters[0].Mass.ToString("F2"), dist.magnitude.ToString("F2")); Vector3d normal = (Random.value >= 0.3) ? Vector3d.back : Vector3d.forward; @@ -137,3 +153,4 @@ void FixedUpdate() } } } +#endif \ No newline at end of file diff --git a/ModuleManager/Collections/ArrayEnumerator.cs b/Source/ModuleManager/Collections/ArrayEnumerator.cs similarity index 77% rename from ModuleManager/Collections/ArrayEnumerator.cs rename to Source/ModuleManager/Collections/ArrayEnumerator.cs index 775a35dd..883eb76b 100644 --- a/ModuleManager/Collections/ArrayEnumerator.cs +++ b/Source/ModuleManager/Collections/ArrayEnumerator.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; diff --git a/ModuleManager/Collections/ImmutableStack.cs b/Source/ModuleManager/Collections/ImmutableStack.cs similarity index 76% rename from ModuleManager/Collections/ImmutableStack.cs rename to Source/ModuleManager/Collections/ImmutableStack.cs index d710c423..303055f4 100644 --- a/ModuleManager/Collections/ImmutableStack.cs +++ b/Source/ModuleManager/Collections/ImmutableStack.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; @@ -29,15 +45,14 @@ public bool MoveNext() currentStack = head; return true; } - else if (!currentStack.IsRoot) + + if (!currentStack.IsRoot) { currentStack = currentStack.parent; return true; } - else - { - return false; - } + + return false; } public void Reset() => currentStack = null; diff --git a/ModuleManager/Collections/KeyValueCache.cs b/Source/ModuleManager/Collections/KeyValueCache.cs similarity index 60% rename from ModuleManager/Collections/KeyValueCache.cs rename to Source/ModuleManager/Collections/KeyValueCache.cs index 0aaee61b..5107e6b0 100644 --- a/ModuleManager/Collections/KeyValueCache.cs +++ b/Source/ModuleManager/Collections/KeyValueCache.cs @@ -1,3 +1,19 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using System.Collections.Generic; diff --git a/ModuleManager/Collections/MessageQueue.cs b/Source/ModuleManager/Collections/MessageQueue.cs similarity index 80% rename from ModuleManager/Collections/MessageQueue.cs rename to Source/ModuleManager/Collections/MessageQueue.cs index b6038a77..69a27a19 100644 --- a/ModuleManager/Collections/MessageQueue.cs +++ b/Source/ModuleManager/Collections/MessageQueue.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; diff --git a/Source/ModuleManager/Command.cs b/Source/ModuleManager/Command.cs new file mode 100644 index 00000000..d865b96f --- /dev/null +++ b/Source/ModuleManager/Command.cs @@ -0,0 +1,41 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +namespace ModuleManager +{ + public enum Command + { + Insert, + + Delete, // - or ! + + Edit, // @ + + Replace, // % + + Copy, // + or $ + + Rename, // | + + Paste, // # + + Special, // * + + Create // & + } +} diff --git a/ModuleManager/CommandParser.cs b/Source/ModuleManager/CommandParser.cs similarity index 70% rename from ModuleManager/CommandParser.cs rename to Source/ModuleManager/CommandParser.cs index 89029b77..54c9b784 100644 --- a/ModuleManager/CommandParser.cs +++ b/Source/ModuleManager/CommandParser.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; namespace ModuleManager { diff --git a/Source/ModuleManager/CustomConfigsManager.cs b/Source/ModuleManager/CustomConfigsManager.cs new file mode 100644 index 00000000..aa126237 --- /dev/null +++ b/Source/ModuleManager/CustomConfigsManager.cs @@ -0,0 +1,56 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using UnityEngine; + +using static ModuleManager.FilePathRepository; + +namespace ModuleManager +{ + [KSPAddon(KSPAddon.Startup.SpaceCentre, false)] + public class CustomConfigsManager : MonoBehaviour + { + internal static bool start_techtree_loaded = false; + internal void Start() + { +#if false + Log("Blah"); + Log(HighLogic.CurrentGame.Parameters.Career.TechTreeUrl); + Log(TECHTREE_CONFIG.Path); + Log(TECHTREE_CONFIG.IsLoadable.ToString()); +#endif + if (start_techtree_loaded) + { + if (HighLogic.CurrentGame.Parameters.Career.TechTreeUrl != TECHTREE_CONFIG.KspPath) + Log("Tech tree was changed by third party to [{0}].", HighLogic.CurrentGame.Parameters.Career.TechTreeUrl); + } + else if (TECHTREE_CONFIG.IsLoadable) + { + Log("Setting modded tech tree as the active one"); + HighLogic.CurrentGame.Parameters.Career.TechTreeUrl = TECHTREE_CONFIG.KspPath; + start_techtree_loaded = true; + } + } + + private static readonly KSPe.Util.Log.Logger log = KSPe.Util.Log.Logger.CreateThreadUnsafeForType(); // No need to use thread safe logging. Yet. + private static void Log(String s, params object[] @params) + { + log.info(s, @params); + } + + } +} diff --git a/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs b/Source/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs similarity index 64% rename from ModuleManager/ExceptionIntercept/InterceptLogHandler.cs rename to Source/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs index 471b1fa8..e95a25f9 100644 --- a/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs +++ b/Source/ModuleManager/ExceptionIntercept/InterceptLogHandler.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.IO; using System.Linq; @@ -16,9 +32,10 @@ class InterceptLogHandler : ILogHandler public static string Warnings { get; private set; } = ""; - public InterceptLogHandler(ILogHandler baseLogHandler) + public InterceptLogHandler() { - this.baseLogHandler = baseLogHandler ?? throw new ArgumentNullException(nameof(baseLogHandler)); + baseLogHandler = Debug.logger.logHandler; + Debug.logger.logHandler = this; gamePathLength = Path.GetFullPath(KSPUtil.ApplicationRootPath).Length; } @@ -36,12 +53,12 @@ public void LogException(Exception exception, Object context) string message = "Intercepted a ReflectionTypeLoadException. List of broken DLLs:\n"; try { - var assemblies = ex.Types.Where(x => x != null).Select(x => x.Assembly).Distinct(); + IEnumerable assemblies = ex.Types.Where(x => x != null).Select(x => x.Assembly).Distinct(); foreach (Assembly assembly in assemblies) { - if (Warnings == "") + if (string.IsNullOrEmpty(Warnings)) { - Warnings = "Mod(s) DLL that are not compatible with this version of KSP\n"; + Warnings = "Add'On(s) DLL that have failed to be dynamically linked on loading\n"; } string modInfo = assembly.GetName().Name + " " + assembly.GetName().Version + " " + assembly.Location.Remove(0, gamePathLength) + "\n"; @@ -57,7 +74,8 @@ public void LogException(Exception exception, Object context) { message += "Exception " + e.GetType().Name + " while handling the exception..."; } - ModuleManager.Log(message); + Logging.ModLogger.LOG.error("**FATAL** {0}", message); + GUI.ShowStopperAlertBox.Show(message); } } } diff --git a/ModuleManager/Extensions/ByteArrayExtensions.cs b/Source/ModuleManager/Extensions/ByteArrayExtensions.cs similarity index 56% rename from ModuleManager/Extensions/ByteArrayExtensions.cs rename to Source/ModuleManager/Extensions/ByteArrayExtensions.cs index 520393df..2f795866 100644 --- a/ModuleManager/Extensions/ByteArrayExtensions.cs +++ b/Source/ModuleManager/Extensions/ByteArrayExtensions.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; namespace ModuleManager.Extensions { diff --git a/ModuleManager/Extensions/ConfigNodeExtensions.cs b/Source/ModuleManager/Extensions/ConfigNodeExtensions.cs similarity index 86% rename from ModuleManager/Extensions/ConfigNodeExtensions.cs rename to Source/ModuleManager/Extensions/ConfigNodeExtensions.cs index 9f552566..d6cf206c 100644 --- a/ModuleManager/Extensions/ConfigNodeExtensions.cs +++ b/Source/ModuleManager/Extensions/ConfigNodeExtensions.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Text; namespace ModuleManager.Extensions diff --git a/Source/ModuleManager/Extensions/IBasicLoggerExtensions.cs b/Source/ModuleManager/Extensions/IBasicLoggerExtensions.cs new file mode 100644 index 00000000..a549d6f9 --- /dev/null +++ b/Source/ModuleManager/Extensions/IBasicLoggerExtensions.cs @@ -0,0 +1,32 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; +using ModuleManager.Logging; + +using K = KSPe.Util.Log; + +namespace ModuleManager.Extensions +{ + public static class IBasicLoggerExtensions + { + public static void Trace(this IBasicLogger logger, string message, params object[] @params) => logger.Log(K.Level.TRACE, message, @params); + public static void Detail(this IBasicLogger logger, string message, params object[] @params) => logger.Log(K.Level.DETAIL, message, @params); + public static void Info(this IBasicLogger logger, string message, params object[] @params) => logger.Log(K.Level.INFO, message, @params); + public static void Warning(this IBasicLogger logger, string message, params object[] @params) => logger.Log(K.Level.WARNING, message, @params); + public static void Error(this IBasicLogger logger, string message, params object[] @params) => logger.Log(K.Level.ERROR, message, @params); + } +} diff --git a/ModuleManager/Extensions/NodeStackExtensions.cs b/Source/ModuleManager/Extensions/NodeStackExtensions.cs similarity index 54% rename from ModuleManager/Extensions/NodeStackExtensions.cs rename to Source/ModuleManager/Extensions/NodeStackExtensions.cs index c6357dca..1fb0a391 100644 --- a/ModuleManager/Extensions/NodeStackExtensions.cs +++ b/Source/ModuleManager/Extensions/NodeStackExtensions.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Linq; using System.Text; using NodeStack = ModuleManager.Collections.ImmutableStack; diff --git a/ModuleManager/Extensions/StringExtensions.cs b/Source/ModuleManager/Extensions/StringExtensions.cs similarity index 64% rename from ModuleManager/Extensions/StringExtensions.cs rename to Source/ModuleManager/Extensions/StringExtensions.cs index 634fab7a..44d6c3c4 100644 --- a/ModuleManager/Extensions/StringExtensions.cs +++ b/Source/ModuleManager/Extensions/StringExtensions.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Text.RegularExpressions; namespace ModuleManager.Extensions diff --git a/ModuleManager/Extensions/UrlConfigExtensions.cs b/Source/ModuleManager/Extensions/UrlConfigExtensions.cs similarity index 70% rename from ModuleManager/Extensions/UrlConfigExtensions.cs rename to Source/ModuleManager/Extensions/UrlConfigExtensions.cs index d5ce9fbe..88d66caf 100644 --- a/ModuleManager/Extensions/UrlConfigExtensions.cs +++ b/Source/ModuleManager/Extensions/UrlConfigExtensions.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Text; namespace ModuleManager.Extensions diff --git a/ModuleManager/Extensions/UrlDirExtensions.cs b/Source/ModuleManager/Extensions/UrlDirExtensions.cs similarity index 70% rename from ModuleManager/Extensions/UrlDirExtensions.cs rename to Source/ModuleManager/Extensions/UrlDirExtensions.cs index 3a57bf6a..bc25d6c7 100644 --- a/ModuleManager/Extensions/UrlDirExtensions.cs +++ b/Source/ModuleManager/Extensions/UrlDirExtensions.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Linq; namespace ModuleManager.Extensions diff --git a/Source/ModuleManager/Extensions/UrlFileExtensions.cs b/Source/ModuleManager/Extensions/UrlFileExtensions.cs new file mode 100644 index 00000000..98d22326 --- /dev/null +++ b/Source/ModuleManager/Extensions/UrlFileExtensions.cs @@ -0,0 +1,32 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +namespace ModuleManager.Extensions +{ + public static class UrlFileExtensions + { + public static string GetUrlWithExtension(this UrlDir.UrlFile urlFile) + { + return $"{urlFile.url}.{urlFile.fileExtension}"; + } + public static string GetNameWithExtension(this UrlDir.UrlFile urlFile) + { + return $"{urlFile.name}.{urlFile.fileExtension}"; + } + } +} diff --git a/ModuleManager/FatalErrorHandler.cs b/Source/ModuleManager/FatalErrorHandler.cs similarity index 62% rename from ModuleManager/FatalErrorHandler.cs rename to Source/ModuleManager/FatalErrorHandler.cs index 06bf686e..71b5d089 100644 --- a/ModuleManager/FatalErrorHandler.cs +++ b/Source/ModuleManager/FatalErrorHandler.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using UnityEngine; namespace ModuleManager @@ -7,12 +23,15 @@ public static class FatalErrorHandler { public static void HandleFatalError(string message) { + Logging.ModLogger.LOG.error(message); try { PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new MultiOptionDialog( +#if !KSP12 "ModuleManagerFatalError", +#endif $"ModuleManager has encountered a fatal error and KSP needs to close.\n\n{message}\n\nPlease see KSP's log for addtional details", "ModuleManager - Fatal Error", HighLogic.UISkin, @@ -29,8 +48,7 @@ public static void HandleFatalError(string message) } catch(Exception ex) { - Debug.LogError("Exception while trying to create the fatal exception dialog"); - Debug.LogException(ex); + Logging.ModLogger.LOG.error(ex, "Exception while trying to create the fatal exception dialog"); Application.Quit(); } } diff --git a/Source/ModuleManager/FilePathRepository.cs b/Source/ModuleManager/FilePathRepository.cs new file mode 100644 index 00000000..f8185698 --- /dev/null +++ b/Source/ModuleManager/FilePathRepository.cs @@ -0,0 +1,34 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using PluginConfig = KSPe.IO.Data.ConfigNode; +using KspConfig = KSPe.IO.KspConfigNode; + +namespace ModuleManager +{ + internal static class FilePathRepository + { + internal static readonly PluginConfig SHA_CONFIG = PluginConfig.For(null, "ConfigSHA.cfg"); + internal static readonly PluginConfig CACHE_CONFIG = PluginConfig.For(null, "ConfigCache.cfg"); + internal static readonly PluginConfig PHYSICS_CONFIG = PluginConfig.For(null, "Physics.cfg"); + internal static readonly PluginConfig TECHTREE_CONFIG = PluginConfig.For("TechTree"); + internal static readonly KspConfig PHYSICS_DEFAULT = new KspConfig("Physics"); + internal static readonly KspConfig PART_DATABASE = new KspConfig("PartDatabase"); + + internal static readonly string MMCfgOutputPath = KSPe.IO.File.Data.Solve("_MMCfgOutput"); + internal static readonly string PATCH_LOG_FILENAME = "MMPatch"; + } +} diff --git a/ModuleManager/Fix16.cs b/Source/ModuleManager/Fix16.cs similarity index 76% rename from ModuleManager/Fix16.cs rename to Source/ModuleManager/Fix16.cs index b567eb56..828d47f2 100644 --- a/ModuleManager/Fix16.cs +++ b/Source/ModuleManager/Fix16.cs @@ -1,4 +1,20 @@ -using System.Collections; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System.Collections; using System.Diagnostics.CodeAnalysis; namespace ModuleManager @@ -75,9 +91,11 @@ private IEnumerator DoFix() yield return null; } + #if !KSP12 public override float LoadWeight() { return 0.1f; } + #endif } } diff --git a/Source/ModuleManager/GUI/Menu.12.cs b/Source/ModuleManager/GUI/Menu.12.cs new file mode 100644 index 00000000..71aea009 --- /dev/null +++ b/Source/ModuleManager/GUI/Menu.12.cs @@ -0,0 +1,43 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; +using UGUI = UnityEngine.GUI; + +namespace ModuleManager.GUI +{ +#if KSP12 +internal class Menu + { + private readonly ModuleManager parent; + private PopupDialog instance; + + internal Menu(ModuleManager parent) + { + this.parent = parent; + } + + internal void Dismiss() + { + this.instance.Dismiss(); + this.instance = null; + } + + internal void OnUpdate(bool inRnDCenter) + { + // TODO Make this work on KSP 1.2! + } + } +#endif +} diff --git a/Source/ModuleManager/GUI/Menu.cs b/Source/ModuleManager/GUI/Menu.cs new file mode 100644 index 00000000..587fae39 --- /dev/null +++ b/Source/ModuleManager/GUI/Menu.cs @@ -0,0 +1,90 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; + +namespace ModuleManager.GUI +{ +#if !KSP12 + internal class Menu + { + private readonly ModuleManager parent; + private PopupDialog instance; + + internal Menu(ModuleManager parent) + { + this.parent = parent; + } + + internal void Dismiss() + { + this.instance.Dismiss(); + this.instance = null; + } + + internal void OnUpdate(bool inRnDCenter) + { + if (GameSettings.MODIFIER_KEY.GetKey() && Input.GetKeyDown(KeyCode.F11) + && (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.MAINMENU) + && !inRnDCenter) + { + if (null == this.instance) + this.Show(); + else + this.Dismiss(); + } + } + + private void Show() + { + this.instance = PopupDialog.SpawnPopupDialog( + new Vector2(0.5f, 0.5f), + new Vector2(0.5f, 0.5f), + new MultiOptionDialog( + "ModuleManagerMenu", + "", + "ModuleManager", + HighLogic.UISkin, + new Rect(0.5f, 0.5f, 220f, 60f), + new DialogGUIFlexibleSpace(), + new DialogGUIVerticalLayout( + new DialogGUIFlexibleSpace(), +#if false + new DialogGUIButton("Reload Database", + delegate + { + this.parent.StartCoroutine(this.parent.DataBaseReloadWithMM(false)); + this.Dismiss(); + }, 200.0f, 30.0f, false), +#endif + new DialogGUIButton("Quick Reload Database", + delegate + { + this.parent.StartCoroutine(this.parent.QuickDataBaseReloadWithMM()); + this.Dismiss(); + }, 200.0f, 30.0f, false), + new DialogGUIButton("Dump Database to Files", + delegate + { + this.parent.StartCoroutine(this.parent.DumpDataBaseToFiles()); + this.Dismiss(); + }, 200.0f, 30.0f, false), + new DialogGUIButton("Close", () => { this.Dismiss(); } , 200.0f, 30.0f, false) + )), + false, + HighLogic.UISkin); + } + } +#endif +} diff --git a/Source/ModuleManager/GUI/ReloadingDatabase.12.cs b/Source/ModuleManager/GUI/ReloadingDatabase.12.cs new file mode 100644 index 00000000..4972bf67 --- /dev/null +++ b/Source/ModuleManager/GUI/ReloadingDatabase.12.cs @@ -0,0 +1,43 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; +using UGUI = UnityEngine.GUI; + +namespace ModuleManager.GUI +{ +#if KSP12 + public class ReloadingDatabaseDialog + { + internal static ReloadingDatabaseDialog Show(ModuleManager parent) + { + return new ReloadingDatabaseDialog(parent); + } + + internal ReloadingDatabaseDialog Dismiss() + { + this.instance.Dismiss(); + this.instance = null; + return null; + } + + private ModuleManager parent; + private PopupDialog instance; + private ReloadingDatabaseDialog(ModuleManager parent) + { + this.parent = parent; + } + } +#endif +} \ No newline at end of file diff --git a/Source/ModuleManager/GUI/ReloadingDatabase.cs b/Source/ModuleManager/GUI/ReloadingDatabase.cs new file mode 100644 index 00000000..472227e9 --- /dev/null +++ b/Source/ModuleManager/GUI/ReloadingDatabase.cs @@ -0,0 +1,124 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; +using UGUI = UnityEngine.GUI; + +namespace ModuleManager.GUI +{ +#if !KSP12 + public class ReloadingDatabaseDialog + { + internal static ReloadingDatabaseDialog Show(ModuleManager parent) + { + return new ReloadingDatabaseDialog(parent); + } + + internal ReloadingDatabaseDialog Dismiss() + { + this.instance.Dismiss(); + this.instance = null; + return null; + } + + private ModuleManager parent; + private PopupDialog instance; + private ReloadingDatabaseDialog(ModuleManager parent) + { + bool startedReload = false; + this.parent = parent; + + UISkinDef skinDef = HighLogic.UISkin; + UIStyle centeredTextStyle = new UIStyle() // FIXME: There must be a smarter way to do that on Unity5, right? + { + name = skinDef.label.name, + normal = skinDef.label.normal, + highlight = skinDef.label.highlight, + disabled = skinDef.label.disabled, + font = skinDef.label.font, + fontSize = skinDef.label.fontSize, + fontStyle = skinDef.label.fontStyle, + wordWrap = skinDef.label.wordWrap, + richText = skinDef.label.richText, + alignment = TextAnchor.UpperCenter, + clipping = skinDef.label.clipping, + lineHeight = skinDef.label.lineHeight, + stretchHeight = skinDef.label.stretchHeight, + stretchWidth = skinDef.label.stretchWidth, + fixedHeight = skinDef.label.fixedHeight, + fixedWidth = skinDef.label.fixedWidth + }; + + float totalLoadWeight = GameDatabase.Instance.LoadWeight() + PartLoader.Instance.LoadWeight(); + + PopupDialog reloadingDialog = PopupDialog.SpawnPopupDialog( + new Vector2(0.5f, 0.5f), + new Vector2(0.5f, 0.5f), + new MultiOptionDialog( + "ModuleManagerReloading", + "", + "ModuleManager - Reloading Database", + skinDef, + new Rect(0.5f, 0.5f, 600f, 60f), + new DialogGUIFlexibleSpace(), + new DialogGUIVerticalLayout( + new DialogGUIFlexibleSpace(), + new DialogGUILabel(delegate () + { + float progressFraction; + if (!startedReload) + { + progressFraction = 0f; + startedReload = true; + } + else if (!GameDatabase.Instance.IsReady() || !PostPatchLoader.Instance.IsReady()) + { + progressFraction = GameDatabase.Instance.ProgressFraction() * GameDatabase.Instance.LoadWeight(); + progressFraction /= totalLoadWeight; + } + else if (!PartLoader.Instance.IsReady()) + { + progressFraction = GameDatabase.Instance.LoadWeight() + (PartLoader.Instance.ProgressFraction() * GameDatabase.Instance.LoadWeight()); + progressFraction /= totalLoadWeight; + } + else + { + progressFraction = 1f; + } + + return $"Overall progress: {progressFraction:P0}"; + }, centeredTextStyle, expandW: true), + new DialogGUILabel(delegate () + { + if (!startedReload) + return "Starting"; + else if (!GameDatabase.Instance.IsReady()) + return GameDatabase.Instance.ProgressTitle(); + else if (!PostPatchLoader.Instance.IsReady()) + return PostPatchLoader.Instance.ProgressTitle(); + else if (!PartLoader.Instance.IsReady()) + return PartLoader.Instance.ProgressTitle(); + else + return ""; + }), + new DialogGUISpace(5f), + new DialogGUILabel(() => this.parent.patchRunner.Status) + ) + ), + false, + skinDef); + } + } +#endif +} \ No newline at end of file diff --git a/Source/ModuleManager/GUI/ShowStopperAlertBox.cs b/Source/ModuleManager/GUI/ShowStopperAlertBox.cs new file mode 100644 index 00000000..2fe0342c --- /dev/null +++ b/Source/ModuleManager/GUI/ShowStopperAlertBox.cs @@ -0,0 +1,37 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; + +namespace ModuleManager.GUI +{ + internal static class ShowStopperAlertBox + { + private static readonly string MSG = @"*THIS IS NOT* the Forum's Module Manager from Sarbian & Blowfish - don't bother them about this. + +{0}"; + + private static readonly string AMSG = @"call for help on the Module Manager /L GitHub page (KSP will close). We will help you on diagnosing the Add'On that is troubling you. "; + + internal static void Show(string message) + { + KSPe.Common.Dialogs.ShowStopperErrorBox.Show( + string.Format(MSG, message), + AMSG, + () => { Application.OpenURL("https://github.com/net-lisias-ksp/ModuleManager/issues/2"); Application.Quit(); } + ); + Logging.ModLogger.LOG.info("\"Houston, we have a Problem!\" was displayed with message {0}", message); + } + } +} diff --git a/Source/ModuleManager/GUI/UnsupportedKSPAlertBox.cs b/Source/ModuleManager/GUI/UnsupportedKSPAlertBox.cs new file mode 100644 index 00000000..353bc0ba --- /dev/null +++ b/Source/ModuleManager/GUI/UnsupportedKSPAlertBox.cs @@ -0,0 +1,37 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; + +namespace ModuleManager.GUI +{ + internal static class UnsupportedKSPAlertBox + { + private static readonly string MSG = @"*THIS IS NOT* the Forum's Module Manager from Sarbian & Blowfish - don't bother them about this. + +This release of Module Manager runs only on KSP {0}, but you are using {1}!"; + + private static readonly string AMSG = @"download and install the appropriated version (KSP will close)."; + + internal static void Show(string intendedKSP, string currentKSP) + { + KSPe.Common.Dialogs.ShowStopperErrorBox.Show( + string.Format(MSG, intendedKSP, currentKSP), + AMSG, + () => { Application.OpenURL("https://github.com/net-lisias-ksp/ModuleManager/releases"); Application.Quit(); } + ); + Logging.ModLogger.LOG.info("\"Houston, we have a Problem!\" about running MM on unsuppoted KSP was displayed"); + } + } +} diff --git a/Source/ModuleManager/Logging/IBasicLogger.cs b/Source/ModuleManager/Logging/IBasicLogger.cs new file mode 100644 index 00000000..06c44a3a --- /dev/null +++ b/Source/ModuleManager/Logging/IBasicLogger.cs @@ -0,0 +1,30 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +using K = KSPe.Util.Log; + +namespace ModuleManager.Logging +{ + // Stripped down version of UnityEngine.ILogger + public interface IBasicLogger + { + void Log(K.Level logType, string message, params object[] @params); + void Exception(Exception exception, string message, params object[] @params); + void Finish(); + } +} diff --git a/Source/ModuleManager/Logging/ModLogger.cs b/Source/ModuleManager/Logging/ModLogger.cs new file mode 100644 index 00000000..2720a675 --- /dev/null +++ b/Source/ModuleManager/Logging/ModLogger.cs @@ -0,0 +1,51 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using UnityEngine; + +using K = KSPe.Util.Log; + +namespace ModuleManager.Logging +{ + public class ModLogger : IBasicLogger + { + internal static readonly K.Logger LOG = K.Logger.CreateThreadUnsafeForType(); // No need to use thread safe logging. Yet. + internal static readonly ModLogger Instance = new ModLogger(); // For legacy code + internal static bool DebugMode => KSPe.Globals.DebugMode; + + private delegate void LogMethod(string message, params object[] @params); + private readonly LogMethod[] methods; + private ModLogger() + { + this.methods = new LogMethod[6]; + int i = 0; + this.methods[i++] = new LogMethod(LOG.error); + this.methods[i++] = new LogMethod(LOG.error); + this.methods[i++] = new LogMethod(LOG.warn); + this.methods[i++] = new LogMethod(LOG.info); + this.methods[i++] = new LogMethod(LOG.detail); + this.methods[i++] = new LogMethod(LOG.error); + } + + public void Log(K.Level logType, string message, params object[] @params) => this.methods[(int)logType](message, @params); + + public void Exception(Exception exception, string message, params object[] @params) + { + LOG.error(exception, message, @params); + } + + public void Finish() { } + } +} diff --git a/Source/ModuleManager/Logging/PatchLogger.cs b/Source/ModuleManager/Logging/PatchLogger.cs new file mode 100644 index 00000000..5b6b8ab7 --- /dev/null +++ b/Source/ModuleManager/Logging/PatchLogger.cs @@ -0,0 +1,56 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using UnityEngine; + +using K = KSPe.Util.Log; + +namespace ModuleManager.Logging +{ + public class PatchLogger : IBasicLogger + { + internal readonly K.Logger log; + internal static bool DebugMode => KSPe.Globals.DebugMode; + + private delegate void LogMethod(string message, params object[] @params); + private readonly LogMethod[] methods; + internal PatchLogger(string filename) + { + this.log = new K.FileChainUnityLogger(filename, 0); + + this.methods = new LogMethod[6]; + int i = 0; + this.methods[i++] = new LogMethod(this.log.error); + this.methods[i++] = new LogMethod(this.log.error); + this.methods[i++] = new LogMethod(this.log.warn); + this.methods[i++] = new LogMethod(this.log.info); + this.methods[i++] = new LogMethod(this.log.detail); + this.methods[i++] = new LogMethod(this.log.trace); + this.log.level = KSPe.Globals.Log.Level; + } + + public void Log(K.Level logType, string message, object[] @params) => this.methods[(int)logType](message, @params); + + public void Exception(Exception exception, string message, params object[] @params) + { + this.log.error(exception, message, @params); + } + + public void Finish() + { + this.log.Close(); + } + } +} diff --git a/ModuleManager/MMPatchLoader.cs b/Source/ModuleManager/MMPatchLoader.cs similarity index 69% rename from ModuleManager/MMPatchLoader.cs rename to Source/ModuleManager/MMPatchLoader.cs index 5278758b..2979feb6 100644 --- a/ModuleManager/MMPatchLoader.cs +++ b/Source/ModuleManager/MMPatchLoader.cs @@ -1,7 +1,21 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using System.Collections.Generic; -using System.Diagnostics; -using System.Diagnostics.CodeAnalysis; using System.Globalization; using System.IO; using System.Linq; @@ -9,23 +23,20 @@ using System.Text; using System.Text.RegularExpressions; -using ModuleManager.Collections; using ModuleManager.Logging; using ModuleManager.Extensions; -using ModuleManager.Threading; using ModuleManager.Tags; using ModuleManager.Patches; -using ModuleManager.Progress; using NodeStack = ModuleManager.Collections.ImmutableStack; using static ModuleManager.FilePathRepository; +using ModuleManager.Utils; namespace ModuleManager { - public class MMPatchLoader + public class MMPatchLoader : LoadingSystem { private const string PHYSICS_NODE_NAME = "PHYSICSGLOBALS"; - private const string TECH_TREE_NODE_NAME = "TechTree"; public string status = ""; @@ -33,73 +44,70 @@ public class MMPatchLoader public static bool keepPartDB = false; - private static readonly KeyValueCache regexCache = new KeyValueCache(); - private string configSha; - private readonly Dictionary filesSha = new Dictionary(); + private int totalConfigFilesSize; + private readonly Dictionary filesShaMap = new Dictionary(); + private readonly Dictionary filesSizeMap = new Dictionary(); private const int STATUS_UPDATE_INVERVAL_MS = 33; private readonly IEnumerable modsAddedByAssemblies; private readonly IBasicLogger logger; + private readonly Progress.ProgressCounter counter; + private readonly Progress.Timings timings; public static void AddPostPatchCallback(ModuleManagerPostPatchCallback callback) { PostPatchLoader.AddPostPatchCallback(callback); } - public MMPatchLoader(IEnumerable modsAddedByAssemblies, IBasicLogger logger) + public MMPatchLoader(IEnumerable modsAddedByAssemblies, IBasicLogger logger, Progress.ProgressCounter counter, Progress.Timings timings) { this.modsAddedByAssemblies = modsAddedByAssemblies ?? throw new ArgumentNullException(nameof(modsAddedByAssemblies)); this.logger = logger ?? throw new ArgumentNullException(nameof(logger)); + this.counter = counter; + this.timings = timings; + } + + ~MMPatchLoader() + { // Being paranoid on memory cleaning... + this.CleanUpCaches(); + ConfigNodeEditUtils.Instance.Destroy(); } public IEnumerable Run() { - Stopwatch patchSw = new Stopwatch(); - patchSw.Start(); + this.timings.Patching.Start(); status = "Checking Cache"; logger.Info(status); - bool useCache = false; - try +#pragma warning disable CS0618 // Type or member is obsolete + ModuleManager.IsLoadedFromCache = false; + try { - useCache = IsCacheUpToDate(); + ModuleManager.IsLoadedFromCache = !ModuleManager.IgnoreCache && IsCacheUpToDate(); } catch (Exception ex) { - logger.Exception("Exception in IsCacheUpToDate", ex); + logger.Exception(ex, "Exception in IsCacheUpToDate"); } -#if DEBUG - //useCache = false; -#endif - IEnumerable databaseConfigs = null; - if (!useCache) + if (!ModuleManager.IsLoadedFromCache) +#pragma warning restore CS0618 // Type or member is obsolete { - if (!Directory.Exists(logsDirPath)) Directory.CreateDirectory(logsDirPath); - MessageQueue patchLogQueue = new MessageQueue(); - QueueLogRunner logRunner = new QueueLogRunner(patchLogQueue); - ITaskStatus loggingThreadStatus = BackgroundTask.Start(delegate - { - using StreamLogger streamLogger = new StreamLogger(new FileStream(patchLogPath, FileMode.Create)); - streamLogger.Info("Log started at " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); - logRunner.Run(streamLogger); - streamLogger.Info("Done!"); - }); - IBasicLogger patchLogger = new LogSplitter(logger, new QueueLogger(patchLogQueue)); + IBasicLogger patchLogger = new PatchLogger(FilePathRepository.PATCH_LOG_FILENAME); - IPatchProgress progress = new PatchProgress(patchLogger); + Progress.IPatchProgress progress = new Progress.PatchProgress(patchLogger, this.counter); status = "Pre patch init"; patchLogger.Info(status); IEnumerable mods = ModListGenerator.GenerateModList(modsAddedByAssemblies, progress, patchLogger); // If we don't use the cache then it is best to clean the PartDatabase.cfg - if (!keepPartDB && File.Exists(partDatabasePath)) - File.Delete(partDatabasePath); + if (!keepPartDB && PART_DATABASE.IsLoadable) + File.Delete(PART_DATABASE.Path); LoadPhysicsConfig(); @@ -112,7 +120,7 @@ public IEnumerable Run() INeedsChecker needsChecker = new NeedsChecker(mods, gameData, progress, patchLogger); ITagListParser tagListParser = new TagListParser(progress); IProtoPatchBuilder protoPatchBuilder = new ProtoPatchBuilder(progress); - IPatchCompiler patchCompiler = new PatchCompiler(); + IPatchCompiler patchCompiler = new PatchCompiler(patchLogger); PatchExtractor extractor = new PatchExtractor(progress, patchLogger, needsChecker, tagListParser, protoPatchBuilder, patchCompiler); // Have to convert to an array because we will be removing patches @@ -161,83 +169,91 @@ public IEnumerable Run() #region Saving Cache - foreach (KeyValuePair item in progress.Counter.warningFiles) + foreach (KeyValuePair item in this.counter.warningFiles) { - patchLogger.Warning(item.Value + " warning" + (item.Value > 1 ? "s" : "") + " related to GameData/" + item.Key); + patchLogger.Warning( + "{0} warning{1} related to GameData/{2}", + item.Value, (item.Value > 1 ? "s" : ""), item.Key + ); } - if (progress.Counter.errors > 0 || progress.Counter.exceptions > 0) + if (this.counter.errors > 0 || this.counter.exceptions > 0) { - foreach (KeyValuePair item in progress.Counter.errorFiles) + foreach (KeyValuePair item in this.counter.errorFiles) { - errors += item.Value + " error" + (item.Value > 1 ? "s" : "") + " related to GameData/" + item.Key - + "\n"; + errors += item.Value + " error" + (item.Value > 1 ? "s" : "") + " related to GameData/" + item.Key + "\n"; } patchLogger.Warning("Errors in patch prevents the creation of the cache"); try { - if (File.Exists(cachePath)) - File.Delete(cachePath); - if (File.Exists(shaPath)) - File.Delete(shaPath); + CACHE_CONFIG.Destroy(); + SHA_CONFIG.Destroy(); } catch (Exception e) { - patchLogger.Exception("Exception while deleting stale cache ", e); + patchLogger.Exception(e, "Exception while deleting stale cache "); } } else { status = "Saving Cache"; - patchLogger.Info(status); - CreateCache(databaseConfigs, progress.Counter.patchedNodes); + CreateCache(databaseConfigs, this.counter.patchedNodes); + patchLogger.Info("Cache saved."); } + patchLogger.Finish(); StatusUpdate(progress); #endregion Saving Cache SaveModdedTechTree(databaseConfigs); SaveModdedPhysics(databaseConfigs); - - logRunner.RequestStop(); - - while (loggingThreadStatus.IsRunning) - { - System.Threading.Thread.Sleep(100); - } - - if (loggingThreadStatus.IsExitedWithError) - { - logger.Error("The patching thread threw an exception"); - throw loggingThreadStatus.Exception; - } } else { status = "Loading from Cache"; logger.Info(status); databaseConfigs = LoadCache(); + } - if (File.Exists(patchLogPath)) + // Using an dedicated external log is nice. Dumping it into KSP.log breaking the known formats is not. + // But... + // Now I see the reason this was done this way. Asking the user to send KSP.log is tricky by itself, and + // sending more than one log is yet more troublesome. + // What I can do is to only dump this on KSP.log when the the KSPe Globals for ModuleManager has Debug set to true. + // (the default KSPe's Global for Module Manager as from KSPe 2.2.3) + string patchLogPath = KSPe.IO.File.Data.Solve(FilePathRepository.PATCH_LOG_FILENAME + ".log"); + if (File.Exists(patchLogPath)) + { +#pragma warning disable CS0618 // Type or member is obsolete + if (ModuleManager.IsLoadedFromCache && ModLogger.DebugMode) +#pragma warning restore CS0618 // Type or member is obsolete { logger.Info("Dumping patch log"); - logger.Info("\n#### BEGIN PATCH LOG ####\n\n\n" + File.ReadAllText(patchLogPath) + "\n\n\n#### END PATCH LOG ####"); + logger.Info("\n#### BEGIN PATCH LOG ####\n\n\n{0}\n\n\n#### END PATCH LOG ####", File.ReadAllText(patchLogPath)); } else - { - logger.Error("Patch log does not exist: " + patchLogPath); - } + logger.Info("The Patch log can be found on {0}", patchLogPath); + } + else + { + logger.Error("Patch log does not exist: {0}", patchLogPath); } +#if !KSP12 if (KSP.Localization.Localizer.Instance != null) KSP.Localization.Localizer.SwitchToLanguage(KSP.Localization.Localizer.CurrentLanguage); +#endif - logger.Info(status + "\n" + errors); + logger.Info("{0}\n{1}", status, errors); - patchSw.Stop(); - logger.Info("Ran in " + ((float)patchSw.ElapsedMilliseconds / 1000).ToString("F3") + "s"); + // Cleaning some memory + ConfigNodeEditUtils.Instance.Destroy(); + this.CleanUpCaches(); + + this.timings.Patching.Stop(); + logger.Info("Ran in {0}", this.timings.Patching); return databaseConfigs; } @@ -247,11 +263,11 @@ private void LoadPhysicsConfig() logger.Info("Loading Physics.cfg"); UrlDir gameDataDir = GameDatabase.Instance.root.AllDirectories.First(d => d.path.EndsWith("GameData") && d.name == "" && d.url == ""); // need to use a file with a cfg extension to get the right fileType or you can't AddConfig on it - UrlDir.UrlFile physicsUrlFile = new UrlDir.UrlFile(gameDataDir, new FileInfo(defaultPhysicsPath)); + UrlDir.UrlFile physicsUrlFile = new UrlDir.UrlFile(gameDataDir, new FileInfo(PHYSICS_DEFAULT.Path)); // Since it loaded the default config badly (sub node only) we clear it first physicsUrlFile.configs.Clear(); // And reload it properly - ConfigNode physicsContent = ConfigNode.Load(defaultPhysicsPath); + ConfigNode physicsContent = ConfigNode.Load(PHYSICS_DEFAULT.Path); physicsContent.name = PHYSICS_NODE_NAME; physicsUrlFile.AddConfig(physicsContent); gameDataDir.files.Add(physicsUrlFile); @@ -264,28 +280,34 @@ private void SaveModdedPhysics(IEnumerable databaseConfigs) if (count == 0) { - logger.Info($"No {PHYSICS_NODE_NAME} node found. No custom Physics config will be saved"); + logger.Info("No {0} node found. No custom Physics config will be saved", PHYSICS_NODE_NAME); return; } if (count > 1) { - logger.Info($"{count} {PHYSICS_NODE_NAME} nodes found. A patch may be wrong. Using the first one"); + logger.Info("{0} {1} nodes found. A patch may be wrong. Using the first one", count, PHYSICS_NODE_NAME); } - configs.First().Node.Save(physicsPath); + PHYSICS_CONFIG.Save(configs.First().Node); + } + + private void CleanUpCaches() + { + this.filesShaMap.Clear(); + this.filesSizeMap.Clear(); } private bool IsCacheUpToDate() { - Stopwatch sw = new Stopwatch(); - sw.Start(); + this.timings.ShaCalc.Start(); - using System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create(); - using System.Security.Cryptography.SHA256 filesha = System.Security.Cryptography.SHA256.Create(); + System.Security.Cryptography.SHA256 sha = System.Security.Cryptography.SHA256.Create(); + System.Security.Cryptography.SHA256 filesha = System.Security.Cryptography.SHA256.Create(); UrlDir.UrlFile[] files = GameDatabase.Instance.root.AllConfigFiles.ToArray(); + this.totalConfigFilesSize = 0; - filesSha.Clear(); + this.CleanUpCaches(); for (int i = 0; i < files.Length; i++) { @@ -293,19 +315,21 @@ private bool IsCacheUpToDate() // Hash the file path so the checksum change if files are moved byte[] pathBytes = Encoding.UTF8.GetBytes(url); sha.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0); + this.totalConfigFilesSize += pathBytes.Length; // hash the file content byte[] contentBytes = File.ReadAllBytes(files[i].fullPath); sha.TransformBlock(contentBytes, 0, contentBytes.Length, contentBytes, 0); filesha.ComputeHash(contentBytes); - if (!filesSha.ContainsKey(url)) + if (!(this.filesShaMap.ContainsKey(url) || this.filesSizeMap.ContainsKey(url))) { - filesSha.Add(url, BitConverter.ToString(filesha.Hash)); + this.filesShaMap.Add(url, BitConverter.ToString(filesha.Hash)); + this.filesSizeMap.Add(url, contentBytes.Length); } else { - logger.Warning("Duplicate fileSha key. This should not append. The key is " + url); + logger.Warning("Duplicate filesShaMap/filesSizeMap key. This should not append. The key is {0}" + url); } } @@ -317,43 +341,60 @@ private bool IsCacheUpToDate() sha.TransformBlock(pathBytes, 0, pathBytes.Length, pathBytes, 0); } - foreach (ModListGenerator.ModAddedByAssembly mod in modsAddedByAssemblies) + // Hash the symbols added by Assemblies, as they impact the patching process. { - byte[] modBytes = Encoding.UTF8.GetBytes(mod.modName); - sha.TransformBlock(modBytes, 0, modBytes.Length, modBytes, 0); + IEnumerable symbols = from s in this.modsAddedByAssemblies + orderby s.modName + select s.modName + ; + foreach (string symbol in symbols) + { + byte[] bytes = Encoding.UTF8.GetBytes(symbol); + sha.TransformBlock(bytes, 0, bytes.Length, bytes, 0); + } } - byte[] godsFinalMessageToHisCreation = Encoding.UTF8.GetBytes("We apologize for the inconvenience."); + byte[] godsFinalMessageToHisCreation = Encoding.UTF8.GetBytes("Fork by Lisias."); sha.TransformFinalBlock(godsFinalMessageToHisCreation, 0, godsFinalMessageToHisCreation.Length); configSha = BitConverter.ToString(sha.Hash); sha.Clear(); filesha.Clear(); - sw.Stop(); + this.timings.ShaCalc.Stop(); - logger.Info("SHA generated in " + ((float)sw.ElapsedMilliseconds / 1000).ToString("F3") + "s"); - logger.Info(" SHA = " + configSha); + logger.Info("SHA generated in {0}", this.timings.ShaCalc); + logger.Info(" SHA = {0}", configSha); + logger.Info(" SIZE = {0}", this.totalConfigFilesSize); bool useCache = false; - if (File.Exists(shaPath)) + if (SHA_CONFIG.IsLoadable) { - ConfigNode shaConfigNode = ConfigNode.Load(shaPath); - if (shaConfigNode != null && shaConfigNode.HasValue("SHA") && shaConfigNode.HasValue("version") && shaConfigNode.HasValue("KSPVersion")) + SHA_CONFIG.Load(); + logger.Info("ConfigSHA loaded"); + if (null != SHA_CONFIG.Node) try { - string storedSHA = shaConfigNode.GetValue("SHA"); - string version = shaConfigNode.GetValue("version"); - string kspVersion = shaConfigNode.GetValue("KSPVersion"); - ConfigNode filesShaNode = shaConfigNode.GetNode("FilesSHA"); - useCache = CheckFilesChange(files, filesShaNode); - useCache = useCache && storedSHA.Equals(configSha); - useCache = useCache && version.Equals(Assembly.GetExecutingAssembly().GetName().Version.ToString()); + KSPe.ConfigNodeWithSteroids cs = KSPe.ConfigNodeWithSteroids.from(SHA_CONFIG.Node); + string storedSHA = cs.GetValue("SHA",""); + int storedTotalSize = cs.GetValue("SIZE", -1); + string version = cs.GetValue("version",""); + string kspVersion = cs.GetValue("KSPVersion",""); + ConfigNode filesShaNode = cs.GetNode("FilesSHA"); + useCache = version.Equals(Assembly.GetExecutingAssembly().GetName().Version.ToString()); useCache = useCache && kspVersion.Equals(Versioning.version_major + "." + Versioning.version_minor + "." + Versioning.Revision + "." + Versioning.BuildID); - useCache = useCache && File.Exists(cachePath); - useCache = useCache && File.Exists(physicsPath); - useCache = useCache && File.Exists(techTreePath); - logger.Info("Cache SHA = " + storedSHA); - logger.Info("useCache = " + useCache); + useCache = useCache && storedSHA.Equals(configSha); + useCache = useCache && storedTotalSize == this.totalConfigFilesSize; + useCache = useCache && CACHE_CONFIG.IsLoadable; + useCache = useCache && PHYSICS_CONFIG.IsLoadable; + useCache = useCache && TECHTREE_CONFIG.IsLoadable; + useCache = useCache && CheckFilesChange(files, filesShaNode); + logger.Info("Cache SHA, SIZE = {0}, {1}", storedSHA, storedTotalSize); + logger.Info("useCache = {0}", useCache); + } + catch (Exception e) + { + logger.Error("Error while reading SHA values from cache: {0}", e); + useCache = false; } } return useCache; @@ -362,22 +403,20 @@ private bool IsCacheUpToDate() private bool CheckFilesChange(UrlDir.UrlFile[] files, ConfigNode shaConfigNode) { bool noChange = true; - StringBuilder changes = new StringBuilder(); - - changes.Append("Changes :\n"); for (int i = 0; i < files.Length; i++) { string url = files[i].GetUrlWithExtension(); ConfigNode fileNode = GetFileNode(shaConfigNode, url); - string fileSha = fileNode?.GetValue("SHA"); + if (fileNode == null) continue; - if (fileNode == null) - continue; + KSPe.ConfigNodeWithSteroids cs = KSPe.ConfigNodeWithSteroids.from(fileNode); + string fileSha = cs.GetValue("SHA", ""); + int fileSize = cs.GetValue("SIZE", -1); - if (fileSha == null || filesSha[url] != fileSha) + if (-1 == fileSize || String.IsNullOrEmpty(fileSha) || filesShaMap[url] != fileSha) { - changes.Append("Changed : " + fileNode.GetValue("filename") + ".cfg\n"); + logger.Info("Changed : {0}.cfg", fileNode.GetValue("filename")); noChange = false; } } @@ -388,18 +427,18 @@ private bool CheckFilesChange(UrlDir.UrlFile[] files, ConfigNode shaConfigNode) if (fileNode == null) { - changes.Append("Added : " + url + "\n"); + logger.Info("Added : {}.cfg", files[i].url); noChange = false; } shaConfigNode.RemoveNode(fileNode); } + foreach (ConfigNode fileNode in shaConfigNode.GetNodes()) { - changes.Append("Deleted : " + fileNode.GetValue("filename") + "\n"); + logger.Info("Deleted : {0}.cfg", fileNode.GetValue("filename")); noChange = false; } - if (!noChange) - logger.Info(changes.ToString()); + return noChange; } @@ -417,19 +456,19 @@ private ConfigNode GetFileNode(ConfigNode shaConfigNode, string filename) private void CreateCache(IEnumerable databaseConfigs, int patchedNodeCount) { - ConfigNode shaConfigNode = new ConfigNode(); - shaConfigNode.AddValue("SHA", configSha); - shaConfigNode.AddValue("version", Assembly.GetExecutingAssembly().GetName().Version.ToString()); - shaConfigNode.AddValue("KSPVersion", Versioning.version_major + "." + Versioning.version_minor + "." + Versioning.Revision + "." + Versioning.BuildID); - ConfigNode filesSHANode = shaConfigNode.AddNode("FilesSHA"); - - ConfigNode cache = new ConfigNode(); + SHA_CONFIG.Clear(); + SHA_CONFIG.Node.AddValue("SHA", configSha); + SHA_CONFIG.Node.AddValue("SIZE", this.totalConfigFilesSize); + SHA_CONFIG.Node.AddValue("version", Assembly.GetExecutingAssembly().GetName().Version.ToString()); + SHA_CONFIG.Node.AddValue("KSPVersion", Versioning.version_major + "." + Versioning.version_minor + "." + Versioning.Revision + "." + Versioning.BuildID); + ConfigNode filesSHANode = SHA_CONFIG.Node.AddNode("FilesSHA"); - cache.AddValue("patchedNodeCount", patchedNodeCount.ToString()); + CACHE_CONFIG.Clear(); + CACHE_CONFIG.Node.AddValue("patchedNodeCount", patchedNodeCount.ToString()); foreach (IProtoUrlConfig urlConfig in databaseConfigs) { - ConfigNode node = cache.AddNode("UrlConfig"); + ConfigNode node = CACHE_CONFIG.Node.AddNode("UrlConfig"); node.AddValue("parentUrl", urlConfig.UrlFile.GetUrlWithExtension()); ConfigNode urlNode = urlConfig.Node.DeepCopy(); @@ -438,16 +477,18 @@ private void CreateCache(IEnumerable databaseConfigs, int patch node.AddNode(urlNode); } - foreach (var file in GameDatabase.Instance.root.AllConfigFiles) + foreach (UrlDir.UrlFile file in GameDatabase.Instance.root.AllConfigFiles) { string url = file.GetUrlWithExtension(); // "/Physics" is the node we created manually to loads the PHYSIC config - if (file.url != "/Physics" && filesSha.ContainsKey(url)) + if (file.url != "/Physics" && filesShaMap.ContainsKey(url)) { ConfigNode shaNode = filesSHANode.AddNode("FILE"); shaNode.AddValue("filename", url); - shaNode.AddValue("SHA", filesSha[url]); - filesSha.Remove(url); + shaNode.AddValue("SHA", filesShaMap[url]); + shaNode.AddValue("SIZE", this.filesSizeMap[url]); + filesShaMap.Remove(url); + filesSizeMap.Remove(url); } } @@ -455,72 +496,73 @@ private void CreateCache(IEnumerable databaseConfigs, int patch try { - shaConfigNode.Save(shaPath); + SHA_CONFIG.Save(); } catch (Exception e) { - logger.Exception("Exception while saving the sha", e); + logger.Exception(e, "Exception while saving the sha"); } try { - cache.Save(cachePath); + CACHE_CONFIG.Save(); return; } catch (NullReferenceException e) { - logger.Exception("NullReferenceException while saving the cache", e); + logger.Exception(e, "NullReferenceException while saving the cache"); } catch (Exception e) { - logger.Exception("Exception while saving the cache", e); + logger.Exception(e, "Exception while saving the cache"); } try { logger.Error("An error occured while creating the cache. Deleting the cache files to avoid keeping a bad cache"); - if (File.Exists(cachePath)) - File.Delete(cachePath); - if (File.Exists(shaPath)) - File.Delete(shaPath); + CACHE_CONFIG.Destroy(); + SHA_CONFIG.Destroy(); } catch (Exception e) { - logger.Exception("Exception while deleting the cache", e); + logger.Exception(e, "Exception while deleting the cache"); } } private void SaveModdedTechTree(IEnumerable databaseConfigs) { - IEnumerable configs = databaseConfigs.Where(config => config.NodeType == TECH_TREE_NODE_NAME); - int count = configs.Count(); + IEnumerable configs = databaseConfigs.Where(config => config.NodeType == TECHTREE_CONFIG.Node.name); + int count = configs.Count(); // FIXME: Why didn't he used .Any()? if (count == 0) { - logger.Info($"No {TECH_TREE_NODE_NAME} node found. No custom {TECH_TREE_NODE_NAME} will be saved"); + logger.Info("No {0} node found. No custom {1} will be saved", TECHTREE_CONFIG.Node.name, TECHTREE_CONFIG.Node.name); return; } if (count > 1) { - logger.Info($"{count} {TECH_TREE_NODE_NAME} nodes found. A patch may be wrong. Using the first one"); + logger.Info("{0} {1} nodes found. A patch may be wrong. Using the first one", count, TECHTREE_CONFIG.Node.name); } - ConfigNode techNode = new ConfigNode(TECH_TREE_NODE_NAME); - techNode.AddNode(configs.First().Node); - techNode.Save(techTreePath); + TECHTREE_CONFIG.Clear(); + TECHTREE_CONFIG.Node.AddData(configs.First().Node); + TECHTREE_CONFIG.Save(); } private IEnumerable LoadCache() { - ConfigNode cache = ConfigNode.Load(cachePath); + ConfigNode cache = CACHE_CONFIG.Load().Node; if (cache.HasValue("patchedNodeCount") && int.TryParse(cache.GetValue("patchedNodeCount"), out int patchedNodeCount)) + { status = "ModuleManager: " + patchedNodeCount + " patch" + (patchedNodeCount != 1 ? "es" : "") + " loaded from cache"; + this.counter.patchedNodes.Set(patchedNodeCount); + } // Create the fake file where we load the physic config cache UrlDir gameDataDir = GameDatabase.Instance.root.AllDirectories.First(d => d.path.EndsWith("GameData") && d.name == "" && d.url == ""); // need to use a file with a cfg extension to get the right fileType or you can't AddConfig on it - UrlDir.UrlFile physicsUrlFile = new UrlDir.UrlFile(gameDataDir, new FileInfo(defaultPhysicsPath)); + UrlDir.UrlFile physicsUrlFile = new UrlDir.UrlFile(gameDataDir, new FileInfo(PHYSICS_CONFIG.KspPath)); gameDataDir.files.Add(physicsUrlFile); List databaseConfigs = new List(cache.nodes.Count); @@ -537,7 +579,7 @@ private IEnumerable LoadCache() } else { - logger.Warning("Parent null for " + parentUrl); + logger.Warning("Parent null for {0}", parentUrl); } } logger.Info("Cache Loaded"); @@ -545,23 +587,23 @@ private IEnumerable LoadCache() return databaseConfigs; } - private void StatusUpdate(IPatchProgress progress, string activity = null) + private void StatusUpdate(Progress.IPatchProgress progress, string activity = null) { - status = "ModuleManager: " + progress.Counter.patchedNodes + " patch" + (progress.Counter.patchedNodes != 1 ? "es" : "") + " applied"; + status = "ModuleManager: " + this.counter.patchedNodes + " patch" + (this.counter.patchedNodes != 1 ? "es" : "") + " applied"; if (progress.ProgressFraction < 1f - float.Epsilon) status += " (" + progress.ProgressFraction.ToString("P0") + ")"; if (activity != null) status += "\n" + activity; - if (progress.Counter.warnings > 0) - status += ", found " + progress.Counter.warnings + " warning" + (progress.Counter.warnings != 1 ? "s" : "") + ""; + if (this.counter.warnings > 0) + status += ", found " + this.counter.warnings + " warning" + (this.counter.warnings != 1 ? "s" : "") + ""; - if (progress.Counter.errors > 0) - status += ", found " + progress.Counter.errors + " error" + (progress.Counter.errors != 1 ? "s" : "") + ""; + if (this.counter.errors > 0) + status += ", found " + this.counter.errors + " error" + (this.counter.errors != 1 ? "s" : "") + ""; - if (progress.Counter.exceptions > 0) - status += ", encountered " + progress.Counter.exceptions + " exception" + (progress.Counter.exceptions != 1 ? "s" : "") + ""; + if (this.counter.exceptions > 0) + status += ", encountered " + this.counter.exceptions + " exception" + (this.counter.exceptions != 1 ? "s" : "") + ""; } #region Applying Patches @@ -571,21 +613,17 @@ private void StatusUpdate(IPatchProgress progress, string activity = null) // ModifyNode applies the ConfigNode mod as a 'patch' to ConfigNode original, then returns the patched ConfigNode. // it uses FindConfigNodeIn(src, nodeType, nodeName, nodeTag) to recurse. - public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchContext context) + public static ConfigNode ModifyNode(IBasicLogger log, NodeStack original, ConfigNode mod, PatchContext context) { ConfigNode newNode = original.value.DeepCopy(); NodeStack nodeStack = original.ReplaceValue(newNode); #region Values - #if LOGSPAM - string vals = "[ModuleManager] modding values"; - #endif + List logModdingValues = new List(); foreach (ConfigNode.Value modVal in mod.values) { - #if LOGSPAM - vals += "\n " + modVal.name + "= " + modVal.value; - #endif + string logModdingValue = modVal.name + " = " + modVal.value; Command cmd = CommandParser.Parse(modVal.name, out string valName); @@ -597,11 +635,11 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon if (cmd == Command.Special) { - ConfigNode.Value val = RecurseVariableSearch(valName, nodeStack.Push(mod), context); + ConfigNode.Value val = RecurseVariableSearch(log, valName, nodeStack.Push(mod), context); if (val == null) { - context.progress.Error(context.patchUrl, "Error - Cannot find value assigning command: " + valName); + context.progress.Error(context.patchUrl, "Error - Cannot find value assigning command: {0}", valName); continue; } @@ -644,7 +682,7 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon Match match = parseValue.Match(valName); if (!match.Success) { - context.progress.Error(context.patchUrl, "Error - Cannot parse value modifying command: " + valName); + context.progress.Error(context.patchUrl, "Error - Cannot parse value modifying command: {0}", valName); continue; } @@ -696,17 +734,19 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon case Command.Insert: if (match.Groups[5].Success) { - context.progress.Error(context.patchUrl, "Error - Cannot use operators with insert value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use operators with insert value: {0}", mod.name); } else { // Insert at the end by default - varValue = ProcessVariableSearch(modVal.value, nodeStack, context); + varValue = ProcessVariableSearch(log, modVal.value, nodeStack, context); if (varValue != null) InsertValue(newNode, match.Groups[2].Success ? index : int.MaxValue, valName, varValue); else - context.progress.Error(context.patchUrl, "Error - Cannot parse variable search when inserting new key " + valName + " = " + - modVal.value); + context.progress.Error(context.patchUrl, + "Error - Cannot parse variable search when inserting new key {0} = {1}", + valName, modVal.value + ); } break; @@ -715,15 +755,15 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon || valName.Contains('?')) { if (match.Groups[2].Success) - context.progress.Error(context.patchUrl, "Error - Cannot use index with replace (%) value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use index with replace (%) value: {0}", mod.name); if (match.Groups[5].Success) - context.progress.Error(context.patchUrl, "Error - Cannot use operators with replace (%) value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use operators with replace (%) value: {0}", mod.name); if (valName.Contains('*') || valName.Contains('?')) - context.progress.Error(context.patchUrl, "Error - Cannot use wildcards (* or ?) with replace (%) value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use wildcards (* or ?) with replace (%) value: {0}", mod.name); } else { - varValue = ProcessVariableSearch(modVal.value, nodeStack, context); + varValue = ProcessVariableSearch(log, modVal.value, nodeStack, context); if (varValue != null) { newNode.RemoveValues(valName); @@ -731,8 +771,10 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon } else { - context.progress.Error(context.patchUrl, "Error - Cannot parse variable search when replacing (%) key " + valName + " = " + - modVal.value); + context.progress.Error(context.patchUrl, + "Error - Cannot parse variable search when replacing (%) key {0} = {1}", + valName, modVal.value + ); } } break; @@ -745,11 +787,11 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon while (index < valCount) { - varValue = ProcessVariableSearch(modVal.value, nodeStack, context); + varValue = ProcessVariableSearch(log, modVal.value, nodeStack, context); if (varValue != null) { - string value = FindAndReplaceValue( + string value = ConfigNodeEditUtils.Instance.FindAndReplaceValue( mod, ref valName, varValue, newNode, @@ -765,10 +807,8 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon if (value != null) { - #if LOGSPAM if (origVal.value != value) - vals += ": " + origVal.value + " -> " + value; - #endif + logModdingValue += " ( was " + origVal.value + ")"; if (cmd != Command.Copy) origVal.value = value; @@ -778,7 +818,10 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon } else { - context.progress.Error(context.patchUrl, "Error - Cannot parse variable search when editing key " + valName + " = " + modVal.value); + context.progress.Error(context.patchUrl, + "Error - Cannot parse variable search when editing key {0} = {1}", + valName, modVal.value + ); } if (isStar) index++; @@ -789,14 +832,14 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon case Command.Delete: if (match.Groups[5].Success) { - context.progress.Error(context.patchUrl, "Error - Cannot use operators with delete (- or !) value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use operators with delete (- or !) value: {0}", mod.name); } else if (match.Groups[2].Success) { while (index < valCount) { // If there is an index, use it. - ConfigNode.Value v = FindValueIn(newNode, valName, index); + ConfigNode.Value v = ConfigNodeEditUtils.Instance.FindValueIn(newNode, valName, index); if (v != null) newNode.values.Remove(v); if (isStar) index++; @@ -809,7 +852,7 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon ConfigNode.Value last = null; while (true) { - ConfigNode.Value v = FindValueIn(newNode, valName, index++); + ConfigNode.Value v = ConfigNodeEditUtils.Instance.FindValueIn(newNode, valName, index++); if (v == last) break; last = v; @@ -837,15 +880,15 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon || valName.Contains('?')) { if (match.Groups[2].Success) - context.progress.Error(context.patchUrl, "Error - Cannot use index with create (&) value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use index with create (&) value: {0}", mod.name); if (match.Groups[5].Success) - context.progress.Error(context.patchUrl, "Error - Cannot use operators with create (&) value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use operators with create (&) value: {0}", mod.name); if (valName.Contains('*') || valName.Contains('?')) - context.progress.Error(context.patchUrl, "Error - Cannot use wildcards (* or ?) with create (&) value: " + mod.name); + context.progress.Error(context.patchUrl, "Error - Cannot use wildcards (* or ?) with create (&) value: {0}", mod.name); } else { - varValue = ProcessVariableSearch(modVal.value, nodeStack, context); + varValue = ProcessVariableSearch(log, modVal.value, nodeStack, context); if (varValue != null) { if (!newNode.HasValue(valName)) @@ -853,16 +896,18 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon } else { - context.progress.Error(context.patchUrl, "Error - Cannot parse variable search when replacing (&) key " + valName + " = " + - modVal.value); + context.progress.Error(context.patchUrl, + "Error - Cannot parse variable search when replacing (&) key {0} = {1}", + valName, modVal.value + ); } } break; } + logModdingValues.Add(logModdingValue); } - #if LOGSPAM - log(vals); - #endif + if (0 != logModdingValues.Count) + log.Trace("\tmodding values: {0}", string.Join(" ; ", logModdingValues.ToArray())); #endregion Values @@ -886,7 +931,7 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon if (command == Command.Insert) { ConfigNode newSubMod = new ConfigNode(subMod.name); - newSubMod = ModifyNode(nodeStack.Push(newSubMod), subMod, context); + newSubMod = ModifyNode(log, nodeStack.Push(newSubMod), subMod, context); subName = newSubMod.name; if (subName.Contains(",") && int.TryParse(subName.Split(',')[1], out int index)) { @@ -913,16 +958,19 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon //string newName = subName.Substring(0, start); //string path = subName.Substring(start + 1, end - start - 1); - ConfigNode toPaste = RecurseNodeSearch(subName.Substring(1), nodeStack, context); + ConfigNode toPaste = RecurseNodeSearch(log, subName.Substring(1), nodeStack, context); if (toPaste == null) { - context.progress.Error(context.patchUrl, "Error - Can not find the node to paste in " + mod.name + " : " + subMod.name + "\n"); + context.progress.Error(context.patchUrl, + "Error - Can not find the node to paste in {0} : {1}\n", // FIXME: Why this \n here? + mod.name, subMod.name + ); continue; } ConfigNode newSubMod = new ConfigNode(toPaste.name); - newSubMod = ModifyNode(nodeStack.Push(newSubMod), toPaste, context); + newSubMod = ModifyNode(log, nodeStack.Push(newSubMod), toPaste, context); if (subName.LastIndexOf(',') > 0 && int.TryParse(subName.Substring(subName.LastIndexOf(',') + 1), out int index)) { // In this case insert the node at position index @@ -937,9 +985,7 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon string tag = ""; string nodeType, nodeName; int index = 0; - #if LOGSPAM - string msg = ""; - #endif + List logspam_msg = new List(); logspam_msg.Add(""); List subNodes = new List(); // three ways to specify: @@ -984,15 +1030,13 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon n = FindConfigNodeIn(newNode, nodeType, nodeName, index++); if (n == last || n == null) break; - if (CheckConstraints(n, constraints)) + if (CheckConstraints(log, n, constraints)) subNodes.Add(n); last = n; } } -#if LOGSPAM else - msg += " cannot wildcard a % node: " + subMod.name + "\n"; -#endif + logspam_msg.Add("Cannot wildcard a % node: " + subMod.name); } else { @@ -1007,26 +1051,22 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon // if the original exists modify it if (subNodes.Count > 0) { - #if LOGSPAM - msg += " Applying subnode " + subMod.name + "\n"; - #endif - ConfigNode newSubNode = ModifyNode(nodeStack.Push(subNodes[0]), subMod, context); + logspam_msg.Add("Applying subnode " + subMod.name); + ConfigNode newSubNode = ModifyNode(log, nodeStack.Push(subNodes[0]), subMod, context); subNodes[0].ShallowCopyFrom(newSubNode); subNodes[0].name = newSubNode.name; } else { // if not add the mod node without the % in its name - #if LOGSPAM - msg += " Adding subnode " + subMod.name + "\n"; - #endif + logspam_msg.Add("Adding subnode " + subMod.name); ConfigNode copy = new ConfigNode(nodeType); if (nodeName != null) copy.AddValueSafe("name", nodeName); - ConfigNode newSubNode = ModifyNode(nodeStack.Push(copy), subMod, context); + ConfigNode newSubNode = ModifyNode(log, nodeStack.Push(copy), subMod, context); newNode.nodes.Add(newSubNode); } } @@ -1034,39 +1074,33 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon { if (subNodes.Count == 0) { - #if LOGSPAM - msg += " Adding subnode " + subMod.name + "\n"; - #endif + logspam_msg.Add("Adding subnode " + subMod.name); ConfigNode copy = new ConfigNode(nodeType); if (nodeName != null) copy.AddValueSafe("name", nodeName); - ConfigNode newSubNode = ModifyNode(nodeStack.Push(copy), subMod, context); + ConfigNode newSubNode = ModifyNode(log, nodeStack.Push(copy), subMod, context); newNode.nodes.Add(newSubNode); } } else { // find each original subnode to modify, modify it and add the modified. - #if LOGSPAM if (subNodes.Count == 0) // no nodes to modify! - msg += " Could not find node(s) to modify: " + subMod.name + "\n"; - #endif + logspam_msg.Add("Could not find node(s) to modify: " + subMod.name); foreach (ConfigNode subNode in subNodes) { - #if LOGSPAM - msg += " Applying subnode " + subMod.name + "\n"; - #endif + logspam_msg.Add("Applying subnode " + subMod.name); ConfigNode newSubNode; switch (command) { case Command.Edit: // Edit in place - newSubNode = ModifyNode(nodeStack.Push(subNode), subMod, context); + newSubNode = ModifyNode(log, nodeStack.Push(subNode), subMod, context); subNode.ShallowCopyFrom(newSubNode); subNode.name = newSubNode.name; break; @@ -1080,15 +1114,14 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon case Command.Copy: // Copy the node - newSubNode = ModifyNode(nodeStack.Push(subNode), subMod, context); + newSubNode = ModifyNode(log, nodeStack.Push(subNode), subMod, context); newNode.nodes.Add(newSubNode); break; } } } - #if LOGSPAM - print(msg); - #endif + if (logspam_msg.Count > 1) // Remember we added an empty line on initialization + log.Trace(String.Join("\n\t", logspam_msg.ToArray())); } } @@ -1099,13 +1132,13 @@ public static ConfigNode ModifyNode(NodeStack original, ConfigNode mod, PatchCon // Search for a ConfigNode by a path alike string - private static ConfigNode RecurseNodeSearch(string path, NodeStack nodeStack, PatchContext context) + private static ConfigNode RecurseNodeSearch(IBasicLogger log, string path, NodeStack nodeStack, PatchContext context) { //log("Path : \"" + path + "\""); if (path[0] == '/') { - return RecurseNodeSearch(path.Substring(1), nodeStack.Root, context); + return RecurseNodeSearch(log, path.Substring(1), nodeStack.Root, context); } int nextSep = path.IndexOf('/'); @@ -1148,10 +1181,10 @@ private static ConfigNode RecurseNodeSearch(string path, NodeStack nodeStack, Pa if (nodeStack.IsRoot) return null; - return RecurseNodeSearch(path.Substring(3), nodeStack.Pop(), context); + return RecurseNodeSearch(log, path.Substring(3), nodeStack.Pop(), context); } - //log("nextSep : \"" + nextSep + " \" root : \"" + root + " \" nodeType : \"" + nodeType + "\" nodeName : \"" + nodeName + "\""); + log.Trace("nextSep : \"{0}\" root : \"{1}\" nodeType : \"{2}\" nodeName : \"{3}\"", nextSep, root, nodeType, nodeName); // @XXXXX if (root) @@ -1165,14 +1198,14 @@ private static ConfigNode RecurseNodeSearch(string path, NodeStack nodeStack, Pa foundNodeType = true; - if (nodeName == null || (node.GetValue("name") is string testNodeName && WildcardMatch(testNodeName, nodeName))) + if (nodeName == null || (node.GetValue("name") is string testNodeName && ConfigNodeEditUtils.Instance.WildcardMatch(testNodeName, nodeName))) { nodeStack = new NodeStack(node); break; } } - if (!foundNodeType) context.logger.Warning("Can't find nodeType:" + nodeType); + if (!foundNodeType) log.Warning("Can't find nodeType: {0}", nodeType); if (nodeStack == null) return null; } else @@ -1189,7 +1222,7 @@ private static ConfigNode RecurseNodeSearch(string path, NodeStack nodeStack, Pa nodeStack = null; break; } - if (CheckConstraints(n, constraint)) + if (CheckConstraints(log, n, constraint)) { nodeStack = nodeStack.Push(n); break; @@ -1209,7 +1242,7 @@ private static ConfigNode RecurseNodeSearch(string path, NodeStack nodeStack, Pa { path = path.Substring(nextSep + 1); //log("NewPath : \"" + path + "\""); - return RecurseNodeSearch(path, nodeStack, context); + return RecurseNodeSearch(log, path, nodeStack, context); } return nodeStack.value; @@ -1219,11 +1252,11 @@ private static ConfigNode RecurseNodeSearch(string path, NodeStack nodeStack, Pa private static readonly Regex parseVarKey = new Regex(@"([\w\&\-\.]+)(?:,((?:[0-9]+)+))?(?:\[((?:[0-9]+)+)(?:,(.))?\])?"); // Search for a value by a path alike string - private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nodeStack, PatchContext context) + private static ConfigNode.Value RecurseVariableSearch(IBasicLogger log, string path, NodeStack nodeStack, PatchContext context) { //log("path:" + path); if (path[0] == '/') - return RecurseVariableSearch(path.Substring(1), nodeStack.Root, context); + return RecurseVariableSearch(log, path.Substring(1), nodeStack.Root, context); int nextSep = path.IndexOf('/'); // make sure we don't stop on a ",/" which would be a value separator @@ -1261,13 +1294,13 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod foundNodeType = true; - if (nodeName == null || (node.GetValue("name") is string testNodeName && WildcardMatch(testNodeName, nodeName))) + if (nodeName == null || (node.GetValue("name") is string testNodeName && ConfigNodeEditUtils.Instance.WildcardMatch(testNodeName, nodeName))) { - return RecurseVariableSearch(path.Substring(nextSep + 1), new NodeStack(node), context); + return RecurseVariableSearch(log, path.Substring(nextSep + 1), new NodeStack(node), context); } } - if (!foundNodeType) context.logger.Warning("Can't find nodeType:" + nodeType); + if (!foundNodeType) log.Warning("Can't find nodeType: {0}", nodeType); return null; } @@ -1276,7 +1309,7 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod if (nodeStack.IsRoot) return null; - return RecurseVariableSearch(path.Substring(3), nodeStack.Pop(), context); + return RecurseVariableSearch(log, path.Substring(3), nodeStack.Pop(), context); } // Node search @@ -1324,8 +1357,8 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod ConfigNode n = FindConfigNodeIn(nodeStack.value, nodeType, nodeName, index++); if (n == last || n == null) break; - if (CheckConstraints(n, constraint)) - return RecurseVariableSearch(path.Substring(nextSep + 1), nodeStack.Push(n), context); + if (CheckConstraints(log, n, constraint)) + return RecurseVariableSearch(log, path.Substring(nextSep + 1), nodeStack.Push(n), context); last = n; } return null; @@ -1335,7 +1368,7 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod // just get one node ConfigNode n = FindConfigNodeIn(nodeStack.value, nodeType, nodeName, index); if (n != null) - return RecurseVariableSearch(path.Substring(nextSep + 1), nodeStack.Push(n), context); + return RecurseVariableSearch(log, path.Substring(nextSep + 1), nodeStack.Push(n), context); return null; } } @@ -1345,7 +1378,7 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod Match match = parseVarKey.Match(path); if (!match.Success) { - context.logger.Warning("Cannot parse variable search command: " + path); + log.Warning("Cannot parse variable search command: {0}", path); return null; } @@ -1355,10 +1388,10 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod if (match.Groups[2].Success) int.TryParse(match.Groups[2].Value, out idx); - ConfigNode.Value cVal = FindValueIn(nodeStack.value, valName, idx); + ConfigNode.Value cVal = ConfigNodeEditUtils.Instance.FindValueIn(nodeStack.value, valName, idx); if (cVal == null) { - context.logger.Warning("Cannot find key " + valName + " in " + nodeStack.value.name); + log.Warning("Cannot find key {0} in {1}", valName, nodeStack.value.name); return null; } @@ -1380,8 +1413,9 @@ private static ConfigNode.Value RecurseVariableSearch(string path, NodeStack nod return cVal; } - private static string ProcessVariableSearch(string value, NodeStack nodeStack, PatchContext context) + private static string ProcessVariableSearch(IBasicLogger log, string value, NodeStack nodeStack, PatchContext context) { + string r = value; // value = #xxxx$yyyyy$zzzzz$aaaa$bbbb // There is 2 or more '$' if (value.Length > 0 && value[0] == '#' && value.IndexOf('$') != -1 && value.IndexOf('$') != value.LastIndexOf('$')) @@ -1397,114 +1431,16 @@ private static string ProcessVariableSearch(string value, NodeStack nodeStack, P for (int i = 1; i < split.Length - 1; i += 2) { - ConfigNode.Value result = RecurseVariableSearch(split[i], nodeStack, context); + ConfigNode.Value result = RecurseVariableSearch(log, split[i], nodeStack, context); if (result == null || result.value == null) return null; builder.Append(result.value); builder.Append(split[i + 1]); } - value = builder.ToString(); - //log("variable search output : =\"" + value + "\""); - } - return value; - } - - private static string FindAndReplaceValue( - ConfigNode mod, - ref string valName, - string value, - ConfigNode newNode, - Operator op, - int index, - out ConfigNode.Value origVal, - PatchContext context, - bool hasPosIndex = false, - int posIndex = 0, - bool hasPosStar = false, - char seperator = ',') - { - origVal = FindValueIn(newNode, valName, index); - if (origVal == null) - return null; - string oValue = origVal.value; - - string[] strArray = new string[] { oValue }; - if (hasPosIndex) - { - strArray = oValue.Split(new char[] { seperator }, StringSplitOptions.RemoveEmptyEntries); - if (posIndex >= strArray.Length) - { - context.progress.Error(context.patchUrl, "Invalid Vector Index!"); - return null; - } + r = builder.ToString(); + log.Detail("variable search output : {0} = \"{1}\"", value, r); } - string backupValue = value; - while (posIndex < strArray.Length) - { - value = backupValue; - oValue = strArray[posIndex]; - if (op != Operator.Assign) - { - if (op == Operator.RegexReplace) - { - try - { - string[] split = value.Split(value[0]); - - Regex replace = regexCache.Fetch(split[1], delegate - { - return new Regex(split[1]); - }); - - value = replace.Replace(oValue, split[2]); - } - catch (Exception ex) - { - context.progress.Exception(context.patchUrl, "Error - Failed to do a regexp replacement: " + mod.name + " : original value=\"" + oValue + - "\" regexp=\"" + value + - "\" \nNote - to use regexp, the first char is used to subdivide the string (much like sed)", ex); - return null; - } - } - else if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out double s) - && double.TryParse(oValue, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out double os)) - { - switch (op) - { - case Operator.Multiply: - value = (os * s).ToString(CultureInfo.InvariantCulture); - break; - - case Operator.Divide: - value = (os / s).ToString(CultureInfo.InvariantCulture); - break; - - case Operator.Add: - value = (os + s).ToString(CultureInfo.InvariantCulture); - break; - - case Operator.Subtract: - value = (os - s).ToString(CultureInfo.InvariantCulture); - break; - - case Operator.Exponentiate: - value = Math.Pow(os, s).ToString(CultureInfo.InvariantCulture); - break; - } - } - else - { - context.progress.Error(context.patchUrl, "Error - Failed to do a maths replacement: " + mod.name + " : original value=\"" + oValue + - "\" operator=" + op + " mod value=\"" + value + "\""); - return null; - } - } - strArray[posIndex] = value; - if (hasPosStar) posIndex++; - else break; - } - value = String.Join(new string(seperator, 1), strArray); - return value; + return r; } #endregion Applying Patches @@ -1535,7 +1471,7 @@ public static List SplitConstraints(string condition) static readonly char[] contraintSeparators = { '[', ']' }; - public static bool CheckConstraints(ConfigNode node, string constraints) + public static bool CheckConstraints(IBasicLogger log, ConfigNode node, string constraints) { constraints = constraints.RemoveWS(); @@ -1576,15 +1512,15 @@ public static bool CheckConstraints(ConfigNode node, string constraints) ConfigNode subNode = FindConfigNodeIn(node, type, name, index++); if (subNode == last || subNode == null) break; - any = any || CheckConstraints(subNode, remainingConstraints); + any = any || CheckConstraints(log, subNode, remainingConstraints); last = subNode; } if (last != null) { - //print("CheckConstraints: " + constraints + " " + (not ^ any)); + log.Trace("\tCheckConstraints: {0} {1}", constraints, (not ^ any)); return not ^ any; } - //print("CheckConstraints: " + constraints + " " + (not ^ false)); + log.Trace("\tCheckConstraints: {0} {1}", constraints, (not ^ false)); return not ^ false; case '#': @@ -1592,11 +1528,11 @@ public static bool CheckConstraints(ConfigNode node, string constraints) // #module[Winglet] if (node.HasValue(type) && WildcardMatchValues(node, type, name)) { - bool ret2 = CheckConstraints(node, remainingConstraints); - //print("CheckConstraints: " + constraints + " " + ret2); + bool ret2 = CheckConstraints(log, node, remainingConstraints); + log.Trace("\tCheckConstraints: {0} {1}", constraints, ret2); return ret2; } - //print("CheckConstraints: " + constraints + " false"); + log.Trace("\tCheckConstraints: {0} false", constraints); return false; case '~': @@ -1605,20 +1541,20 @@ public static bool CheckConstraints(ConfigNode node, string constraints) // or: ~breakingForce[100] will be true if it's present but not 100, too. if (name == "" && node.HasValue(type)) { - //print("CheckConstraints: " + constraints + " false"); + log.Trace("\tCheckConstraints: {0} false", constraints); return false; } if (name != "" && WildcardMatchValues(node, type, name)) { - //print("CheckConstraints: " + constraints + " false"); + log.Trace("\tCheckConstraints: {0} false", constraints); return false; } - bool ret = CheckConstraints(node, remainingConstraints); - //print("CheckConstraints: " + constraints + " " + ret); + bool ret = CheckConstraints(log, node, remainingConstraints); + log.Trace("\tCheckConstraints: {0} {1}", constraints, ret); return ret; default: - //print("CheckConstraints: " + constraints + " false"); + log.Trace("\tCheckConstraints: {0} false", constraints); return false; } } @@ -1626,9 +1562,9 @@ public static bool CheckConstraints(ConfigNode node, string constraints) bool ret3 = true; foreach (string constraint in constraintList) { - ret3 = ret3 && CheckConstraints(node, constraint); + ret3 = ret3 && CheckConstraints(log, node, constraint); } - //print("CheckConstraints: " + constraints + " " + ret3); + log.Trace("\tCheckConstraints: {0} {1}", constraints, ret3); return ret3; } @@ -1641,7 +1577,7 @@ public static bool WildcardMatchValues(ConfigNode node, string type, string valu string[] values = node.GetValues(type); for (int i = 0; i < values.Length; i++) { - if (!compare && WildcardMatch(values[i], value)) + if (!compare && ConfigNodeEditUtils.Instance.WildcardMatch(values[i], value)) return true; if (compare && double.TryParse(values[i], NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out double val2) @@ -1653,19 +1589,6 @@ public static bool WildcardMatchValues(ConfigNode node, string type, string valu return false; } - public static bool WildcardMatch(string s, string wildcard) - { - if (wildcard == null) - return true; - string pattern = "^" + Regex.Escape(wildcard).Replace(@"\*", ".*").Replace(@"\?", ".") + "$"; - - Regex regex = regexCache.Fetch(pattern, delegate - { - return new Regex(pattern); - }); - return regex.IsMatch(s); - } - #endregion Condition checking #region Config Node Utilities @@ -1719,7 +1642,7 @@ public static ConfigNode FindConfigNodeIn( int c = src.nodes.Count; for(int i = 0; i < c; ++i) { - if (WildcardMatch(src.nodes[i].name, nodeType)) + if (ConfigNodeEditUtils.Instance.WildcardMatch(src.nodes[i].name, nodeType)) nodes.Add(src.nodes[i]); } int nodeCount = nodes.Count; @@ -1736,7 +1659,7 @@ public static ConfigNode FindConfigNodeIn( { for (int i = 0; i < nodeCount; ++i) { - if (nodes[i].HasValue("name") && WildcardMatch(nodes[i].GetValue("name"), nodeName)) + if (nodes[i].HasValue("name") && ConfigNodeEditUtils.Instance.WildcardMatch(nodes[i].GetValue("name"), nodeName)) { last = nodes[i]; if (--index < 0) @@ -1747,7 +1670,7 @@ public static ConfigNode FindConfigNodeIn( } for (int i = nodeCount - 1; i >= 0; --i) { - if (nodes[i].HasValue("name") && WildcardMatch(nodes[i].GetValue("name"), nodeName)) + if (nodes[i].HasValue("name") && ConfigNodeEditUtils.Instance.WildcardMatch(nodes[i].GetValue("name"), nodeName)) { last = nodes[i]; if (++index >= 0) @@ -1757,21 +1680,6 @@ public static ConfigNode FindConfigNodeIn( return last; } - private static ConfigNode.Value FindValueIn(ConfigNode newNode, string valName, int index) - { - ConfigNode.Value v = null; - for (int i = 0; i < newNode.values.Count; ++i) - { - if (WildcardMatch(newNode.values[i].name, valName)) - { - v = newNode.values[i]; - if (--index < 0) - return v; - } - } - return v; - } - #endregion Config Node Utilities } } diff --git a/ModuleManager/MMPatchRunner.cs b/Source/ModuleManager/MMPatchRunner.cs similarity index 53% rename from ModuleManager/MMPatchRunner.cs rename to Source/ModuleManager/MMPatchRunner.cs index 6c3d63a0..42eca196 100644 --- a/ModuleManager/MMPatchRunner.cs +++ b/Source/ModuleManager/MMPatchRunner.cs @@ -1,8 +1,22 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; -using System.IO; -using ModuleManager.Collections; using ModuleManager.Extensions; using ModuleManager.Logging; using ModuleManager.Threading; @@ -14,44 +28,33 @@ namespace ModuleManager public class MMPatchRunner { private readonly IBasicLogger kspLogger; + private readonly Progress.ProgressCounter counter; + private readonly Progress.Timings timings; public string Status { get; private set; } = ""; public string Errors { get; private set; } = ""; - public MMPatchRunner(IBasicLogger kspLogger) + internal MMPatchLoader patchLoader; + + public MMPatchRunner(IBasicLogger kspLogger, Progress.ProgressCounter counter, Progress.Timings timings) { this.kspLogger = kspLogger ?? throw new ArgumentNullException(nameof(kspLogger)); + this.counter = counter; + this.timings = timings; } public IEnumerator Run() { PostPatchLoader.Instance.databaseConfigs = null; - if (!Directory.Exists(logsDirPath)) Directory.CreateDirectory(logsDirPath); - - kspLogger.Info("Patching started on a new thread, all output will be directed to " + logPath); - - MessageQueue mmLogQueue = new MessageQueue(); - QueueLogRunner logRunner = new QueueLogRunner(mmLogQueue); - ITaskStatus loggingThreadStatus = BackgroundTask.Start(delegate - { - using StreamLogger streamLogger = new StreamLogger(new FileStream(logPath, FileMode.Create)); - streamLogger.Info("Log started at " + DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss.fff")); - logRunner.Run(streamLogger); - streamLogger.Info("Done!"); - }); - // Wait for game database to be initialized for the 2nd time and wait for any plugins to initialize yield return null; yield return null; - IBasicLogger mmLogger = new QueueLogger(mmLogQueue); - - IEnumerable modsAddedByAssemblies = ModListGenerator.GetAdditionalModsFromStaticMethods(mmLogger); + IEnumerable modsAddedByAssemblies = ModListGenerator.GetAdditionalModsFromStaticMethods(ModLogger.Instance); IEnumerable databaseConfigs = null; - - MMPatchLoader patchLoader = new MMPatchLoader(modsAddedByAssemblies, mmLogger); + this.patchLoader = new MMPatchLoader(modsAddedByAssemblies, ModLogger.Instance, this.counter, this.timings); ITaskStatus patchingThreadStatus = BackgroundTask.Start(delegate { @@ -62,29 +65,19 @@ public IEnumerator Run() { yield return null; - if (!patchingThreadStatus.IsRunning) - logRunner.RequestStop(); - Status = patchLoader.status; Errors = patchLoader.errors; - if (!patchingThreadStatus.IsRunning && !loggingThreadStatus.IsRunning) break; + if (!patchingThreadStatus.IsRunning) break; } if (patchingThreadStatus.IsExitedWithError) { - kspLogger.Exception("The patching thread threw an exception", patchingThreadStatus.Exception); + kspLogger.Exception(patchingThreadStatus.Exception, "The patching thread threw an exception"); FatalErrorHandler.HandleFatalError("The patching thread threw an exception"); yield break; } - if (loggingThreadStatus.IsExitedWithError) - { - kspLogger.Exception("The logging thread threw an exception", loggingThreadStatus.Exception); - FatalErrorHandler.HandleFatalError("The logging thread threw an exception"); - yield break; - } - if (databaseConfigs == null) { kspLogger.Error("The patcher returned a null collection of configs"); diff --git a/ModuleManager/ModListGenerator.cs b/Source/ModuleManager/ModListGenerator.cs similarity index 72% rename from ModuleManager/ModListGenerator.cs rename to Source/ModuleManager/ModListGenerator.cs index 5d017232..eb8b021c 100644 --- a/ModuleManager/ModListGenerator.cs +++ b/Source/ModuleManager/ModListGenerator.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -69,7 +85,7 @@ public static IEnumerable GenerateModList(IEnumerable GenerateModList(IEnumerable> forneedsConflict = new Dictionary>(); modListInfo.Append("Non-DLL mods added (:FOR[xxx]):\n"); foreach (UrlDir.UrlConfig cfgmod in GameDatabase.Instance.root.AllConfigs) { @@ -101,6 +118,28 @@ public static IEnumerable GenerateModList(IEnumerable()); + forneedsConflict[dependency].Add(cfgmod); + } + } + if (!mods.Contains(dependency, StringComparer.OrdinalIgnoreCase)) { // found one, now add it to the list. @@ -110,17 +149,28 @@ public static IEnumerable GenerateModList(IEnumerable dir.type == UrlDir.DirectoryType.GameData); foreach (UrlDir subDir in gameData.children) { string cleanName = subDir.name.RemoveWS(); + + // Since the :FOR[foo]:NEEDS[foo] is only really a problem when nothing else had declared the + // name as a modname, if a tag created by a directory is found we remove the conflict from the dictionary + // as it's now harmless and it's not the best of ideas to warn users for things that "look" like problems + // without really being one - unless we could not tell one from another, what we can do here. + if (forneedsConflict.ContainsKey(cleanName)) + forneedsConflict.Remove(cleanName); + if (!mods.Contains(cleanName, StringComparer.OrdinalIgnoreCase)) { mods.Add(cleanName); @@ -128,6 +178,9 @@ public static IEnumerable GenerateModList(IEnumerable GenerateModList(IEnumerable GetAdditionalModsFromStaticMethods string methodName = $"{ass.GetName().Name}.{type.Name}.{method.Name}()"; try { - logger.Info("Calling " + methodName); + logger.Info("Calling {0}", methodName); IEnumerable modsToAdd = (IEnumerable)method.Invoke(null, null); if (modsToAdd == null) { - logger.Error("ModuleManagerAddToModList returned null: " + methodName); + logger.Error("ModuleManagerAddToModList returned null: {0}", methodName); continue; } @@ -196,14 +249,14 @@ public static IEnumerable GetAdditionalModsFromStaticMethods } catch (Exception e) { - logger.Exception("Exception while calling " + methodName, e); + logger.Exception(e, "Exception while calling {0}", methodName); } } } } catch (Exception e) { - logger.Exception("Add to mod list threw an exception in loading " + ass.FullName, e); + logger.Exception(e, "Add to mod list threw an exception in loading {0}", ass.FullName); } } @@ -216,12 +269,12 @@ public static IEnumerable GetAdditionalModsFromStaticMethods string methodName = $"{obj.GetType().Name}.{method.Name}()"; try { - logger.Info("Calling " + methodName); + logger.Info("Calling {0}", methodName); IEnumerable modsToAdd = (IEnumerable)method.Invoke(obj, null); if (modsToAdd == null) { - logger.Error("ModuleManagerAddToModList returned null: " + methodName); + logger.Error("ModuleManagerAddToModList returned null: {0}", methodName); continue; } @@ -232,7 +285,7 @@ public static IEnumerable GetAdditionalModsFromStaticMethods } catch (Exception e) { - logger.Exception("Exception while calling " + methodName, e); + logger.Exception(e, "Exception while calling {0}", methodName); } } } diff --git a/Source/ModuleManager/ModuleManager.12.csproj b/Source/ModuleManager/ModuleManager.12.csproj new file mode 100644 index 00000000..8df72cf2 --- /dev/null +++ b/Source/ModuleManager/ModuleManager.12.csproj @@ -0,0 +1,206 @@ + + + + Debug + AnyCPU + 10.0.0 + 2.0 + {02C8E3AF-69F9-4102-AB60-DD6DE60662D4} + ..\..\obj\12 + Library + ModuleManager + ModuleManager + v3.5 + + + True + full + False + ..\..\bin\Debug12\ + KSP12;DEBUG;LOGSPAM + prompt + 4 + False + default + + + none + True + ..\..\bin\Release12\ + KSP12 + prompt + 4 + False + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Version.tt + + + + + + + + + + + + + + + + + + + + + + + ..\..\..\..\..\..\LIB\plugins\KSPe.dll + False + + + ..\..\..\..\..\..\LIB\managed\1.2.2\Assembly-CSharp.dll + False + + + ..\..\..\..\..\..\LIB\managed\1.2.2\UnityEngine.UI.dll + False + + + ..\..\..\..\..\..\LIB\managed\1.2.2\UnityEngine.dll + False + + + ..\..\..\..\..\..\LIB\plugins\KSPe.UI.dll + False + + + + + + + + + TextTemplatingFileGenerator + Version.cs + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/ModuleManager/ModuleManager.cs b/Source/ModuleManager/ModuleManager.cs similarity index 52% rename from ModuleManager/ModuleManager.cs rename to Source/ModuleManager/ModuleManager.cs index dd5e04e5..57e3bc1c 100644 --- a/ModuleManager/ModuleManager.cs +++ b/Source/ModuleManager/ModuleManager.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; @@ -8,11 +24,13 @@ using System.Reflection; using TMPro; using UnityEngine; -using Debug = UnityEngine.Debug; +#if CATS using ModuleManager.Cats; +#endif using ModuleManager.Extensions; using ModuleManager.Logging; using ModuleManager.UnityLogHandle; +using ModuleManager.Utils; namespace ModuleManager { @@ -34,14 +52,37 @@ public class ModuleManager : MonoBehaviour public static bool dumpPostPatch = false; public static bool DontCopyLogs { get; private set; } = false; - private PopupDialog menu; + [Obsolete("This attribute is not Standard MM. Do not use it on things to be published on Forum")] + public static bool IsExperimentalActive { get; private set; } = false; - private MMPatchRunner patchRunner; + [Obsolete("This attribute is not Standard MM. Do not use it on things to be published on Forum")] + public static bool IsLoadedFromCache { get; internal set; } + + internal static bool IgnoreCache { get; private set; } + #if DEBUG + = true; + #else + = false; + #endif + + private GUI.Menu menu; + + internal MMPatchRunner patchRunner; + private readonly Progress.ProgressCounter counter; + private readonly Progress.Timings timings; + + private InterceptLogHandler interceptLogHandler; #endregion state private static bool loadedInScene; + private ModuleManager() + { + this.counter = new Progress.ProgressCounter(); + this.timings = new Progress.Timings(); + } + internal void OnRnDCenterSpawn() { inRnDCenter = true; @@ -52,15 +93,9 @@ internal void OnRnDCenterDeSpawn() inRnDCenter = false; } - public static void Log(String s) - { - print("[ModuleManager] " + s); - } - - private readonly Stopwatch totalTime = new Stopwatch(); - internal void Awake() { + Detail("Awake"); if (LoadingScreen.Instance == null) { Destroy(gameObject); @@ -71,36 +106,34 @@ internal void Awake() if (loadedInScene || !ElectionAndCheck()) { Assembly currentAssembly = Assembly.GetExecutingAssembly(); - Log("Multiple copies of current version. Using the first copy. Version: " + - currentAssembly.GetName().Version); + Log("Multiple copies of current version. Using the first copy. Version: {0}", currentAssembly.GetName().Version); Destroy(gameObject); return; } - totalTime.Start(); + DontDestroyOnLoad(gameObject); + this.menu = new GUI.Menu(this); + PerformanceMetrics.Instance.Start(); - Debug.unityLogger.logHandler = new InterceptLogHandler(Debug.unityLogger.logHandler); + interceptLogHandler = new InterceptLogHandler(); // Allow loading the background in the loading screen Application.runInBackground = true; - QualitySettings.vSyncCount = 0; - Application.targetFrameRate = -1; // More cool loading screen. Less 4 stoke logo. for (int i = 0; i < LoadingScreen.Instance.Screens.Count; i++) { - var state = LoadingScreen.Instance.Screens[i]; + LoadingScreen.LoadingScreenState state = LoadingScreen.Instance.Screens[i]; state.fadeInTime = i < 3 ? 0.1f : 1; state.displayTime = i < 3 ? 1 : 3; state.fadeOutTime = i < 3 ? 0.1f : 1; } TextMeshProUGUI[] texts = LoadingScreen.Instance.gameObject.GetComponentsInChildren(); - foreach (var text in texts) + foreach (TextMeshProUGUI text in texts) { textPos = Mathf.Min(textPos, text.rectTransform.localPosition.y); } - DontDestroyOnLoad(gameObject); // Subscribe to the RnD center spawn/deSpawn events GameEvents.onGUIRnDComplexSpawn.Add(OnRnDCenterSpawn); @@ -127,10 +160,11 @@ internal void Awake() GameObject aGameObject = new GameObject("ModuleManager"); DontDestroyOnLoad(aGameObject); - Log(string.Format("Adding post patch to the loading screen {0}", list.Count)); + Log("Adding post patch to the loading screen {0}", list.Count); list.Insert(gameDatabaseIndex + 1, aGameObject.AddComponent()); + PostPatchLoader.Instance.Set(this.timings); - patchRunner = new MMPatchRunner(new PrefixLogger("ModuleManager", new UnityLogger(Debug.unityLogger))); + this.patchRunner = new MMPatchRunner(ModLogger.Instance, this.counter, this.timings); StartCoroutine(patchRunner.Run()); // Workaround for 1.6.0 Editor bug after a PartDatabase rebuild. @@ -141,17 +175,20 @@ internal void Awake() } } - bool foolsDay = (DateTime.Now.Month == 4 && DateTime.Now.Day == 1); - bool catDay = (DateTime.Now.Month == 2 && DateTime.Now.Day == 22); - nyan = foolsDay - || Environment.GetCommandLineArgs().Contains("-nyan-nyan"); - - nCats = catDay - || Environment.GetCommandLineArgs().Contains("-ncats"); - + { + bool foolsDay = (DateTime.Now.Month == 4 && DateTime.Now.Day == 1); + bool catDay = (DateTime.Now.Month == 2 && DateTime.Now.Day == 22); + nyan = foolsDay || Environment.GetCommandLineArgs().Contains("-nyan-nyan"); + nCats = catDay || Environment.GetCommandLineArgs().Contains("-ncats"); + } dumpPostPatch = Environment.GetCommandLineArgs().Contains("-mm-dump"); - DontCopyLogs = Environment.GetCommandLineArgs().Contains("-mm-dont-copy-logs"); + IgnoreCache = Environment.GetCommandLineArgs().Contains("-ignore-cache"); + +#pragma warning disable CS0618 // Type or member is obsolete + // To supress features non Stock. + IsExperimentalActive = Environment.GetCommandLineArgs().Contains("-mm-experimental"); +#pragma warning restore CS0618 // Type or member is obsolete loadedInScene = true; } @@ -163,11 +200,13 @@ internal void Awake() [SuppressMessage("Code Quality", "IDE0051", Justification = "Called by Unity")] private void Start() { + Detail("Start"); +#if CATS if (nCats) CatManager.LaunchCats(); else if (nyan) CatManager.LaunchCat(); - +#endif Canvas canvas = LoadingScreen.Instance.GetComponentInChildren(); status = CreateTextObject(canvas, "MMStatus"); @@ -181,25 +220,13 @@ private void Start() // //if (GUI.Button(new Rect(Screen.width / 2f - 100, offsetY, 200, 20), "Click to open the Forum thread")) // // Application.OpenURL("http://forum.kerbalspaceprogram.com/index.php?/topic/124998-silent-patch-for-ksp-105-published/"); //} - - if (Versioning.version_major == 1 && Versioning.version_minor >= 8) - { - foreach (AssemblyLoader.LoadedAssembly assembly in AssemblyLoader.loadedAssemblies) - { - AssemblyName assemblyName = assembly.assembly.GetName(); - if (assemblyName.Name == "Firespitter" && assemblyName.Version <= Version.Parse("7.3.7175.38653")) - { - warning.text = "You are using a version of Firespitter that does not run properly on KSP 1.8+\nThis version may prevent the game from loading properly and may create problems for other mods"; - } - } - } } private TextMeshProUGUI CreateTextObject(Canvas canvas, string name) { GameObject statusGameObject = new GameObject(name); TextMeshProUGUI text = statusGameObject.AddComponent(); - text.text = "STATUS"; + text.text = name; text.fontSize = 18; text.autoSizeTextContainer = true; text.font = Resources.Load("Fonts/Calibri SDF", typeof(TMP_FontAsset)) as TMP_FontAsset; @@ -217,66 +244,47 @@ private TextMeshProUGUI CreateTextObject(Canvas canvas, string name) // Unsubscribe from events when the behavior dies internal void OnDestroy() { + Detail("OnDestroy"); GameEvents.onGUIRnDComplexSpawn.Remove(OnRnDCenterSpawn); GameEvents.onGUIRnDComplexDespawn.Remove(OnRnDCenterDeSpawn); } internal void Update() { - if (GameSettings.MODIFIER_KEY.GetKey() && Input.GetKeyDown(KeyCode.F11) - && (HighLogic.LoadedScene == GameScenes.SPACECENTER || HighLogic.LoadedScene == GameScenes.MAINMENU) - && !inRnDCenter) + this.menu.OnUpdate(this.inRnDCenter); + + if (PerformanceMetrics.Instance.IsRunning && HighLogic.LoadedScene == GameScenes.MAINMENU) { - if (menu == null) + PerformanceMetrics.Instance.Stop(); + if (0 == this.counter.totalPatches.Value) { - menu = PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), - new Vector2(0.5f, 0.5f), - new MultiOptionDialog( - "ModuleManagerMenu", - "", - "ModuleManager", - HighLogic.UISkin, - new Rect(0.5f, 0.5f, 150f, 60f), - new DialogGUIFlexibleSpace(), - new DialogGUIVerticalLayout( - new DialogGUIFlexibleSpace(), - new DialogGUIButton("Reload Database", - delegate - { - MMPatchLoader.keepPartDB = false; - StartCoroutine(DataBaseReloadWithMM()); - }, 140.0f, 30.0f, true), - new DialogGUIButton("Quick Reload Database", - delegate - { - MMPatchLoader.keepPartDB = true; - StartCoroutine(DataBaseReloadWithMM()); - }, 140.0f, 30.0f, true), - new DialogGUIButton("Dump Database to Files", - delegate - { - StartCoroutine(DataBaseReloadWithMM(true)); - }, 140.0f, 30.0f, true), - new DialogGUIButton("Close", () => { }, 140.0f, 30.0f, true) - )), - false, - HighLogic.UISkin); + Log("Loaded {0} patch(es) from cache." + , this.counter.patchedNodes.Value + ); + Log("Total loading Time = {0:0.000}s." + , PerformanceMetrics.Instance.ElapsedTimeInSecs + ); } else { - menu.Dismiss(); - menu = null; + Log("Found {0} and applied {1} patch(es), with {2} warning(s) and {3} error(s). {4} node(s) patched." + , this.counter.totalPatches.Value + , this.counter.appliedPatches.Value + , this.counter.warnings.Value + , this.counter.errors.Value + , this.counter.patchedNodes.Value + ); + Log("{0} were removed by unsatisfied :NEEDS and {1} tags (modnames) were harvested from :FOR ." + , this.counter.needsUnsatisfied.Value + , this.counter.tagLists.Value + ); + Log("Total loading Time = {0:0.000}s, with {1} on patching and {2} on post patching (both parallel to loading)." + , PerformanceMetrics.Instance.ElapsedTimeInSecs + , (string)this.timings.Patching + , (string)this.timings.PostPatching + ); } - } - - if (totalTime.IsRunning && HighLogic.LoadedScene == GameScenes.MAINMENU) - { - totalTime.Stop(); - Log("Total loading Time = " + ((float)totalTime.ElapsedMilliseconds / 1000).ToString("F3") + "s"); - - Application.runInBackground = GameSettings.SIMULATE_IN_BACKGROUND; - QualitySettings.vSyncCount = GameSettings.SYNC_VBL; - Application.targetFrameRate = GameSettings.FRAMERATE_LIMIT; + PerformanceMetrics.Instance.Destroy(); } float offsetY = textPos; @@ -320,149 +328,124 @@ public static bool IsABadIdea() } */ - private IEnumerator DataBaseReloadWithMM(bool dump = false) - { - QualitySettings.vSyncCount = 0; - Application.targetFrameRate = -1; - - patchRunner = new MMPatchRunner(new PrefixLogger("ModuleManager", new UnityLogger(Debug.unityLogger))); - - float totalLoadWeight = GameDatabase.Instance.LoadWeight() + PartLoader.Instance.LoadWeight(); - bool startedReload = false; - - UISkinDef skinDef = HighLogic.UISkin; - UIStyle centeredTextStyle = new UIStyle(skinDef.label) - { - alignment = TextAnchor.UpperCenter - }; - - PopupDialog reloadingDialog = PopupDialog.SpawnPopupDialog(new Vector2(0.5f, 0.5f), - new Vector2(0.5f, 0.5f), - new MultiOptionDialog( - "ModuleManagerReloading", - "", - "ModuleManager - Reloading Database", - skinDef, - new Rect(0.5f, 0.5f, 600f, 60f), - new DialogGUIFlexibleSpace(), - new DialogGUIVerticalLayout( - new DialogGUIFlexibleSpace(), - new DialogGUILabel(delegate () - { - float progressFraction; - if (!startedReload) - { - progressFraction = 0f; - } - else if (!GameDatabase.Instance.IsReady() || !PostPatchLoader.Instance.IsReady()) - { - progressFraction = GameDatabase.Instance.ProgressFraction() * GameDatabase.Instance.LoadWeight(); - progressFraction /= totalLoadWeight; - } - else if (!PartLoader.Instance.IsReady()) - { - progressFraction = GameDatabase.Instance.LoadWeight() + (PartLoader.Instance.ProgressFraction() * GameDatabase.Instance.LoadWeight()); - progressFraction /= totalLoadWeight; - } - else - { - progressFraction = 1f; - } - - return $"Overall progress: {progressFraction:P0}"; - }, centeredTextStyle, expandW: true), - new DialogGUILabel(delegate () - { - if (!startedReload) - return "Starting"; - else if (!GameDatabase.Instance.IsReady()) - return GameDatabase.Instance.ProgressTitle(); - else if (!PostPatchLoader.Instance.IsReady()) - return PostPatchLoader.Instance.ProgressTitle(); - else if (!PartLoader.Instance.IsReady()) - return PartLoader.Instance.ProgressTitle(); - else - return ""; - }), - new DialogGUISpace(5f), - new DialogGUILabel(() => patchRunner.Status) - ) - ), - false, - skinDef); - - yield return null; - - GameDatabase.Instance.Recompile = true; - GameDatabase.Instance.StartLoad(); - - startedReload = true; - - yield return null; - StartCoroutine(patchRunner.Run()); - - // wait for it to finish - while (!GameDatabase.Instance.IsReady()) - yield return null; - - PostPatchLoader.Instance.StartLoad(); - - while (!PostPatchLoader.Instance.IsReady()) - yield return null; - - if (dump) - OutputAllConfigs(); - - PartLoader.Instance.StartLoad(); - - while (!PartLoader.Instance.IsReady()) - yield return null; - - // Needs more work. - //ConfigNode game = HighLogic.CurrentGame.config.GetNode("GAME"); - - //if (game != null && ResearchAndDevelopment.Instance != null) - //{ - // ScreenMessages.PostScreenMessage("GAME found"); - // ConfigNode scenario = game.GetNodes("SCENARIO").FirstOrDefault((ConfigNode n) => n.name == "ResearchAndDevelopment"); - // if (scenario != null) - // { - // ScreenMessages.PostScreenMessage("SCENARIO found"); - // ResearchAndDevelopment.Instance.OnLoad(scenario); - // } - //} - - QualitySettings.vSyncCount = GameSettings.SYNC_VBL; - Application.targetFrameRate = GameSettings.FRAMERATE_LIMIT; - - reloadingDialog.Dismiss(); - } + internal IEnumerator DataBaseReloadWithMM(bool keepPartDB) + { + MMPatchLoader.keepPartDB = keepPartDB; + + GUI.ReloadingDatabaseDialog reloadingDialog = GUI.ReloadingDatabaseDialog.Show(this); + try + { + patchRunner = new MMPatchRunner(ModLogger.Instance, this.counter, this.timings); + + yield return null; + + GameDatabase.Instance.Recompile = true; + GameDatabase.Instance.StartLoad(); + + yield return null; + StartCoroutine(patchRunner.Run()); + + // wait for it to finish + while (!GameDatabase.Instance.IsReady()) + yield return null; + + PostPatchLoader.Instance.Set(this.timings); + + while (!PostPatchLoader.Instance.IsReady()) + yield return null; + + PartLoader.Instance.StartLoad(); + + while (!PartLoader.Instance.IsReady()) + yield return null; + + // Needs more work. + //ConfigNode game = HighLogic.CurrentGame.config.GetNode("GAME"); + + //if (game != null && ResearchAndDevelopment.Instance != null) + //{ + // ScreenMessages.PostScreenMessage("GAME found"); + // ConfigNode scenario = game.GetNodes("SCENARIO").FirstOrDefault((ConfigNode n) => n.name == "ResearchAndDevelopment"); + // if (scenario != null) + // { + // ScreenMessages.PostScreenMessage("SCENARIO found"); + // ResearchAndDevelopment.Instance.OnLoad(scenario); + // } + //} + } + finally + { + reloadingDialog = reloadingDialog.Dismiss(); + } + } + + internal IEnumerator QuickDataBaseReloadWithMM() + { + ModLogger.LOG.info("Quick loading DataBase from Config Cache..."); + if (!FilePathRepository.CACHE_CONFIG.IsLoadable) + { + ModLogger.LOG.warn("Config Cache file not found. Aborting Quick Reload."); + yield break; + } + + ConfigNode cache = FilePathRepository.CACHE_CONFIG.Load().Node; + + UrlDir gameDataDir = GameDatabase.Instance.root.AllDirectories.First(d => d.path.EndsWith("GameData") && d.name == "" && d.url == ""); + UrlDir.UrlFile physicsUrlFile = new UrlDir.UrlFile(gameDataDir, new FileInfo(FilePathRepository.PHYSICS_CONFIG.KspPath)); + gameDataDir.files.Add(physicsUrlFile); + + List databaseConfigs = new List(cache.nodes.Count); + + foreach (ConfigNode node in cache.nodes) + { + string parentUrl = node.GetValue("parentUrl"); + + UrlDir.UrlFile parent = gameDataDir.Find(parentUrl); + if (parent != null) + { + node.nodes[0].UnescapeValuesRecursive(); + databaseConfigs.Add(new ProtoUrlConfig(parent, node.nodes[0])); + } + } + + foreach (UrlDir.UrlFile file in GameDatabase.Instance.root.AllConfigFiles) + file.configs.Clear(); + + foreach (IProtoUrlConfig protoConfig in databaseConfigs) + protoConfig.UrlFile.AddConfig(protoConfig.Node); + + ModLogger.LOG.info("Quick loading DataBase finished."); + yield return null; + } + + internal IEnumerator DumpDataBaseToFiles() + { + ModLogger.LOG.info("Dumping DataBase to files."); + OutputAllConfigs(); + ModLogger.LOG.info("DataBase dump finished."); + yield return null; + } public static void OutputAllConfigs() { - string path = Path.GetFullPath(Path.Combine(KSPUtil.ApplicationRootPath, "_MMCfgOutput")); try { - Directory.CreateDirectory(path); - foreach (string file in Directory.GetFiles(path)) + Directory.CreateDirectory(FilePathRepository.MMCfgOutputPath); + foreach (string file in Directory.GetFiles(FilePathRepository.MMCfgOutputPath)) { File.Delete(file); } - foreach (string dir in Directory.GetDirectories(path)) + foreach (string dir in Directory.GetDirectories(FilePathRepository.MMCfgOutputPath)) { Directory.Delete(dir, true); } } - catch (IOException ioException) - { - Log("Exception while cleaning the export dir\n" + ioException); - } - catch (UnauthorizedAccessException unauthorizedAccessException) + catch (Exception e) when (e is IOException || e is UnauthorizedAccessException) { - Log("Exception while cleaning the export dir\n" + unauthorizedAccessException); + Log("Exception {0}, while cleaning the export dir!", e); } - static void WriteDirectoryRecursive(UrlDir currentDir, string dirPath) + void WriteDirectoryRecursive(UrlDir currentDir, string dirPath) { if (currentDir.files.Count > 0) Directory.CreateDirectory(dirPath); @@ -475,22 +458,24 @@ static void WriteDirectoryRecursive(UrlDir currentDir, string dirPath) bool first = true; - using FileStream stream = new FileStream(filePath, FileMode.Create); - using StreamWriter writer = new StreamWriter(stream); - foreach (UrlDir.UrlConfig urlConfig in urlFile.configs) + using (FileStream stream = new FileStream(filePath, FileMode.Create)) + using (StreamWriter writer = new StreamWriter(stream)) { - try + foreach (UrlDir.UrlConfig urlConfig in urlFile.configs) { - if (first) first = false; - else writer.Write("\n"); + try + { + if (first) first = false; + else writer.Write("\n"); - ConfigNode copy = urlConfig.config.DeepCopy(); - copy.EscapeValuesRecursive(); - writer.Write(copy.ToString()); - } - catch (Exception e) - { - Log("Exception while trying to write the file " + filePath + "\n" + e); + ConfigNode copy = urlConfig.config.DeepCopy(); + copy.EscapeValuesRecursive(); + writer.Write(copy.ToString()); + } + catch (Exception e) + { + Log("Exception while trying to write the file " + filePath + "\n" + e); + } } } } @@ -503,7 +488,7 @@ static void WriteDirectoryRecursive(UrlDir currentDir, string dirPath) try { - WriteDirectoryRecursive(GameDatabase.Instance.root, path); + WriteDirectoryRecursive(GameDatabase.Instance.root, FilePathRepository.MMCfgOutputPath); } catch (DirectoryNotFoundException directoryNotFoundException) { @@ -547,14 +532,11 @@ public bool ElectionAndCheck() string status = "You have old versions of Module Manager (older than 1.5) or MMSarbianExt.\nYou will need to remove them for Module Manager and the mods using it to work\nExit KSP and delete those files :\n" + String.Join("\n", badPaths.ToArray()); - PopupDialog.SpawnPopupDialog(new Vector2(0f, 1f), new Vector2(0f, 1f), "ModuleManagerOldVersions", "Old versions of Module Manager", status, "OK", false, UISkinManager.defaultSkin); - Log("Old version of Module Manager present. Stopping"); + GUI.ShowStopperAlertBox.Show(status); return false; } - //PopupDialog.SpawnPopupDialog(new Vector2(0.1f, 1f), new Vector2(0.2f, 1f), "Test of the dialog", "Stuff", "OK", false, UISkinManager.defaultSkin); - Assembly currentAssembly = Assembly.GetExecutingAssembly(); IEnumerable eligible = from a in AssemblyLoader.loadedAssemblies let ass = a.assembly @@ -568,8 +550,7 @@ orderby ass.GetName().Version descending, a.path ascending if (eligible.First().assembly != currentAssembly) { //loaded = true; - Log("version " + currentAssembly.GetName().Version + " at " + currentAssembly.Location + - " lost the election"); + Log("version {0} at {1} lost the election", currentAssembly.GetName().Version, currentAssembly.Location); Destroy(gameObject); return false; } @@ -577,17 +558,31 @@ orderby ass.GetName().Version descending, a.path ascending foreach (AssemblyLoader.LoadedAssembly a in eligible) { if (currentAssembly.Location != a.path) - candidates += "Version " + a.assembly.GetName().Version + " " + a.path + " " + "\n"; + candidates += string.Format("Version {0} {1} \n", a.assembly.GetName().Version, a.path); } if (candidates.Length > 0) { - Log("version " + currentAssembly.GetName().Version + " at " + currentAssembly.Location + - " won the election against\n" + candidates); + Log("version {0} at {1} won the election against\n{2}", currentAssembly.GetName().Version, currentAssembly.Location, candidates); } #endregion Type election return true; } + + private static void Log(String s) + { + ModLogger.LOG.info(s); + } + + private static void Log(String format, params object[] p) + { + ModLogger.LOG.info(format, p); + } + + private static void Detail(string s) + { + ModLogger.LOG.detail(s); + } } } diff --git a/ModuleManager/ModuleManager.csproj b/Source/ModuleManager/ModuleManager.csproj similarity index 68% rename from ModuleManager/ModuleManager.csproj rename to Source/ModuleManager/ModuleManager.csproj index 20fe0da1..5aec44b1 100644 --- a/ModuleManager/ModuleManager.csproj +++ b/Source/ModuleManager/ModuleManager.csproj @@ -1,42 +1,40 @@  - + Debug AnyCPU 10.0.0 2.0 {02C8E3AF-69F9-4102-AB60-DD6DE60662D3} + ..\..\obj Library ModuleManager ModuleManager - v4.7.1 - + v3.5 True full False - bin\Debug\ - DEBUG; + ..\..\bin\Debug\ + DEBUG prompt 4 False default - false none True - bin\Release\ + ..\..\bin\Release\ prompt 4 False - false - - - 8.0 + + + @@ -44,7 +42,6 @@ - @@ -53,24 +50,15 @@ - - - - - - - - - - - - + + + @@ -80,11 +68,7 @@ - - - - @@ -93,7 +77,10 @@ - + + + + @@ -111,54 +98,51 @@ - - - - - False - False - - - False - False - - - - - - False - False - - - False - False + + Version.tt + + + + + + + + + + + + + + + + + + - - False - False + - - False + + ..\..\..\..\..\..\LIB\plugins\KSPe.dll False - - False + + ..\..\..\..\..\..\LIB\managed\1.3.1\Assembly-CSharp.dll False - - False + + ..\..\..\..\..\..\LIB\managed\1.3.1\UnityEngine.UI.dll False - - False + + ..\..\..\..\..\..\LIB\managed\1.3.1\UnityEngine.dll False - - False + + ..\..\..\..\..\..\LIB\plugins\KSPe.UI.dll False @@ -167,6 +151,10 @@ + + TextTemplatingFileGenerator + Version.cs + @@ -207,9 +195,11 @@ - + + + - sh -c "TARGET_PATH='$(TargetPath)' TARGET_DIR='$(TargetDir)' TARGET_NAME='$(TargetName)' sh '$(ProjectDir)/copy_build.sh'" + \ No newline at end of file diff --git a/ModuleManager/ModuleManagerTestRunner.cs b/Source/ModuleManager/ModuleManagerTestRunner.cs similarity index 67% rename from ModuleManager/ModuleManagerTestRunner.cs rename to Source/ModuleManager/ModuleManagerTestRunner.cs index 2f90a453..0fa78532 100644 --- a/ModuleManager/ModuleManagerTestRunner.cs +++ b/Source/ModuleManager/ModuleManagerTestRunner.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using System.Text; @@ -27,10 +43,12 @@ public void RunTestCases(UrlDir gameDatabaseRoot) UrlDir.UrlFile parent = expect.parent; if (parent.configs.Count != expect.config.CountNodes + 1) { - logger.Error("Test " + parent.name + " failed as expected number of nodes differs expected: " + - expect.config.CountNodes + " found: " + (parent.configs.Count - 1)); + logger.Error( + "Test {0} failed as expected number of nodes differs expected: {1} found: {2}", + parent.name, expect.config.CountNodes, (parent.configs.Count - 1) + ); for (int i = 0; i < parent.configs.Count; ++i) - logger.Info(parent.configs[i].config.ToString()); + logger.Detail("{0}", parent.configs[i].config); continue; } for (int i = 0; i < expect.config.CountNodes; ++i) @@ -39,9 +57,10 @@ public void RunTestCases(UrlDir gameDatabaseRoot) ConfigNode expectNode = expect.config.nodes[i]; if (!CompareRecursive(expectNode, gotNode)) { - logger.Error("Test " + parent.name + "[" + i + - "] failed as expected output and actual output differ.\nexpected:\n" + expectNode + - "\nActually got:\n" + gotNode); + logger.Error( + "Test {0}[{1}] failed as expected output and actual output differ.\nexpected:\n{2}\nActually got:\n{3}", + parent.name, i, expectNode, gotNode + ); } } diff --git a/ModuleManager/NeedsChecker.cs b/Source/ModuleManager/NeedsChecker.cs similarity index 83% rename from ModuleManager/NeedsChecker.cs rename to Source/ModuleManager/NeedsChecker.cs index 94f2ad29..8160154a 100644 --- a/ModuleManager/NeedsChecker.cs +++ b/Source/ModuleManager/NeedsChecker.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Linq; @@ -138,12 +154,12 @@ private void CheckNeedsRecursive(NodeStack nodeStack, UrlDir.UrlConfig urlConfig } catch (ArgumentOutOfRangeException e) { - progress.Exception("ArgumentOutOfRangeException in CheckNeeds for value \"" + val.name + "\"", e); + progress.Exception(e, "ArgumentOutOfRangeException in CheckNeeds for value \"{0}\"", val.name); throw; } catch (Exception e) { - progress.Exception("General Exception in CheckNeeds for value \"" + val.name + "\"", e); + progress.Exception(e, "General Exception in CheckNeeds for value \"{0}\"", val.name); throw; } } @@ -155,7 +171,10 @@ private void CheckNeedsRecursive(NodeStack nodeStack, UrlDir.UrlConfig urlConfig if (nodeName == null) { - progress.Error(urlConfig, "Error - Node in file " + urlConfig.SafeUrl() + " subnode: " + nodeStack.GetPath() + " has config.name == null"); + progress.Error(urlConfig, + "Error - Node in file {0} subnode: {1} has config.name == null", + urlConfig.SafeUrl(), nodeStack.GetPath() + ); } try @@ -174,12 +193,12 @@ private void CheckNeedsRecursive(NodeStack nodeStack, UrlDir.UrlConfig urlConfig } catch (ArgumentOutOfRangeException e) { - progress.Exception("ArgumentOutOfRangeException in CheckNeeds for node \"" + node.name + "\"", e); + progress.Exception(e, "ArgumentOutOfRangeException in CheckNeeds for node \"{0}\"", node.name); throw; } catch (Exception e) { - progress.Exception("General Exception " + e.GetType().Name + " for node \"" + node.name + "\"", e); + progress.Exception(e, "General Exception {0} for node \"{1}\"", e.GetType().Name, node.name); throw; } } diff --git a/ModuleManager/NodeMatcher.cs b/Source/ModuleManager/NodeMatcher.cs similarity index 63% rename from ModuleManager/NodeMatcher.cs rename to Source/ModuleManager/NodeMatcher.cs index 8777de97..1baabfff 100644 --- a/ModuleManager/NodeMatcher.cs +++ b/Source/ModuleManager/NodeMatcher.cs @@ -1,5 +1,23 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using ModuleManager.Extensions; +using ModuleManager.Logging; +using ModuleManager.Utils; namespace ModuleManager { @@ -10,12 +28,15 @@ public interface INodeMatcher public class NodeMatcher : INodeMatcher { + private readonly IBasicLogger log; private readonly string type; private readonly string[] namePatterns = null; private readonly string constraints = ""; - public NodeMatcher(string type, string name, string constraints) + public NodeMatcher(IBasicLogger log, string type, string name, string constraints) { + this.log = log; + if (type == string.Empty) throw new ArgumentException("can't be empty", nameof(type)); this.type = type ?? throw new ArgumentNullException(nameof(type)); @@ -42,7 +63,7 @@ public bool IsMatch(ConfigNode node) bool match = false; foreach (string pattern in namePatterns) { - if (MMPatchLoader.WildcardMatch(name, pattern)) + if (ConfigNodeEditUtils.Instance.WildcardMatch(name, pattern)) { match = true; break; @@ -52,7 +73,7 @@ public bool IsMatch(ConfigNode node) if (!match) return false; } - return MMPatchLoader.CheckConstraints(node, constraints); + return MMPatchLoader.CheckConstraints(this.log, node, constraints); } } } diff --git a/Source/ModuleManager/Operator.cs b/Source/ModuleManager/Operator.cs new file mode 100644 index 00000000..f4d090c9 --- /dev/null +++ b/Source/ModuleManager/Operator.cs @@ -0,0 +1,31 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +namespace ModuleManager +{ + public enum Operator + { + Assign, + Add, + Subtract, + Multiply, + Divide, + Exponentiate, + RegexReplace, + } +} diff --git a/ModuleManager/OperatorParser.cs b/Source/ModuleManager/OperatorParser.cs similarity index 72% rename from ModuleManager/OperatorParser.cs rename to Source/ModuleManager/OperatorParser.cs index e85eebab..9b5eeb7e 100644 --- a/ModuleManager/OperatorParser.cs +++ b/Source/ModuleManager/OperatorParser.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; namespace ModuleManager { diff --git a/ModuleManager/Pass.cs b/Source/ModuleManager/Pass.cs similarity index 61% rename from ModuleManager/Pass.cs rename to Source/ModuleManager/Pass.cs index c7db8684..471be5ed 100644 --- a/ModuleManager/Pass.cs +++ b/Source/ModuleManager/Pass.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; using ModuleManager.Patches; diff --git a/ModuleManager/PatchApplier.cs b/Source/ModuleManager/PatchApplier.cs similarity index 65% rename from ModuleManager/PatchApplier.cs rename to Source/ModuleManager/PatchApplier.cs index adaade88..335fbd8a 100644 --- a/ModuleManager/PatchApplier.cs +++ b/Source/ModuleManager/PatchApplier.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using ModuleManager.Logging; using ModuleManager.Extensions; @@ -45,8 +61,8 @@ private void ApplyPatches(LinkedList databaseConfigs, IPass pas } catch (Exception e) { - progress.Exception(patch.UrlConfig, "Exception while processing node : " + patch.UrlConfig.SafeUrl(), e); - logger.Error("Processed node was\n" + patch.UrlConfig.PrettyPrint()); + progress.Exception(e, patch.UrlConfig, "Exception while processing node : {0}", patch.UrlConfig.SafeUrl()); + logger.Error("Processed node was\n{0}", patch.UrlConfig.PrettyPrint()); } } } diff --git a/ModuleManager/PatchContext.cs b/Source/ModuleManager/PatchContext.cs similarity index 55% rename from ModuleManager/PatchContext.cs rename to Source/ModuleManager/PatchContext.cs index 09e2f441..b37b8b6b 100644 --- a/ModuleManager/PatchContext.cs +++ b/Source/ModuleManager/PatchContext.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using ModuleManager.Logging; using ModuleManager.Progress; diff --git a/ModuleManager/PatchExtractor.cs b/Source/ModuleManager/PatchExtractor.cs similarity index 69% rename from ModuleManager/PatchExtractor.cs rename to Source/ModuleManager/PatchExtractor.cs index 6c8765f4..350f09be 100644 --- a/ModuleManager/PatchExtractor.cs +++ b/Source/ModuleManager/PatchExtractor.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Diagnostics.CodeAnalysis; using ModuleManager.Extensions; using ModuleManager.Logging; @@ -43,7 +59,7 @@ public IPatch ExtractPatch(UrlDir.UrlConfig urlConfig) { if (!urlConfig.type.IsBracketBalanced()) { - progress.Error(urlConfig, "Error - node name does not have balanced brackets (or a space - if so replace with ?):\n" + urlConfig.SafeUrl()); + progress.Error(urlConfig, "Error - node name does not have balanced brackets (or a space - if so replace with ?):\n{0}", urlConfig.SafeUrl()); return null; } @@ -51,27 +67,27 @@ public IPatch ExtractPatch(UrlDir.UrlConfig urlConfig) if (command == Command.Replace) { - progress.Error(urlConfig, $"Error - replace command (%) is not valid on a root node: {urlConfig.SafeUrl()}"); + progress.Error(urlConfig, "Error - replace command (%) is not valid on a root node: {0}", urlConfig.SafeUrl()); return null; } else if (command == Command.Create) { - progress.Error(urlConfig, $"Error - create command (&) is not valid on a root node: {urlConfig.SafeUrl()}"); + progress.Error(urlConfig, "Error - create command (&) is not valid on a root node: {0}", urlConfig.SafeUrl()); return null; } else if (command == Command.Rename) { - progress.Error(urlConfig, $"Error - rename command (|) is not valid on a root node: {urlConfig.SafeUrl()}"); + progress.Error(urlConfig, "Error - rename command (|) is not valid on a root node: {0}", urlConfig.SafeUrl()); return null; } else if (command == Command.Paste) { - progress.Error(urlConfig, $"Error - paste command (#) is not valid on a root node: {urlConfig.SafeUrl()}"); + progress.Error(urlConfig, "Error - paste command (#) is not valid on a root node: {0}", urlConfig.SafeUrl()); return null; } else if (command == Command.Special) { - progress.Error(urlConfig, $"Error - special command (*) is not valid on a root node: {urlConfig.SafeUrl()}"); + progress.Error(urlConfig, "Error - special command (*) is not valid on a root node: {0}", urlConfig.SafeUrl()); return null; } @@ -79,10 +95,14 @@ public IPatch ExtractPatch(UrlDir.UrlConfig urlConfig) try { tagList = tagListParser.Parse(name, urlConfig); + progress.ProcessingTagList(tagList, urlConfig); } catch (FormatException ex) { - progress.Error(urlConfig, $"Cannot parse node name as tag list: {ex.Message}\non: {urlConfig.SafeUrl()}"); + progress.Error(urlConfig, + "Cannot parse node name as tag list: {0}\non: {1}", + ex.Message, urlConfig.SafeUrl() + ); return null; } @@ -108,7 +128,7 @@ public IPatch ExtractPatch(UrlDir.UrlConfig urlConfig) } catch(Exception e) { - progress.Exception(urlConfig, $"Exception while attempting to create patch from config: {urlConfig.SafeUrl()}", e); + progress.Exception(e, urlConfig, "Exception while attempting to create patch from config: {0}", urlConfig.SafeUrl()); return null; } } diff --git a/ModuleManager/PatchList.cs b/Source/ModuleManager/PatchList.cs similarity index 91% rename from ModuleManager/PatchList.cs rename to Source/ModuleManager/PatchList.cs index d3990540..784e7bbc 100644 --- a/ModuleManager/PatchList.cs +++ b/Source/ModuleManager/PatchList.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; using ModuleManager.Patches; diff --git a/ModuleManager/Patches/CopyPatch.cs b/Source/ModuleManager/Patches/CopyPatch.cs similarity index 62% rename from ModuleManager/Patches/CopyPatch.cs rename to Source/ModuleManager/Patches/CopyPatch.cs index 45ee09fe..4766b968 100644 --- a/ModuleManager/Patches/CopyPatch.cs +++ b/Source/ModuleManager/Patches/CopyPatch.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using NodeStack = ModuleManager.Collections.ImmutableStack; using ModuleManager.Extensions; @@ -10,13 +26,15 @@ namespace ModuleManager.Patches { public class CopyPatch : IPatch { + private readonly IBasicLogger log; public UrlDir.UrlConfig UrlConfig { get; } public INodeMatcher NodeMatcher { get; } public IPassSpecifier PassSpecifier { get; } public bool CountsAsPatch => true; - public CopyPatch(UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier) + public CopyPatch(IBasicLogger log, UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier) { + this.log = log; UrlConfig = urlConfig ?? throw new ArgumentNullException(nameof(urlConfig)); NodeMatcher = nodeMatcher ?? throw new ArgumentNullException(nameof(nodeMatcher)); PassSpecifier = passSpecifier ?? throw new ArgumentNullException(nameof(passSpecifier)); @@ -37,10 +55,13 @@ public void Apply(LinkedList databaseConfigs, IPatchProgress pr { if (!NodeMatcher.IsMatch(protoConfig.Node)) continue; - ConfigNode clone = MMPatchLoader.ModifyNode(new NodeStack(protoConfig.Node), UrlConfig.config, context); + ConfigNode clone = MMPatchLoader.ModifyNode(this.log, new NodeStack(protoConfig.Node), UrlConfig.config, context); if (protoConfig.Node.GetValue("name") is string name && name == clone.GetValue("name")) { - progress.Error(UrlConfig, $"Error - when applying copy {UrlConfig.SafeUrl()} to {protoConfig.FullUrl} - the copy needs to have a different name than the parent (use @name = xxx)"); + progress.Error(UrlConfig, + "Error - when applying copy {0} to {1} - the copy needs to have a different name than the parent (use @name = xxx)", + UrlConfig.SafeUrl(), protoConfig.FullUrl + ); } else { @@ -50,7 +71,10 @@ public void Apply(LinkedList databaseConfigs, IPatchProgress pr } catch (Exception ex) { - progress.Exception(UrlConfig, $"Exception while applying copy {UrlConfig.SafeUrl()} to {protoConfig.FullUrl}", ex); + progress.Exception(ex, UrlConfig, + "Exception while applying copy {0} to {1}", + UrlConfig.SafeUrl(), protoConfig.FullUrl + ); } } } diff --git a/ModuleManager/Patches/DeletePatch.cs b/Source/ModuleManager/Patches/DeletePatch.cs similarity index 65% rename from ModuleManager/Patches/DeletePatch.cs rename to Source/ModuleManager/Patches/DeletePatch.cs index 46d46a94..48566bb9 100644 --- a/ModuleManager/Patches/DeletePatch.cs +++ b/Source/ModuleManager/Patches/DeletePatch.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using ModuleManager.Extensions; using ModuleManager.Logging; @@ -9,13 +25,15 @@ namespace ModuleManager.Patches { public class DeletePatch : IPatch { + private readonly IBasicLogger log; public UrlDir.UrlConfig UrlConfig { get; } public INodeMatcher NodeMatcher { get; } public IPassSpecifier PassSpecifier { get; } public bool CountsAsPatch => true; - public DeletePatch(UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier) + public DeletePatch(IBasicLogger log, UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier) { + this.log = log; UrlConfig = urlConfig ?? throw new ArgumentNullException(nameof(urlConfig)); NodeMatcher = nodeMatcher ?? throw new ArgumentNullException(nameof(nodeMatcher)); PassSpecifier = passSpecifier ?? throw new ArgumentNullException(nameof(passSpecifier)); @@ -43,7 +61,10 @@ public void Apply(LinkedList databaseConfigs, IPatchProgress pr } catch (Exception ex) { - progress.Exception(UrlConfig, $"Exception while applying delete {UrlConfig.SafeUrl()} to {protoConfig.FullUrl}", ex); + progress.Exception(ex, UrlConfig, + "Exception while applying delete {0} to {1}", + UrlConfig.SafeUrl(), protoConfig.FullUrl + ); } } } diff --git a/ModuleManager/Patches/EditPatch.cs b/Source/ModuleManager/Patches/EditPatch.cs similarity index 66% rename from ModuleManager/Patches/EditPatch.cs rename to Source/ModuleManager/Patches/EditPatch.cs index 91613879..65582a03 100644 --- a/ModuleManager/Patches/EditPatch.cs +++ b/Source/ModuleManager/Patches/EditPatch.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using NodeStack = ModuleManager.Collections.ImmutableStack; using ModuleManager.Extensions; @@ -10,6 +26,7 @@ namespace ModuleManager.Patches { public class EditPatch : IPatch { + private readonly IBasicLogger log; private readonly bool loop; public UrlDir.UrlConfig UrlConfig { get; } @@ -17,8 +34,9 @@ public class EditPatch : IPatch public IPassSpecifier PassSpecifier { get; } public bool CountsAsPatch => true; - public EditPatch(UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier) + public EditPatch(IBasicLogger log, UrlDir.UrlConfig urlConfig, INodeMatcher nodeMatcher, IPassSpecifier passSpecifier) { + this.log = log; UrlConfig = urlConfig ?? throw new ArgumentNullException(nameof(urlConfig)); NodeMatcher = nodeMatcher ?? throw new ArgumentNullException(nameof(nodeMatcher)); PassSpecifier = passSpecifier ?? throw new ArgumentNullException(nameof(passSpecifier)); @@ -44,14 +62,18 @@ public void Apply(LinkedList databaseConfigs, IPatchProgress pr do { progress.ApplyingUpdate(protoConfig, UrlConfig); - listNode.Value = protoConfig = new ProtoUrlConfig(protoConfig.UrlFile, MMPatchLoader.ModifyNode(new NodeStack(protoConfig.Node), UrlConfig.config, context)); + listNode.Value = protoConfig = new ProtoUrlConfig(protoConfig.UrlFile, MMPatchLoader.ModifyNode(this.log, new NodeStack(protoConfig.Node), UrlConfig.config, context)); + if (loop) logger.Trace("Loop!"); } while (loop && NodeMatcher.IsMatch(protoConfig.Node)); if (loop) protoConfig.Node.RemoveNodes("MM_PATCH_LOOP"); } catch (Exception ex) { - progress.Exception(UrlConfig, $"Exception while applying update {UrlConfig.SafeUrl()} to {protoConfig.FullUrl}", ex); + progress.Exception(ex, UrlConfig, + "Exception while applying update {0} to {1}", + UrlConfig.SafeUrl(), protoConfig.FullUrl + ); } } } diff --git a/Source/ModuleManager/Patches/IPatch.cs b/Source/ModuleManager/Patches/IPatch.cs new file mode 100644 index 00000000..7ce2d03a --- /dev/null +++ b/Source/ModuleManager/Patches/IPatch.cs @@ -0,0 +1,32 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using System.Collections.Generic; +using ModuleManager.Logging; +using ModuleManager.Patches.PassSpecifiers; +using ModuleManager.Progress; + +namespace ModuleManager.Patches +{ + public interface IPatch + { + UrlDir.UrlConfig UrlConfig { get; } + IPassSpecifier PassSpecifier { get; } + bool CountsAsPatch { get; } + void Apply(LinkedList configs, IPatchProgress progress, IBasicLogger logger); + } +} diff --git a/ModuleManager/Patches/InsertPatch.cs b/Source/ModuleManager/Patches/InsertPatch.cs similarity index 62% rename from ModuleManager/Patches/InsertPatch.cs rename to Source/ModuleManager/Patches/InsertPatch.cs index c5f2c17f..718f9bec 100644 --- a/ModuleManager/Patches/InsertPatch.cs +++ b/Source/ModuleManager/Patches/InsertPatch.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using ModuleManager.Extensions; using ModuleManager.Logging; @@ -9,13 +25,15 @@ namespace ModuleManager.Patches { public class InsertPatch : IPatch { + private readonly IBasicLogger log; public UrlDir.UrlConfig UrlConfig { get; } public string NodeType { get; } public IPassSpecifier PassSpecifier { get; } public bool CountsAsPatch => false; - public InsertPatch(UrlDir.UrlConfig urlConfig, string nodeType, IPassSpecifier passSpecifier) + public InsertPatch(IBasicLogger log, UrlDir.UrlConfig urlConfig, string nodeType, IPassSpecifier passSpecifier) { + this.log = log; UrlConfig = urlConfig ?? throw new ArgumentNullException(nameof(urlConfig)); NodeType = nodeType ?? throw new ArgumentNullException(nameof(nodeType)); PassSpecifier = passSpecifier ?? throw new ArgumentNullException(nameof(passSpecifier)); diff --git a/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs similarity index 65% rename from ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs rename to Source/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs index a50b99c5..765dc69e 100644 --- a/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs +++ b/Source/ModuleManager/Patches/PassSpecifiers/AfterPassSpecifier.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using ModuleManager.Progress; namespace ModuleManager.Patches.PassSpecifiers diff --git a/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs similarity index 65% rename from ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs rename to Source/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs index 9f509f43..0f1194d6 100644 --- a/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs +++ b/Source/ModuleManager/Patches/PassSpecifiers/BeforePassSpecifier.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using ModuleManager.Progress; namespace ModuleManager.Patches.PassSpecifiers diff --git a/Source/ModuleManager/Patches/PassSpecifiers/FinalPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/FinalPassSpecifier.cs new file mode 100644 index 00000000..ec1c74c1 --- /dev/null +++ b/Source/ModuleManager/Patches/PassSpecifiers/FinalPassSpecifier.cs @@ -0,0 +1,33 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using ModuleManager.Progress; + +namespace ModuleManager.Patches.PassSpecifiers +{ + public class FinalPassSpecifier : IPassSpecifier + { + public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) + { + if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); + if (progress == null) throw new ArgumentNullException(nameof(progress)); + return true; + } + + public string Descriptor => ":FINAL"; + } +} diff --git a/Source/ModuleManager/Patches/PassSpecifiers/FirstPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/FirstPassSpecifier.cs new file mode 100644 index 00000000..af6a37f3 --- /dev/null +++ b/Source/ModuleManager/Patches/PassSpecifiers/FirstPassSpecifier.cs @@ -0,0 +1,33 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using ModuleManager.Progress; + +namespace ModuleManager.Patches.PassSpecifiers +{ + public class FirstPassSpecifier : IPassSpecifier + { + public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) + { + if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); + if (progress == null) throw new ArgumentNullException(nameof(progress)); + return true; + } + + public string Descriptor => ":FIRST"; + } +} diff --git a/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs similarity index 65% rename from ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs rename to Source/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs index 3256a072..f25e1d94 100644 --- a/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs +++ b/Source/ModuleManager/Patches/PassSpecifiers/ForPassSpecifier.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using ModuleManager.Progress; namespace ModuleManager.Patches.PassSpecifiers diff --git a/Source/ModuleManager/Patches/PassSpecifiers/IPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/IPassSpecifier.cs new file mode 100644 index 00000000..3e062887 --- /dev/null +++ b/Source/ModuleManager/Patches/PassSpecifiers/IPassSpecifier.cs @@ -0,0 +1,27 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using ModuleManager.Progress; + +namespace ModuleManager.Patches.PassSpecifiers +{ + public interface IPassSpecifier + { + bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress); + string Descriptor { get; } + } +} diff --git a/Source/ModuleManager/Patches/PassSpecifiers/InsertPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/InsertPassSpecifier.cs new file mode 100644 index 00000000..f3ff035f --- /dev/null +++ b/Source/ModuleManager/Patches/PassSpecifiers/InsertPassSpecifier.cs @@ -0,0 +1,33 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using ModuleManager.Progress; + +namespace ModuleManager.Patches.PassSpecifiers +{ + public class InsertPassSpecifier : IPassSpecifier + { + public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) + { + if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); + if (progress == null) throw new ArgumentNullException(nameof(progress)); + return true; + } + + public string Descriptor => ":INSERT (initial)"; + } +} diff --git a/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs similarity index 51% rename from ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs rename to Source/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs index e0d4fcc4..2975c6ad 100644 --- a/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs +++ b/Source/ModuleManager/Patches/PassSpecifiers/LastPassSpecifier.cs @@ -1,3 +1,19 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using ModuleManager.Progress; diff --git a/Source/ModuleManager/Patches/PassSpecifiers/LegacyPassSpecifier.cs b/Source/ModuleManager/Patches/PassSpecifiers/LegacyPassSpecifier.cs new file mode 100644 index 00000000..67e7f541 --- /dev/null +++ b/Source/ModuleManager/Patches/PassSpecifiers/LegacyPassSpecifier.cs @@ -0,0 +1,33 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using ModuleManager.Progress; + +namespace ModuleManager.Patches.PassSpecifiers +{ + public class LegacyPassSpecifier : IPassSpecifier + { + public bool CheckNeeds(INeedsChecker needsChecker, IPatchProgress progress) + { + if (needsChecker == null) throw new ArgumentNullException(nameof(needsChecker)); + if (progress == null) throw new ArgumentNullException(nameof(progress)); + return true; + } + + public string Descriptor => ":LEGACY (default)"; + } +} diff --git a/Source/ModuleManager/Patches/PatchCompiler.cs b/Source/ModuleManager/Patches/PatchCompiler.cs new file mode 100644 index 00000000..7c7bd48b --- /dev/null +++ b/Source/ModuleManager/Patches/PatchCompiler.cs @@ -0,0 +1,59 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +using ModuleManager.Logging; + +namespace ModuleManager.Patches +{ + public interface IPatchCompiler + { + IPatch CompilePatch(ProtoPatch protoPatch); + } + + public class PatchCompiler : IPatchCompiler + { + private readonly IBasicLogger log; + public PatchCompiler(IBasicLogger patchLogger) + { + this.log = patchLogger; + } + + public IPatch CompilePatch(ProtoPatch protoPatch) + { + if (protoPatch == null) throw new ArgumentNullException(nameof(protoPatch)); + + switch (protoPatch.command) + { + case Command.Insert: + return new InsertPatch(this.log, protoPatch.urlConfig, protoPatch.nodeType, protoPatch.passSpecifier); + + case Command.Edit: + return new EditPatch(this.log, protoPatch.urlConfig, new NodeMatcher(this.log, protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier); + + case Command.Copy: + return new CopyPatch(this.log, protoPatch.urlConfig, new NodeMatcher(this.log, protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier); + + case Command.Delete: + return new DeletePatch(this.log, protoPatch.urlConfig, new NodeMatcher(this.log, protoPatch.nodeType, protoPatch.nodeName, protoPatch.has), protoPatch.passSpecifier); + + default: + throw new ArgumentException("has an invalid command for a root node: " + protoPatch.command, nameof(protoPatch)); + } + } + } +} diff --git a/ModuleManager/Patches/ProtoPatch.cs b/Source/ModuleManager/Patches/ProtoPatch.cs similarity index 60% rename from ModuleManager/Patches/ProtoPatch.cs rename to Source/ModuleManager/Patches/ProtoPatch.cs index c1ad8572..100945bb 100644 --- a/ModuleManager/Patches/ProtoPatch.cs +++ b/Source/ModuleManager/Patches/ProtoPatch.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using ModuleManager.Patches.PassSpecifiers; namespace ModuleManager.Patches diff --git a/ModuleManager/Patches/ProtoPatchBuilder.cs b/Source/ModuleManager/Patches/ProtoPatchBuilder.cs similarity index 79% rename from ModuleManager/Patches/ProtoPatchBuilder.cs rename to Source/ModuleManager/Patches/ProtoPatchBuilder.cs index 377855fa..2805c4ff 100644 --- a/ModuleManager/Patches/ProtoPatchBuilder.cs +++ b/Source/ModuleManager/Patches/ProtoPatchBuilder.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using ModuleManager.Extensions; using ModuleManager.Patches.PassSpecifiers; using ModuleManager.Progress; @@ -33,18 +49,18 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta if (command == Command.Insert && nodeName != null) { - progress.Error(urlConfig, "name specifier detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "name specifier detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; } if (nodeName == string.Empty) { - progress.Warning(urlConfig, "empty brackets detected on patch name: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "empty brackets detected on patch name: {0}", urlConfig.SafeUrl()); nodeName = null; } if (tagList.PrimaryTag.trailer != null) - progress.Warning(urlConfig, "unrecognized trailer: '" + tagList.PrimaryTag.trailer + "' on: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "unrecognized trailer: '{0}' on: {1}", tagList.PrimaryTag.trailer, urlConfig.SafeUrl()); string needs = null; string has = null; @@ -53,18 +69,18 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta foreach (Tag tag in tagList) { if (tag.trailer != null) - progress.Warning(urlConfig, "unrecognized trailer: '" + tag.trailer + "' on: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "unrecognized trailer: '{0}' on: {1}", tag.trailer, urlConfig.SafeUrl()); if (tag.key.Equals("NEEDS", StringComparison.CurrentCultureIgnoreCase)) { if (needs != null) { - progress.Warning(urlConfig, "more than one :NEEDS tag detected, ignoring all but the first: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "more than one :NEEDS tag detected, ignoring all but the first: {0}", urlConfig.SafeUrl()); continue; } if (string.IsNullOrEmpty(tag.value)) { - progress.Error(urlConfig, "empty :NEEDS tag detected: " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "empty :NEEDS tag detected: {0}", urlConfig.SafeUrl()); error = true; continue; } @@ -75,18 +91,18 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta { if (command == Command.Insert) { - progress.Error(urlConfig, ":HAS detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, ":HAS detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; continue; } if (has != null) { - progress.Warning(urlConfig, "more than one :HAS tag detected, ignoring all but the first: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "more than one :HAS tag detected, ignoring all but the first: {0}", urlConfig.SafeUrl()); continue; } if (string.IsNullOrEmpty(tag.value)) { - progress.Error(urlConfig, "empty :HAS tag detected: " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "empty :HAS tag detected: {0}", urlConfig.SafeUrl()); error = true; continue; } @@ -97,18 +113,18 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta { if (tag.value != null) { - progress.Warning(urlConfig, "value detected on :FIRST tag: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "value detected on :FIRST tag: {0}", urlConfig.SafeUrl()); } if (command == Command.Insert) { - progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; continue; } if (passSpecifier != null) { - progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: {0}", urlConfig.SafeUrl()); continue; } @@ -118,14 +134,14 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta { if (string.IsNullOrEmpty(tag.value)) { - progress.Error(urlConfig, "empty :BEFORE tag detected: " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "empty :BEFORE tag detected: {0}", urlConfig.SafeUrl()); error = true; continue; } if (command == Command.Insert) { - progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; continue; } @@ -141,20 +157,20 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta { if (string.IsNullOrEmpty(tag.value)) { - progress.Error(urlConfig, "empty :FOR tag detected: " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "empty :FOR tag detected: {0}", urlConfig.SafeUrl()); error = true; continue; } if (command == Command.Insert) { - progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; continue; } if (passSpecifier != null) { - progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: {0}", urlConfig.SafeUrl()); continue; } @@ -164,20 +180,20 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta { if (string.IsNullOrEmpty(tag.value)) { - progress.Error(urlConfig, "empty :AFTER tag detected: " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "empty :AFTER tag detected: {0}", urlConfig.SafeUrl()); error = true; continue; } if (command == Command.Insert) { - progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; continue; } if (passSpecifier != null) { - progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: {0}", urlConfig.SafeUrl()); continue; } @@ -187,20 +203,20 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta { if (string.IsNullOrEmpty(tag.value)) { - progress.Error(urlConfig, "empty :LAST tag detected: " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "empty :LAST tag detected: {0}", urlConfig.SafeUrl()); error = true; continue; } if (command == Command.Insert) { - progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; continue; } if (passSpecifier != null) { - progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: {0}", urlConfig.SafeUrl()); continue; } @@ -210,18 +226,18 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta { if (tag.value != null) { - progress.Warning(urlConfig, "value detected on :FINAL tag: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "value detected on :FINAL tag: {0}", urlConfig.SafeUrl()); } if (command == Command.Insert) { - progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): " + urlConfig.SafeUrl()); + progress.Error(urlConfig, "pass specifier detected on insert node (not a patch): {0}", urlConfig.SafeUrl()); error = true; continue; } if (passSpecifier != null) { - progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "more than one pass specifier detected, ignoring all but the first: {0}", urlConfig.SafeUrl()); continue; } @@ -229,7 +245,7 @@ public ProtoPatch Build(UrlDir.UrlConfig urlConfig, Command command, ITagList ta } else { - progress.Warning(urlConfig, "unrecognized tag: '" + tag.key + "' on: " + urlConfig.SafeUrl()); + progress.Warning(urlConfig, "unrecognized tag: '{0}' on: {1}", tag.key, urlConfig.SafeUrl()); } } diff --git a/ModuleManager/PostPatchLoader.cs b/Source/ModuleManager/PostPatchLoader.cs similarity index 66% rename from ModuleManager/PostPatchLoader.cs rename to Source/ModuleManager/PostPatchLoader.cs index d850e4e1..5b9b1dc2 100644 --- a/ModuleManager/PostPatchLoader.cs +++ b/Source/ModuleManager/PostPatchLoader.cs @@ -1,8 +1,22 @@ -using System; -using System.IO; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; -using System.Diagnostics; using System.Reflection; using UnityEngine; using ModuleManager.Extensions; @@ -23,7 +37,8 @@ public class PostPatchLoader : LoadingSystem private static readonly List postPatchCallbacks = new List(); - private readonly IBasicLogger logger = new PrefixLogger("ModuleManager", new UnityLogger(UnityEngine.Debug.unityLogger)); + private readonly IBasicLogger logger = ModLogger.Instance; + private Progress.Timings timings; private bool ready = false; @@ -48,7 +63,9 @@ private void Awake() public override bool IsReady() => ready; + #if !KSP12 public override float LoadWeight() => 0; + #endif public override float ProgressFraction() => 1; @@ -60,20 +77,25 @@ public override void StartLoad() StartCoroutine(Run()); } + internal void Set(Progress.Timings timings) + { + this.timings = timings; + } + private IEnumerator Run() { - Stopwatch waitTimer = new Stopwatch(); - waitTimer.Start(); + while (null == this.timings) yield return null; + + this.timings.Wait.Start(); progressTitle = "ModuleManager: Waiting for patching to finish"; while (databaseConfigs == null) yield return null; - waitTimer.Stop(); - logger.Info("Waited " + ((float)waitTimer.ElapsedMilliseconds / 1000).ToString("F3") + "s for patching to finish"); + this.timings.Wait.Stop(); + logger.Info("Waited {0} for patching to finish", this.timings.Wait); - Stopwatch postPatchTimer = new Stopwatch(); - postPatchTimer.Start(); + this.timings.PostPatching.Start(); progressTitle = "ModuleManager: Applying patched game database"; logger.Info("Applying patched game database"); @@ -92,24 +114,19 @@ private IEnumerator Run() yield return null; +#if false + // Using an dedicated external log is nice. Dumping it into KSP.log breaking the known formats is not. if (File.Exists(logPath)) { - if (ModuleManager.DontCopyLogs) - { - logger.Info("Not dumping log because -mm-dont-copy-logs was set"); - } - else - { - progressTitle = "ModuleManager: Dumping log to KSP log"; - logger.Info("Dumping ModuleManager log to main log"); - logger.Info("\n#### BEGIN MODULEMANAGER LOG ####\n\n\n" + File.ReadAllText(logPath) + "\n\n\n#### END MODULEMANAGER LOG ####"); - } + progressTitle = "ModuleManager: Dumping log to KSP log"; + logger.Info("Dumping ModuleManager log to main log"); + logger.Info("\n#### BEGIN MODULEMANAGER LOG ####\n\n\n" + File.ReadAllText(logPath) + "\n\n\n#### END MODULEMANAGER LOG ####"); } else { logger.Error("ModuleManager log does not exist: " + logPath); } - +#endif yield return null; #if DEBUG @@ -145,7 +162,7 @@ private IEnumerator Run() } catch (Exception e) { - logger.Exception("Exception while running a post patch callback", e); + logger.Exception(e, "Exception while running a post patch callback"); } yield return null; } @@ -164,19 +181,19 @@ private IEnumerator Run() { try { - logger.Info("Calling " + ass.GetName().Name + "." + type.Name + "." + method.Name + "()"); + logger.Info("Calling {0}.{1}.{2}()", ass.GetName().Name, type.Name, method.Name); method.Invoke(null, null); } catch (Exception e) { - logger.Exception("Exception while calling " + ass.GetName().Name + "." + type.Name + "." + method.Name + "()", e); + logger.Exception(e, "Exception while calling {0}.{1}.{3}()", ass.GetName().Name, type.Name, method.Name); } } } } catch (Exception e) { - logger.Exception("Post run call threw an exception in loading " + ass.FullName, e); + logger.Exception(e, "Post run call threw an exception in loading {0}", ass.FullName); } } @@ -191,12 +208,18 @@ private IEnumerator Run() { try { - logger.Info("Calling " + obj.GetType().Name + "." + method.Name + "()"); + logger.Info( + "Calling {0}.{1}()", + obj.GetType().Name, method.Name + ); method.Invoke(obj, null); } catch (Exception e) { - logger.Exception("Exception while calling " + obj.GetType().Name + "." + method.Name + "() :\n", e); + logger.Exception(e, + "Exception while calling {0}.{1}() :", + obj.GetType().Name, method.Name + ); } } } @@ -206,26 +229,23 @@ private IEnumerator Run() if (ModuleManager.dumpPostPatch) ModuleManager.OutputAllConfigs(); - postPatchTimer.Stop(); - logger.Info("Post patch ran in " + ((float)postPatchTimer.ElapsedMilliseconds / 1000).ToString("F3") + "s"); + this.timings.PostPatching.Stop(); + logger.Info("Post patch ran in {0}", this.timings.PostPatching); ready = true; } private void LoadModdedPhysics() { - if (!File.Exists(physicsPath)) + if (PHYSICS_CONFIG.IsLoadable) { - logger.Error("Physics file not found"); - return; + logger.Info("Setting modded physics as the active one"); + PhysicsGlobals.PhysicsDatabaseFilename = PHYSICS_CONFIG.Path; + if (!PhysicsGlobals.Instance.LoadDatabase()) + logger.Info("Something went wrong while setting the active physics config."); } - - logger.Info("Setting modded physics as the active one"); - - PhysicsGlobals.PhysicsDatabaseFilename = physicsFile; - - if (!PhysicsGlobals.Instance.LoadDatabase()) - logger.Error("Something went wrong while setting the active physics config."); + else + logger.Error("Physics file not found"); } } } diff --git a/Source/ModuleManager/Progress/IPatchProgress.cs b/Source/ModuleManager/Progress/IPatchProgress.cs new file mode 100644 index 00000000..086a4942 --- /dev/null +++ b/Source/ModuleManager/Progress/IPatchProgress.cs @@ -0,0 +1,48 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +namespace ModuleManager.Progress +{ + public interface IPatchProgress + { + float ProgressFraction { get; } + + EventVoid OnPatchApplied { get; } + EventData OnPassStarted { get; } + + void Warning(UrlDir.UrlConfig url, string message, params object[] @params); + void ForWithInvalidNeedsWarning(string modName, UrlDir.UrlConfig cfgmod); + void Error(UrlDir.UrlConfig url, string message, params object[] @params); + void Error(string message, params object[] @params); + void Exception(Exception exception, string message, params object[] @params); + void Exception(Exception exception, UrlDir.UrlConfig url, string message, params object[] @params); + void ProcessingTagList(Tags.ITagList tagList, UrlDir.UrlConfig urlConfig); + void NeedsUnsatisfiedRoot(UrlDir.UrlConfig url); + void NeedsUnsatisfiedNode(UrlDir.UrlConfig url, string path); + void NeedsUnsatisfiedValue(UrlDir.UrlConfig url, string path); + void NeedsUnsatisfiedBefore(UrlDir.UrlConfig url); + void NeedsUnsatisfiedFor(UrlDir.UrlConfig url); + void NeedsUnsatisfiedAfter(UrlDir.UrlConfig url); + void ApplyingCopy(IUrlConfigIdentifier original, UrlDir.UrlConfig patch); + void ApplyingDelete(IUrlConfigIdentifier original, UrlDir.UrlConfig patch); + void ApplyingUpdate(IUrlConfigIdentifier original, UrlDir.UrlConfig patch); + void PatchAdded(); + void PatchApplied(); + void PassStarted(IPass pass); + } +} diff --git a/ModuleManager/Progress/PatchProgress.cs b/Source/ModuleManager/Progress/PatchProgress.cs similarity index 53% rename from ModuleManager/Progress/PatchProgress.cs rename to Source/ModuleManager/Progress/PatchProgress.cs index 61fd0d33..79f8e16a 100644 --- a/ModuleManager/Progress/PatchProgress.cs +++ b/Source/ModuleManager/Progress/PatchProgress.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using ModuleManager.Extensions; using ModuleManager.Logging; @@ -23,16 +39,10 @@ public float ProgressFraction public EventVoid OnPatchApplied { get; } = new EventVoid("OnPatchApplied"); public EventData OnPassStarted { get; } = new EventData("OnPassStarted"); - public PatchProgress(IBasicLogger logger) + public PatchProgress(IBasicLogger logger, ProgressCounter counter) { this.logger = logger; - Counter = new ProgressCounter(); - } - - public PatchProgress(IPatchProgress progress, IBasicLogger logger) - { - this.logger = logger; - Counter = progress.Counter; + this.Counter = counter; } public void PatchAdded() @@ -43,25 +53,25 @@ public void PatchAdded() public void PassStarted(IPass pass) { if (pass == null) throw new ArgumentNullException(nameof(pass)); - logger.Info(pass.Name + " pass"); + logger.Info("{0} pass", pass.Name); OnPassStarted.Fire(pass); } public void ApplyingUpdate(IUrlConfigIdentifier original, UrlDir.UrlConfig patch) { - logger.Info($"Applying update {patch.SafeUrl()} to {original.FullUrl}"); + logger.Info("Applying update {0} to {1}", patch.SafeUrl(), original.FullUrl); Counter.patchedNodes.Increment(); } public void ApplyingCopy(IUrlConfigIdentifier original, UrlDir.UrlConfig patch) { - logger.Info($"Applying copy {patch.SafeUrl()} to {original.FullUrl}"); + logger.Info("Applying copy {0} to {1}", patch.SafeUrl(), original.FullUrl); Counter.patchedNodes.Increment(); } public void ApplyingDelete(IUrlConfigIdentifier original, UrlDir.UrlConfig patch) { - logger.Info($"Applying delete {patch.SafeUrl()} to {original.FullUrl}"); + logger.Info("Applying delete {0} to {1}", patch.SafeUrl(), original.FullUrl); Counter.patchedNodes.Increment(); } @@ -71,69 +81,84 @@ public void PatchApplied() OnPatchApplied.Fire(); } + public void ProcessingTagList(Tags.ITagList tagList, UrlDir.UrlConfig url) + { + logger.Detail("Procesing Tag (modname) {0} in file {1} node: {2}", tagList.PrimaryTag, url.parent.url, url.type); + Counter.tagLists.Increment(); + } + public void NeedsUnsatisfiedRoot(UrlDir.UrlConfig url) { - logger.Info($"Deleting root node in file {url.parent.url} node: {url.type} as it can't satisfy its NEEDS"); + logger.Info("Deleting root node in file {0} node: {1} as it can't satisfy its NEEDS", url.parent.url, url.type); Counter.needsUnsatisfied.Increment(); } public void NeedsUnsatisfiedNode(UrlDir.UrlConfig url, string path) { - logger.Info($"Deleting node in file {url.parent.url} subnode: {path} as it can't satisfy its NEEDS"); + logger.Info("Deleting node in file {0} subnode: {0} as it can't satisfy its NEEDS", url.parent.url, path); + Counter.needsUnsatisfied.Increment(); } public void NeedsUnsatisfiedValue(UrlDir.UrlConfig url, string path) { - logger.Info($"Deleting value in file {url.parent.url} value: {path} as it can't satisfy its NEEDS"); + logger.Info("Deleting value in file {0} value: {1} as it can't satisfy its NEEDS", url.parent.url, path); + Counter.needsUnsatisfied.Increment(); } public void NeedsUnsatisfiedBefore(UrlDir.UrlConfig url) { - logger.Info($"Deleting root node in file {url.parent.url} node: {url.type} as it can't satisfy its BEFORE"); + logger.Info("Deleting root node in file {0} node: {1} as it can't satisfy its BEFORE", url.parent.url, url.type); Counter.needsUnsatisfied.Increment(); } public void NeedsUnsatisfiedFor(UrlDir.UrlConfig url) { - logger.Warning($"Deleting root node in file {url.parent.url} node: {url.type} as it can't satisfy its FOR (this shouldn't happen)"); + logger.Warning("Deleting root node in file {0} node: {1} as it can't satisfy its FOR (this shouldn't happen)", url.parent.url, url.type); Counter.needsUnsatisfied.Increment(); } public void NeedsUnsatisfiedAfter(UrlDir.UrlConfig url) { - logger.Info($"Deleting root node in file {url.parent.url} node: {url.type} as it can't satisfy its AFTER"); + logger.Info("Deleting root node in file {0} node: {1} as it can't satisfy its AFTER", url.parent.url, url.type); Counter.needsUnsatisfied.Increment(); } - public void Warning(UrlDir.UrlConfig url, string message) + public void Warning(UrlDir.UrlConfig url, string message, params object[] @params) { Counter.warnings.Increment(); - logger.Warning(message); + logger.Warning(message, @params); RecordWarningFile(url); } - public void Error(UrlDir.UrlConfig url, string message) + public void ForWithInvalidNeedsWarning(string tag, UrlDir.UrlConfig url) + { + Counter.warnings.Increment(); + logger.Warning("Name {0} shouldn't be used both on :FOR and :NEEDS, as :FOR takes precedence rendering :NEEDS innocuous. Check file {1} node: {2}", tag, url.parent.url, url.type); + RecordWarningFile(url); + } + + public void Error(UrlDir.UrlConfig url, string message, params object[] @params) { Counter.errors.Increment(); - logger.Error(message); + logger.Error(message, @params); RecordErrorFile(url); } - public void Error(string message) + public void Error(string message, params object[] @params) { Counter.errors.Increment(); - logger.Error(message); + logger.Error(message, @params); } - public void Exception(string message, Exception exception) + public void Exception(Exception exception, string message, params object[] @params) { Counter.exceptions.Increment(); - logger.Exception(message, exception); + logger.Exception(exception, message, @params); } - public void Exception(UrlDir.UrlConfig url, string message, Exception exception) + public void Exception(Exception exception, UrlDir.UrlConfig url, string message, params object[] @params) { - Exception(message, exception); + Exception(exception, message, @params); RecordErrorFile(url); } diff --git a/Source/ModuleManager/Progress/ProgressCounter.cs b/Source/ModuleManager/Progress/ProgressCounter.cs new file mode 100644 index 00000000..25608831 --- /dev/null +++ b/Source/ModuleManager/Progress/ProgressCounter.cs @@ -0,0 +1,37 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using System.Collections.Generic; +using ModuleManager.Utils; + +namespace ModuleManager.Progress +{ + public class ProgressCounter + { + public readonly Counter totalPatches = new Counter(); + public readonly Counter appliedPatches = new Counter(); + public readonly SetableCounter patchedNodes = new SetableCounter(); + public readonly Counter warnings = new Counter(); + public readonly Counter errors = new Counter(); + public readonly Counter exceptions = new Counter(); + public readonly Counter needsUnsatisfied = new Counter(); + public readonly Counter tagLists = new Counter(); + + public readonly Dictionary warningFiles = new Dictionary(); + public readonly Dictionary errorFiles = new Dictionary(); + } +} diff --git a/Source/ModuleManager/Progress/Timings.cs b/Source/ModuleManager/Progress/Timings.cs new file mode 100644 index 00000000..1e3f17ac --- /dev/null +++ b/Source/ModuleManager/Progress/Timings.cs @@ -0,0 +1,29 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using ModuleManager.Utils; +using KSPe.Util; + +namespace ModuleManager.Progress +{ + public class Timings + { + internal Stopwatch Wait = new Stopwatch(); + internal Stopwatch Patching = new Stopwatch(); + internal Stopwatch PostPatching = new Stopwatch(); + internal Stopwatch ShaCalc = new Stopwatch(); + } +} diff --git a/Source/ModuleManager/Properties/AssemblyInfo.cs b/Source/ModuleManager/Properties/AssemblyInfo.cs new file mode 100644 index 00000000..63498b4d --- /dev/null +++ b/Source/ModuleManager/Properties/AssemblyInfo.cs @@ -0,0 +1,31 @@ +using System.Reflection; + +// Information about this assembly is defined by the following attributes. +// Change them to the values specific to your project. + +[assembly: AssemblyTitle("Module Manager /L")] +[assembly: AssemblyDescription("ModuleManager is mod that let you write patch file that edit other part at load time.")] +[assembly: AssemblyConfiguration("")] +[assembly: AssemblyCompany(ModuleManager.LegalMamboJambo.Company)] +[assembly: AssemblyProduct(ModuleManager.LegalMamboJambo.Product)] +[assembly: AssemblyCopyright(ModuleManager.LegalMamboJambo.Copyright)] +[assembly: AssemblyTrademark(ModuleManager.LegalMamboJambo.Trademark)] +[assembly: AssemblyCulture("")] + +// The assembly version has the format "{Major}.{Minor}.{Build}.{Revision}". +// The form "{Major}.{Minor}.*" will automatically update the build and revision, +// and "{Major}.{Minor}.{Build}.*" will update just the revision. + +[assembly: AssemblyVersion(ModuleManager.Version.Number)] +[assembly: AssemblyFileVersion(ModuleManager.Version.Number)] +[assembly: KSPAssembly("ModuleManager", ModuleManager.Version.major, ModuleManager.Version.minor)] + +// The following attributes are used to specify the signing key for the assembly, +// if desired. See the Mono documentation for more information about signing. + +//[assembly: AssemblyDelaySign(false)] +//[assembly: AssemblyKeyFile("")] + +[assembly: KSPAssemblyDependency("KSPe", 2, 5)] +[assembly: KSPAssemblyDependency("KSPe.UI", 2, 5)] + diff --git a/Source/ModuleManager/Properties/LegalMamboJambo.cs b/Source/ModuleManager/Properties/LegalMamboJambo.cs new file mode 100644 index 00000000..008a69c4 --- /dev/null +++ b/Source/ModuleManager/Properties/LegalMamboJambo.cs @@ -0,0 +1,25 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +namespace ModuleManager +{ + public static class LegalMamboJambo + { + public const string Company = "L Aerospace KSP Division"; + public const string Product = "Module Manager"; + public const string Copyright = "©2018-2026 Lisias"; + public const string Trademark = "Module Manager /L"; + } +} diff --git a/ModuleManager/Properties/Resources.Designer.cs b/Source/ModuleManager/Properties/Resources.Designer.cs similarity index 90% rename from ModuleManager/Properties/Resources.Designer.cs rename to Source/ModuleManager/Properties/Resources.Designer.cs index 43d089d5..8aead968 100644 --- a/ModuleManager/Properties/Resources.Designer.cs +++ b/Source/ModuleManager/Properties/Resources.Designer.cs @@ -9,7 +9,23 @@ //------------------------------------------------------------------------------ namespace ModuleManager.Properties { - using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian using System; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; /// diff --git a/ModuleManager/Properties/Resources.resx b/Source/ModuleManager/Properties/Resources.resx similarity index 100% rename from ModuleManager/Properties/Resources.resx rename to Source/ModuleManager/Properties/Resources.resx diff --git a/Source/ModuleManager/Properties/Version.tt b/Source/ModuleManager/Properties/Version.tt new file mode 100644 index 00000000..b91f47da --- /dev/null +++ b/Source/ModuleManager/Properties/Version.tt @@ -0,0 +1,98 @@ +<# /* This file is licensed under the Do What the F* You Want to Public License ( http://www.wtfpl.net ) + * by LisiasT. http://ksp.lisias.net + * + * You are allowed to copy, modify and use this file unrestrictly. Just don't bother me with ridiculous demands. Please. :) + */ +#> + +<# // from https://docs.microsoft.com/en-us/visualstudio/modeling/walkthrough-generating-code-by-using-text-templates?view=vs-2017 #> +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ output extension=".cs" #> +<#@ import namespace="System.IO" #> +<# + string PROJECT_NAME = "ModuleManager"; + int major = 0; + int minor = 0; + int patch = 0; + int build = 0; + + try + { + string file = this.Host.ResolvePath("../../../" + PROJECT_NAME + #if KSP12 + + ".122" + #else + + "" + #endif + + ".version"); + string text = File.ReadAllText(file); + + { + int i = text.IndexOf("\"VERSION\"", System.StringComparison.Ordinal); + int j = text.IndexOf("}", i + 1, System.StringComparison.Ordinal); + text = text.Substring(i, j-i+1); + } + + try + { + int i = text.IndexOf("\"MAJOR\"", System.StringComparison.Ordinal); + while (!Char.IsNumber(text[i])) ++i; + int j = i; + while (Char.IsNumber(text[j])) ++j; + Int32.TryParse(text.Substring(i,j-i), out major); + } + catch { } + + try + { + int i = text.IndexOf("\"MINOR\"", System.StringComparison.Ordinal); + while (!Char.IsNumber(text[i])) ++i; + int j = i; + while (Char.IsNumber(text[j])) ++j; + Int32.TryParse(text.Substring(i,j-i), out minor); + } + catch { } + + try + { + int i = text.IndexOf("\"PATCH\"", System.StringComparison.Ordinal); + while (!Char.IsNumber(text[i])) ++i; + int j = i; + while (Char.IsNumber(text[j])) ++j; + Int32.TryParse(text.Substring(i,j-i), out patch); + } + catch { } + + try + { + int i = text.IndexOf("\"BUILD\"", System.StringComparison.Ordinal); + while (!Char.IsNumber(text[i])) ++i; + int j = i; + while (Char.IsNumber(text[j])) ++j; + Int32.TryParse(text.Substring(i,j-i), out build); + } + catch { } + } + catch (Exception e) + { + Write("Error: " + e.Message); + } +#> + +// Automatically generated code. Any changes will be lost! +namespace <#= PROJECT_NAME #> +{ + public static class Version + { + public const int major = <#= major #>; + public const int minor = <#= minor #>; + public const int patch = <#= patch #>; + public const int build = <#= build #>; + public const string Number = "<#= major #>.<#= minor #>.<#= patch #>.<#= build #>"; + #if KSP12 + public const string Text = Number + " /L for KSP 1.2.2 Beta"; + #else + public const string Text = Number + " /L"; + #endif + } +} diff --git a/ModuleManager/Properties/cat-1.png b/Source/ModuleManager/Properties/cat-1.png similarity index 100% rename from ModuleManager/Properties/cat-1.png rename to Source/ModuleManager/Properties/cat-1.png diff --git a/ModuleManager/Properties/cat-10.png b/Source/ModuleManager/Properties/cat-10.png similarity index 100% rename from ModuleManager/Properties/cat-10.png rename to Source/ModuleManager/Properties/cat-10.png diff --git a/ModuleManager/Properties/cat-11.png b/Source/ModuleManager/Properties/cat-11.png similarity index 100% rename from ModuleManager/Properties/cat-11.png rename to Source/ModuleManager/Properties/cat-11.png diff --git a/ModuleManager/Properties/cat-12.png b/Source/ModuleManager/Properties/cat-12.png similarity index 100% rename from ModuleManager/Properties/cat-12.png rename to Source/ModuleManager/Properties/cat-12.png diff --git a/ModuleManager/Properties/cat-2.png b/Source/ModuleManager/Properties/cat-2.png similarity index 100% rename from ModuleManager/Properties/cat-2.png rename to Source/ModuleManager/Properties/cat-2.png diff --git a/ModuleManager/Properties/cat-3.png b/Source/ModuleManager/Properties/cat-3.png similarity index 100% rename from ModuleManager/Properties/cat-3.png rename to Source/ModuleManager/Properties/cat-3.png diff --git a/ModuleManager/Properties/cat-4.png b/Source/ModuleManager/Properties/cat-4.png similarity index 100% rename from ModuleManager/Properties/cat-4.png rename to Source/ModuleManager/Properties/cat-4.png diff --git a/ModuleManager/Properties/cat-5.png b/Source/ModuleManager/Properties/cat-5.png similarity index 100% rename from ModuleManager/Properties/cat-5.png rename to Source/ModuleManager/Properties/cat-5.png diff --git a/ModuleManager/Properties/cat-6.png b/Source/ModuleManager/Properties/cat-6.png similarity index 100% rename from ModuleManager/Properties/cat-6.png rename to Source/ModuleManager/Properties/cat-6.png diff --git a/ModuleManager/Properties/cat-7.png b/Source/ModuleManager/Properties/cat-7.png similarity index 100% rename from ModuleManager/Properties/cat-7.png rename to Source/ModuleManager/Properties/cat-7.png diff --git a/ModuleManager/Properties/cat-8.png b/Source/ModuleManager/Properties/cat-8.png similarity index 100% rename from ModuleManager/Properties/cat-8.png rename to Source/ModuleManager/Properties/cat-8.png diff --git a/ModuleManager/Properties/cat-9.png b/Source/ModuleManager/Properties/cat-9.png similarity index 100% rename from ModuleManager/Properties/cat-9.png rename to Source/ModuleManager/Properties/cat-9.png diff --git a/ModuleManager/Properties/rainbow2.png b/Source/ModuleManager/Properties/rainbow2.png similarity index 100% rename from ModuleManager/Properties/rainbow2.png rename to Source/ModuleManager/Properties/rainbow2.png diff --git a/ModuleManager/ProtoUrlConfig.cs b/Source/ModuleManager/ProtoUrlConfig.cs similarity index 65% rename from ModuleManager/ProtoUrlConfig.cs rename to Source/ModuleManager/ProtoUrlConfig.cs index 71f39df3..1578da7d 100644 --- a/ModuleManager/ProtoUrlConfig.cs +++ b/Source/ModuleManager/ProtoUrlConfig.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; namespace ModuleManager { diff --git a/Source/ModuleManager/Startup.cs b/Source/ModuleManager/Startup.cs new file mode 100644 index 00000000..a67847a3 --- /dev/null +++ b/Source/ModuleManager/Startup.cs @@ -0,0 +1,40 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using UnityEngine; + +using ModuleManager.Logging; + +namespace ModuleManager +{ + [KSPAddon(KSPAddon.Startup.Instantly, true)] + internal class Startup : MonoBehaviour + { + private void Start() + { + ModLogger.LOG.force("Version {0}", Version.Text); + #if KSP12 + if (KSPe.Util.KSP.Version.Current != KSPe.Util.KSP.Version.FindByVersion(1,2,2)) + GUI.UnsupportedKSPAlertBox.Show("1.2.2", KSPe.Util.KSP.Version.Current.ToString()); + #else + if (KSPe.Util.KSP.Version.Current < KSPe.Util.KSP.Version.FindByVersion(1,3,0)) + GUI.UnsupportedKSPAlertBox.Show(">= 1.3.0", KSPe.Util.KSP.Version.Current.ToString()); + #endif + } + } + +} diff --git a/ModuleManager/Tags/Tag.cs b/Source/ModuleManager/Tags/Tag.cs similarity index 64% rename from ModuleManager/Tags/Tag.cs rename to Source/ModuleManager/Tags/Tag.cs index 173058a9..5f085aa2 100644 --- a/ModuleManager/Tags/Tag.cs +++ b/Source/ModuleManager/Tags/Tag.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; namespace ModuleManager.Tags { diff --git a/ModuleManager/Tags/TagList.cs b/Source/ModuleManager/Tags/TagList.cs similarity index 59% rename from ModuleManager/Tags/TagList.cs rename to Source/ModuleManager/Tags/TagList.cs index 0744c411..9f75a60a 100644 --- a/ModuleManager/Tags/TagList.cs +++ b/Source/ModuleManager/Tags/TagList.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; using System.Collections.Generic; using System.Linq; diff --git a/ModuleManager/Tags/TagListParser.cs b/Source/ModuleManager/Tags/TagListParser.cs similarity index 89% rename from ModuleManager/Tags/TagListParser.cs rename to Source/ModuleManager/Tags/TagListParser.cs index c9ff1eed..72e91db8 100644 --- a/ModuleManager/Tags/TagListParser.cs +++ b/Source/ModuleManager/Tags/TagListParser.cs @@ -1,6 +1,23 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using ModuleManager.Progress; +using ModuleManager.Extensions; namespace ModuleManager.Tags { @@ -106,7 +123,7 @@ private void ParseTag(string toParse, int start, ref List tags, UrlDir.UrlC else if (c == ':') { if (i == start) - progress.Warning(urlConfig, "extra : detected"); + progress.Warning(urlConfig, String.Format("extra : detected at {0}", urlConfig.SafeUrl())); else tags.Add(new Tag(toParse.Substring(start, i - start), null, null)); diff --git a/ModuleManager/Threading/BackgroundTask.cs b/Source/ModuleManager/Threading/BackgroundTask.cs similarity index 53% rename from ModuleManager/Threading/BackgroundTask.cs rename to Source/ModuleManager/Threading/BackgroundTask.cs index 64891c04..9dd6d9ed 100644 --- a/ModuleManager/Threading/BackgroundTask.cs +++ b/Source/ModuleManager/Threading/BackgroundTask.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Threading; namespace ModuleManager.Threading @@ -20,7 +36,7 @@ void RunAction() } catch (Exception ex) { - status.Error(ex); + status.Finished(ex); } } diff --git a/Source/ModuleManager/Threading/ITaskStatus.cs b/Source/ModuleManager/Threading/ITaskStatus.cs new file mode 100644 index 00000000..135d992f --- /dev/null +++ b/Source/ModuleManager/Threading/ITaskStatus.cs @@ -0,0 +1,28 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +namespace ModuleManager.Threading +{ + public interface ITaskStatus + { + bool IsRunning { get; } + bool IsFinished { get; } + bool IsExitedWithError { get; } + Exception Exception { get; } + } +} diff --git a/ModuleManager/Threading/TaskStatus.cs b/Source/ModuleManager/Threading/TaskStatus.cs similarity index 67% rename from ModuleManager/Threading/TaskStatus.cs rename to Source/ModuleManager/Threading/TaskStatus.cs index 1d2c6b67..cca010c3 100644 --- a/ModuleManager/Threading/TaskStatus.cs +++ b/Source/ModuleManager/Threading/TaskStatus.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; namespace ModuleManager.Threading { @@ -40,7 +56,7 @@ public void Finished() } } - public void Error(Exception exception) + public void Finished(Exception exception) { lock(lockObject) { diff --git a/Source/ModuleManager/Threading/TaskStatusWrapper.cs b/Source/ModuleManager/Threading/TaskStatusWrapper.cs new file mode 100644 index 00000000..207705d4 --- /dev/null +++ b/Source/ModuleManager/Threading/TaskStatusWrapper.cs @@ -0,0 +1,35 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +namespace ModuleManager.Threading +{ + public class TaskStatusWrapper : ITaskStatus + { + private readonly ITaskStatus inner; + + public TaskStatusWrapper(ITaskStatus inner) + { + this.inner = inner; + } + + public bool IsRunning => inner.IsRunning; + public bool IsFinished => inner.IsFinished; + public bool IsExitedWithError => inner.IsExitedWithError; + public Exception Exception => inner.Exception; + } +} diff --git a/Source/ModuleManager/Utils/ConfigNodeEditUtils.cs b/Source/ModuleManager/Utils/ConfigNodeEditUtils.cs new file mode 100644 index 00000000..6e993e45 --- /dev/null +++ b/Source/ModuleManager/Utils/ConfigNodeEditUtils.cs @@ -0,0 +1,167 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using System.Globalization; +using System.Text.RegularExpressions; +using ModuleManager.Collections; + +namespace ModuleManager.Utils +{ + public class ConfigNodeEditUtils + { + private static ConfigNodeEditUtils _instance = null; + public static ConfigNodeEditUtils Instance = _instance??(_instance = new ConfigNodeEditUtils()); + + private readonly KeyValueCache regexCache = new KeyValueCache(); + + private ConfigNodeEditUtils() { } + + public void Destroy() + { + _instance = null; + } + + public string FindAndReplaceValue( + ConfigNode mod, + ref string valName, + string value, + ConfigNode newNode, + Operator op, + int index, + out ConfigNode.Value origVal, + PatchContext context, + bool hasPosIndex = false, + int posIndex = 0, + bool hasPosStar = false, + char seperator = ',' + ) { + origVal = FindValueIn(newNode, valName, index); + if (origVal == null) + return null; + string oValue = origVal.value; + + string[] strArray = new string[] { oValue }; + if (hasPosIndex) + { + strArray = oValue.Split(new char[] { seperator }, StringSplitOptions.RemoveEmptyEntries); + if (posIndex >= strArray.Length) + { + context.progress.Error(context.patchUrl, "Invalid Vector Index!"); + return null; + } + } + string backupValue = value; + while (posIndex < strArray.Length) + { + value = backupValue; + oValue = strArray[posIndex]; + if (op != Operator.Assign) + { + if (op == Operator.RegexReplace) + { + try + { + string[] split = value.Split(value[0]); + + Regex replace = this.Fetch(split[1], delegate + { + return new Regex(split[1]); + }); + + value = replace.Replace(oValue, split[2]); + } + catch (Exception ex) + { + context.progress.Exception(ex, context.patchUrl, + "Error - Failed to do a regexp replacement: {0} : original value=\"{1}\" regexp=\"{2}\" \nNote - to use regexp, the first char is used to subdivide the string (much like sed)", + mod.name, oValue, value + ); + return null; + } + } + else if (double.TryParse(value, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out double s) + && double.TryParse(oValue, NumberStyles.Float, CultureInfo.InvariantCulture.NumberFormat, out double os)) + { + switch (op) + { + case Operator.Multiply: + value = (os * s).ToString(CultureInfo.InvariantCulture); + break; + + case Operator.Divide: + value = (os / s).ToString(CultureInfo.InvariantCulture); + break; + + case Operator.Add: + value = (os + s).ToString(CultureInfo.InvariantCulture); + break; + + case Operator.Subtract: + value = (os - s).ToString(CultureInfo.InvariantCulture); + break; + + case Operator.Exponentiate: + value = Math.Pow(os, s).ToString(CultureInfo.InvariantCulture); + break; + } + } + else + { + context.progress.Error(context.patchUrl, + "Error - Failed to do a maths replacement: {0} : original value=\"{1}\" operator={2} mod value=\"{2}\"", + mod.name, oValue, op, value + ); + return null; + } + } + strArray[posIndex] = value; + if (hasPosStar) posIndex++; + else break; + } + value = String.Join(new string(seperator, 1), strArray); + return value; + } + + public ConfigNode.Value FindValueIn(ConfigNode newNode, string valName, int index) + { + ConfigNode.Value v = null; + for (int i = 0; i < newNode.values.Count; ++i) + { + if (WildcardMatch(newNode.values[i].name, valName)) + { + v = newNode.values[i]; + if (--index < 0) + return v; + } + } + return v; + } + + public bool WildcardMatch(string s, string wildcard) + { + if (wildcard == null) + return true; + string pattern = "^" + Regex.Escape(wildcard).Replace(@"\*", ".*").Replace(@"\?", ".") + "$"; + + Regex regex = ConfigNodeEditUtils.Instance.Fetch(pattern, delegate + { + return new Regex(pattern); + }); + return regex.IsMatch(s); + } + + private Regex Fetch(string key, Func createValue) => this.regexCache.Fetch(key, createValue); + } +} diff --git a/Source/ModuleManager/Utils/Counter.cs b/Source/ModuleManager/Utils/Counter.cs new file mode 100644 index 00000000..7b0b6af6 --- /dev/null +++ b/Source/ModuleManager/Utils/Counter.cs @@ -0,0 +1,44 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; + +namespace ModuleManager.Utils +{ + public class Counter + { + public int Value { get; protected set; } = 0; + + public void Increment() + { + Value++; + } + + public override string ToString() + { + return Value.ToString(); + } + + public static implicit operator int(Counter counter) => counter.Value; + } + + public class SetableCounter:Counter + { + public void Set(int value) { this.Value = value; } + + public static implicit operator int(SetableCounter counter) => counter.Value; + } +} diff --git a/Source/ModuleManager/Utils/FileUtils.cs b/Source/ModuleManager/Utils/FileUtils.cs new file mode 100644 index 00000000..0a6dce63 --- /dev/null +++ b/Source/ModuleManager/Utils/FileUtils.cs @@ -0,0 +1,86 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using System.IO; +using System.Security.Cryptography; +using System.Threading; + +using ModuleManager.Extensions; +using Log = ModuleManager.Logging.ModLogger; + +namespace ModuleManager.Utils +{ + public static class FileUtils + { + public static string FileSHA(string filename) + { + if (!File.Exists(filename)) throw new FileNotFoundException("File does not exist", filename); + + byte[] data = null; + + { + /* + * This one is hairy. Absolutely hairy. + * + * By some reason, pretty powerful rigs are getting screwed by what I think is a race condition (perhaps induced by MM being + * instantiated twice somehow), with the file failing being opened due it being already opened by someone else. + * + * It was postulated that KSP would be the one keeping these files opened. I think it's not because by the time + * Module Manager is started up, KSP had already loaded and resolved every single DLL (and its dependencies) and, so, + * there will be just not a single logic reason to keep them opened in memory - unless KSP is not calling the Dispose + * or not using the `using` construction and, so, we have a file handlers leaking on this damned thing. + * + * In a way or another, the proposed solution on pull/request 180 to the upstream is, IMHO, less than ideal. + * **WE JUST DON'T** open executable files with Writing privileges, **POINT**. At very least, this will prevent anti-virus + * software from being triggered on us, avoiding slowing down KSP's file accesses. + * + * So I will not use `FileShare.ReadWrite` no matter what. I terminantly refuse to do so. + * + * But I had to reconsider and use `FileShare.Read` after doing some benchmarks, as by some reason it's the fastest + * way to open a file under C#, even on a UNIX. + * + * See: + * + https://github.com/sarbian/ModuleManager/pull/180 + * + https://forum.kerbalspaceprogram.com/index.php?/topic/50533-18x-112x-module-manager-422-june-18th-2022-the-heatwave-edition/page/302/#comment-4283448 + * + https://forum.kerbalspaceprogram.com/index.php?/topic/50533-18x-112x-module-manager-422-june-18th-2022-the-heatwave-edition/page/303/#comment-4284427 + * + https://github.com/net-lisias-ksp/KSPe/commit/4fcced165ce72edcf5db2c95311ebafc02d6a921 + */ + Exception ex = null; + int i = 8; // Max wait: 1 second + while (i-- > 0) try + { + using (SHA256 sha = SHA256.Create()) + using (FileStream fs = File.Open(filename, FileMode.Open, FileAccess.Read, FileShare.Read)) + data = sha.ComputeHash(fs); + break; + } + catch (Exception e) + { + ex = e; + Log.LOG.detail("Error {0} on reading {1} on regressive count {2}!", e.Message, filename, i); + GC.Collect(); // For the hypothesis KSP is leaking file handlers + Thread.Sleep(125); // In milliseconds + } + if (0 == i && null != ex) throw ex; + if (null != ex) + Log.LOG.warn("File {0} suffered at least one Exception with message \"{1}\" while being processed. The problem was recovered, but this log was issued to mark the event.", filename, ex.Message); + } + + return data.ToHex(); + } + } +} diff --git a/Source/ModuleManager/Utils/PerformanceMetrics.cs b/Source/ModuleManager/Utils/PerformanceMetrics.cs new file mode 100644 index 00000000..44161ecd --- /dev/null +++ b/Source/ModuleManager/Utils/PerformanceMetrics.cs @@ -0,0 +1,83 @@ +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using UnityEngine; +using KU = KSPe.Util; + +namespace ModuleManager.Utils +{ + /** + * That's the history: + * + * The Loading Scene is taking more time than needed on most cases, due the FramePerSecond settings on Unity. It's a collateal + * effect from the fact that the Coroutines works around the Update, and the Update is called (Standard conditions for temperature + * and pressure) once per frame! + * + * So, by trimming down the FPS or activating the V-Sync, you end up sabotaging your loading times! + * + * This "fixes" the problem by cranking up the FPS to ome absudly high value (to avoid any trimming down by Unity), and then + * restoring the original values once the loading is done. + * + * PROBLEM: The original code already did that, as you can check on the commit this message was added. Exactly **why** this + * thing gave me a small boost is not understood at this moment. On a first though, this should not had happened... + */ + internal class PerformanceMetrics + { + private static PerformanceMetrics INSTANCE; + internal static PerformanceMetrics Instance => INSTANCE ?? (INSTANCE = new PerformanceMetrics()); + + private readonly KU.Stopwatch totalTime = new KU.Stopwatch(); + private readonly int vSyncCount; + private readonly int targetFrameRate; + private readonly bool runInBackground; + + internal bool IsRunning => this.totalTime.IsRunning; + internal float ElapsedTimeInSecs => this.totalTime; + + private PerformanceMetrics() + { + this.vSyncCount = GameSettings.SYNC_VBL; + this.targetFrameRate = GameSettings.FRAMERATE_LIMIT; + this.runInBackground = GameSettings.SIMULATE_IN_BACKGROUND; + Logging.ModLogger.Instance.Log(KU.Log.Level.DETAIL, "PerformanceMetrics: Unity Settings On Constructor: {0} {1} {2}", QualitySettings.vSyncCount, Application.targetFrameRate, Application.runInBackground); + Logging.ModLogger.Instance.Log(KU.Log.Level.DETAIL, "PerformanceMetrics: GameSettings On Constructor: {0} {1} {2}", this.vSyncCount, this.targetFrameRate, this.runInBackground); + } + + internal void Start() + { + if (this.IsRunning) return; // Playing safe + + Application.targetFrameRate = 99999; // What the heck, why not? :D + QualitySettings.vSyncCount = 0; + this.totalTime.Start(); + Logging.ModLogger.Instance.Log(KU.Log.Level.DETAIL, "PerformanceMetrics: Unity Settings On Start: {0} {1} {2}", QualitySettings.vSyncCount, Application.targetFrameRate, Application.runInBackground); + } + + internal void Stop() + { + this.totalTime.Stop(); + Application.targetFrameRate = this.targetFrameRate; // GameSettings.FRAMERATE_LIMIT ? + QualitySettings.vSyncCount = this.vSyncCount; // GameSettings.SYNC_VBL ? + Application.runInBackground = this.runInBackground; // GameSettings.SIMULATE_IN_BACKGROUND ? + Logging.ModLogger.Instance.Log(KU.Log.Level.DETAIL, "PerformanceMetrics: Unity Settings after Stop: {0} {1} {2}", QualitySettings.vSyncCount, Application.targetFrameRate, Application.runInBackground); + } + + internal void Destroy() + { + if (this.IsRunning) this.Stop(); // Playing safe + INSTANCE = null; + Logging.ModLogger.Instance.Log(KU.Log.Level.DETAIL, "PerformanceMetrics: Unity Settings On Destroy: {0} {1} {2}", QualitySettings.vSyncCount, Application.targetFrameRate, Application.runInBackground); + } + } +} diff --git a/ModuleManager/packages.config b/Source/ModuleManager/packages.config similarity index 100% rename from ModuleManager/packages.config rename to Source/ModuleManager/packages.config diff --git a/ModuleManagerTests/Collections/ArrayEnumeratorTest.cs b/Source/ModuleManagerTests/Collections/ArrayEnumeratorTest.cs similarity index 89% rename from ModuleManagerTests/Collections/ArrayEnumeratorTest.cs rename to Source/ModuleManagerTests/Collections/ArrayEnumeratorTest.cs index 7ba5cf64..c2aa9ade 100644 --- a/ModuleManagerTests/Collections/ArrayEnumeratorTest.cs +++ b/Source/ModuleManagerTests/Collections/ArrayEnumeratorTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using Xunit; using ModuleManager.Collections; diff --git a/ModuleManagerTests/Collections/ImmutableStackTest.cs b/Source/ModuleManagerTests/Collections/ImmutableStackTest.cs similarity index 88% rename from ModuleManagerTests/Collections/ImmutableStackTest.cs rename to Source/ModuleManagerTests/Collections/ImmutableStackTest.cs index 56265d45..0e86a24a 100644 --- a/ModuleManagerTests/Collections/ImmutableStackTest.cs +++ b/Source/ModuleManagerTests/Collections/ImmutableStackTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Linq; using Xunit; diff --git a/ModuleManagerTests/Collections/KeyValueCacheTest.cs b/Source/ModuleManagerTests/Collections/KeyValueCacheTest.cs similarity index 72% rename from ModuleManagerTests/Collections/KeyValueCacheTest.cs rename to Source/ModuleManagerTests/Collections/KeyValueCacheTest.cs index 4fc5a9e6..4447b45c 100644 --- a/ModuleManagerTests/Collections/KeyValueCacheTest.cs +++ b/Source/ModuleManagerTests/Collections/KeyValueCacheTest.cs @@ -1,3 +1,19 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using Xunit; using ModuleManager.Collections; diff --git a/ModuleManagerTests/Collections/MessageQueueTest.cs b/Source/ModuleManagerTests/Collections/MessageQueueTest.cs similarity index 68% rename from ModuleManagerTests/Collections/MessageQueueTest.cs rename to Source/ModuleManagerTests/Collections/MessageQueueTest.cs index baf35d20..daa86032 100644 --- a/ModuleManagerTests/Collections/MessageQueueTest.cs +++ b/Source/ModuleManagerTests/Collections/MessageQueueTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager.Collections; diff --git a/ModuleManagerTests/CommandParserTest.cs b/Source/ModuleManagerTests/CommandParserTest.cs similarity index 81% rename from ModuleManagerTests/CommandParserTest.cs rename to Source/ModuleManagerTests/CommandParserTest.cs index fd5d729e..f479bd01 100644 --- a/ModuleManagerTests/CommandParserTest.cs +++ b/Source/ModuleManagerTests/CommandParserTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/Source/ModuleManagerTests/DummyTest.cs b/Source/ModuleManagerTests/DummyTest.cs new file mode 100644 index 00000000..db64fd3a --- /dev/null +++ b/Source/ModuleManagerTests/DummyTest.cs @@ -0,0 +1,30 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using Xunit; + +namespace ModuleManagerTests +{ + public class DummyTest + { + [Fact] + public void PassingTest() + { + Assert.True(true); + } + } +} diff --git a/ModuleManagerTests/Extensions/ByteArrayExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/ByteArrayExtensionsTest.cs similarity index 52% rename from ModuleManagerTests/Extensions/ByteArrayExtensionsTest.cs rename to Source/ModuleManagerTests/Extensions/ByteArrayExtensionsTest.cs index ee53dcc8..7c51fb79 100644 --- a/ModuleManagerTests/Extensions/ByteArrayExtensionsTest.cs +++ b/Source/ModuleManagerTests/Extensions/ByteArrayExtensionsTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager.Extensions; diff --git a/ModuleManagerTests/Extensions/ConfigNodeExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/ConfigNodeExtensionsTest.cs similarity index 95% rename from ModuleManagerTests/Extensions/ConfigNodeExtensionsTest.cs rename to Source/ModuleManagerTests/Extensions/ConfigNodeExtensionsTest.cs index 471be9cb..e00f5915 100644 --- a/ModuleManagerTests/Extensions/ConfigNodeExtensionsTest.cs +++ b/Source/ModuleManagerTests/Extensions/ConfigNodeExtensionsTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Text; using Xunit; using TestUtils; diff --git a/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs similarity index 78% rename from ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs rename to Source/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs index 74e82d88..0dc8ab9a 100644 --- a/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs +++ b/Source/ModuleManagerTests/Extensions/IBasicLoggerExtensionsTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using ModuleManager.Logging; diff --git a/ModuleManagerTests/Extensions/NodeStackExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/NodeStackExtensionsTest.cs similarity index 50% rename from ModuleManagerTests/Extensions/NodeStackExtensionsTest.cs rename to Source/ModuleManagerTests/Extensions/NodeStackExtensionsTest.cs index 2539d10b..cbfef9ed 100644 --- a/ModuleManagerTests/Extensions/NodeStackExtensionsTest.cs +++ b/Source/ModuleManagerTests/Extensions/NodeStackExtensionsTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager.Collections; using ModuleManager.Extensions; diff --git a/ModuleManagerTests/Extensions/StringExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/StringExtensionsTest.cs similarity index 77% rename from ModuleManagerTests/Extensions/StringExtensionsTest.cs rename to Source/ModuleManagerTests/Extensions/StringExtensionsTest.cs index acf9274e..1eb45e47 100644 --- a/ModuleManagerTests/Extensions/StringExtensionsTest.cs +++ b/Source/ModuleManagerTests/Extensions/StringExtensionsTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/ModuleManagerTests/Extensions/UrlConfigExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/UrlConfigExtensionsTest.cs similarity index 90% rename from ModuleManagerTests/Extensions/UrlConfigExtensionsTest.cs rename to Source/ModuleManagerTests/Extensions/UrlConfigExtensionsTest.cs index 953edfe9..1f15f5a0 100644 --- a/ModuleManagerTests/Extensions/UrlConfigExtensionsTest.cs +++ b/Source/ModuleManagerTests/Extensions/UrlConfigExtensionsTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using TestUtils; using ModuleManager.Extensions; diff --git a/ModuleManagerTests/Extensions/UrlDirExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/UrlDirExtensionsTest.cs similarity index 81% rename from ModuleManagerTests/Extensions/UrlDirExtensionsTest.cs rename to Source/ModuleManagerTests/Extensions/UrlDirExtensionsTest.cs index d7ff2316..76c66415 100644 --- a/ModuleManagerTests/Extensions/UrlDirExtensionsTest.cs +++ b/Source/ModuleManagerTests/Extensions/UrlDirExtensionsTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using TestUtils; using ModuleManager.Extensions; diff --git a/Source/ModuleManagerTests/Extensions/UrlFileExtensionsTest.cs b/Source/ModuleManagerTests/Extensions/UrlFileExtensionsTest.cs new file mode 100644 index 00000000..9fa1aaee --- /dev/null +++ b/Source/ModuleManagerTests/Extensions/UrlFileExtensionsTest.cs @@ -0,0 +1,33 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using Xunit; +using TestUtils; +using ModuleManager.Extensions; + +namespace ModuleManagerTests.Extensions +{ + public static class UrlFileExtensionsTest + { + [Fact] + public static void TestGetUrlWithExtension() + { + UrlDir.UrlFile urlFile = UrlBuilder.CreateFile("abc/def/ghi.cfg"); + Assert.Equal("abc/def/ghi.cfg", urlFile.GetUrlWithExtension()); + } + } +} diff --git a/ModuleManagerTests/InGameTestRunnerTest.cs b/Source/ModuleManagerTests/InGameTestRunnerTest.cs similarity index 91% rename from ModuleManagerTests/InGameTestRunnerTest.cs rename to Source/ModuleManagerTests/InGameTestRunnerTest.cs index a75897f4..b397f027 100644 --- a/ModuleManagerTests/InGameTestRunnerTest.cs +++ b/Source/ModuleManagerTests/InGameTestRunnerTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Linq; using Xunit; using NSubstitute; diff --git a/Source/ModuleManagerTests/Logging/ExceptionMessageTest.cs b/Source/ModuleManagerTests/Logging/ExceptionMessageTest.cs new file mode 100644 index 00000000..7ed23718 --- /dev/null +++ b/Source/ModuleManagerTests/Logging/ExceptionMessageTest.cs @@ -0,0 +1,38 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian using System; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 2.0 + along with TweakScale /L. If not, see . +*/ +using System; +using Xunit; +using NSubstitute; +using ModuleManager.Logging; + +namespace ModuleManagerTests.Logging +{ + public class ExceptionMessageTest + { + [Fact] + public void TestLogTo() + { + IBasicLogger logger = Substitute.For(); + + Exception e = new Exception(); + ExceptionMessage message = new ExceptionMessage("An exception was thrown", e); + message.LogTo(logger); + + logger.Received().Exception("An exception was thrown", e); + } + } +} diff --git a/ModuleManagerTests/Logging/LogMessageTest.cs b/Source/ModuleManagerTests/Logging/LogMessageTest.cs similarity index 88% rename from ModuleManagerTests/Logging/LogMessageTest.cs rename to Source/ModuleManagerTests/Logging/LogMessageTest.cs index d70fe8db..526dab9f 100644 --- a/ModuleManagerTests/Logging/LogMessageTest.cs +++ b/Source/ModuleManagerTests/Logging/LogMessageTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using UnityEngine; diff --git a/ModuleManagerTests/Logging/LogSplitterTest.cs b/Source/ModuleManagerTests/Logging/LogSplitterTest.cs similarity index 75% rename from ModuleManagerTests/Logging/LogSplitterTest.cs rename to Source/ModuleManagerTests/Logging/LogSplitterTest.cs index 4135f92d..f42a2a91 100644 --- a/ModuleManagerTests/Logging/LogSplitterTest.cs +++ b/Source/ModuleManagerTests/Logging/LogSplitterTest.cs @@ -1,3 +1,19 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using Xunit; using NSubstitute; diff --git a/Source/ModuleManagerTests/Logging/ModLoggerTest.cs b/Source/ModuleManagerTests/Logging/ModLoggerTest.cs new file mode 100644 index 00000000..1f15558f --- /dev/null +++ b/Source/ModuleManagerTests/Logging/ModLoggerTest.cs @@ -0,0 +1,102 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian using System; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 2.0 + along with TweakScale /L. If not, see . +*/ +using System; +using Xunit; +using NSubstitute; +using UnityEngine; +using ModuleManager.Logging; + +namespace ModuleManagerTests.Logging +{ + public class ModLoggerTest + { + private IBasicLogger innerLogger; + private ModLogger logger; + + public ModLoggerTest() + { + innerLogger = Substitute.For(); + logger = new ModLogger("MyMod", innerLogger); + } + + [Fact] + public void TestConstructor__PrefixNull() + { + ArgumentNullException e = Assert.Throws(delegate + { + new ModLogger(null, innerLogger); + }); + + Assert.Equal("prefix", e.ParamName); + } + + [Fact] + public void TestConstructor__PrefixBlank() + { + ArgumentNullException e = Assert.Throws(delegate + { + new ModLogger("", innerLogger); + }); + + Assert.Equal("prefix", e.ParamName); + } + + [Fact] + public void TestConstructor__LoggerNull() + { + ArgumentNullException e = Assert.Throws(delegate + { + new ModLogger("blah", null); + }); + + Assert.Equal("logger", e.ParamName); + } + + [Fact] + public void TestLog__Info() + { + logger.Log(LogType.Log, "well hi there"); + + innerLogger.Received().Log(LogType.Log, "[MyMod] well hi there"); + } + + [Fact] + public void TestLog__Warning() + { + logger.Log(LogType.Warning, "I'm warning you"); + + innerLogger.Received().Log(LogType.Warning, "[MyMod] I'm warning you"); + } + + [Fact] + public void TestLog__Error() + { + logger.Log(LogType.Error, "You have made a grave mistake"); + + innerLogger.Received().Log(LogType.Error, "[MyMod] You have made a grave mistake"); + } + + [Fact] + public void TestException() + { + Exception e = new Exception(); + logger.Exception("An exception was thrown", e); + + innerLogger.Received().Exception("[MyMod] An exception was thrown", e); + } + } +} diff --git a/Source/ModuleManagerTests/Logging/NormalMessageTest.cs b/Source/ModuleManagerTests/Logging/NormalMessageTest.cs new file mode 100644 index 00000000..7707c99b --- /dev/null +++ b/Source/ModuleManagerTests/Logging/NormalMessageTest.cs @@ -0,0 +1,53 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian using System; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 2.0 + along with TweakScale /L. If not, see . +*/ +using System; +using Xunit; +using NSubstitute; +using UnityEngine; +using ModuleManager.Logging; + +namespace ModuleManagerTests.Logging +{ + public class NormalMessageTest + { + private IBasicLogger logger = Substitute.For(); + + [Fact] + public void TestLogTo__Info() + { + NormalMessage message = new NormalMessage(LogType.Log, "everything is ok"); + message.LogTo(logger); + logger.Received().Log(LogType.Log, "everything is ok"); + } + + [Fact] + public void TestLogTo__Warning() + { + NormalMessage message = new NormalMessage(LogType.Warning, "I'm warning you"); + message.LogTo(logger); + logger.Received().Log(LogType.Warning, "I'm warning you"); + } + + [Fact] + public void TestLogTo__Error() + { + NormalMessage message = new NormalMessage(LogType.Error, "You went too far"); + message.LogTo(logger); + logger.Received().Log(LogType.Error, "You went too far"); + } + } +} diff --git a/ModuleManagerTests/Logging/PrefixLoggerTest.cs b/Source/ModuleManagerTests/Logging/PrefixLoggerTest.cs similarity index 79% rename from ModuleManagerTests/Logging/PrefixLoggerTest.cs rename to Source/ModuleManagerTests/Logging/PrefixLoggerTest.cs index 5aaf0113..2fc51ad2 100644 --- a/ModuleManagerTests/Logging/PrefixLoggerTest.cs +++ b/Source/ModuleManagerTests/Logging/PrefixLoggerTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using UnityEngine; diff --git a/ModuleManagerTests/Logging/QueueLogRunnerTest.cs b/Source/ModuleManagerTests/Logging/QueueLogRunnerTest.cs similarity index 91% rename from ModuleManagerTests/Logging/QueueLogRunnerTest.cs rename to Source/ModuleManagerTests/Logging/QueueLogRunnerTest.cs index 6a975bd2..86f220c9 100644 --- a/ModuleManagerTests/Logging/QueueLogRunnerTest.cs +++ b/Source/ModuleManagerTests/Logging/QueueLogRunnerTest.cs @@ -1,3 +1,19 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using Xunit; using NSubstitute; diff --git a/ModuleManagerTests/Logging/QueueLoggerTest.cs b/Source/ModuleManagerTests/Logging/QueueLoggerTest.cs similarity index 67% rename from ModuleManagerTests/Logging/QueueLoggerTest.cs rename to Source/ModuleManagerTests/Logging/QueueLoggerTest.cs index 25e1abbe..01f447b6 100644 --- a/ModuleManagerTests/Logging/QueueLoggerTest.cs +++ b/Source/ModuleManagerTests/Logging/QueueLoggerTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using ModuleManager.Collections; diff --git a/ModuleManagerTests/Logging/StreamLoggerTest.cs b/Source/ModuleManagerTests/Logging/StreamLoggerTest.cs similarity index 81% rename from ModuleManagerTests/Logging/StreamLoggerTest.cs rename to Source/ModuleManagerTests/Logging/StreamLoggerTest.cs index 296eeac2..86faa214 100644 --- a/ModuleManagerTests/Logging/StreamLoggerTest.cs +++ b/Source/ModuleManagerTests/Logging/StreamLoggerTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.IO; using Xunit; using NSubstitute; diff --git a/ModuleManagerTests/Logging/UnityLoggerTest.cs b/Source/ModuleManagerTests/Logging/UnityLoggerTest.cs similarity index 70% rename from ModuleManagerTests/Logging/UnityLoggerTest.cs rename to Source/ModuleManagerTests/Logging/UnityLoggerTest.cs index 7c4dc4a1..ede5e1dd 100644 --- a/ModuleManagerTests/Logging/UnityLoggerTest.cs +++ b/Source/ModuleManagerTests/Logging/UnityLoggerTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using UnityEngine; diff --git a/ModuleManagerTests/LoggingAssertionHelpers.cs b/Source/ModuleManagerTests/LoggingAssertionHelpers.cs similarity index 84% rename from ModuleManagerTests/LoggingAssertionHelpers.cs rename to Source/ModuleManagerTests/LoggingAssertionHelpers.cs index 74ae5cc4..2979e4a1 100644 --- a/ModuleManagerTests/LoggingAssertionHelpers.cs +++ b/Source/ModuleManagerTests/LoggingAssertionHelpers.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using UnityEngine; using NSubstitute; using ModuleManager.Logging; diff --git a/ModuleManagerTests/MMPatchLoaderTest.cs b/Source/ModuleManagerTests/MMPatchLoaderTest.cs similarity index 90% rename from ModuleManagerTests/MMPatchLoaderTest.cs rename to Source/ModuleManagerTests/MMPatchLoaderTest.cs index b0617fe8..b8f04a1b 100644 --- a/ModuleManagerTests/MMPatchLoaderTest.cs +++ b/Source/ModuleManagerTests/MMPatchLoaderTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Linq; using Xunit; using NSubstitute; diff --git a/ModuleManagerTests/ModuleManagerTests.csproj b/Source/ModuleManagerTests/ModuleManagerTests.csproj similarity index 89% rename from ModuleManagerTests/ModuleManagerTests.csproj rename to Source/ModuleManagerTests/ModuleManagerTests.csproj index f3afbbf5..f09bbaa5 100644 --- a/ModuleManagerTests/ModuleManagerTests.csproj +++ b/Source/ModuleManagerTests/ModuleManagerTests.csproj @@ -1,8 +1,8 @@  - - - + + + Debug @@ -37,33 +37,29 @@ 4 false - - 8.0 - - ..\packages\Castle.Core.4.4.1\lib\net45\Castle.Core.dll + ..\packages\Castle.Core.4.3.1\lib\net45\Castle.Core.dll - - ..\packages\NSubstitute.4.2.2\lib\net46\NSubstitute.dll + + ..\packages\NSubstitute.3.1.0\lib\net46\NSubstitute.dll - - ..\packages\System.Runtime.CompilerServices.Unsafe.5.0.0\lib\net45\System.Runtime.CompilerServices.Unsafe.dll + + ..\packages\System.Runtime.CompilerServices.Unsafe.4.5.2\lib\netstandard2.0\System.Runtime.CompilerServices.Unsafe.dll - - ..\packages\System.Threading.Tasks.Extensions.4.5.4\lib\net461\System.Threading.Tasks.Extensions.dll + + ..\packages\System.Threading.Tasks.Extensions.4.5.1\lib\netstandard2.0\System.Threading.Tasks.Extensions.dll - ..\packages\xunit.abstractions.2.0.3\lib\net35\xunit.abstractions.dll True @@ -159,10 +155,10 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + - - \ No newline at end of file diff --git a/ModuleManagerTests/NeedsCheckerTest.cs b/Source/ModuleManagerTests/NeedsCheckerTest.cs similarity index 96% rename from ModuleManagerTests/NeedsCheckerTest.cs rename to Source/ModuleManagerTests/NeedsCheckerTest.cs index 4d3540b9..08cd8ee6 100644 --- a/ModuleManagerTests/NeedsCheckerTest.cs +++ b/Source/ModuleManagerTests/NeedsCheckerTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; diff --git a/ModuleManagerTests/NodeMatcherTest.cs b/Source/ModuleManagerTests/NodeMatcherTest.cs similarity index 94% rename from ModuleManagerTests/NodeMatcherTest.cs rename to Source/ModuleManagerTests/NodeMatcherTest.cs index 866c69fc..920463df 100644 --- a/ModuleManagerTests/NodeMatcherTest.cs +++ b/Source/ModuleManagerTests/NodeMatcherTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using TestUtils; using ModuleManager; diff --git a/ModuleManagerTests/OperatorParserTest.cs b/Source/ModuleManagerTests/OperatorParserTest.cs similarity index 84% rename from ModuleManagerTests/OperatorParserTest.cs rename to Source/ModuleManagerTests/OperatorParserTest.cs index dfc35d2a..67dea405 100644 --- a/ModuleManagerTests/OperatorParserTest.cs +++ b/Source/ModuleManagerTests/OperatorParserTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager; diff --git a/ModuleManagerTests/PassTest.cs b/Source/ModuleManagerTests/PassTest.cs similarity index 74% rename from ModuleManagerTests/PassTest.cs rename to Source/ModuleManagerTests/PassTest.cs index bc829816..33a72ad3 100644 --- a/ModuleManagerTests/PassTest.cs +++ b/Source/ModuleManagerTests/PassTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Linq; using Xunit; using NSubstitute; diff --git a/ModuleManagerTests/PatchApplierTest.cs b/Source/ModuleManagerTests/PatchApplierTest.cs similarity index 88% rename from ModuleManagerTests/PatchApplierTest.cs rename to Source/ModuleManagerTests/PatchApplierTest.cs index d54ac286..fde4b0db 100644 --- a/ModuleManagerTests/PatchApplierTest.cs +++ b/Source/ModuleManagerTests/PatchApplierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using Xunit; using NSubstitute; diff --git a/ModuleManagerTests/PatchExtractorTest.cs b/Source/ModuleManagerTests/PatchExtractorTest.cs similarity index 96% rename from ModuleManagerTests/PatchExtractorTest.cs rename to Source/ModuleManagerTests/PatchExtractorTest.cs index 49a12583..61a7b8a3 100644 --- a/ModuleManagerTests/PatchExtractorTest.cs +++ b/Source/ModuleManagerTests/PatchExtractorTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; diff --git a/ModuleManagerTests/PatchListTest.cs b/Source/ModuleManagerTests/PatchListTest.cs similarity index 94% rename from ModuleManagerTests/PatchListTest.cs rename to Source/ModuleManagerTests/PatchListTest.cs index 4dc5c751..717ec05f 100644 --- a/ModuleManagerTests/PatchListTest.cs +++ b/Source/ModuleManagerTests/PatchListTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using Xunit; diff --git a/ModuleManagerTests/Patches/CopyPatchTest.cs b/Source/ModuleManagerTests/Patches/CopyPatchTest.cs similarity index 95% rename from ModuleManagerTests/Patches/CopyPatchTest.cs rename to Source/ModuleManagerTests/Patches/CopyPatchTest.cs index ee6443dd..97235f17 100644 --- a/ModuleManagerTests/Patches/CopyPatchTest.cs +++ b/Source/ModuleManagerTests/Patches/CopyPatchTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using Xunit; diff --git a/ModuleManagerTests/Patches/DeletePatchTest.cs b/Source/ModuleManagerTests/Patches/DeletePatchTest.cs similarity index 92% rename from ModuleManagerTests/Patches/DeletePatchTest.cs rename to Source/ModuleManagerTests/Patches/DeletePatchTest.cs index f45916fa..f91be2a5 100644 --- a/ModuleManagerTests/Patches/DeletePatchTest.cs +++ b/Source/ModuleManagerTests/Patches/DeletePatchTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using Xunit; using NSubstitute; diff --git a/ModuleManagerTests/Patches/EditPatchTest.cs b/Source/ModuleManagerTests/Patches/EditPatchTest.cs similarity index 94% rename from ModuleManagerTests/Patches/EditPatchTest.cs rename to Source/ModuleManagerTests/Patches/EditPatchTest.cs index 7c76cf48..f948e0cb 100644 --- a/ModuleManagerTests/Patches/EditPatchTest.cs +++ b/Source/ModuleManagerTests/Patches/EditPatchTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using Xunit; @@ -236,7 +252,7 @@ public void TestApply__Loop() Received.InOrder(delegate { - logger.AssertInfo("Looping on ghi/jkl/@NODE to abc/def.cfg/NODE"); + logger.Log(LogType.Log, "Looping on ghi/jkl/@NODE to abc/def.cfg/NODE"); progress.ApplyingUpdate(urlConfig, patch.UrlConfig); progress.ApplyingUpdate(modifiedUrlConfigs[1], patch.UrlConfig); progress.ApplyingUpdate(modifiedUrlConfigs[2], patch.UrlConfig); diff --git a/ModuleManagerTests/Patches/InsertPatchTest.cs b/Source/ModuleManagerTests/Patches/InsertPatchTest.cs similarity index 92% rename from ModuleManagerTests/Patches/InsertPatchTest.cs rename to Source/ModuleManagerTests/Patches/InsertPatchTest.cs index f1e134a4..3af9473e 100644 --- a/ModuleManagerTests/Patches/InsertPatchTest.cs +++ b/Source/ModuleManagerTests/Patches/InsertPatchTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using Xunit; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs similarity index 84% rename from ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs index 6e086b57..a5a8f71d 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/AfterPassSpecifierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs similarity index 84% rename from ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs index 937da7c2..2689642b 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/BeforePassSpecifierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/FinalPassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/FinalPassSpecifierTest.cs similarity index 71% rename from ModuleManagerTests/Patches/PassSpecifiers/FinalPassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/FinalPassSpecifierTest.cs index 74b90123..3fcec2c4 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/FinalPassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/FinalPassSpecifierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using ModuleManager; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/FirstPassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/FirstPassSpecifierTest.cs similarity index 71% rename from ModuleManagerTests/Patches/PassSpecifiers/FirstPassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/FirstPassSpecifierTest.cs index e8d22151..d5e90f1f 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/FirstPassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/FirstPassSpecifierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using ModuleManager; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs similarity index 84% rename from ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs index cec25628..f5252048 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/ForPassSpecifierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/InsertPassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/InsertPassSpecifierTest.cs similarity index 72% rename from ModuleManagerTests/Patches/PassSpecifiers/InsertPassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/InsertPassSpecifierTest.cs index 9c6cccf1..35f14aa1 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/InsertPassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/InsertPassSpecifierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using ModuleManager; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs similarity index 73% rename from ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs index bdf6bee5..91e899ca 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/LastPassSpecifierTest.cs @@ -1,3 +1,19 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using Xunit; using NSubstitute; diff --git a/ModuleManagerTests/Patches/PassSpecifiers/LegacyPassSpecifierTest.cs b/Source/ModuleManagerTests/Patches/PassSpecifiers/LegacyPassSpecifierTest.cs similarity index 72% rename from ModuleManagerTests/Patches/PassSpecifiers/LegacyPassSpecifierTest.cs rename to Source/ModuleManagerTests/Patches/PassSpecifiers/LegacyPassSpecifierTest.cs index e565655c..3358d237 100644 --- a/ModuleManagerTests/Patches/PassSpecifiers/LegacyPassSpecifierTest.cs +++ b/Source/ModuleManagerTests/Patches/PassSpecifiers/LegacyPassSpecifierTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using ModuleManager; diff --git a/ModuleManagerTests/Patches/PatchCompilerTest.cs b/Source/ModuleManagerTests/Patches/PatchCompilerTest.cs similarity index 95% rename from ModuleManagerTests/Patches/PatchCompilerTest.cs rename to Source/ModuleManagerTests/Patches/PatchCompilerTest.cs index bb786dc5..105a0cdd 100644 --- a/ModuleManagerTests/Patches/PatchCompilerTest.cs +++ b/Source/ModuleManagerTests/Patches/PatchCompilerTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using Xunit; diff --git a/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs b/Source/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs similarity index 98% rename from ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs rename to Source/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs index fd2ff4ab..3ca271d9 100644 --- a/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs +++ b/Source/ModuleManagerTests/Patches/ProtoPatchBuilderTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; diff --git a/ModuleManagerTests/Progress/PatchProgressTest.cs b/Source/ModuleManagerTests/Progress/PatchProgressTest.cs similarity index 76% rename from ModuleManagerTests/Progress/PatchProgressTest.cs rename to Source/ModuleManagerTests/Progress/PatchProgressTest.cs index c78964e3..c4438ce6 100644 --- a/ModuleManagerTests/Progress/PatchProgressTest.cs +++ b/Source/ModuleManagerTests/Progress/PatchProgressTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; @@ -34,8 +50,8 @@ public void Test__Constructor__Nested() progress2.ApplyingUpdate(original, patch1); Assert.Equal(1, progress.Counter.patchedNodes); - logger.AssertNoLog(); - logger2.AssertInfo("Applying update ghi/jkl/@SOME_NODE to abc/def.cfg/SOME_NODE"); + logger.DidNotReceiveWithAnyArgs().Log(LogType.Log, null); + logger2.Received().Log(LogType.Log, "Applying update ghi/jkl/@SOME_NODE to abc/def.cfg/SOME_NODE"); } [Fact] @@ -60,11 +76,11 @@ public void TestApplyingUpdate() progress.ApplyingUpdate(original, patch1); Assert.Equal(1, progress.Counter.patchedNodes); - logger.AssertInfo("Applying update ghi/jkl/@SOME_NODE to abc/def.cfg/SOME_NODE"); + logger.Received().Log(LogType.Log, "Applying update ghi/jkl/@SOME_NODE to abc/def.cfg/SOME_NODE"); progress.ApplyingUpdate(original, patch2); Assert.Equal(2, progress.Counter.patchedNodes); - logger.AssertInfo("Applying update pqr/stu/@SOME_NODE to abc/def.cfg/SOME_NODE"); + logger.Received().Log(LogType.Log, "Applying update pqr/stu/@SOME_NODE to abc/def.cfg/SOME_NODE"); } [Fact] @@ -79,11 +95,11 @@ public void TesApplyingCopy() progress.ApplyingCopy(original, patch1); Assert.Equal(1, progress.Counter.patchedNodes); - logger.AssertInfo("Applying copy ghi/jkl/+SOME_NODE to abc/def.cfg/SOME_NODE"); + logger.Received().Log(LogType.Log, "Applying copy ghi/jkl/+SOME_NODE to abc/def.cfg/SOME_NODE"); progress.ApplyingCopy(original, patch2); Assert.Equal(2, progress.Counter.patchedNodes); - logger.AssertInfo("Applying copy pqr/stu/+SOME_NODE to abc/def.cfg/SOME_NODE"); + logger.Received().Log(LogType.Log, "Applying copy pqr/stu/+SOME_NODE to abc/def.cfg/SOME_NODE"); } [Fact] @@ -98,11 +114,11 @@ public void TesApplyingDelete() progress.ApplyingDelete(original, patch1); Assert.Equal(1, progress.Counter.patchedNodes); - logger.AssertInfo("Applying delete ghi/jkl/!SOME_NODE to abc/def.cfg/SOME_NODE"); + logger.Received().Log(LogType.Log, "Applying delete ghi/jkl/!SOME_NODE to abc/def.cfg/SOME_NODE"); progress.ApplyingDelete(original, patch2); Assert.Equal(2, progress.Counter.patchedNodes); - logger.AssertInfo("Applying delete pqr/stu/!SOME_NODE to abc/def.cfg/SOME_NODE"); + logger.Received().Log(LogType.Log, "Applying delete pqr/stu/!SOME_NODE to abc/def.cfg/SOME_NODE"); } [Fact] @@ -129,11 +145,11 @@ public void TestNeedsUnsatisfiedRoot() progress.NeedsUnsatisfiedRoot(config1); Assert.Equal(1, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its NEEDS"); + logger.Received().Log(LogType.Log, "Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its NEEDS"); progress.NeedsUnsatisfiedRoot(config2); Assert.Equal(2, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its NEEDS"); + logger.Received().Log(LogType.Log, "Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its NEEDS"); } [Fact] @@ -146,11 +162,11 @@ public void TestNeedsUnsatisfiedNode() progress.NeedsUnsatisfiedNode(config1, "SOME/NODE/PATH/SOME_CHILD_NODE"); Assert.Equal(0, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting node in file abc/def subnode: SOME/NODE/PATH/SOME_CHILD_NODE as it can't satisfy its NEEDS"); + logger.Received().Log(LogType.Log, "Deleting node in file abc/def subnode: SOME/NODE/PATH/SOME_CHILD_NODE as it can't satisfy its NEEDS"); progress.NeedsUnsatisfiedNode(config2, "SOME/NODE/PATH/SOME_OTHER_CHILD_NODE"); Assert.Equal(0, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting node in file ghi/jkl subnode: SOME/NODE/PATH/SOME_OTHER_CHILD_NODE as it can't satisfy its NEEDS"); + logger.Received().Log(LogType.Log, "Deleting node in file ghi/jkl subnode: SOME/NODE/PATH/SOME_OTHER_CHILD_NODE as it can't satisfy its NEEDS"); } [Fact] @@ -163,11 +179,11 @@ public void TestNeedsUnsatisfiedValue() progress.NeedsUnsatisfiedValue(config1, "SOME/NODE/PATH/some_value"); Assert.Equal(0, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting value in file abc/def value: SOME/NODE/PATH/some_value as it can't satisfy its NEEDS"); + logger.Received().Log(LogType.Log, "Deleting value in file abc/def value: SOME/NODE/PATH/some_value as it can't satisfy its NEEDS"); progress.NeedsUnsatisfiedValue(config2, "SOME/NODE/PATH/some_other_value"); Assert.Equal(0, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting value in file ghi/jkl value: SOME/NODE/PATH/some_other_value as it can't satisfy its NEEDS"); + logger.Received().Log(LogType.Log, "Deleting value in file ghi/jkl value: SOME/NODE/PATH/some_other_value as it can't satisfy its NEEDS"); } [Fact] @@ -180,11 +196,11 @@ public void TestNeedsUnsatisfiedBefore() progress.NeedsUnsatisfiedBefore(config1); Assert.Equal(1, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its BEFORE"); + logger.Received().Log(LogType.Log, "Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its BEFORE"); progress.NeedsUnsatisfiedBefore(config2); Assert.Equal(2, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its BEFORE"); + logger.Received().Log(LogType.Log, "Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its BEFORE"); } [Fact] @@ -197,11 +213,11 @@ public void TestNeedsUnsatisfiedFor() progress.NeedsUnsatisfiedFor(config1); Assert.Equal(1, progress.Counter.needsUnsatisfied); - logger.AssertWarning("Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its FOR (this shouldn't happen)"); + logger.Received().Log(LogType.Warning, "Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its FOR (this shouldn't happen)"); progress.NeedsUnsatisfiedFor(config2); Assert.Equal(2, progress.Counter.needsUnsatisfied); - logger.AssertWarning("Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its FOR (this shouldn't happen)"); + logger.Received().Log(LogType.Warning, "Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its FOR (this shouldn't happen)"); } [Fact] @@ -214,11 +230,11 @@ public void TestNeedsUnsatisfiedAfter() progress.NeedsUnsatisfiedAfter(config1); Assert.Equal(1, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its AFTER"); + logger.Received().Log(LogType.Log, "Deleting root node in file abc/def node: SOME_NODE as it can't satisfy its AFTER"); progress.NeedsUnsatisfiedAfter(config2); Assert.Equal(2, progress.Counter.needsUnsatisfied); - logger.AssertInfo("Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its AFTER"); + logger.Received().Log(LogType.Log, "Deleting root node in file ghi/jkl node: SOME_OTHER_NODE as it can't satisfy its AFTER"); } [Fact] @@ -231,7 +247,7 @@ public void TestStartingPass() progress.PassStarted(pass1); - logger.AssertInfo(":SOME_PASS pass"); + logger.Received().Log(LogType.Log, ":SOME_PASS pass"); onEvent.Received()(pass1); } @@ -248,7 +264,7 @@ public void TestStartingPass__NullArgument() Assert.Equal("pass", ex.ParamName); - logger.AssertNoLog(); + logger.DidNotReceiveWithAnyArgs().Log(LogType.Log, null); onEvent.DidNotReceiveWithAnyArgs()(null); } @@ -263,12 +279,12 @@ public void TestWarning() progress.Warning(config1, "I'm warning you"); Assert.Equal(1, progress.Counter.warnings); Assert.Equal(1, progress.Counter.warningFiles["abc/def.cfg"]); - logger.AssertWarning("I'm warning you"); + logger.Received().Log(LogType.Warning, "I'm warning you"); progress.Warning(config2, "You should probably pay attention to this"); Assert.Equal(2, progress.Counter.warnings); Assert.Equal(2, progress.Counter.warningFiles["abc/def.cfg"]); - logger.AssertWarning("You should probably pay attention to this"); + logger.Received().Log(LogType.Warning, "You should probably pay attention to this"); } [Fact] @@ -295,12 +311,12 @@ public void TestError__Config() progress.Error(config1, "An error message no one is going to read"); Assert.Equal(1, progress.Counter.errors); Assert.Equal(1, progress.Counter.errorFiles["abc/def.cfg"]); - logger.AssertError("An error message no one is going to read"); + logger.Received().Log(LogType.Error, "An error message no one is going to read"); progress.Error(config2, "Maybe someone will read this one"); Assert.Equal(2, progress.Counter.errors); Assert.Equal(2, progress.Counter.errorFiles["abc/def.cfg"]); - logger.AssertError("Maybe someone will read this one"); + logger.Received().Log(LogType.Error, "Maybe someone will read this one"); } [Fact] @@ -313,11 +329,11 @@ public void TestException() progress.Exception("An exception was thrown", e1); Assert.Equal(1, progress.Counter.exceptions); - logger.AssertException("An exception was thrown", e1); + logger.Received().Exception("An exception was thrown", e1); progress.Exception("An exception was tossed", e2); Assert.Equal(2, progress.Counter.exceptions); - logger.AssertException("An exception was tossed", e2); + logger.Received().Exception("An exception was tossed", e2); } [Fact] @@ -334,12 +350,12 @@ public void TestException__Url() progress.Exception(config1, "An exception was thrown", e1); Assert.Equal(1, progress.Counter.exceptions); Assert.Equal(1, progress.Counter.errorFiles["abc/def.cfg"]); - logger.AssertException("An exception was thrown", e1); + logger.Received().Exception("An exception was thrown", e1); progress.Exception(config2, "An exception was tossed", e2); Assert.Equal(2, progress.Counter.exceptions); Assert.Equal(2, progress.Counter.errorFiles["abc/def.cfg"]); - logger.AssertException("An exception was tossed", e2); + logger.Received().Exception("An exception was tossed", e2); } [Fact] diff --git a/ModuleManagerTests/Properties/AssemblyInfo.cs b/Source/ModuleManagerTests/Properties/AssemblyInfo.cs similarity index 100% rename from ModuleManagerTests/Properties/AssemblyInfo.cs rename to Source/ModuleManagerTests/Properties/AssemblyInfo.cs diff --git a/ModuleManagerTests/ProtoUrlConfigTest.cs b/Source/ModuleManagerTests/ProtoUrlConfigTest.cs similarity index 82% rename from ModuleManagerTests/ProtoUrlConfigTest.cs rename to Source/ModuleManagerTests/ProtoUrlConfigTest.cs index f16cd1bd..cb594b56 100644 --- a/ModuleManagerTests/ProtoUrlConfigTest.cs +++ b/Source/ModuleManagerTests/ProtoUrlConfigTest.cs @@ -1,3 +1,19 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ using System; using Xunit; using TestUtils; diff --git a/ModuleManagerTests/Tags/TagListParserTest.cs b/Source/ModuleManagerTests/Tags/TagListParserTest.cs similarity index 93% rename from ModuleManagerTests/Tags/TagListParserTest.cs rename to Source/ModuleManagerTests/Tags/TagListParserTest.cs index 9ee395d0..5d3761b0 100644 --- a/ModuleManagerTests/Tags/TagListParserTest.cs +++ b/Source/ModuleManagerTests/Tags/TagListParserTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using NSubstitute; using TestUtils; @@ -234,7 +250,7 @@ public void TestParse__TagStartsWithColon() { ITagList tagList = tagListParser.Parse("abc:def::ghi", urlConfig); - progress.Received().Warning(urlConfig, "extra : detected"); + progress.Received().Warning(urlConfig, "extra : detected at {0}".format(urlConfig.SafeUrl())); Assert.Equal(new Tag("abc", null, null), tagList.PrimaryTag); Assert.Equal(new[] { diff --git a/ModuleManagerTests/Tags/TagListTest.cs b/Source/ModuleManagerTests/Tags/TagListTest.cs similarity index 66% rename from ModuleManagerTests/Tags/TagListTest.cs rename to Source/ModuleManagerTests/Tags/TagListTest.cs index 0d3d40dd..c22f0b65 100644 --- a/ModuleManagerTests/Tags/TagListTest.cs +++ b/Source/ModuleManagerTests/Tags/TagListTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager.Tags; diff --git a/ModuleManagerTests/Tags/TagTest.cs b/Source/ModuleManagerTests/Tags/TagTest.cs similarity index 86% rename from ModuleManagerTests/Tags/TagTest.cs rename to Source/ModuleManagerTests/Tags/TagTest.cs index fec92b91..ea49a5fd 100644 --- a/ModuleManagerTests/Tags/TagTest.cs +++ b/Source/ModuleManagerTests/Tags/TagTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager.Tags; diff --git a/ModuleManagerTests/Threading/BackgroundTaskTest.cs b/Source/ModuleManagerTests/Threading/BackgroundTaskTest.cs similarity index 76% rename from ModuleManagerTests/Threading/BackgroundTaskTest.cs rename to Source/ModuleManagerTests/Threading/BackgroundTaskTest.cs index c9ebc594..717a34dd 100644 --- a/ModuleManagerTests/Threading/BackgroundTaskTest.cs +++ b/Source/ModuleManagerTests/Threading/BackgroundTaskTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager.Threading; diff --git a/ModuleManagerTests/Threading/TaskStatusTest.cs b/Source/ModuleManagerTests/Threading/TaskStatusTest.cs similarity index 84% rename from ModuleManagerTests/Threading/TaskStatusTest.cs rename to Source/ModuleManagerTests/Threading/TaskStatusTest.cs index a32983ff..f402bb4f 100644 --- a/ModuleManagerTests/Threading/TaskStatusTest.cs +++ b/Source/ModuleManagerTests/Threading/TaskStatusTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using ModuleManager.Threading; diff --git a/ModuleManagerTests/Utils/CounterTest.cs b/Source/ModuleManagerTests/Utils/CounterTest.cs similarity index 71% rename from ModuleManagerTests/Utils/CounterTest.cs rename to Source/ModuleManagerTests/Utils/CounterTest.cs index 2004e36a..d100c8e6 100644 --- a/ModuleManagerTests/Utils/CounterTest.cs +++ b/Source/ModuleManagerTests/Utils/CounterTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections.Generic; using System.Linq; using System.Text; diff --git a/ModuleManagerTests/app.config b/Source/ModuleManagerTests/app.config similarity index 77% rename from ModuleManagerTests/app.config rename to Source/ModuleManagerTests/app.config index fe205877..1d152980 100644 --- a/ModuleManagerTests/app.config +++ b/Source/ModuleManagerTests/app.config @@ -4,11 +4,11 @@ - + - + diff --git a/ModuleManagerTests/packages.config b/Source/ModuleManagerTests/packages.config similarity index 65% rename from ModuleManagerTests/packages.config rename to Source/ModuleManagerTests/packages.config index b159434d..dc5635be 100644 --- a/ModuleManagerTests/packages.config +++ b/Source/ModuleManagerTests/packages.config @@ -1,9 +1,9 @@  - - - - + + + + @@ -11,6 +11,6 @@ - - + + \ No newline at end of file diff --git a/TestUtils/Properties/AssemblyInfo.cs b/Source/TestUtils/Properties/AssemblyInfo.cs similarity index 100% rename from TestUtils/Properties/AssemblyInfo.cs rename to Source/TestUtils/Properties/AssemblyInfo.cs diff --git a/TestUtils/TestConfigNode.cs b/Source/TestUtils/TestConfigNode.cs similarity index 50% rename from TestUtils/TestConfigNode.cs rename to Source/TestUtils/TestConfigNode.cs index 694fc55e..354113f4 100644 --- a/TestUtils/TestConfigNode.cs +++ b/Source/TestUtils/TestConfigNode.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.Collections; namespace TestUtils diff --git a/TestUtils/TestUtils.csproj b/Source/TestUtils/TestUtils.csproj similarity index 72% rename from TestUtils/TestUtils.csproj rename to Source/TestUtils/TestUtils.csproj index 5c53b27c..96c87a58 100644 --- a/TestUtils/TestUtils.csproj +++ b/Source/TestUtils/TestUtils.csproj @@ -1,10 +1,11 @@  - + Debug AnyCPU {20EAAFE6-510D-4374-8D2F-6B52D0178E85} + ..\..\obj Library Properties TestUtils @@ -17,7 +18,7 @@ true full false - bin\Debug\ + ..\..\bin\Debug\ DEBUG;TRACE prompt 4 @@ -26,24 +27,23 @@ pdbonly true - bin\Release\ + ..\..\bin\Release\ TRACE prompt 4 false - - 8.0 - - - - - - - - - + + + + ..\..\..\..\..\..\LIB\managed\1.4.1\Assembly-CSharp.dll + False + + + ..\..\..\..\..\..\LIB\managed\1.4.1\UnityEngine.dll + False + diff --git a/TestUtils/UrlBuilder.cs b/Source/TestUtils/UrlBuilder.cs similarity index 92% rename from TestUtils/UrlBuilder.cs rename to Source/TestUtils/UrlBuilder.cs index e8e60bd5..03da52ba 100644 --- a/TestUtils/UrlBuilder.cs +++ b/Source/TestUtils/UrlBuilder.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2026 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using System.IO; using System.Linq; using System.Reflection; diff --git a/Source/TestUtilsTests/DummyTest.cs b/Source/TestUtilsTests/DummyTest.cs new file mode 100644 index 00000000..bddda4fc --- /dev/null +++ b/Source/TestUtilsTests/DummyTest.cs @@ -0,0 +1,30 @@ +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; +using Xunit; + +namespace TestUtilsTests +{ + public class DummyTest + { + [Fact] + public void PassingTest() + { + Assert.True(true); + } + } +} diff --git a/TestUtilsTests/Properties/AssemblyInfo.cs b/Source/TestUtilsTests/Properties/AssemblyInfo.cs similarity index 100% rename from TestUtilsTests/Properties/AssemblyInfo.cs rename to Source/TestUtilsTests/Properties/AssemblyInfo.cs diff --git a/TestUtilsTests/TestConfigNodeTest.cs b/Source/TestUtilsTests/TestConfigNodeTest.cs similarity index 82% rename from TestUtilsTests/TestConfigNodeTest.cs rename to Source/TestUtilsTests/TestConfigNodeTest.cs index e544da78..e4a890e5 100644 --- a/TestUtilsTests/TestConfigNodeTest.cs +++ b/Source/TestUtilsTests/TestConfigNodeTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using TestUtils; diff --git a/TestUtilsTests/TestUtilsTests.csproj b/Source/TestUtilsTests/TestUtilsTests.csproj similarity index 90% rename from TestUtilsTests/TestUtilsTests.csproj rename to Source/TestUtilsTests/TestUtilsTests.csproj index cfe71bf2..7391a16f 100644 --- a/TestUtilsTests/TestUtilsTests.csproj +++ b/Source/TestUtilsTests/TestUtilsTests.csproj @@ -1,8 +1,8 @@  - - - + + + Debug @@ -37,9 +37,6 @@ 4 false - - 8.0 - @@ -89,10 +86,10 @@ This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}. + + - - \ No newline at end of file diff --git a/TestUtilsTests/UrlBuilderTest.cs b/Source/TestUtilsTests/UrlBuilderTest.cs similarity index 96% rename from TestUtilsTests/UrlBuilderTest.cs rename to Source/TestUtilsTests/UrlBuilderTest.cs index 38a788f0..599d1450 100644 --- a/TestUtilsTests/UrlBuilderTest.cs +++ b/Source/TestUtilsTests/UrlBuilderTest.cs @@ -1,4 +1,20 @@ -using System; +/* + This file is part of Module Manager /L + © 2018-2023 LisiasT + © 2013-2018 Sarbian; Blowfish + © 2013 ialdabaoth + + Module Manager /L is licensed as follows: + * GPL 3.0 : https://www.gnu.org/licenses/gpl-3.0.txt + + Module Manager /L is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + + You should have received a copy of the GNU General Public License 3.0 + along with Module Manager /L. If not, see . +*/ +using System; using Xunit; using TestUtils; diff --git a/TestUtilsTests/packages.config b/Source/TestUtilsTests/packages.config similarity index 78% rename from TestUtilsTests/packages.config rename to Source/TestUtilsTests/packages.config index 8cf69e4f..bbb4cb82 100644 --- a/TestUtilsTests/packages.config +++ b/Source/TestUtilsTests/packages.config @@ -7,6 +7,6 @@ - - + + \ No newline at end of file diff --git a/TestUtilsTests/DummyTest.cs b/TestUtilsTests/DummyTest.cs deleted file mode 100644 index 815d8fb6..00000000 --- a/TestUtilsTests/DummyTest.cs +++ /dev/null @@ -1,14 +0,0 @@ -using System; -using Xunit; - -namespace TestUtilsTests -{ - public class DummyTest - { - [Fact] - public void PassingTest() - { - Assert.True(true); - } - } -} diff --git a/Tests/ForNeedsSameName.cfg b/Tests/ForNeedsSameName.cfg new file mode 100644 index 00000000..39c9d003 --- /dev/null +++ b/Tests/ForNeedsSameName.cfg @@ -0,0 +1,15 @@ +@PART[HeatShield0]:FOR[forneedstest]:NEEDS[forneedstest] +{ +} + +@PART[HeatShield0]:FOR[forneedstest]:NEEDS[forneedstest,Squad,Something,Else] +{ +} + +@PART[HeatShield0]:FOR[forneedstest]:NEEDS[!forneedstest&Squad|Something,!Else] +{ +} + +@PART[HeatShield0]:FOR[forneedstest]:NEEDS[Squad|!Something] +{ +} diff --git a/check.sh b/check.sh new file mode 100755 index 00000000..8422352f --- /dev/null +++ b/check.sh @@ -0,0 +1,23 @@ +#!/usr/bin/env bash + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' +source ./CONFIG.inc + +echo "LIB = ${LIB}" +echo "PACKAGE = $PACKAGE" +echo "TARGETDIR = $TARGETDIR" +echo "TARGETBINDIR = $TARGETBINDIR" +echo "PROJECTSDIR = $PROJECTSDIR" +echo "DLLS = $DLLS" +echo "PD_DLLS = $PD_DLLS" +echo "PD_SUB_DLLS = $PD_SUB_DLLS" +echo "PD_SUB_DIRS = $PD_SUB_DIRS" +echo "GD_DLLS = $GD_DLLS" +echo "GD_PRIORITY = $GD_PRIORITY" +echo "LIB_DLLS = $LIB_DLLS" +echo "PROJECT_BRANCH = $PROJECT_BRANCH" +echo "PROJECT_STATE = $PROJECT_STATE" +echo "VERSION = $VERSION" +echo "KSP_DEV = $KSP_DEV" diff --git a/clean.sh b/clean.sh new file mode 100755 index 00000000..564174fa --- /dev/null +++ b/clean.sh @@ -0,0 +1,28 @@ +#!/usr/bin/env bash + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' +source ./CONFIG.inc + +clean() { + local DLL=$1.dll + + find ./bin -name "$DLL" -delete + find ./obj -name "$DLL" -delete + rm -f "./GameData/$DLL" + rm -f "./GameData/$TARGETBINDIR/$DLL" + rm -f "$LIB/$DLL" + rm -f "${KSP_DEV}/GameData/$DLL" + rm -f "${KSP_DEV}/GameData/$TARGETBINDIR/$DLL" +} + +VERSIONFILE=$PACKAGE.version + +rm -f "./GameData/$TARGETDIR/$VERSIONFILE" +rm -f "./GameData/$TARGETDIR/CHANGE_LOG.md" +rm -f "./GameData/$TARGETDIR/README.md" +rm -f "./GameData/$TARGETDIR/LICENSE*" +for dll in $DLLS ; do + clean $dll +done diff --git a/deploy-and-run.sh b/deploy-and-run.sh new file mode 100755 index 00000000..8e7e16b8 --- /dev/null +++ b/deploy-and-run.sh @@ -0,0 +1,12 @@ +#!/usr/bin/env bash + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' + +. ./CONFIG.inc +. ./deploy.sh + +echo "Running ${KSP_DEV}" +open ${KSP_DEV}/KSP.app + diff --git a/deploy.sh b/deploy.sh new file mode 100755 index 00000000..053d2030 --- /dev/null +++ b/deploy.sh @@ -0,0 +1,115 @@ +#!/usr/bin/env bash + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' +source ./CONFIG.inc +IFS=$' ' + +check() { + if [ ! -d "./GameData/$TARGETBINDIR/" ] ; then + rm -f "./GameData/$TARGETBINDIR/" + mkdir -p "./GameData/$TARGETBINDIR/" + fi + + for dll in $EXT_DLLS ; do + if [ ! -f "${LIB}/$dll.dll" ] ; then + echo "$dll not found!!! Aborting." + exit -1 + fi + done +} + +deploy_dev() { + local DLL=$1.dll + + if [ -f "./bin/Release/$DLL" ] ; then + cp "./bin/Release/$DLL" "$LIB" + fi +} + +deploy() { + local DLL=$1.dll + + if [ -f "./bin/Release/$DLL" ] ; then + cp -R "./bin/Release/$DLL" "./GameData/$TARGETBINDIR/" + if [ -d "${KSP_DEV}/GameData/$TARGETBINDIR/" ] ; then + cp -R "./bin/Release/$DLL" "${KSP_DEV}/GameData/$TARGETBINDIR/" + fi + fi + if [ -f "./bin/Debug/$DLL" ] ; then + if [ -d "${KSP_DEV}/GameData/$TARGETBINDIR/" ] ; then + cp -R "./bin/Debug/$DLL" "${KSP_DEV}GameData/$TARGETBINDIR/" + fi + fi +} + +deploy_plugindata() { + local DLL=$1.dll + + if [ -f "./bin/Release/$DLL" ] ; then + cp "./bin/Release/$DLL" "./GameData/$TARGETBINDIR/PluginData/" + if [ -d "${KSP_DEV}/GameData/" ] ; then + cp "./bin/Release/$DLL" "${KSP_DEV}GameData/$TARGETBINDIR/PluginData/" + fi + fi + if [ -f "./bin/Debug/$DLL" ] ; then + if [ -d "${KSP_DEV}/GameData/" ] ; then + cp "./bin/Debug/$DLL" "${KSP_DEV}GameData/$TARGETBINDIR/PluginData/" + fi + fi +} + +deploy_gamedata() { + local PLACE=$1 + local DLL=$2.dll + + if [ -f "./bin/Release/$DLL" ] ; then + cp "./bin/Release/$DLL" "./GameData/000_$DLL" + if [ -d "${KSP_DEV}/GameData/" ] ; then + cp "./bin/Release/$DLL" "${KSP_DEV/}GameData/${PLACE}_$DLL" + fi + fi + if [ -f "./bin/Debug/$DLL" ] ; then + if [ -d "${KSP_DEV}/GameData/" ] ; then + cp "./bin/Debug/$DLL" "${KSP_DEV}GameData/${PLACE}_$DLL" + fi + fi +} + +deploy_ext() { + local DLL=$1.dll + + if [ -f "$LIB/$DLL" ] ; then + cp -R "$LIB/$DLL" "./GameData/$TARGETBINDIR/" + if [ -d "${KSP_DEV}/GameData/" ] ; then + cp -R "$LIB/$DLL" "${KSP_DEV/}GameData/$TARGETBINDIR/" + fi + fi +} + +check + +cp $VERSIONFILE "./GameData/$TARGETDIR/" +cp CHANGE_LOG.md "./GameData/$TARGETDIR/" +cp README.md "./GameData/$TARGETDIR/" +cp LICENSE "./GameData/$TARGETDIR/" +cp NOTICE "./GameData/$TARGETDIR/" + +for dll in $GD_DLLS ; do + deploy_dev $dll + deploy_gamedata $GD_PRIORITY $dll +done + +for dll in $PD_DLLS ; do + deploy_plugindata $dll +done + +for dll in $DLLS ; do + deploy_dev $dll + TARGETBINDIR="" deploy $dll +done + +for dll in $EXT_DLLS ; do + deploy_ext $dll +done diff --git a/pack-curse.sh b/pack-curse.sh new file mode 100755 index 00000000..8ee1f979 --- /dev/null +++ b/pack-curse.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +echo "CurseForge packaging is not needed anymore, this thing is being redistributed in 'Modular Management' there." +exit 0 + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' +source ./CONFIG.inc + +clean() { + rm -fR $FILE + if [ ! -d Archive ] ; then + mkdir Archive + fi +} + +pwd=$(pwd) +FILE=${pwd}/Archive/$PACKAGE-$VERSION${PROJECT_STATE}-CurseForge.zip +echo $FILE +clean +cd GameData + +zip -r $FILE ./$PACKAGE/* -x ".*" +zip -d $FILE __MACOSX "**/.DS_Store" +cd $pwd diff --git a/pack-full.sh b/pack-full.sh new file mode 100755 index 00000000..280bcdf9 --- /dev/null +++ b/pack-full.sh @@ -0,0 +1,26 @@ +#!/usr/bin/env bash + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' +source ./CONFIG.inc + +clean() { + rm -fR $FILE + if [ ! -d Archive ] ; then + mkdir Archive + fi +} + +pwd=$(pwd) +FILE=${pwd}/Archive/$PACKAGE-$VERSION${PROJECT_STATE}.zip +echo $FILE +clean +zip -r $FILE ./GameData/* -x ".*" +set +e +zip -r $FILE ./PluginData/* -x ".*" +zip -r $FILE ./Extras/* -x ".*" +zip $FILE INSTALL.md +zip -d $FILE "__MACOSX/*" "**/.DS_Store" +set -e +cd $pwd diff --git a/pack.sh b/pack.sh new file mode 100755 index 00000000..bbb11095 --- /dev/null +++ b/pack.sh @@ -0,0 +1,11 @@ +#!/usr/bin/env bash + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' + +pwd=$(pwd) +./pack-full.sh +cd $pwd +./pack-curse.sh +cd $pwd diff --git a/publish.sh b/publish.sh new file mode 100755 index 00000000..bf31bee5 --- /dev/null +++ b/publish.sh @@ -0,0 +1,29 @@ +#!/usr/bin/env bash + +# see http://redsymbol.net/articles/unofficial-bash-strict-mode/ +set -euo pipefail +IFS=$'\n\t' +source ./CONFIG.inc + +VERSIONFILE=$PACKAGE.version + +deploy_md() { + local MD=$1 + local TARGET=$2 + #![NxMyyTK.png](./PR_material/img/NxMyyTK.png) -> ![NxMyyTK.png](./PR_material/$PACKAGE/img/NxMyyTK.png) + sed $MD -e "s/\\.\\/PR_material\\//.\\/PR_material\\/$PACKAGE\\//g" | ssh -i $SSH_ID $SITE "cat - >$TARGET_CMS_PATH/$TARGET" +} + +deploy_assets() { + local IN_DIR=$1 + local OUT_DIR=$2 + ssh -i $SSH_ID $SITE "mkdir ${TARGET_CONTENT_PATH}$OUT_DIR" + local cur_path=`pwd` + cd $IN_DIR + scp -i $SSH_ID -rp `find . -type f \! -name ".DS_Store" ` "$SITE:${TARGET_CONTENT_PATH}$OUT_DIR" + cd $cur_path +} + +scp -i $SSH_ID ./GameData/$PACKAGE/$VERSIONFILE $SITE:/$TARGET_CONTENT_PATH +deploy_assets ./PR_material ./PR_material/$PACKAGE +deploy_md README.md $PACKAGE.md