diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000..dfa817f --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +patreon: linuxgurugamer diff --git a/.gitignore b/.gitignore index 869c4f7..8408f40 100644 --- a/.gitignore +++ b/.gitignore @@ -1,10 +1,3 @@ -# Build Folders (you can keep bin if you'd like, to store dlls and pdbs) -[Bb]in/ -[Oo]bj/ - -# mstest test results -TestResults - ## Ignore Visual Studio temporary files, build results, and ## files generated by popular Visual Studio add-ons. @@ -15,9 +8,30 @@ TestResults # Build results [Dd]ebug/ +[Dd]ebugPublic/ +[Rr]elease/ x64/ +build/ +bld/ +[Bb]in/ +[Oo]bj/ + +# MSTest test Results +[Tt]est[Rr]esult*/ +[Bb]uild[Ll]og.* + +#NUNIT +*.VisualState.xml +TestResult.xml + +# Build Results of an ATL Project +[Dd]ebugPS/ +[Rr]eleasePS/ +dlldata.c + *_i.c *_p.c +*_i.h *.ilk *.meta *.obj @@ -31,10 +45,17 @@ x64/ *.tli *.tlh *.tmp +*.tmp_proj *.log *.vspscc *.vssscc .builds +*.pidb +*.svclog +*.scc + +# Chutzpah Test files +_Chutzpah* # Visual C++ cache files ipch/ @@ -42,27 +63,47 @@ ipch/ *.ncb *.opensdf *.sdf +*.cachefile # Visual Studio profiler *.psess *.vsp *.vspx +# TFS 2012 Local Workspace +$tf/ + # Guidance Automation Toolkit *.gpState # ReSharper is a .NET coding add-in -_ReSharper* +_ReSharper*/ +*.[Rr]e[Ss]harper +*.DotSettings.user -# Mindbench SASS cache -.sass-cache/ +# JustCode is a .NET coding addin-in +.JustCode + +# TeamCity is a build add-in +_TeamCity* + +# DotCover is a Code Coverage Tool +*.dotCover # NCrunch *.ncrunch* +_NCrunch_* .*crunch*.local.xml -# Installshield output folder -[Ee]xpress +# MightyMoose +*.mm.* +AutoTest.Net/ + +# Web workbench (sass) +.sass-cache/ + +# Installshield output folder +[Ee]xpress/ # DocProject is a documentation generator add-in DocProject/buildhelp/ @@ -75,43 +116,121 @@ DocProject/Help/Html2 DocProject/Help/html # Click-Once directory -publish +publish/ # Publish Web Output -*.Publish.xml +*.[Pp]ublish.xml +*.azurePubxml # NuGet Packages Directory -packages +packages/ +## TODO: If the tool you use requires repositories.config uncomment the next line +#!packages/repositories.config + +# Enable "build/" folder in the NuGet Packages folder since NuGet packages use it for MSBuild targets +# This line needs to be after the ignore of the build folder (and the packages folder if the line above has been uncommented) +!packages/build/ # Windows Azure Build Output -csx +csx/ *.build.csdef # Windows Store app package directory AppPackages/ # Others -sql -TestResults -[Tt]est[Rr]esult* +sql/ *.Cache -ClientBin +ClientBin/ [Ss]tyle[Cc]op.* ~$* +*~ *.dbmdl -Generated_Code #added for RIA/Silverlight projects +*.dbproj.schemaview +*.pfx +*.publishsettings +node_modules/ + +# RIA/Silverlight projects +Generated_Code/ # 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 +UpgradeLog*.htm # SQL Server files -App_Data/*.mdf -App_Data/*.ldf +*.mdf +*.ldf + +# Business Intelligence projects +*.rdl.data +*.bim.layout +*.bim_*.settings + +# Microsoft Fakes +FakesAssemblies/ + +# ========================= +# Operating System Files +# ========================= + +# OSX +# ========================= + +.DS_Store +.AppleDouble +.LSOverride + +# Icon must ends with two \r. +Icon + +# Thumbnails +._* + +# Files that might appear on external disk +.Spotlight-V100 +.Trashes + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk -*.zip -*.bat -[Gg]ame/ -[Rr]elease/ \ No newline at end of file + + +# Windows +# ========================= + +# Windows image file caches +Thumbs.db +ehthumbs.db + +# Folder config file +Desktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# +# Vim files +# +*~ +*.swp +*.dll +*.exe +*.pdb +.vs diff --git a/AVCToolkit/AVCToolkit.csproj b/AVCToolkit/AVCToolkit.csproj index aae7dc3..cf34e90 100644 --- a/AVCToolkit/AVCToolkit.csproj +++ b/AVCToolkit/AVCToolkit.csproj @@ -9,7 +9,7 @@ Properties AVCToolkit AVCToolkit - v3.5 + v4.5 512 @@ -22,6 +22,7 @@ DEBUG;TRACE prompt 4 + false AnyCPU @@ -31,6 +32,7 @@ TRACE prompt 4 + false false @@ -45,35 +47,3 @@ - - - - - - - - - - - - - - $(PostBuildEventDependsOn); - PostBuildMacros; - - del "$(SolutionDir)Release\AVCToolkit\*" /Q -xcopy "$(SolutionDir)Documents\AVCToolkit\*" "$(SolutionDir)Release\AVCToolkit\Documents\*" /E /Y -7z.exe a -tzip -mx3 "$(SolutionDir)Release\AVCToolkit\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Output\AVCToolkit" -7z.exe a -tzip -mx3 "$(SolutionDir)Release\AVCToolkit\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Documents\AVCToolkit\*" - - - del "$(TargetDir)*" /Q - - - \ No newline at end of file diff --git a/AVCToolkit/AVCToolkit.csproj.173 b/AVCToolkit/AVCToolkit.csproj.173 new file mode 100644 index 0000000..5f71882 --- /dev/null +++ b/AVCToolkit/AVCToolkit.csproj.173 @@ -0,0 +1,78 @@ + + + + + Debug + AnyCPU + {FD522EDB-A592-41C8-9342-C3629C18A6AD} + Exe + Properties + AVCToolkit + AVCToolkit + v3.5 + 512 + + + + AnyCPU + true + full + false + ..\Output\AVCToolkit\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + none + true + ..\Output\AVCToolkit\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + $(PostBuildEventDependsOn); + PostBuildMacros; + + + + + + + + + + \ No newline at end of file diff --git a/AVCToolkit/AVCToolkit.csproj.orig b/AVCToolkit/AVCToolkit.csproj.orig new file mode 100644 index 0000000..5f71882 --- /dev/null +++ b/AVCToolkit/AVCToolkit.csproj.orig @@ -0,0 +1,78 @@ + + + + + Debug + AnyCPU + {FD522EDB-A592-41C8-9342-C3629C18A6AD} + Exe + Properties + AVCToolkit + AVCToolkit + v3.5 + 512 + + + + AnyCPU + true + full + false + ..\Output\AVCToolkit\ + DEBUG;TRACE + prompt + 4 + + + AnyCPU + none + true + ..\Output\AVCToolkit\ + TRACE + prompt + 4 + false + + + + + + + + + + + + + + + + + + + + + + + + + + + $(PostBuildEventDependsOn); + PostBuildMacros; + + + + + + + + + + \ No newline at end of file diff --git a/AVCToolkit/Properties/AssemblyInfo.cs b/AVCToolkit/Properties/AssemblyInfo.cs index 880fc09..f11d11e 100644 --- a/AVCToolkit/Properties/AssemblyInfo.cs +++ b/AVCToolkit/Properties/AssemblyInfo.cs @@ -28,7 +28,7 @@ [assembly: AssemblyTitle("AVCToolkit")] [assembly: AssemblyProduct("AVCToolkit")] -[assembly: AssemblyCopyright("Copyright © 2014 CYBUTEK")] +[assembly: AssemblyCopyright("Copyright © 2014 CYBUTEK, Linuxgurugamer 2018")] // Setting ComVisible to false makes the types in this assembly not visible // to COM components. If you need to access a type in this assembly from diff --git a/ChangeLog.txt b/ChangeLog.txt new file mode 100644 index 0000000..256f9e9 --- /dev/null +++ b/ChangeLog.txt @@ -0,0 +1,225 @@ +Changelog + +2.0.0 +MiniAVC-V2 + Renamed MiniAVC to MiniAVC-V2 + All threading removed from MiniAVC + +KSP-AVC +1.4.1.8 + Fixed dummy AVC-dLL in the ZeroMiniAVc from being detected as a duplicate dll + +1.4.1.7 +KSP-AVC + Version bump to verify locations + +1.4.1.6 + Added AssemblyFileVersion + Updated version file for 1.12 + +1.4.1.5 +KSP-AVC + Version bump for Github + +1.1.6.5 +KSP-AVC/AddonInfo + + Add code to ensure that the Min/max are both there, and that they override the KSPVersion if it is there + Added Min/Max functions to VersionInfo + Added FixMissingMinMax after parsing files + + if KSP_VERSION is outside the bounds of KSP_VERSION_MIN and KSP_VERSION_MAX, it will be replaced with the appropriate one. + If only one of the KSP_VERSION_MIN and KSP_VERSION_MAX are specified and KSP_VERSION is specified, then the missing parameter + will be set to either the appropriate min/max against KSP_VERSION + + Disabled the remote overriding local if the versions were identical + + Added some messages to indicate what sort of error occurred + + Updated the "built for" message to be either a single version or a range of versions + + +1.1.6.6 + Fixed crazy numbers being shown when no min or max is specified + Fixed MiniAVC dll + +Test Cases +For all the following, VERSION < remote VERSION. The following cases should all result in an update available message + + KSP_VERSION only + KSPActual == remote KSP_VERSION + + KSP_VERSION & KSP_MIN_VERSION + KSPActual >= remote KSP_MIN_VERSION + + KSP_VERSION & KSP_MAX_VERSION + KSPActual <= remote KSP_MAX_VERSION + + KSP_MIN_VERSION & KSP_MAX_VERSION + KSPActual >= remote KSP_MIN_VERSION && KSPActual <= remote KSP_MAX_VERSION + +1.1.6.7 + Fixed null ref which showed one time when displaying addons + Fixed bug where a missing VERSION would cause the dropdown to cause nullrefs + Removed Min/Max functions to VersionInfno as not needed anymore + Removed FixMissingMinMax after parsing files as not needed anymore + +1.1.6.8 + Fixed issue where KSP_VERSION was missing + +1.1.6.9 + Fixed check of Min/Max being null when displaying error + Added and improved error messages in log + Added code updates to MiniAVC + Deleted dlls + +1.1.6.10 + Fixed when min and max are equal, it was showing a from/to + Added jenkins config for MiniAVC + +1.2.0 + Release + +1.2.0.1 + Re-enabled the remote overriding local if the versions were identical + +1.2.0.2 + Updated version file for all 1.4 + +1.2.0.3 + Fixed MiniAVC.dll to not show the same .version file if there are multiplie copies of the MiniAVC.dll in the path, thanks @HebaruSan + Moved initialization for the Logger class into the Awake() method + Fixed error in full KSP-AVC where it wasn't showing available updates + +1.2.0.4 + Version bump for 1.5 rebuild + +1.2.0.5 + Version bump to fix .version file + +1.3.0 + Thanks to 4x4cheesecake for this: + Added some features to AVC and MiniAVC + + AVC + + Added Compatibility Override incl. GUI + Added Update Frequency + Added command line flag to write just a separate AVC.log + MiniAVC + + -Added Update Frequency + + Compatibility Override + Allows to set a single addon or a range of versions to be compatible with a different KSP version, configurable via GUI. + GUI becomes available after all addons have been checked for updates. Can be accessed via a button in the dropdown addon list or by pressing "modkey + 2". + Mod authors can disallow the override for their mod by adding <"DISALLOW_VERSION_OVERRIDE": true> to the .version file. + Update notifications are not affected! + + Update Frequency + Allows to skip AVC version check for a some time or to disable it at all. Configurable via config file: + + "-1" to disable AVC + "0" to run at each game launch (default) + "x > 0" skip AVC for the next x hours + Logging + Prevent AVC to write into the KSP.log and output_log by adding the command line parameter "-AVC-log-only". + +1.3.0.1 + Fixed reset button not clearing toggles + Fixed toggle not becoming enabled after entering value manually + Fixed issue when MinTimeBetweenAvcRuns > 0, the dropdown list was being shown when it wasn't supposed to + Added new field in config file: STRICT_VERSION, if set true, then the Min and Max versions are ignored. + +1.3.0.2 + Disabled the STRICT_VERSION with a compile-time setting. To enable it, add STRICT to the conditional compilation symbols + Added Sorting for mod names and version numbers. + +1.3.0.3 + Moved default values to addon list + Added toggle button to hide the default values (Advanced Settings) + Decent highlighting of addons on the ignore list (bold and italic) + Fixed: Issue during text input validation + Fixed: Windows don't close after loading a savegame + Some internal code changes (CompatibilityState) + +1.3.0.4 + Added KSP_VERSION_EXCLUDE to allow specific versions to be excluded from being seen as compatible + "KSP_VERSION_EXCLUDE": [ + { "MAJOR": 1, "MINOR": 6, "PATCH": 1 }, + { "MAJOR": 2, "MINOR": 6, "PATCH": 2 } + ] + Added KSP_VERSION_INCLUDE to allow specific versions to be compatible + "KSP_VERSION_INCLUDE": [ + { "MAJOR": 1, "MINOR": 6, "PATCH": 1 }, + { "MAJOR": 2, "MINOR": 6, "PATCH": 2 } + ] + Following from @4x4cheesecake: + -Fixed wrong log entry + -Fix JSON format for DISALLOW_VERSION_OVERRIDE + -Removed obsolete AVC.cfg from "GameData/KSP-AVC". + +1.3.1 + Version bump for 1.7.2 + Updated AssemblyVersion.tt + +1.3.1.1 + MiniAVC update to show correct min version + + Note: still not working ot show an unsupported version, tested on a 1.7.2 system with mod haivng a min of 1.7.3 + +1.4.0.0 + Added InstallChecker to full KSP-AVC + Updated Event.repaint to Event.Repaint in IssueGui.cs, DropDownList.cs + Replaced all WWW with UnityWebRequest + Rebuild both for 1.8 + +1.4.0.1 + Changed install loc for KSP-AVC.dll to Plugins + +1.4.0.2 + Fixed a nasty bug with MiniAVC and KSP 1.8 which was causing the game to crash badly + +1.4.0.3 + Fixed path to textures in full KSP-AVC + +1.4.1 + Replaced Unity web calls with HttpWebRequest calls because Unity is not thread safe + +1.4.1.1 + Shortened the timeout on HttpWebRequest + +1.4.1.2 + Thanks to github user @ccaviness for these: + Update HttpWebRequest Timeout to be 10 seconds, not 10 milliseconds + +1.4.1.3 + Fixed a few more Unity calls, were causing mod to hang when getting changelogs + Disabled all old Kerbalstuff code + +1.4.1.4 + Thanks to Github user @WuphonsReach for this: + Add null check in MiniAVC for kspExcludeVersions + Report which configPath was not found + Removed threading from full AVC, was not working properly with HTTPWebRequest + Added checks for null or empty changelog to avoid exception with empty changelog + Cleaned up error logging, no need to exception for a web error + Moved log into Logs directory for full KSP-AVC + Removed all threading from MiniAVC + Converted UnityWebRequest to HTTPWebRequest in MiniAVC + +1.4.1.5 + Version bump for Github + +1.4.1.6 + Added AssemblyFileVersion + Updated version file for 1.12 + +1.4.1.7 + Version bump to verify locations + +1.4.1.8 + Fixed dummy AVC-dLL in the ZeroMiniAVc from being detected as a duplicate dll + +1.4.1.9 + update to fix install location check \ No newline at end of file diff --git a/GameData/KSP-AVC/CHANGES.txt b/GameData/KSP-AVC/CHANGES.txt new file mode 100644 index 0000000..815ad99 --- /dev/null +++ b/GameData/KSP-AVC/CHANGES.txt @@ -0,0 +1,91 @@ +1.1.6.2 + Build on KSP 1.2.0.1586 + Fixed: URLs are escaped before being processed. + Fixed: UI is destroyed upon entering the Space Centre. This mitigates issues that may cause the progress window to remain visible indefinitely. + +1.1.6.1 + Build on KSP 1.1.0.1230 + +1.1.6.0 + Built on KSP Experimental 1.1.0.1171 + Added: 10-second timeout on invalid URLs. + Added: DevHelper GUI avoidence. + +1.1.5.0 + Added: Remote version files take priority when local/remote add-on versions are the same. + Added: 'Any' type versions are now fully supported. + Added: Wildcards for version fields with '-1'. + Added: New informational toolbar to the top left of the screen, replacing the drop down button. + Added: Toolbar display's the number of installed add-ons that are KSP-AVC ready. + Added: Toolbar has a dynamic list that will allow scrolling when taller than half the game screen height. + Added: Toolbar has a 'Copy to Clipboard' button that will copy the list and environment information (KSP/Unity/OS) to the clipboard. + +1.1.4.3 + Updated for KSP v0.25.0 + Fixed: Typo in AddonInfo.ToString() + Fixed: Bug with empty version files which would cause the top drop down to not work. + +1.1.4.2 + Changed: Done a lot of under the hood refactoring. + Fixed: Bug that would freeze the computer when checking many add-ons. + Fixed: Bug that caused the compatibility display to show as a long thin window. + +1.1.4.1 + Fixed: Log spam. + Fixed: Checking window staying open after displaying the first run / updated window. + +1.1.4.0 + Added: Drop down action menu support allowing for multiple actions per add-on. + Added: Change log support, allowing the player to view the add-on's change log. + Added: Drop down list showing all KSP-AVC ready add-ons on loading and main menu. + Changed: Versions will always have the minimum formatting of 'x.x'. + Fixed: Issue with non-RAW GitHub version file hosting, extending the url formatter. + Fixed: Bug where it would do a re-check when reloading the database. + +1.1.3.1 + Fixed: Game breaking bug. + +1.1.3.0 + Added: GitHub latest release checking. + Added: Version file reading is now case insensitive. + Fixed: Bug in version equality checking. (Now using a custom VersionInfo object). + +1.1.2.0 + Added: Tooltip when hovering over the download button showing the destination URL. + Fixed: Certain situations would cause the root directory to be incorrect. + Fixed: File not found handling solving the lock whilst on the checking display. + +1.1.1.0 + Added: Blanket exception handling and logging. + Added: Logger will flush on destruction and GC finaliser. + Added: Check to remove '/tree/' from github urls. + Changed: Remote checking back to WWW because WebRequest in Mono does not support TLS/SSL. + Changed: Version file search is now limited to just the GameData directory. + Fixed: Possible null refs caused by invalid remote urls. + +1.1.0.0 + Complete re-write of the core code. + Added: Replaced LitJson with embeded MiniJson for compatibility and to reduce dependancies. + Added: Better utilisation of multi-threading. + Added: Check progress window which will show whilst processing. + Changed: Remote version file fetching now uses WebRequest instead of Unity's archaic WWW. + Fixed: Version formatting bug where it did not recognise build numbers in certain cases. + +1.0.4.0 + Added: Url check to fix problems caused by non-raw github .version files. + Added: Logging system now also saves into the standard ksp log file. + Changed: Extended logging system now saves with the associated '.dll' file. + +1.0.3.0 + Updated for KSP version 0.24.2. + Added: Extended logging system that saves to "KSP-AVC.log". + Added: First run checker which will show to indicate a successful install. + Changed: Window is now centred on the screen. + +1.0.2.0 + Updated for KSP version 0.24. + Fixed a small bug with parsing KSP versions. + +1.0.1.0 + Added minimum and maximum KSP version support. + Updates will only be shown if the remote version is compatible with the installed version of KSP. \ No newline at end of file diff --git a/GameData/KSP-AVC/KSP-AVC.version b/GameData/KSP-AVC/KSP-AVC.version new file mode 100644 index 0000000..ac23306 --- /dev/null +++ b/GameData/KSP-AVC/KSP-AVC.version @@ -0,0 +1,25 @@ +{ + "NAME": "KSP-AVC Plugin", + "URL": "http://ksp.spacetux.net/avc/KSP-AVC", + "DOWNLOAD": "https://github.com/linuxgurugamer/KSPAddonVersionChecker/releases", + "GITHUB": { + "USERNAME": "linuxgurugamer", + "REPOSITORY": "KSPAddonVersionChecker" + }, + "VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1, + "BUILD": 8 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 12, + "PATCH": 2 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 12, + "PATCH": 0 + } +} diff --git a/GameData/KSP-AVC/LICENSE.txt b/GameData/KSP-AVC/LICENSE.txt new file mode 100644 index 0000000..94a9ed0 --- /dev/null +++ b/GameData/KSP-AVC/LICENSE.txt @@ -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. + + + Copyright (C) + + 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: + + Copyright (C) + 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 +. diff --git a/GameData/KSP-AVC/README.htm b/GameData/KSP-AVC/README.htm new file mode 100644 index 0000000..8258025 --- /dev/null +++ b/GameData/KSP-AVC/README.htm @@ -0,0 +1,264 @@ + + + + + KSP-AVC Plugin - README + + + + +
+
KSP Add-on Version Checker
+ +
+

Developer

+

CYBUTEK

+
+ +
+

KSP-AVC Ready

+

+ KSP Add-on Version Checker is a standardised system for versioning mods. You can get more information on the + forum thread. +

+
+ +
+

Description

+

+ On starting KSP this plugin will search your game directory for '.version' files. It will then proceed to check each one for version related issues. If any issues are found, an issue monitor will be displayed notifying you of what they are. There are two main types of version issues, with the first being related to the add-on's version and the second being its compatibility with your version of KSP. Some add-ons will also support a download option in their version check. If you require an update of an add-on and it has a download location set, you will be given a button which will open up your default browser and take you there. This could link directly to the .zip file or to a page with details on how to update. Note that you will need to close down KSP, install the updates and then restart KSP for them to work. +

+
+ +
+

Installation

+
    +
  • Copy the 'KSP-AVC' folder into the 'GameData' folder located within your Kerbal Space Program installation directory.
  • +
+
+ +
+

Version File Breakdown

+

+

    +
  • NAME - Required
    + The display name for the add-on.
    +
  • +
  • URL - Optional
    + Location of a remote version file for update checking. +
  • +
  • DOWNLOAD - Optional
    + Web address where the latest version can be downloaded.
    + This is only used from the remote version file. +
  • +
  • CHANGE_LOG - Optional
    + The complete or incremental change log for the add-on.
    + This is only used from the remote version file. +
  • +
  • CHANGE_LOG_URL - Optional
    + Populates the CHANGE_LOG field using the file at this url.
    + This is only used from the remote version file. +
  • +
  • GITHUB - Optional
    + Allows KSP-AVC to do release checks with GitHub including setting a download location if one is not specified.
    + If the latest release version is not equal to the version in the file, an update notification will not appear.
    + This is only used from the remote version file. +
      +
    • USERNAME - Required
      + Your GitHub username. +
    • +
    • REPOSITORY - Required
      + The name of the source repository. +
    • +
    • ALLOW_PRE_RELEASE - Optional
      + Include pre-releases in the latest release search.
      + The default value is false. +
    • +
    +
  • +
  • VERSION - Required
    + The version of the add-on. +
  • +
  • KSP_VERSION - Optional, Required for MIN/MAX
    + Version of KSP that the add-on was made to support. +
  • +
  • KSP_VERSION_MIN - Optional
    + Minimum version of KSP that the add-on supports.
    + Requires KSP_VERSION field to work. +
  • +
  • KSP_VERSION_MAX - Optional
    + Maximum version of KSP that the add-on supports.
    + Requires KSP_VERSION field to work. +
  • +
+
+ For simple management of your version files you can use the KSP-AVC Online website at: ksp-avc.cybutek.net. +

+
+ +
+

Version File Example

+

+ {
+     "NAME":"KSP-AVC",
+     "URL":"http://ksp-avc.cybutek.net/version.php?id=2",
+     "DOWNLOAD":"http://kerbal.curseforge.com/ksp-mods/220462-ksp-avc-add-on-version-checker",
+     "GITHUB":
+     {
+         "USERNAME":"YourGitHubUserName",
+         "REPOSITORY":"YourGitHubRepository",
+         "ALLOW_PRE_RELEASE":false,
+     },
+     "VERSION":
+     {
+         "MAJOR":1,
+         "MINOR":1,
+         "PATCH":0,
+         "BUILD":0
+     },
+     "KSP_VERSION":
+     {
+         "MAJOR":0,
+         "MINOR":24,
+         "PATCH":2
+     },
+     "KSP_VERSION_MIN":
+     {
+         "MAJOR":0,
+         "MINOR":24,
+         "PATCH":0
+     },
+     "KSP_VERSION_MAX":
+     {
+         "MAJOR":0,
+         "MINOR":24,
+         "PATCH":2
+     }
+ } +

+
+ +
+

Change Log

+ +
+ +
+

Software License

+

+ Licensed under the GNU General Public License v3. +

+
+ + +
+ +
+ README design by CYBUTEK (GPLv3) +
+ + \ No newline at end of file diff --git a/GameData/KSP-AVC/Textures/DropDownActive.png b/GameData/KSP-AVC/Textures/DropDownActive.png new file mode 100644 index 0000000..7a9fed0 Binary files /dev/null and b/GameData/KSP-AVC/Textures/DropDownActive.png differ diff --git a/GameData/KSP-AVC/Textures/DropDownBackground.png b/GameData/KSP-AVC/Textures/DropDownBackground.png new file mode 100644 index 0000000..402cdae Binary files /dev/null and b/GameData/KSP-AVC/Textures/DropDownBackground.png differ diff --git a/GameData/KSP-AVC/Textures/DropDownHover.png b/GameData/KSP-AVC/Textures/DropDownHover.png new file mode 100644 index 0000000..cdf02e2 Binary files /dev/null and b/GameData/KSP-AVC/Textures/DropDownHover.png differ diff --git a/GameData/KSP-AVC/Textures/DropDownNormal.png b/GameData/KSP-AVC/Textures/DropDownNormal.png new file mode 100644 index 0000000..178c8a5 Binary files /dev/null and b/GameData/KSP-AVC/Textures/DropDownNormal.png differ diff --git a/GameData/KSP-AVC/Textures/DropDownOnHover.png b/GameData/KSP-AVC/Textures/DropDownOnHover.png new file mode 100644 index 0000000..17ff50a Binary files /dev/null and b/GameData/KSP-AVC/Textures/DropDownOnHover.png differ diff --git a/GameData/KSP-AVC/Textures/DropDownOnNormal.png b/GameData/KSP-AVC/Textures/DropDownOnNormal.png new file mode 100644 index 0000000..f65afbf Binary files /dev/null and b/GameData/KSP-AVC/Textures/DropDownOnNormal.png differ diff --git a/GameData/KSP-AVC/Textures/OverlayBackground.png b/GameData/KSP-AVC/Textures/OverlayBackground.png new file mode 100644 index 0000000..2bbad42 Binary files /dev/null and b/GameData/KSP-AVC/Textures/OverlayBackground.png differ diff --git a/GameData/MiniAVC-V2/Plugins/placeholder.txt b/GameData/MiniAVC-V2/Plugins/placeholder.txt new file mode 100644 index 0000000..e69de29 diff --git a/KSP-AVC.schema.json b/KSP-AVC.schema.json new file mode 100644 index 0000000..6e5a0cf --- /dev/null +++ b/KSP-AVC.schema.json @@ -0,0 +1,172 @@ +{ + "$schema": "http://json-schema.org/draft-04/schema#", + "title": "Add-on Version Checker file", + "description": "A KSP-AVC version file's content", + "type": "object", + "properties": { + "NAME": { + "description": "The display name for the add-on", + "type": "string" + }, + "URL": { + "description": "Location of a remote version file for update checking", + "type": "string", + "format": "uri" + }, + "DOWNLOAD": { + "description": "Web address where the latest version can be downloaded", + "type": "string", + "format": "uri" + }, + "CHANGE_LOG": { + "description": "The complete or incremental change log for the add-on", + "type": "string" + }, + "CHANGE_LOG_URL": { + "description": "Populates the CHANGE_LOG field using the file at this url", + "type": "string", + "format": "uri" + }, + "GITHUB": { + "description": "Allows KSP-AVC to do release checks with GitHub including setting a download location if one is not specified. If the latest release version is not equal to the version in the file, an update notification will not appear.", + "type": "object", + "properties": { + "USERNAME ": { + "description": "Your GitHub username", + "type": "string" + }, + "REPOSITORY ": { + "description": "The name of the source repository", + "type": "string" + }, + "ALLOW_PRE_RELEASE ": { + "description": "Include pre-releases in the latest release search", + "type": "boolean" + } + }, + "required": [ + "USERNAME", + "REPOSITORY" + ] + }, + "KERBAL_STUFF_URL": { + "description": "URL to this mod's page on KerbalStuff", + "type": "string", + "format": "uri" + }, + "VERSION": { + "description": "The version of the add-on", + "$ref": "#/definitions/version" + }, + "KSP_VERSION": { + "description": "Version of KSP that the add-on was made to support", + "$ref": "#/definitions/version" + }, + "KSP_VERSION_MIN": { + "description": "Minimum version of KSP that the add-on supports", + "$ref": "#/definitions/version" + }, + "KSP_VERSION_MAX": { + "description": "Maximum version of KSP that the add-on supports", + "$ref": "#/definitions/version" + }, + "DISALLOW_VERSION_OVERRIDE": { + "type": "boolean", + "description": "If true, don't trust KSP-AVC's idea of which game versions are compatible with which other game versions, based on user configuration" + }, + "ASSEMBLY_NAME": { + "type": "string", + "description": "DO NOT USE, won't work with CKAN; name of a DLL to check for VERSION on the fly" + }, + "KSP_VERSION_INCLUDE": { + "description": "DO NOT USE, won't work with CKAN; a list of versions with which this mod is compatible", + "type": "array", + "items": { + "$ref": "#/definitions/version" + }, + "uniqueItems": true + }, + "KSP_VERSION_EXCLUDE": { + "description": "DO NOT USE, won't work with CKAN; a list of versions with which this mod is incompatible", + "type": "array", + "items": { + "$ref": "#/definitions/version" + }, + "uniqueItems": true + }, + "LOCAL_HAS_PRIORITY": { + "type": "boolean", + "description": "DO NOT USE, won't work with CKAN; if true, don't override properties using the remote version file" + }, + "REMOTE_HAS_PRIORITY": { + "type": "boolean", + "description": "DO NOT USE, won't work with CKAN; if false, don't override properties using the remote version file" + }, + "INSTALL_LOC|INSTALL_LOC*": { + "description": "Stanza to define file location to check, used by MADLAD", + "$ref": "#/definitions/install_loc" + } + }, + "required": [ + "NAME", + "VERSION" + ], + "definitions": { + "version": { + "description": "A semantic(?) version", + "anyOf": [ + { + "type": "string", + "pattern": "^(any|[0-9]+\\.[0-9]+(\\.[0-9]+)?)$" + }, + { + "type": "object", + "properties": { + "MAJOR": { + "description": "Change major version when you make incompatible API changes", + "type": "integer" + }, + "MINOR": { + "description": "Change minor version when you add functionality in a backwards-compatible manner", + "type": "integer" + }, + "PATCH": { + "description": "Change patch version when you make backwards-compatible bug fixes", + "type": "integer" + }, + "BUILD": { + "description": "Build informaion", + "type": "integer" + } + }, + "required": [ + "MAJOR" + ] + } + ] + }, + "install_loc": { + "description": "definition of the install_loc fields", + "NAME": { + "type": "string", + "description": "Name of the mod, If not specified, uses the Modname from the .version file" + }, + "PATH": { + "type": "string", + "description": "Path to the directory, begins below the GameData. Must be there, but will be empty in most cases" + }, + "DIRECTORY": { + "type": "string", + "description": "Directory where file is" + }, + "FILE": { + "type": "string", + "description": "filename to be checked. If not specified, then it checks for the directory only" + }, + "required": [ + "PATH", + "DIRECTORY" + ] + } + } +} diff --git a/KSP-AVC.sln b/KSP-AVC.sln index 6dbb497..906564d 100644 --- a/KSP-AVC.sln +++ b/KSP-AVC.sln @@ -1,14 +1,43 @@  Microsoft Visual Studio Solution File, Format Version 12.00 -# Visual Studio 2013 -VisualStudioVersion = 12.0.30110.0 +# Visual Studio Version 16 +VisualStudioVersion = 16.0.30204.135 MinimumVisualStudioVersion = 10.0.40219.1 Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KSP-AVC", "KSP-AVC\KSP-AVC.csproj", "{F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniAVC", "MiniAVC\MiniAVC.csproj", "{F1351BAB-76F1-41DE-B01C-496163CB44D8}" +Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniAVC-V2", "MiniAVC-V2\MiniAVC-V2.csproj", "{F1351BAB-76F1-41DE-B01C-496163CB44D8}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "AVCToolkit", "AVCToolkit\AVCToolkit.csproj", "{FD522EDB-A592-41C8-9342-C3629C18A6AD}" EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{6DF0E8C4-1D1F-40BA-A655-FF074C24FE50}" + ProjectSection(SolutionItems) = preProject + buildRelease.bat = buildRelease.bat + ChangeLog.txt = ChangeLog.txt + deploy.bat = deploy.bat + jenkins.txt = jenkins.txt + jenkinsMiniAVC.txt = jenkinsMiniAVC.txt + KSP-AVC.version = KSP-AVC.version + MiniAVC-V2.version = MiniAVC-V2.version + TODO.txt = TODO.txt + EndProjectSection +EndProject +Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "TestCases", "TestCases", "{34AF4147-05C0-43DB-B9C4-9D2162560CAE}" + ProjectSection(SolutionItems) = preProject + TestCases\KspMaxVersion.version = TestCases\KspMaxVersion.version + TestCases\KspMaxVersion1.version = TestCases\KspMaxVersion1.version + TestCases\KspMaxVersion2.version = TestCases\KspMaxVersion2.version + TestCases\KspMinMaxVersion.version = TestCases\KspMinMaxVersion.version + TestCases\KspMinMaxVersion1.version = TestCases\KspMinMaxVersion1.version + TestCases\KspMinMaxVersion2.version = TestCases\KspMinMaxVersion2.version + TestCases\KspMinMaxVersion3.version = TestCases\KspMinMaxVersion3.version + TestCases\KspMinVersion.version = TestCases\KspMinVersion.version + TestCases\KspMinVersion1.version = TestCases\KspMinVersion1.version + TestCases\KspMinVersion2.version = TestCases\KspMinVersion2.version + TestCases\KspVersion.version = TestCases\KspVersion.version + TestCases\KspVersion1.version = TestCases\KspVersion1.version + TestCases\KspVersion2.version = TestCases\KspVersion2.version + EndProjectSection +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -31,4 +60,7 @@ Global GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE EndGlobalSection + GlobalSection(ExtensibilityGlobals) = postSolution + SolutionGuid = {C215420A-C972-49E5-B498-3C8E2BC4C6D5} + EndGlobalSection EndGlobal diff --git a/KSP-AVC.version b/KSP-AVC.version new file mode 100644 index 0000000..583249d --- /dev/null +++ b/KSP-AVC.version @@ -0,0 +1,25 @@ +{ + "NAME": "KSP-AVC Plugin", + "URL": "http://ksp.spacetux.net/avc/KSP-AVC", + "DOWNLOAD": "https://github.com/linuxgurugamer/KSPAddonVersionChecker/releases", + "GITHUB": { + "USERNAME": "linuxgurugamer", + "REPOSITORY": "KSPAddonVersionChecker" + }, + "VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1, + "BUILD": 9 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 12, + "PATCH": 2 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 12, + "PATCH": 0 + } +} diff --git a/KSP-AVC/Addon.cs b/KSP-AVC/Addon.cs index 9c96072..b11fa0e 100644 --- a/KSP-AVC/Addon.cs +++ b/KSP-AVC/Addon.cs @@ -19,10 +19,11 @@ using System; using System.IO; -using System.Threading; +using System.Net; +//using System.Threading; using UnityEngine; - +using UnityEngine.Networking; #endregion namespace KSP_AVC @@ -42,9 +43,39 @@ public Addon(string path) public bool HasError { get; private set; } + public bool TriggerIssueGui + { + get + { + return this.LocalInfo.TriggerIssueGui; + } + } + public bool IsCompatible { - get { return this.IsLocalReady && this.LocalInfo.IsCompatible; } + get { return (this.IsLocalReady && this.LocalInfo.IsCompatible); } + + } + + public bool IsForcedCompatibleByVersion + { + get + { + return this.LocalInfo.IsForcedCompatibleByVersion; + } + } + + public bool IsForcedCompatibleByName + { + get + { + return this.LocalInfo.IsForcedCompatibleByName; + } + } + + public bool IsLockedByCreator + { + get { return this.LocalInfo.IsLockedByCreator; } } public bool IsLocalReady { get; private set; } @@ -55,7 +86,18 @@ public bool IsCompatible public bool IsUpdateAvailable { - get { return this.IsProcessingComplete && this.LocalInfo.Version != null && this.RemoteInfo.Version != null && this.RemoteInfo.Version > this.LocalInfo.Version && this.RemoteInfo.IsCompatibleKspVersion && this.RemoteInfo.IsCompatibleGitHubVersion; } + get { + bool b = this.IsProcessingComplete && + this.LocalInfo.Version != null && + this.RemoteInfo.Version != null && + this.RemoteInfo.Version > this.LocalInfo.Version && + //this.RemoteInfo.IsCompatibleKspVersion && + this.RemoteInfo.IsCompatible && + this.RemoteInfo.IsCompatibleGitHubVersion; + + return b; + + } } public AddonInfo LocalInfo { get; private set; } @@ -73,12 +115,14 @@ public string Name public void RunProcessLocalInfo(string path) { - ThreadPool.QueueUserWorkItem(this.ProcessLocalInfo, path); + this.ProcessLocalInfo( path); + //ThreadPool.QueueUserWorkItem(this.ProcessLocalInfo, path); } public void RunProcessRemoteInfo() { - ThreadPool.QueueUserWorkItem(this.ProcessRemoteInfo); + this.ProcessRemoteInfo(null); + //ThreadPool.QueueUserWorkItem(this.ProcessRemoteInfo); } #endregion @@ -98,23 +142,66 @@ private void FetchLocalInfo(string path) } } } - + //const long TicsPerSec = 10000000; private void FetchRemoteInfo() { - const float timeoutSeconds = 10.0f; - float startTime = Time.time; - float currentTime = startTime; +#if false + const float timeoutSeconds = 10.0f; + long startTime = DateTime.Now.Ticks; + long currentTime = startTime; +#endif if (string.IsNullOrEmpty(this.LocalInfo.Url) == false) { - using (var www = new WWW(Uri.EscapeUriString(this.LocalInfo.Url))) + HttpWebResponse response = null; + try { - while ((!www.isDone) && ((currentTime - startTime) < timeoutSeconds)) + HttpWebRequest request = HttpWebRequest.Create(Uri.EscapeUriString(this.LocalInfo.Url)) as HttpWebRequest; + + request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; + request.Accept= "text/html,application/xhtml+xm…plication/xml; q=0.9,*/*;q=0.8"; + request.UserAgent = "KSP-AVC"; + request.Timeout = 10000; // milliseconds + request.Method = WebRequestMethods.Http.Get; + response = request.GetResponse() as HttpWebResponse; + if (response.StatusCode == HttpStatusCode.OK) + { + Stream data = response.GetResponseStream(); + string html = String.Empty; + using (StreamReader sr = new StreamReader(data)) + { + html = sr.ReadToEnd(); + } + response.Close(); + this.SetRemoteAvcInfo(html); + } + else + { + this.SetLocalInfoOnly(); + } + } + catch (WebException ex) + { + Logger.Log("Exception fetching data from: " + this.LocalInfo.Url); + if (ex.Status == WebExceptionStatus.ProtocolError) + { + Logger.Log("Status Code : " + ((int)((HttpWebResponse)ex.Response).StatusCode).ToString() + " - " + ((HttpWebResponse)ex.Response).StatusCode.ToString()); + Logger.Log("Status Description : " + ((HttpWebResponse)ex.Response).StatusDescription); + } + else + Logger.Exception(ex); + + this.SetLocalInfoOnly(); + } +#if false + using (UnityWebRequest www = UnityWebRequest.Get(Uri.EscapeUriString(this.LocalInfo.Url))) + { + while ((!www.isDone) && ((currentTime - startTime) / TicsPerSec < timeoutSeconds)) { Thread.Sleep(100); - currentTime = Time.time; + currentTime = DateTime.Now.Ticks; } - if ((www.error == null) && ((currentTime - startTime) < timeoutSeconds)) + if ((www.error == null) && ((currentTime - startTime)/TicsPerSec < timeoutSeconds)) { this.SetRemoteAvcInfo(www); } @@ -123,6 +210,7 @@ private void FetchRemoteInfo() this.SetLocalInfoOnly(); } } +#endif } else { @@ -142,7 +230,7 @@ private void ProcessLocalInfo(object state) } else { - Logger.Log("File Not Found: " + path); + Logger.Error("File Not Found: " + path); this.SetHasError(); } } @@ -157,8 +245,9 @@ private void ProcessRemoteInfo(object state) { try { - if (String.IsNullOrEmpty(this.LocalInfo.Url) && String.IsNullOrEmpty(this.LocalInfo.KerbalStuffUrl)) + if (String.IsNullOrEmpty(this.LocalInfo.Url)) // && String.IsNullOrEmpty(this.LocalInfo.KerbalStuffUrl)) { + Logger.Log("LocalInfo.Url are empty"); this.SetLocalInfoOnly(); return; } @@ -167,6 +256,7 @@ private void ProcessRemoteInfo(object state) } catch (Exception ex) { + Logger.Log("Exception with URL: " + this.LocalInfo.Url); Logger.Exception(ex); this.SetLocalInfoOnly(); } @@ -183,25 +273,35 @@ private void SetLocalInfoOnly() this.RemoteInfo = this.LocalInfo; this.IsRemoteReady = true; this.IsProcessingComplete = true; - Logger.Log(this.LocalInfo); + Logger.Blank(); } - - private void SetRemoteAvcInfo(WWW www) +#if false + private void SetRemoteAvcInfo(UnityWebRequest www) + { + SetRemoteAvcInfo(www.url); + } +#endif + private void SetRemoteAvcInfo(string json) { - this.RemoteInfo = new AddonInfo(this.LocalInfo.Url, www.text, AddonInfo.RemoteType.AVC); + // this.RemoteInfo = new AddonInfo(this.LocalInfo.Url, www.text, AddonInfo.RemoteType.AVC); + this.RemoteInfo = new AddonInfo(this.LocalInfo.Url, json, AddonInfo.RemoteType.AVC); + this.RemoteInfo.FetchRemoteData(); + +#if true if (this.LocalInfo.Version == this.RemoteInfo.Version) { Logger.Log("Identical remote version found: Using remote version information only."); - Logger.Log(this.RemoteInfo); + Logger.Log("SetRemoteAvcInfo, RemoteInfo "+ this.RemoteInfo.ToString()); Logger.Blank(); this.LocalInfo = this.RemoteInfo; } else +#endif { - Logger.Log(this.LocalInfo); + Logger.Log("SetRemoteAvcInfo, LocalInfo" + this.LocalInfo.ToString()); Logger.Log(this.RemoteInfo + "\n\tUpdateAvailable: " + this.IsUpdateAvailable); Logger.Blank(); } @@ -209,21 +309,21 @@ private void SetRemoteAvcInfo(WWW www) this.IsRemoteReady = true; this.IsProcessingComplete = true; } - - private void SetRemoteKerbalStuffInfo(WWW www) +#if false + private void SetRemoteKerbalStuffInfo(UnityWebRequest www) { - this.RemoteInfo = new AddonInfo(this.LocalInfo.KerbalStuffUrl, www.text, AddonInfo.RemoteType.KerbalStuff); + this.RemoteInfo = new AddonInfo(this.LocalInfo.KerbalStuffUrl, www.url, AddonInfo.RemoteType.KerbalStuff); if (this.LocalInfo.Version == this.RemoteInfo.Version) { Logger.Log("Identical remote version found: Using remote version information only."); - Logger.Log(this.RemoteInfo); + Logger.Log("SetRemoteKerbalStuffInfo, RemoteInfo", this.RemoteInfo); Logger.Blank(); this.LocalInfo = this.RemoteInfo; } else { - Logger.Log(this.LocalInfo); + Logger.Log("SetRemoteKerbalStuffInfo, LocalInfo", this.LocalInfo); Logger.Log(this.RemoteInfo + "\n\tUpdateAvailable: " + this.IsUpdateAvailable); Logger.Blank(); } @@ -231,7 +331,8 @@ private void SetRemoteKerbalStuffInfo(WWW www) this.IsRemoteReady = true; this.IsProcessingComplete = true; } +#endif - #endregion +#endregion } -} \ No newline at end of file +} diff --git a/KSP-AVC/AddonInfo.cs b/KSP-AVC/AddonInfo.cs index 05b3dca..5c02c33 100644 --- a/KSP-AVC/AddonInfo.cs +++ b/KSP-AVC/AddonInfo.cs @@ -20,9 +20,13 @@ using System; using System.Collections.Generic; using System.Linq; -using System.Threading; +//using System.Threading; using UnityEngine; +//using UnityEngine.Networking; + +using System.IO; +using System.Net; #endregion @@ -39,6 +43,8 @@ public class AddonInfo private VersionInfo kspVersion; private VersionInfo kspVersionMax; private VersionInfo kspVersionMin; + private List kspExcludeVersions; + private List kspIncludeVersions; #endregion @@ -46,23 +52,30 @@ public class AddonInfo public AddonInfo(string path, string json, RemoteType remoteType) { + // Following because some files are returning a few gibberish chars when downloading from Github + json = DeleteCharsPrecedingBrace(json); + try { this.path = path; switch (remoteType) { case RemoteType.AVC: - this.ParseAvc(json); + this.ParseAvc(path, json); break; - +#if false case RemoteType.KerbalStuff: this.ParseKerbalStuff(json); break; +#endif } + + ValidateKspMinMax(); } catch { this.ParseError = true; + this.AddParseErrorMsg = "Error parsing: " + path; throw; } finally @@ -70,10 +83,23 @@ public AddonInfo(string path, string json, RemoteType remoteType) if (this.ParseError) { Logger.Log("Version file contains errors: " + path); + foreach (var s in this.ParseErrorMsgs) + Logger.Log("Error: " + s); + throw new ArgumentException("Not a valid JSON object."); } } } + string DeleteCharsPrecedingBrace(string json) + { + int i = json.IndexOf('{'); + if (i == 0) + return json; + if (i == -1) + return ""; + return json.Substring(i); + + } static AddonInfo() { actualKspVersion = new VersionInfo(Versioning.version_major, Versioning.version_minor, Versioning.Revision); @@ -85,8 +111,8 @@ static AddonInfo() public enum RemoteType { - AVC, - KerbalStuff + AVC + // , KerbalStuff } #endregion @@ -108,9 +134,123 @@ public static VersionInfo ActualKspVersion public GitHubInfo GitHub { get; private set; } + public bool TriggerIssueGui + { + get + { + if (!IsCompatible && !IsForcedCompatibleByName && !IsForcedCompatibleByVersion) + { + return true; + } + return false; + } + } + public bool IsCompatible { - get { return this.IsCompatibleKspVersion || ((this.kspVersionMin != null || this.kspVersionMax != null) && this.IsCompatibleKspVersionMin && this.IsCompatibleKspVersionMax); } + get + { + if (kspIncludeVersions != null && this.IsKspIncludedVersion) + return true; + bool b = (this.IsCompatibleKspVersion && this.KspVersionMinIsNull && this.KspVersionMaxIsNull) + || + ((this.kspVersionMin != null || this.kspVersionMax != null) && this.IsCompatibleKspVersionMin && this.IsCompatibleKspVersionMax); + if (b) + { + if (kspExcludeVersions != null && this.IsKspExcludedVersion) + b = false; + } + return b; + } + } + + //Handles the Compatibility Override by versionnumbers, set in the AVC.cfg + public bool IsForcedCompatibleByVersion + { + get + { + if (this.IsCompatible || this.IsLockedByCreator || this.IgnoreOverride || Configuration.OverrideIsDisabledGlobal) + { + return false; + } + + bool compatible = (this.IsForcedCompatibleKspVersion && this.KspVersionMinIsNull && this.KspVersionMaxIsNull) + || + ((!this.KspVersionMinIsNull || !this.KspVersionMaxIsNull) && this.IsForcedCompatibleKspVersionMin && this.IsForcedCompatibleKspVersionMax); + return compatible; + } + } + + //Handles the Compatibility Override by Name, set in the AVC.cfg + public bool IsForcedCompatibleByName + { + get + { + if (this.IsCompatible || this.IsLockedByCreator || Configuration.OverrideIsDisabledGlobal) + { + return false; + } + + bool isForcedCompatible = (from d in Configuration.OverrideCompatibilityByName + where d == this.Name + select d).Any(); + + return isForcedCompatible; + } + } + + public bool IsForcedCompatibleKspVersionMin + { + get + { + bool isForcedCompatible = (from d in Configuration.CompatibleVersions + where KspVersionMin <= new VersionInfo(d.Key) + where d.Value.compatWithVersion.Contains(actualKspVersion) + select d).Any(); + + return isForcedCompatible; + } + } + + public bool IsForcedCompatibleKspVersionMax + { + get + { + bool isForcedCompatible = (from d in Configuration.CompatibleVersions + where KspVersionMax >= new VersionInfo(d.Key) + where d.Value.compatWithVersion.Contains(actualKspVersion) + select d).Any(); + + return isForcedCompatible; + } + } + + public bool IsForcedCompatibleKspVersion + { + get + { + bool isForcedCompatible = (from d in Configuration.CompatibleVersions + where KspVersion == new VersionInfo(d.Key) + where d.Value.compatWithVersion.Contains(actualKspVersion) + select d).Any(); + + return isForcedCompatible; + } + } + + //Checks for mods which need to ignore the Compatibility Override, this should be Kopernicus by default (set in AVC.cfg) + public bool IgnoreOverride + { + get + { + bool onIgnoreList = false; + foreach (var modName in Configuration.modsIgnoreOverride) + { + if (modName == this.Name) + return true; + } + return onIgnoreList; + } } public bool IsCompatibleGitHubVersion @@ -120,31 +260,87 @@ public bool IsCompatibleGitHubVersion public bool IsCompatibleKspVersion { - get { return Equals(this.KspVersion, actualKspVersion); } + get + { + var b = Equals(this.KspVersion, actualKspVersion); + + //This code mixes up the regular version control with the compatibility override but I need separated boolean values + //If someone doesn't like my LINQ method to access the dictionary, feel free to replace it with something like this ;) + //if (!b) + //{ + // CompatVersions cv; + // if (!Configuration.CompatibleVersions.TryGetValue(this.KspVersion.Version, out cv)) + // return false; + // b = cv.compatibleWithVersion.Contains(actualKspVersion.Version); + //} + return b; + } } public bool IsCompatibleKspVersionMax { - get { return this.KspVersionMax >= actualKspVersion; } + get + { + bool b = this.KspVersionMax >= actualKspVersion; + return b; + } } public bool IsCompatibleKspVersionMin { - get { return this.KspVersionMin <= actualKspVersion; } + get + { + bool b = this.KspVersionMin <= actualKspVersion; + return b; + } + } + public bool IsKspExcludedVersion + { + get + { + if (this.kspExcludeVersions == null) + return false; + bool b = this.kspExcludeVersions.Contains(actualKspVersion); + return b; + } + } + public bool IsKspIncludedVersion + { + get + { + if (this.kspIncludeVersions == null) + return false; + bool b = this.kspIncludeVersions.Contains(actualKspVersion); + return b; + } } - public string KerbalStuffUrl { get; private set; } + //public string KerbalStuffUrl { get; private set; } public VersionInfo KspVersion { get { return this.kspVersion ?? VersionInfo.AnyValue; } } + public bool KspVersionMaxIsNull + { + get { return this.kspVersionMax == null; } + } + public VersionInfo KspVersionMax { - get { return this.kspVersionMax ?? VersionInfo.MaxValue; } + get { return this.kspVersionMax ?? actualKspVersion; } } + public bool KspVersionMinIsNull + { + get { return this.kspVersionMin == null; } + } + + public bool KspExcludeVersionsIsNull { get { return this.kspExcludeVersions == null; } } + + public bool KspIncludeVersionsIsNull { get { return this.kspIncludeVersions == null; } } + public VersionInfo KspVersionMin { get { return this.kspVersionMin ?? VersionInfo.MinValue; } @@ -152,8 +348,16 @@ public VersionInfo KspVersionMin public string Name { get; private set; } + public LocalRemotePriority Priority { get; private set; } + + public bool IsLockedByCreator { get; private set; } //Enable/Disable the Compatibility Override feature for this mod, set in the version file + public bool ParseError { get; private set; } + private List parseErrorMsgs = new List(); + public string AddParseErrorMsg { set { parseErrorMsgs.Add(value); } } + internal List ParseErrorMsgs { get { return parseErrorMsgs; } } + public string Url { get; private set; } public VersionInfo Version { get; private set; } @@ -169,7 +373,7 @@ public void FetchRemoteData() this.GitHub.FetchRemoteData(); } - if (this.ChangeLogUrl != null) + if (!String.IsNullOrEmpty(this.ChangeLogUrl)) { this.FetchChangeLog(); } @@ -177,19 +381,39 @@ public void FetchRemoteData() public override string ToString() { - return this.path + + string str = this.path + "\n\tNAME: " + (String.IsNullOrEmpty(this.Name) ? "NULL (required)" : this.Name) + "\n\tURL: " + (String.IsNullOrEmpty(this.Url) ? "NULL" : this.Url) + "\n\tDOWNLOAD: " + (String.IsNullOrEmpty(this.Download) ? "NULL" : this.Download) + "\n\tGITHUB: " + (this.GitHub != null ? this.GitHub.ToString() : "NULL") + + "\n\tDISALLOW_VERSION_OVERRIDE: " + this.IsLockedByCreator.ToString() + "\n\tVERSION: " + (this.Version != null ? this.Version.ToString() : "NULL (required)") + "\n\tKSP_VERSION: " + this.KspVersion + "\n\tKSP_VERSION_MIN: " + (this.kspVersionMin != null ? this.kspVersionMin.ToString() : "NULL") + - "\n\tKSP_VERSION_MAX: " + (this.kspVersionMax != null ? this.kspVersionMax.ToString() : "NULL") + + "\n\tKSP_VERSION_MAX: " + (this.kspVersionMax != null ? this.kspVersionMax.ToString() : "NULL"); + if (kspExcludeVersions != null) + { + str += "\n\tKSP_VERSION_EXCLUDE:"; + foreach (var s in kspExcludeVersions) + { + str += "\n\t\t" + s; + } + } + if (kspIncludeVersions != null) + { + str += "\n\tKSP_VERSION_INCLUDE:"; + foreach (var s in kspIncludeVersions) + { + str += "\n\t\t" + s; + } + } + str += "\n\tCompatibleKspVersion: " + this.IsCompatibleKspVersion + "\n\tCompatibleKspVersionMin: " + this.IsCompatibleKspVersionMin + "\n\tCompatibleKspVersionMax: " + this.IsCompatibleKspVersionMax + "\n\tCompatibleGitHubVersion: " + this.IsCompatibleGitHubVersion; + + return str; } #endregion @@ -249,7 +473,48 @@ private static VersionInfo ParseVersion(Dictionary data) private void FetchChangeLog() { - using (var www = new WWW(this.ChangeLogUrl)) + try + { + HttpWebRequest request = HttpWebRequest.Create(Uri.EscapeUriString(this.ChangeLogUrl)) as HttpWebRequest; + + request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; + request.Accept = "text/html,application/xhtml+xm…plication/xml; q=0.9,*/*;q=0.8"; ; + request.UserAgent = "KSP-AVC"; + request.Timeout = 10000; // milliseconds + request.Method = WebRequestMethods.Http.Get; + HttpWebResponse response = request.GetResponse() as HttpWebResponse; + + if (response.StatusCode == HttpStatusCode.OK) + { + Stream data = response.GetResponseStream(); + string html = String.Empty; + using (StreamReader sr = new StreamReader(data)) + { + html = sr.ReadToEnd(); + } + response.Close(); + this.ChangeLog = html; + } + else + { + Logger.Log( "HTTP error: " + response.StatusCode + ", fetching data from URL: " + this.ChangeLogUrl); + } + } + catch (WebException ex) + { + Logger.Log("Exception fetching data from: " + this.ChangeLogUrl); + if (ex.Status == WebExceptionStatus.ProtocolError) + { + Logger.Log("Status Code : " + ((int)((HttpWebResponse)ex.Response).StatusCode).ToString() + " - " + ((HttpWebResponse)ex.Response).StatusCode.ToString()); + Logger.Log("Status Description : " + ((HttpWebResponse)ex.Response).StatusDescription); + } + else + Logger.Exception(ex); + } + +#if false + + using (UnityWebRequest www = UnityWebRequest.Get(this.ChangeLogUrl)) { while (!www.isDone) { @@ -257,30 +522,80 @@ private void FetchChangeLog() } if (www.error == null) { - this.ChangeLog = www.text; + this.ChangeLog = www.url; } } +#endif } - private void ParseAvc(string json) + private void ParseAvc(string path, string json) { var data = Json.Deserialize(json) as Dictionary; if (data == null) { this.ParseError = true; - return; + this.AddParseErrorMsg = "Error in Json.Deserialize, file: " + path; + + throw new ArgumentException("Not a valid JSON object."); } foreach (var key in data.Keys) { switch (key.ToUpper()) { + + case "LOCAL_HAS_PRIORITY": + { + string s = (string)data[key]; + switch (s.ToUpper()) + { + case "TRUE": + this.Priority = LocalRemotePriority.local; + break; + case "FALSE": + this.Priority = LocalRemotePriority.remote; + break; + } + } + break; + + case "REMOTE_HAS_PRIORITY": + { + string s = (string)data[key]; + switch (s.ToUpper()) + { + case "TRUE": + this.Priority = LocalRemotePriority.remote; + break; + case "FALSE": + this.Priority = LocalRemotePriority.local; + break; + } + } + break; + + case "DISALLOW_VERSION_OVERRIDE": + { + string s = (string)data[key]; + switch (s.ToUpper()) + { + case "TRUE": + this.IsLockedByCreator = true; + break; + case "FALSE": + this.IsLockedByCreator = false; + break; + } + } + break; + case "NAME": this.Name = (string)data[key]; break; - +#if false case "KERBAL_STUFF_URL": this.KerbalStuffUrl = (string)data[key]; break; +#endif case "URL": this.Url = FormatCompatibleUrl((string)data[key]); @@ -319,28 +634,65 @@ private void ParseAvc(string json) break; case "KSP_VERSION_MIN": +#if STRICT + if (!Configuration.StrictVersion) +#endif this.kspVersionMin = GetVersion(data[key]); break; case "KSP_VERSION_MAX": +#if STRICT + if (!Configuration.StrictVersion) +#endif this.kspVersionMax = GetVersion(data[key]); break; + case "KSP_VERSION_EXCLUDE": + kspExcludeVersions = new List(); + List ExcludeList = (List)data[key]; + foreach (System.Object el in ExcludeList) + { + var s = GetVersion(el); + kspExcludeVersions.Add(s); + } + break; + case "KSP_VERSION_INCLUDE": + kspIncludeVersions = new List(); + List IncludeList = (List)data[key]; + foreach (System.Object el in IncludeList) + { + var s = GetVersion(el); + kspIncludeVersions.Add(s); + } + break; } } } + private void ValidateKspMinMax() + { + if (KspVersionMin > KspVersionMax) + { + this.ParseError = true; + this.AddParseErrorMsg = "KSP_VERSION_MIN greater than KSP_VERSION_MAX"; + throw new ArgumentException("KSP_VERSION_MIN greater than KSP_VERSION_MAX"); + } + + + } + private void ParseKerbalStuff(string json) { var data = Json.Deserialize(json) as Dictionary; if (data == null) { this.ParseError = true; - return; + this.AddParseErrorMsg = "No data from Json (kerbalstuff)"; + throw new ArgumentException("No data from Json (kerbalstuff)"); } this.Name = (string)data["name"]; } - +#if false private void ParseKerbalStuffVersion(Dictionary data) { foreach (var key in data.Keys) @@ -357,6 +709,7 @@ private void ParseKerbalStuffVersion(Dictionary data) } } } +#endif #endregion @@ -385,6 +738,9 @@ public GitHubInfo(object obj, AddonInfo addonInfo) public bool AllowPreRelease { get; private set; } public bool ParseError { get; private set; } + private List parseErrorMsgs = new List(); + public string AddParseErrorMsg { set { parseErrorMsgs.Add(value); } } + internal List ParseErrorMsgs { get { return parseErrorMsgs; } } public string Repository { get; private set; } @@ -400,9 +756,34 @@ public GitHubInfo(object obj, AddonInfo addonInfo) public void FetchRemoteData() { + HttpWebResponse response = null; try { - using (var www = new WWW("https://api.github.com/repos/" + this.Username + "/" + this.Repository + "/releases")) +#if true + string uri = "https://api.github.com/repos/" + this.Username + "/" + this.Repository + "/releases"; + HttpWebRequest request = HttpWebRequest.Create(Uri.EscapeUriString(uri)) as HttpWebRequest; + + request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; + request.Accept = "text/html,application/xhtml+xm…plication/xml; q=0.9,*/*;q=0.8"; + request.UserAgent = "KSP-AVC"; + request.Timeout = 10000; // milliseconds + request.Method = WebRequestMethods.Http.Get; + response = request.GetResponse() as HttpWebResponse; + if (response.StatusCode == HttpStatusCode.OK) + { + Stream data = response.GetResponseStream(); + string html = String.Empty; + using (StreamReader sr = new StreamReader(data)) + { + html = sr.ReadToEnd(); + } + response.Close(); + ParseGitHubJson(html); + } + +#else + + using (UnityWebRequest www = UnityWebRequest.Get("https://api.github.com/repos/" + this.Username + "/" + this.Repository + "/releases")) { while (!www.isDone) { @@ -410,13 +791,21 @@ public void FetchRemoteData() } if (www.error == null) { - this.ParseGitHubJson(www.text); + this.ParseGitHubJson(www.url); } } +#endif } - catch (Exception ex) + catch (WebException ex) { - Logger.Exception(ex); + Logger.Log("Exception fetching data from Github: " + "https://api.github.com/repos/" + this.Username + "/" + this.Repository + "/releases"); + if (ex.Status == WebExceptionStatus.ProtocolError) + { + Logger.Log("Status Code : " + ((int)((HttpWebResponse)ex.Response).StatusCode).ToString() + " - " + ((HttpWebResponse)ex.Response).StatusCode.ToString()); + Logger.Log("Status Description : " + ((HttpWebResponse)ex.Response).StatusDescription); + } + else + Logger.Exception(ex); } } @@ -437,7 +826,8 @@ private void ParseGitHubJson(string json) if (obj == null || obj.Count == 0) { this.ParseError = true; - return; + this.AddParseErrorMsg = "No data after parsing Github Json"; + throw new ArgumentException("No data after parsing Github Json"); } foreach (Dictionary data in obj) @@ -471,7 +861,8 @@ private void ParseJson(object obj) if (data == null) { this.ParseError = true; - return; + this.AddParseErrorMsg = "No data in dictionary (ParseJson)"; + throw new ArgumentException("No data in dictionary (ParseJson)"); } foreach (var key in data.Keys) diff --git a/KSP-AVC/AddonLibrary.cs b/KSP-AVC/AddonLibrary.cs index 4227e25..c81152d 100644 --- a/KSP-AVC/AddonLibrary.cs +++ b/KSP-AVC/AddonLibrary.cs @@ -23,6 +23,7 @@ using System.Linq; using System.Reflection; using System.Threading; +using UnityEngine; #endregion @@ -42,7 +43,6 @@ public static class AddonLibrary static AddonLibrary() { rootPath = GetRootPath(); - Logger.Log("Checking Root: " + rootPath); ThreadPool.QueueUserWorkItem(ProcessAddonPopulation); } @@ -93,6 +93,9 @@ private static void ProcessAddonPopulation(object state) try { Populated = false; + var addonList = Directory.GetFiles(rootPath, "*.version", SearchOption.AllDirectories).ToList(); + foreach (var a in addonList) + Logger.Log("addonList: " + a); addons = Directory.GetFiles(rootPath, "*.version", SearchOption.AllDirectories).Select(path => new Addon(path)).ToList(); Populated = true; } diff --git a/KSP-AVC/AssemblyVersion.cs b/KSP-AVC/AssemblyVersion.cs new file mode 100644 index 0000000..339afae --- /dev/null +++ b/KSP-AVC/AssemblyVersion.cs @@ -0,0 +1,9 @@ + + // This code was generated by a tool. Any changes made manually will be lost + // the next time this code is regenerated. + // + + using System.Reflection; + + [assembly: AssemblyFileVersion("1.4.1.8")] + [assembly: AssemblyVersion("1.4.1.8")] diff --git a/KSP-AVC/AssemblyVersion.tt b/KSP-AVC/AssemblyVersion.tt new file mode 100644 index 0000000..c3c9e4a --- /dev/null +++ b/KSP-AVC/AssemblyVersion.tt @@ -0,0 +1,101 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ import namespace="System.IO" #> +<#@ output extension=".cs" #> + +<#@ assembly name="EnvDTE" #><# /* This assembly provides access to Visual Studio project properties. */ #> +<# + + // Instructions + // 1. Add a new Text Template to the project + // 2. Copy this file into the new template + // 3. Update the string: versionfile with the complete path to the .version file + // 4. Remove the following line from the file AssemblyInfo.cs (usually located in the "Property" folder inside your C# project): + // [assembly: AssemblyVersion("1.0.0.0")] + // 5. Add the following to the PreBuild steps: + // + // set textTemplatingPath="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\IDE\texttransform.exe" + // %textTemplatingPath% "$(ProjectDir)AssemblyVersion.tt" + + + int major = 0; + int minor = 0; + int build = 0; + int patch = 0; + bool versionSection = false; + + int i = 0; + int i2 = 0; + string s; + + + // For Visual Studio / MSBuild Build-Time Template Resolution + string RootDirectory = System.IO.Path.GetDirectoryName(Host.TemplateFile) + @"\..\"; + + // + // Update the following with the name of the .version file which is in the root directory + // + string versionfile = RootDirectory + "KSP-AVC.version"; + + if (!File.Exists(versionfile)) + { + Write("File: " + versionfile + " missing\n"); + } + + try + { + foreach (var line in File.ReadAllLines(versionfile)) + { + if (line != null) + { + if (!versionSection) + { + if (line.Contains("\"VERSION\"")) + versionSection = true; + } + else + { + if (line.Contains("}")) + versionSection = false; + i = line.IndexOf(":"); + i2 = line.IndexOf(","); + if (i2 == -1) + i2 = line.Length; + if (i >= 0 && i2 >= 0) + { + s = line.Substring(i + 1, i2 - i - 1); + + if (line.Contains("MAJOR")) + Int32.TryParse(s, out major); + + if (line.Contains("MINOR")) + Int32.TryParse(s, out minor); + + if (line.Contains("PATCH")) + Int32.TryParse(s, out patch); + + if (line.Contains("BUILD")) + Int32.TryParse(s, out build); + } + } + } + } + + } + catch + { + major = 1; + minor = 0; + patch = 0; + build = 0; + } + //Write("File done"); + + #> + // This code was generated by a tool. Any changes made manually will be lost + // the next time this code is regenerated. + // + + using System.Reflection; + + [assembly: AssemblyFileVersion("<#= major #>.<#= minor #>.<#= patch #>.<#= build #>")] + [assembly: AssemblyVersion("<#= major #>.<#= minor #>.<#= patch #>.<#= build #>")] diff --git a/KSP-AVC/ChangeLogGui.cs b/KSP-AVC/ChangeLogGui.cs index bfd5638..c829fe7 100644 --- a/KSP-AVC/ChangeLogGui.cs +++ b/KSP-AVC/ChangeLogGui.cs @@ -56,7 +56,6 @@ protected void Awake() { Logger.Exception(ex); } - Logger.Log("ChangeLogGui was created."); } protected void OnDestroy() diff --git a/KSP-AVC/CheckerProgressGui.cs b/KSP-AVC/CheckerProgressGui.cs index ad66aa1..55a8547 100644 --- a/KSP-AVC/CheckerProgressGui.cs +++ b/KSP-AVC/CheckerProgressGui.cs @@ -50,7 +50,6 @@ protected void Awake() { Logger.Exception(ex); } - Logger.Log("CheckerProgressGui was created."); } protected void OnDestroy() diff --git a/KSP-AVC/CompatibilityOverrideAdvSettingsGui.cs b/KSP-AVC/CompatibilityOverrideAdvSettingsGui.cs new file mode 100644 index 0000000..1970cb5 --- /dev/null +++ b/KSP-AVC/CompatibilityOverrideAdvSettingsGui.cs @@ -0,0 +1,262 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace KSP_AVC +{ + class CompatibilityOverrideAdvSettingsGui : MonoBehaviour + { + #region Fields + + //private enum OverrideType { name, version, ignore, locked }; + private GUIStyle boxStyle; + private GUIStyle buttonStyle; + private GUIStyle labelStyle; + private GUIStyle labelStyleWhite; + private GUIStyle labelStyleYellow; + private GUIStyle labelStyleCyan; + private GUIStyle toggleStyle; + private GUIStyle scrollList; + private GUIStyle topLevelTitleStyle; + private bool hasCentred; + private Rect position = new Rect(Screen.width, Screen.height, 0, 0); + private Vector2 scrollPosition = Vector2.zero; + + #endregion + + #region Methods: protected + + protected void Awake() + { + try + { + DontDestroyOnLoad(this); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + protected void Start() + { + try + { + this.InitialiseStyles(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + protected void OnDestroy() + { + if (Configuration.CfgUpdated) + { + Configuration.SaveCfg(); + } + } + + protected void OnGUI() + { + try + { + this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KSP Add-on Version Checker - Advanced Settings", HighLogic.Skin.window); + this.CentreWindow(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + #endregion + + #region Methods : Private + + private void Window(int id) + { + this.DrawIgnoreOverride(); + if (GUILayout.Button("CLOSE", this.buttonStyle)) + { + Configuration.SaveCfg(); + Destroy(this); + } + GUI.DragWindow(); + } + + private void CentreWindow() + { + if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) + { + return; + } + this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); + this.hasCentred = true; + } + + private void DrawIgnoreOverride() + { + GUILayout.BeginVertical(); + GUILayout.BeginHorizontal(this.boxStyle); + DrawAdvancedInfo(); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + DrawIgnoreOverrideSettings(); + GUILayout.EndHorizontal(); + GUILayout.BeginHorizontal(); + DrawDefaultValueSettings(); + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + } + + private void DrawDefaultValueSettings() + { + bool toggleState = Configuration.ShowDefaultValues; + GUILayout.BeginVertical(); + DrawHeadingsDefaultValue(); + GUILayout.BeginHorizontal(this.scrollList); + GUILayout.Label("Show preset values in addon list", this.labelStyleWhite); + GUILayout.FlexibleSpace(); + toggleState = GUILayout.Toggle(toggleState, "", this.toggleStyle); + if(toggleState != Configuration.ShowDefaultValues) + { + Configuration.ShowDefaultValues = !Configuration.ShowDefaultValues; + } + GUILayout.Space(25); + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + } + + private void DrawHeadingsDefaultValue() + { + GUILayout.Label("OTHER SETTINGS", this.topLevelTitleStyle); + } + + private void DrawAdvancedInfo() + { + GUILayout.BeginHorizontal(); + GUILayout.Label("This is the ignore list for the compatibile version override." + + "\nAny mod on the ignore list will no longer be affected by the version range. " + + "It is still possible to put an ignored mod, on the \"ALWAYS OVERRIDE\" list.", this.labelStyle); + GUILayout.EndHorizontal(); + } + + private void DrawIgnoreOverrideSettings() + { + GUILayout.BeginVertical(); + DrawHeadingsIgnoreInfo(); + scrollPosition = GUILayout.BeginScrollView(scrollPosition, this.scrollList, GUILayout.Width(430), GUILayout.Height(180)); + DrawIgnoreList(); + GUILayout.EndScrollView(); + GUILayout.EndVertical(); + } + + private void DrawHeadingsIgnoreInfo() + { + GUILayout.BeginHorizontal(); + GUILayout.Label("ACTIVE VERSION OVERRIDE", this.topLevelTitleStyle); + GUILayout.FlexibleSpace(); + GUILayout.Label("IGNORE", this.topLevelTitleStyle); + GUILayout.Space(10); + GUILayout.EndHorizontal(); + } + + private void DrawIgnoreList() + { + List overrideMods = AddonLibrary.Addons.Where(x => x.IsForcedCompatibleByVersion || GuiHelper.CompatibilityState(OverrideType.ignore, x)).OrderBy(x => x.Name).ToList(); + int m = overrideMods.Count; + for(int i = 0; i < m; i++) + { + var addon = overrideMods[i]; + bool toggleState = GuiHelper.CompatibilityState(OverrideType.ignore, addon); + GUIStyle labelStyleIgnore = GuiHelper.CompatibilityState(OverrideType.ignore, addon) ? this.labelStyleYellow : this.labelStyleCyan; + + GUILayout.BeginHorizontal(); + GUILayout.Label(addon.Name, labelStyleIgnore); + GUILayout.FlexibleSpace(); + + toggleState = GUILayout.Toggle(toggleState, "", this.toggleStyle); + if(toggleState != GuiHelper.CompatibilityState(OverrideType.ignore, addon)) + { + GuiHelper.UpdateCompatibilityState(OverrideType.ignore, addon); + } + GUILayout.Space(25); + GUILayout.EndHorizontal(); + } + } + + #endregion + + #region Styles + + private void InitialiseStyles() + { + this.boxStyle = new GUIStyle(HighLogic.Skin.box) + { + padding = new RectOffset(10, 10, 5, 5), + }; + + this.buttonStyle = new GUIStyle(HighLogic.Skin.button) + { + normal = + { + textColor = Color.white + }, + fontStyle = FontStyle.Bold, + }; + + this.labelStyle = new GUIStyle(HighLogic.Skin.label) + { + alignment = TextAnchor.MiddleLeft + }; + + this.labelStyleWhite = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.white + }, + alignment = TextAnchor.MiddleLeft, + fontStyle = FontStyle.Bold, + }; + + this.labelStyleYellow = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.yellow + }, + alignment = TextAnchor.MiddleLeft, + }; + + this.labelStyleCyan = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.cyan + }, + alignment = TextAnchor.MiddleLeft, + }; + + this.topLevelTitleStyle = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.white + }, + alignment = TextAnchor.MiddleLeft, + fontStyle = FontStyle.Bold, + }; + + this.scrollList = new GUIStyle(HighLogic.Skin.box); + + this.toggleStyle = new GUIStyle(HighLogic.Skin.toggle); + } + + #endregion + } +} diff --git a/KSP-AVC/CompatibilityOverrideEnableGui.cs b/KSP-AVC/CompatibilityOverrideEnableGui.cs new file mode 100644 index 0000000..221db58 --- /dev/null +++ b/KSP-AVC/CompatibilityOverrideEnableGui.cs @@ -0,0 +1,152 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace KSP_AVC +{ + class CompatibilityOverrideEnableGui : MonoBehaviour + { + #region Fields + + private GUIStyle boxStyle; + private GUIStyle buttonStyle; + private bool hasCentred; + private GUIStyle labelStyle; + private Rect position = new Rect(Screen.width, Screen.height, 0, 0); + private GUIStyle topLevelTitleStyle; + + #endregion + + #region Methods: protected + + protected void Awake() + { + try + { + DontDestroyOnLoad(this); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + this.name = "OverrideEnableGui"; + } + + protected void Start() + { + try + { + this.InitialiseStyles(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + protected void OnDestroy() + { + if (Configuration.CfgUpdated) + { + Configuration.SaveCfg(); + } + } + + protected void OnGUI() + { + try + { + this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KSP Add-on Version Checker - Compatibility Override", HighLogic.Skin.window); + this.CentreWindow(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + #endregion + + #region Methods : Private + + private void DrawQuestion() + { + GUILayout.BeginHorizontal(this.boxStyle, GUILayout.Width(400)); + GUILayout.Label("The Compatibility Override is currently disabled!\nDo you want to enable it?", this.labelStyle); + GUILayout.EndHorizontal(); + } + + private void DrawButtons() + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button("YES", this.buttonStyle)) + { + Configuration.OverrideIsDisabledGlobal = false; + this.gameObject.AddComponent(); + Destroy(this); + } + if (GUILayout.Button("NO", this.buttonStyle)) + { + Destroy(this); + } + GUILayout.EndHorizontal(); + } + + private void Window(int id) + { + DrawQuestion(); + DrawButtons(); + GUI.DragWindow(); + } + + private void CentreWindow() + { + if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) + { + return; + } + this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); + this.hasCentred = true; + } + + #endregion + + #region Styles + + private void InitialiseStyles() + { + this.boxStyle = new GUIStyle(HighLogic.Skin.box) + { + padding = new RectOffset(10, 10, 5, 5), + }; + + this.buttonStyle = new GUIStyle(HighLogic.Skin.button) + { + normal = + { + textColor = Color.white + }, + fontStyle = FontStyle.Bold, + }; + + this.labelStyle = new GUIStyle(HighLogic.Skin.label) + { + alignment = TextAnchor.MiddleLeft + }; + + this.topLevelTitleStyle = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.white + }, + alignment = TextAnchor.MiddleLeft, + fontStyle = FontStyle.Bold, + }; + } + + #endregion + } +} diff --git a/KSP-AVC/CompatibilityOverrideGui.cs b/KSP-AVC/CompatibilityOverrideGui.cs new file mode 100644 index 0000000..28acd79 --- /dev/null +++ b/KSP-AVC/CompatibilityOverrideGui.cs @@ -0,0 +1,657 @@ +using System; +using System.Collections.Generic; +using System.Reflection; +using System.Linq; +using UnityEngine; + +namespace KSP_AVC +{ + class CompatibilityOverrideGui : MonoBehaviour + { + #region Fields + + private readonly VersionInfo version = Assembly.GetExecutingAssembly().GetName().Version; + private Rect position = new Rect(Screen.width, Screen.height, 0, 0); + private bool hasCentred; + private bool ShowAdvancedSettings = Configuration.OverrideIsDisabledGlobal; + private GUIStyle buttonStyle; + private GUIStyle scrollList; + private GUIStyle topLevelTitleStyle; + private GUIStyle centeredTitelStyle; + private GUIStyle buttonStyleRed; + private GUIStyle labelStyle; + private GUIStyle labelStyleBold; + private GUIStyle labelStyleYellow; + private GUIStyle labelStyleCyan; + private GUIStyle buttonStyleGreen; + private GUIStyle labelStyleIgnore; + private Vector2 scrollPositionVersionInfo = Vector2.zero; + private Vector2 scrollPositionAddonList = Vector2.zero; + private Vector2 scrollPositionNameList = Vector2.zero; + + + private List versions; + private bool[] enabledCompatVersions = new bool[100]; + + #endregion + + #region Methods: protected + + protected void Awake() + { + try + { + DontDestroyOnLoad(this); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + protected void Start() + { + try + { + this.InitialiseStyles(); + versions = new List(); + for (int i = 3; i <= Versioning.version_minor; i++) + versions.Add("1." + i.ToString() + ".*"); + + //InitEnabledCompatVersions(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + protected void OnDestroy() + { + if (Configuration.CfgUpdated) + { + Configuration.SaveCfg(); + } + } + + protected void OnGUI() + { + try + { + this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KSP Add-on Version Checker - Compatibility Override", HighLogic.Skin.window); + this.CentreWindow(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + #endregion + + #region Methods : private + + private void DrawDisabled() + { + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + GUILayout.Label("DISABLED", this.centeredTitelStyle); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } + + private void DrawNoIncompatibleAddons() + { + GUILayout.BeginHorizontal(); + GUILayout.FlexibleSpace(); + GUILayout.Label("NO INCOMPATIBLE ADDONS DETECTED", this.centeredTitelStyle); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } + + private void DrawEnableDisableButton() + { + string buttonLabel = "DISABLED"; + + + GUIStyle coloredButton = this.buttonStyleRed; + if (!Configuration.OverrideIsDisabledGlobal) + { + buttonLabel = "ENABLED"; + coloredButton = this.buttonStyleGreen; + } + + GUIContent content = new GUIContent(buttonLabel); + + GUIStyle style = GUI.skin.box; + style.alignment = TextAnchor.MiddleCenter; + + // Compute how large the button needs to be. + Vector2 size = style.CalcSize(content); + + if (GUI.Button(new Rect(position.width - size.x - 20, 5, 20 + size.x, 20), buttonLabel, coloredButton)) + { + Configuration.ToggleOverrideFeature(); + } + } + + #endregion + + #region WindowOverrideVersionInfo + + //Version override box + private void DrawOverrideVersionInfo() + { + GUILayout.BeginVertical(); + DrawHeadingsOverrideVersion(); + scrollPositionVersionInfo = GUILayout.BeginScrollView(scrollPositionVersionInfo, this.scrollList, GUILayout.Width(230), GUILayout.Height(275)); + DrawVersionList(); + //DrawStdCompatToggles(); + GUILayout.EndScrollView(); + DrawInputOverrideVersion(); + GUILayout.EndVertical(); + } + + //Heading for the version override box + private void DrawHeadingsOverrideVersion() + { + GUILayout.BeginHorizontal(); + GUILayout.Label("COMPATIBLE VERSION OVERRIDE", this.topLevelTitleStyle, GUILayout.MinWidth(230)); + GUILayout.EndHorizontal(); + } + + //List of active version overrides + private void DrawVersionList() + { + if (Configuration.OverrideIsDisabledGlobal) + { + DrawDisabled(); + return; + } + var listKeys = Configuration.CompatibleVersions.Keys.ToList(); + listKeys.Sort(); + foreach (var key in listKeys) + { + for (int i = 0; i < Configuration.CompatibleVersions[key].compatibleWithVersion.Count; i++) + { + GUILayout.BeginHorizontal(); + GUILayout.Label(Configuration.CompatibleVersions[key].currentVersion.Replace("-1", "*") + " \u279C " + Configuration.CompatibleVersions[key].compatibleWithVersion[i], this.labelStyle); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("X", this.buttonStyleRed, GUILayout.Width(25), GUILayout.Height(25))) + { + GuiHelper.UpdateCompatibilityState(OverrideType.version, null, Configuration.CompatibleVersions[key].currentVersion + "," + Configuration.CompatibleVersions[key].compatibleWithVersion[i], true); + //if (Configuration.CompatibleVersions[key].compatibleWithVersion[i] == AddonInfo.ActualKspVersion.ToString() ) + //{ + // for (int i1 = 0; i1 < versions.Count(); i1++) + // { + // if (versions[i1] == Configuration.CompatibleVersions[key].currentVersion.Replace("-1", "*")) + // { + // enabledCompatVersions[i1] = false; + // } + // } + //} + } + GUILayout.EndHorizontal(); + } + } + Configuration.DeleteFinally(); + } + + //void InitEnabledCompatVersions() + //{ + // for (int i = 0; i < versions.Count(); i++) + // { + // string v = versions[i].Replace("*", "-1"); + // CompatVersions cv; + // if (Configuration.CompatibleVersions.TryGetValue(v, out cv)) + // { + // VersionInfo vi = new VersionInfo(Versioning.version_major, Versioning.version_minor, Versioning.Revision, 0); + + // if (cv.compatWithVersion.Contains(vi)) + // { + // enabledCompatVersions[i] = true; + // } + // } + // } + //} + + //void CheckCompatVersion(string version) + //{ + // Debug.Log("CheckCompatVersion, version: " + version); + // for (int i = 0; i < versions.Count(); i++) + // { + // Debug.Log("versions[" + i + "]: " + versions[i]); + // if (version == versions[i]) + // enabledCompatVersions[i] = true; + // } + //} + + //void DrawStdCompatToggles() + //{ + // if (Configuration.OverrideIsDisabledGlobal) + // return; + // for (int i = 0; i < versions.Count(); i++) + // { + // Debug.Log("DrawStdCompatToggles, i:" + i); + // GUILayout.BeginHorizontal(); + // bool b = GUILayout.Toggle(enabledCompatVersions[i], versions[i]); + // if (b != enabledCompatVersions[i]) + // { + // string v = versions[i].Replace("*", "-1"); + // enabledCompatVersions[i] = b; + // if (enabledCompatVersions[i]) + // { + // GuiHelper.UpdateCompatibilityState(OverrideType.version, null, v); + // Logger.Log($"AVC Compatibility Override, Version input: " + v); + // } + // else + // { + // GuiHelper.UpdateCompatibilityState(OverrideType.version , null, v + "," + AddonInfo.ActualKspVersion.ToString(), true); + // Logger.Log($"AVC Compatibility Override remove , Version input: " + v); + // } + // } + // GUILayout.EndHorizontal(); + // } + //} + + private void DrawInputOverrideVersion() + { + GUILayout.BeginHorizontal(); + GuiHelper.userInput = GUILayout.TextField(GuiHelper.userInput, GUILayout.Width(150.0f), GUILayout.Height(20)); + if (GUILayout.Button("ADD", this.buttonStyle, GUILayout.Width(75), GUILayout.Height(20))) + { + Logger.Log("userInput: " , GuiHelper.userInput); + //CheckCompatVersion(GuiHelper.userInput); + GuiHelper.UpdateCompatibilityState(OverrideType.version, null, GuiHelper.userInput); + + Logger.Log($"AVC Compatibility Override, Version input: {GuiHelper.userInput}"); + } + GUILayout.EndHorizontal(); + } + +#endregion + +#region WindowOverrideAddonList + + private void DrawOverrideAddonList() + { + GUILayout.BeginVertical(); + DrawHeadingsAddonList(); + scrollPositionAddonList = GUILayout.BeginScrollView(scrollPositionAddonList, this.scrollList, GUILayout.MinWidth(430), GUILayout.Height(300)); + DrawIncompatibleMods(); + GUILayout.EndScrollView(); + GUILayout.EndVertical(); + } + + private void DrawHeadingsAddonList() + { + GUILayout.BeginHorizontal(); + GUILayout.Space(55); + GUILayout.Label("INCOMPATIBLE ADDON", this.topLevelTitleStyle, GUILayout.MinWidth(230.0f)); + GUILayout.Space(10); + GUILayout.Label("FOR KSP", this.topLevelTitleStyle, GUILayout.MinWidth(60)); + GUILayout.EndHorizontal(); + } + + private void DrawIncompatibleMods() + { + if (Configuration.OverrideIsDisabledGlobal) + { + DrawDisabled(); + return; + } + List listIncompatibleMods = AddonLibrary.Addons.Where(a => !a.IsCompatible).OrderBy(a => a.Name).ToList(); + int m = listIncompatibleMods.Count(); + if (m == 0) + { + DrawNoIncompatibleAddons(); + return; + } + if (Configuration.ShowDefaultValues) + { + DrawDefaultValues(); + } + for (int i = 0; i < m; i++) + { + Addon addon = listIncompatibleMods[i]; + GUIStyle coloredLabel = (GuiHelper.CompatibilityState(OverrideType.version, addon) || GuiHelper.CompatibilityState(OverrideType.name, addon)) ? this.labelStyleCyan : GuiHelper.CompatibilityState(OverrideType.ignore, addon) ? this.labelStyleIgnore : this.labelStyleYellow; //highlighting ignored mods + VersionInfo versionNumber = addon.LocalInfo.KspVersionMaxIsNull && addon.LocalInfo.KspVersionMinIsNull ? addon.LocalInfo.KspVersion : addon.LocalInfo.KspVersionMax; + + GUILayout.BeginHorizontal(); + DrawButtonArrowLeft(addon); + GUILayout.Space(18); + GUILayout.Label(addon.Name, coloredLabel, GUILayout.MinWidth(230.0f)); + GUILayout.Space(10); + GUILayout.Label($"{versionNumber}", coloredLabel, GUILayout.MinWidth(65)); + GUILayout.Space(18); + DrawButtonArrowRight(addon); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } + } + + private void DrawDefaultValues() + { + for (int i = 0; i < versions.Count(); i++) + { + GUIStyle coloredLabel = GuiHelper.CompatibilityState(OverrideType.version, null, versions[i]) ? this.labelStyleCyan : this.labelStyleYellow; + GUILayout.BeginHorizontal(); + GUILayout.Space(51); + GUILayout.Label("(PRESET) Enable Override for:", coloredLabel, GUILayout.MinWidth(230.0f)); + GUILayout.Space(10); + GUILayout.Label(versions[i], coloredLabel, GUILayout.MinWidth(65)); + GUILayout.Space(18); + DrawButtonArrowRight(versions[i]); + GUILayout.FlexibleSpace(); + GUILayout.EndHorizontal(); + } + } + + private void DrawButtonArrowRight(Addon addon) + { + if (GuiHelper.CompatibilityState(OverrideType.locked, addon) || GuiHelper.CompatibilityState(OverrideType.name, addon)) + { + GUILayout.Space(25); //fill the space which would usually taken by the button at this position + return; + } + + GUIStyle coloredButtonStyle = GuiHelper.CompatibilityState(OverrideType.version, addon) ? buttonStyleGreen : buttonStyle; + string buttonLabel = "\u25B6"; //unicode for a triangle, pointing to the right + if (GUILayout.Button(buttonLabel, coloredButtonStyle, GUILayout.Width(25), GUILayout.Height(25))) + { + if (!GuiHelper.CompatibilityState(OverrideType.version, addon)) + { + GuiHelper.UpdateCompatibilityState(OverrideType.version, null, addon.LocalInfo.KspVersionMaxIsNull && addon.LocalInfo.KspVersionMinIsNull ? addon.LocalInfo.KspVersion.ToString() : addon.LocalInfo.KspVersionMax.ToString()); + } + } + } + + private void DrawButtonArrowRight(string VersionNumber) + { + GUIStyle coloredButtonStyle = GuiHelper.CompatibilityState(OverrideType.version, null, VersionNumber) ? buttonStyleGreen : buttonStyle; + string buttonLabel = "\u25B6"; //unicode for a triangle, pointing to the right + if (GUILayout.Button(buttonLabel, coloredButtonStyle, GUILayout.Width(25), GUILayout.Height(25))) + { + if (!GuiHelper.CompatibilityState(OverrideType.version, null, VersionNumber)) + { + GuiHelper.UpdateCompatibilityState(OverrideType.version, null, VersionNumber); + } + } + } + + private void DrawButtonArrowLeft(Addon addon) + { + if (GuiHelper.CompatibilityState(OverrideType.locked, addon) || (GuiHelper.CompatibilityState(OverrideType.version, addon) && !GuiHelper.CompatibilityState(OverrideType.ignore, addon))) + { + GUILayout.Space(33); //fill the space which would usually taken by the button at this position + return; + } + + GUIStyle coloredButtonStyle = GuiHelper.CompatibilityState(OverrideType.name, addon) ? buttonStyleGreen : buttonStyle; + string buttonLabel = "\u25C0"; //unicode for a triangle, pointing to the left + if (GUILayout.Button(buttonLabel, coloredButtonStyle, GUILayout.Width(25), GUILayout.Height(25))) + { + if (!GuiHelper.CompatibilityState(OverrideType.name, addon)) + { + GuiHelper.UpdateCompatibilityState(OverrideType.name, addon); + } + } + } + +#endregion + +#region WindowOverrideNameList + + private void DrawOverrideNameList() + { + GUILayout.BeginVertical(); + DrawHeadingsOverrideInfo(); + scrollPositionNameList = GUILayout.BeginScrollView(scrollPositionNameList, this.scrollList, GUILayout.Width(230), GUILayout.Height(300)); + DrawCompatibleByName(); + GUILayout.EndScrollView(); + GUILayout.EndVertical(); + } + + private void DrawHeadingsOverrideInfo() + { + GUILayout.BeginHorizontal(); + GUILayout.Label("ALWAYS COMPATIBLE", this.topLevelTitleStyle, GUILayout.MinWidth(200)); + GUILayout.EndHorizontal(); + } + + private void DrawCompatibleByName() + { + if (Configuration.OverrideIsDisabledGlobal) + { + DrawDisabled(); + return; + } + List listCompatibleByName = AddonLibrary.Addons.Where(a => a.IsForcedCompatibleByName).OrderBy(a => a.Name).ToList(); + int m = listCompatibleByName.Count(); + for (int i = 0; i < m; i++) + { + var addon = listCompatibleByName[i]; + GUILayout.BeginHorizontal(); + GUILayout.Label(addon.Name, this.labelStyle, GUILayout.MinWidth(190.0f)); + GUILayout.FlexibleSpace(); + if (GUILayout.Button("X", this.buttonStyleRed, GUILayout.Width(25), GUILayout.Height(25))) + { + GuiHelper.UpdateCompatibilityState(OverrideType.name, addon); + } + GUILayout.EndHorizontal(); + } + } + +#endregion + +#region WindowAdvancedSettings + + private void DrawCompatibilityOverrideGui2() + { + GUILayout.BeginVertical(); + GUILayout.BeginHorizontal(); + DrawOverrideNameList(); + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + } + +#endregion + +#region MainWindow + + private void DrawCompatibilityOverrideGui() + { + GUILayout.BeginVertical(); + GUILayout.BeginHorizontal(); + DrawOverrideNameList(); + GUILayout.Space(10); + DrawOverrideAddonList(); + GUILayout.Space(13); + DrawOverrideVersionInfo(); + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + } + + private void Window(int id) + { + this.DrawCompatibilityOverrideGui(); + DrawEnableDisableButton(); + DrawBottomButtons(); + GUI.DragWindow(); + } + + private void DrawBottomButtons() + { + GUILayout.BeginHorizontal(); + if (GUILayout.Button("ADVANCED SETTINGS", this.buttonStyle, GUILayout.Width(180))) + { + if (!this.GetComponent()) + { + this.gameObject.AddComponent(); + return; + } + else + { + Destroy(this.GetComponent()); + } + } + GUILayout.FlexibleSpace(); + if (GUILayout.Button("RESET", this.buttonStyle, GUILayout.Width(180))) + { + for (int i = 0; i < versions.Count(); i++) + enabledCompatVersions[i] = false; + + foreach (Addon addon in AddonLibrary.Addons.Where(x => !x.IsCompatible)) + { + if (GuiHelper.CompatibilityState(OverrideType.ignore, addon)) + { + Configuration.RemoveFromIgnore(addon); + } + if (GuiHelper.CompatibilityState(OverrideType.name, addon)) + { + Configuration.RemoveOverrideName(addon); + } + } + if (Configuration.CompatibleVersions.Count != 0) + { + Configuration.CompatibleVersions.Clear(); + } + } + GUILayout.FlexibleSpace(); + if (GUILayout.Button("HELP", this.buttonStyle, GUILayout.Width(180))) + { + if (!this.GetComponent()) + { + this.gameObject.AddComponent(); + return; + } + else + { + Destroy(this.GetComponent()); + } + } + GUILayout.FlexibleSpace(); + if (GUILayout.Button("CLOSE", this.buttonStyle, GUILayout.Width(180))) + { + Configuration.SaveCfg(); + Destroy(this); + } + GUILayout.EndHorizontal(); + } + + private void CentreWindow() + { + if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) + { + return; + } + this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); + this.hasCentred = true; + } + + #endregion + +#region Styles + + private void InitialiseStyles() + { + this.buttonStyle = new GUIStyle(HighLogic.Skin.button) + { + normal = + { + textColor = Color.white + }, + fontStyle = FontStyle.Bold, + }; + + this.buttonStyleGreen = new GUIStyle(HighLogic.Skin.button) + { + normal = + { + textColor = Color.green + }, + fontStyle = FontStyle.Bold, + }; + + this.buttonStyleRed = new GUIStyle(HighLogic.Skin.button) + { + normal = + { + textColor = Color.red + }, + fontStyle = FontStyle.Bold, + }; + + this.scrollList = new GUIStyle(HighLogic.Skin.box); + + this.topLevelTitleStyle = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.white + }, + alignment = TextAnchor.MiddleLeft, + fontStyle = FontStyle.Bold, + }; + + this.centeredTitelStyle = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.red + }, + alignment = TextAnchor.MiddleCenter, + fontStyle = FontStyle.Bold, + }; + + this.buttonStyleRed = new GUIStyle(HighLogic.Skin.button) + { + normal = + { + textColor = Color.red + }, + fontStyle = FontStyle.Bold, + }; + + this.labelStyle = new GUIStyle(HighLogic.Skin.label) + { + alignment = TextAnchor.MiddleLeft + }; + + this.labelStyleBold = new GUIStyle(HighLogic.Skin.label) + { + fontSize = 16, + fontStyle = FontStyle.Bold, + alignment = TextAnchor.MiddleCenter + }; + + this.labelStyleYellow = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.yellow + }, + alignment = TextAnchor.MiddleLeft, + }; + + this.labelStyleCyan = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.cyan + }, + alignment = TextAnchor.MiddleLeft, + }; + + this.labelStyleIgnore = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.yellow + }, + fontStyle = FontStyle.BoldAndItalic, + }; + } +#endregion + } +} diff --git a/KSP-AVC/CompatibilityOverrideHelpGui.cs b/KSP-AVC/CompatibilityOverrideHelpGui.cs new file mode 100644 index 0000000..fe592a4 --- /dev/null +++ b/KSP-AVC/CompatibilityOverrideHelpGui.cs @@ -0,0 +1,208 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; + +namespace KSP_AVC +{ + class CompatibilityOverrideHelpGui : MonoBehaviour + { + #region Fields + + private GUIStyle boxStyle; + private GUIStyle buttonStyle; + private bool hasCentred; + private GUIStyle labelStyle; + private Rect position = new Rect(Screen.width, Screen.height,640, 800); + private GUIStyle topLevelTitleStyle; + + #endregion + + #region Methods: protected + + protected void Awake() + { + try + { + DontDestroyOnLoad(this); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + Logger.Log("Awake CompatibilityOverrideHelpGui."); + } + + protected void Start() + { + try + { + this.InitialiseStyles(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + protected void OnDestroy() + { + if (Configuration.CfgUpdated) + { + Configuration.SaveCfg(); + } + Logger.Log("Destroyed CompatibilityOverrideHelpGui."); + } + + protected void OnGUI() + { + try + { + this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KSP Add-on Version Checker - Help", HighLogic.Skin.window); + this.CentreWindow(); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + } + + #endregion + + #region HelpWindow + Vector2 scrollPos; + + private void DrawHelpWindow() + { + scrollPos = GUILayout.BeginScrollView(scrollPos); + GUILayout.BeginVertical(); + GUILayout.Label("Compatibility Override", this.topLevelTitleStyle); + GUILayout.BeginHorizontal(this.boxStyle,GUILayout.Width(600)); + DrawHelpGeneral(); + GUILayout.EndHorizontal(); + GUILayout.Label("How to use the Override", this.topLevelTitleStyle); + GUILayout.BeginHorizontal(this.boxStyle, GUILayout.Width(600)); + DrawHelpOverride(); + GUILayout.EndHorizontal(); + GUILayout.Label("Always Compatible", this.topLevelTitleStyle); + GUILayout.BeginHorizontal(this.boxStyle, GUILayout.Width(600)); + DrawHelpAlwaysOverride(); + GUILayout.EndHorizontal(); + GUILayout.Label("Compat. Version Override", this.topLevelTitleStyle); + GUILayout.BeginHorizontal(this.boxStyle, GUILayout.Width(600)); + DrawHelpVersionOverride(); + GUILayout.EndHorizontal(); + GUILayout.EndVertical(); + GUILayout.EndScrollView(); + } + + private void DrawHelpGeneral() + { + GUILayout.Label("The Compatibility Override provides you some control over the AVC Add-on Version Checker." + + "\nIt allows you to set an addon to be compatible with a different game version than the one written in the .version file.", this.labelStyle); + } + + private void DrawHelpAlwaysOverride() + { + GUILayout.Label("The left panel, lists addons which will bypass the compatibility check at all. If a name is on this list," + + "\n\nAVC will no longer report any compatibility issues with this addon." + + "\n\nYou can add mod names by clicking the \u25C0 button in the center panel, and remove mod names by clicking the red X", this.labelStyle); + } + + private void DrawHelpOverride() + { + GUILayout.Label( + "The main window has three panels. The center panel is the most important to understand.\n" + + + "The center panel shows a list of all addons which are currently reported as incompatible with the running game version," + + " and the max. game version which is allowed by the .version file. " + + "\n\nThe addon names are color-coded:" + + "\n Yellow = incompatible" + + "\n Blue = affected by any compatibility override" + + "\n\nThe list also contains two buttons: \u25C0 and \u25B6" + + "\nThese buttons allow you to put an addon name on the \"ALWAYS COMPATIBLE\" list or to draft the version number to the \"VERSION OVERRIDE\" list. " + + "If these buttons don't appear, the addon creator doesn't allow any compatibility overrides. " + + "Update notifications are still provided. in any case", this.labelStyle); + } + + private void DrawHelpVersionOverride() + { + GUILayout.Label("This panel provides control over the compatibility between addons and the game. This will affect many addons at once. " + + "An active version override is displayed like this:" + + "\n\n 1.4.1 \u279C 1.6.1" + + "\n\nIn this example, any addon which is compatible with KSP 1.4.1, will become compatible with KSP 1.6.1. " + + "\n\nThere are different ways to add version numbers:" + + "\n\n1. If the \u25B6 button is used to add a version number to this list, it will always be set to be compatible with the curent game version. " + + "\n2. There is a list of toggles listing several prior versions of KSP with a wildcard, clicking the toggle will add that version to the list" + + "\n3. You can type in one or more version numbers into the text field and click on the \"ADD\" button. Multiple versions need to be separated by a comma and will " + + "set the first version number to be compatible with every other game version followed." + + "\n\nA single version number will be handled like the \u25B6 button. " + + "\n\nYou can also use a wildcard/asterisk on a single version number, but just on the third (patch) number. " + + "In order to set each KSP 1.4.x version to be compatible, type in \" 1.4.* \" and click on \"ADD\"." + + "\n\nClick the red X to remove a line", this.labelStyle); + } + + #endregion + + #region Methods : Private + + private void Window(int id) + { + this.DrawHelpWindow(); + if (GUILayout.Button("CLOSE", this.buttonStyle)) + { + Destroy(this); + } + GUI.DragWindow(); + } + + private void CentreWindow() + { + if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) + { + return; + } + this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); + this.hasCentred = true; + } + + #endregion + + #region Styles + + private void InitialiseStyles() + { + this.boxStyle = new GUIStyle(HighLogic.Skin.box) + { + padding = new RectOffset(10, 10, 5, 5), + }; + + this.buttonStyle = new GUIStyle(HighLogic.Skin.button) + { + normal = + { + textColor = Color.white + }, + fontStyle = FontStyle.Bold, + }; + + this.labelStyle = new GUIStyle(HighLogic.Skin.label) + { + alignment = TextAnchor.MiddleLeft + }; + + this.topLevelTitleStyle = new GUIStyle(HighLogic.Skin.label) + { + normal = + { + textColor = Color.white + }, + alignment = TextAnchor.MiddleLeft, + fontStyle = FontStyle.Bold, + }; + } + + #endregion + } +} diff --git a/KSP-AVC/Configuration.cs b/KSP-AVC/Configuration.cs index f2c9e50..18332c2 100644 --- a/KSP-AVC/Configuration.cs +++ b/KSP-AVC/Configuration.cs @@ -21,16 +21,51 @@ using System.IO; using System.Reflection; using System.Xml.Serialization; - +using System.Collections.Generic; +using System.Linq; #endregion namespace KSP_AVC { + public enum LocalRemotePriority { none, local, remote }; + public class CompatVersions + { + public string currentVersion; + public List compatibleWithVersion; + + public VersionInfo curVersion; + public List compatWithVersion; + + public void AddCompatibleWithVersion(string version) + { + if(!this.compatibleWithVersion.Contains(version)) + { + this.compatibleWithVersion.Add(version); + this.compatWithVersion.Add(new VersionInfo(version)); + return; + } + //Logger.Log($"Cannot add {version} to the compatibility list, entry already exists"); + } + + public void RemoveCompatibleWithVersion(string version) + { + if(this.compatibleWithVersion.Contains(version)) + { + this.compatibleWithVersion.Remove(version); + this.compatWithVersion.Remove(new VersionInfo(version)); + return; + } + //Logger.Log($"Cannot remove {version} from the compatibility list, entry doesn't exists"); + } + } + public class Configuration { #region Fields - + private static readonly string fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "xml"); + readonly static string AvcConfigFile = KSPUtil.ApplicationRootPath + "GameData/KSP-AVC/PluginData/AVC.cfg"; + readonly static string AvcConfigFilePath = KSPUtil.ApplicationRootPath + "GameData/KSP-AVC/PluginData"; #endregion @@ -56,10 +91,138 @@ static Configuration() public string Version { get; set; } + public static List OverrideCompatibilityByName { get; private set; } = new List(); + + public static bool OverrideIsDisabledGlobal { get; set; } + + public static int AvcInterval { get; set; } + + public static DateTime NextRun { get; private set; } + + public static bool CfgUpdated { get; set; } + + //public static bool UseKspSkin { get; set; } + + public static List ToDelete { get; private set; } = new List(); + + public static bool ShowDefaultValues { get; set; } + #endregion #region Methods: public + public static void ToggleOverrideFeature() + { + OverrideIsDisabledGlobal = !OverrideIsDisabledGlobal; + CfgUpdated = true; + } + + public static void AddOverrideName(Addon addon) + { + if(!OverrideCompatibilityByName.Contains(addon.Name)) + { + OverrideCompatibilityByName.Add(addon.Name); + //Logger.Log($"Compatibility Override (by name) enabled for {addon.Name}"); + CfgUpdated = true; + return; + } + //Logger.Log($"Cannot add {addon.Name}, entry already exists."); //Should never happen but just in case + } + + public static void RemoveOverrideName(Addon addon) + { + if (OverrideCompatibilityByName.Contains(addon.Name)) + { + OverrideCompatibilityByName.Remove(addon.Name); + //Logger.Log($"Compatibility Override (by name) disabled for {addon.Name}"); + CfgUpdated = true; + return; + } + //Logger.Log($"Cannot remove {addon.Name}. Entry doesn't exists."); //Should never happen but just in case + } + + public static void AddOverrideVersion(string oldVersion, string newVersion) + { + string tempOldVersion = oldVersion.Replace("*", "-1"); + + //check if there is already an dictionary key which contains the oldversion + var dictKeys = CompatibleVersions.Keys; + if (dictKeys.Contains(tempOldVersion)) + { + //add an additional new version to the list of compatible versions + CompatibleVersions[tempOldVersion].AddCompatibleWithVersion(newVersion); + CfgUpdated = true; + return; + } + + //If the key doesn't match, we have to create a whole new dictionary entry + //Basically the same code which is used to load the config + CompatVersions cv = new CompatVersions(); + + cv.currentVersion = tempOldVersion; + cv.curVersion = new VersionInfo(cv.currentVersion); + cv.compatibleWithVersion = new List(); + cv.compatWithVersion = new List(); + + cv.compatibleWithVersion.Add(newVersion); + cv.compatWithVersion.Add(new VersionInfo(newVersion)); + CompatibleVersions.Add(cv.currentVersion, cv); + CfgUpdated = true; + } + + public static void RemoveOverrideVersion(string oldVersion, string newVersion) + { + var dictKeys = CompatibleVersions.Keys; + string tempOldVersion = oldVersion.Replace("*", "-1"); + + if (dictKeys.Contains(tempOldVersion)) + { + if(CompatibleVersions[tempOldVersion].compatibleWithVersion.Count == 1) + { + //CompatibleVersions.Remove(oldVersion); + ToDelete.Add(tempOldVersion); //need to collect keys which are meant to be deleted, bad things will happen if you try this while iterating over the dictionary :o + CfgUpdated = true; + return; + } + CompatibleVersions[tempOldVersion].RemoveCompatibleWithVersion(newVersion); + CfgUpdated = true; + } + } + + public static void DeleteFinally() + { + if (ToDelete.Count > 0) + { + foreach (string version in ToDelete) + { + CompatibleVersions.Remove(version); + } + ToDelete.Clear(); + } + } + + public static void AddToIgnore(Addon addon) + { + if(!modsIgnoreOverride.Contains(addon.Name)) + { + modsIgnoreOverride.Add(addon.Name); + //Logger.Log($"{addon.Name} added to ignore list."); + CfgUpdated = true; + } + //Logger.Log($"Cannot add {addon.Name} to ignore list, entry already exists."); + } + + public static void RemoveFromIgnore(Addon addon) + { + if (modsIgnoreOverride.Contains(addon.Name)) + { + modsIgnoreOverride.Remove(addon.Name); + //Logger.Log($"{addon.Name} removed from ignore list."); + CfgUpdated = true; + } + //Logger.Log($"Cannot remove {addon.Name} from ignore list, doesn't exists."); + } + public static bool GetFirstRun() { return Instance.FirstRun; @@ -121,6 +284,258 @@ public static void SetVersion(string value) Save(); } - #endregion + public static void SaveCfg() + { + Logger.Log("SaveCfg"); + CfgUpdated = false; + + if (!File.Exists(AvcConfigFile) || !Directory.Exists(AvcConfigFilePath)) + { + Directory.CreateDirectory(AvcConfigFilePath); + var ConfigFileStream = File.Create(AvcConfigFile); + ConfigFileStream.Close(); //avoid System.IO access violation + //Some default values so this method can create a config file + //modsIgnoreOverride.Add("Kopernicus"); //Unfortunately, the name of Kopernicus is actually "Kopernicus" which may irritates some users + OverrideIsDisabledGlobal = true; + ShowDefaultValues = true; + AvcInterval = 0; + //UseKspSkin = true; + CfgUpdated = true; + //For some reason, if a config file is missing, it will just create an empty config. + //By setting the bool CfgUpdated = true, this method will run again on destroy of the starter, which creates the empty config nodes within the file. + } + + ConfigNode cfgnode = new ConfigNode(); + ConfigNode KSPAVC = cfgnode.AddNode("KSP-AVC"); + + //KSPAVC.AddValue("KSP_SKIN", UseKspSkin); + KSPAVC.AddValue("OVERRIDE_PRIORITY", OverridePriority); + KSPAVC.AddValue("SIMPLE_PRIORITY", SimplePriority); + KSPAVC.AddValue("DISABLE_COMPATIBLE_VERSION_OVERRIDE", OverrideIsDisabledGlobal); + KSPAVC.AddValue("SHOW_DEFAULT_VALUES", ShowDefaultValues); +#if STRICT + KSPAVC.AddValue("STRICT_VERSION", StrictVersion); +#endif + + ConfigNode OverrideName = KSPAVC.AddNode("OVERRIDE_NAME"); + foreach (string ModName in OverrideCompatibilityByName) + { + OverrideName.AddValue("OverrideEnabled", ModName); + } + + ConfigNode OverrideVersion = KSPAVC.AddNode("OVERRIDE_VERSION"); + foreach (KeyValuePair kvp in CompatibleVersions) + { + string temp = kvp.Key.Replace("-1", "*"); + for (int i = 0; i < kvp.Value.compatibleWithVersion.Count; i++) + { + temp = temp + $", {kvp.Value.compatibleWithVersion[i]}"; + } + OverrideVersion.AddValue("OverrideEnabled", temp); + } + + ConfigNode OverrideIgnore = KSPAVC.AddNode("OVERRIDE_IGNORE"); + foreach (string ModName in modsIgnoreOverride) + { + OverrideIgnore.AddValue("IgnoreOverride", ModName); + } + + ConfigNode Interval = KSPAVC.AddNode("INTERVAL"); + { + Interval.AddValue("MinTimeBetweenAvcRuns", AvcInterval.ToString() + " //Timespan between AVC runs in hours"); + + if(DateTime.Compare(DateTime.Now, NextRun) >= 0 && AvcInterval > 0) + { + Interval.AddValue("AvcRunsNext", DateTime.Now.AddHours(AvcInterval).ToString()); + CfgUpdated = true; + } + else + { + Interval.AddValue("AvcRunsNext", NextRun.ToString()); + } + } + cfgnode.Save(AvcConfigFile); + } + + public static void LoadCfg() + { + Logger.Log("LoadCfg"); + OverridePriority = LocalRemotePriority.none; + SimplePriority = LocalRemotePriority.none; + CfgUpdated = false; + //Logger.Log("KSP-AVC node count: " + GameDatabase.Instance.GetConfigNodes("KSP-AVC").Length); + //foreach (ConfigNode node in GameDatabase.Instance.GetConfigNodes("KSP-AVC")) + if (!File.Exists(AvcConfigFile)) + { + SaveCfg(); + return; + } + + ConfigNode LoadNodeFromFile = ConfigNode.Load(AvcConfigFile); + ConfigNode node = LoadNodeFromFile.GetNode("KSP-AVC"); + + //if (node.HasValue("KSP_SKIN")) + //{ + // try + // { + // if (node.GetValue("KSP_SKIN").ToLower() == "false") + // UseKspSkin = false; + // else + // UseKspSkin = true; + // //Logger.Log($"UseKspSkin: {UseKspSkin}"); + // } + // catch { } + //} + if (node.HasValue("OVERRIDE_PRIORITY")) + { + try + { + OverridePriority = (LocalRemotePriority)Enum.Parse(typeof(LocalRemotePriority), node.GetValue("OVERRIDE_PRIORITY")); + //Logger.Log("OverridePriority: " + OverridePriority); + } + catch { } + } + if (node.HasValue("SIMPLE_PRIORITY")) + { + try + { + SimplePriority = (LocalRemotePriority)Enum.Parse(typeof(LocalRemotePriority), node.GetValue("SIMPLE_PRIORITY")); + //Logger.Log("SimplePriority: " + SimplePriority); + } + catch { } + } + if(node.HasValue("DISABLE_COMPATIBLE_VERSION_OVERRIDE")) + { + try + { + if (node.GetValue("DISABLE_COMPATIBLE_VERSION_OVERRIDE").ToLower() == "false") + OverrideIsDisabledGlobal = false; + else + OverrideIsDisabledGlobal = true; + //Logger.Log($"OverrideIsDisabled: {OverrideIsDisabledGlobal}"); + } + catch { } + } + if (node.HasValue("SHOW_DEFAULT_VALUES")) + { + try + { + if (node.GetValue("SHOW_DEFAULT_VALUES").ToLower() == "false") + ShowDefaultValues = false; + else + ShowDefaultValues = true; + //Logger.Log($"OverrideIsDisabled: {OverrideIsDisabledGlobal}"); + } + catch { } + } +#if STRICT + if (node.HasValue("STRICT_VERSION")) + { + try + { + if (node.GetValue("STRICT_VERSION").ToLower() == "false") + StrictVersion = false; + else + StrictVersion = true; + //Logger.Log($"OverrideIsDisabled: {OverrideIsDisabledGlobal}"); + } + catch { } + } + else + StrictVersion = false; +#endif + if (node.HasNode("OVERRIDE_NAME")) + { + try + { + ConfigNode _temp = new ConfigNode(); + _temp = node.GetNode("OVERRIDE_NAME"); + + OverrideCompatibilityByName = _temp.GetValuesList("OverrideEnabled"); + } + catch { } + } + if (node.HasNode("OVERRIDE_VERSION")) + { + try + { + ConfigNode _temp = new ConfigNode(); + _temp = node.GetNode("OVERRIDE_VERSION"); + var compatVerList = _temp.GetValuesList("OverrideEnabled"); + foreach (var a in compatVerList) + { + CompatVersions cv = new CompatVersions(); + var ar = a.Split(',').Select(x => x.Trim()).ToArray(); + + cv.currentVersion = ar[0].Replace("*", "-1"); + cv.curVersion = new VersionInfo(cv.currentVersion); + cv.compatibleWithVersion = new List(); + cv.compatWithVersion = new List(); //initializing the list before adding stuff to it helps to prevent a NRE :) + for (int i = 1; i < ar.Length; i++) + { + cv.compatibleWithVersion.Add(ar[i]); + cv.compatWithVersion.Add(new VersionInfo(ar[i])); + Logger.Log("OVERRIDE_VERSION, currentVersion: " + ar[0].Replace("-1", "*") + ", compatibleWithVersion: " + ar[i]); + } + CompatibleVersions.Add(cv.currentVersion, cv); + } + } + catch { } + } + if(node.HasNode("OVERRIDE_IGNORE")) + { + try + { + ConfigNode _temp = new ConfigNode(); + _temp = node.GetNode("OVERRIDE_IGNORE"); + + List ignoredMods = _temp.GetValuesList("IgnoreOverride"); + foreach (string modName in ignoredMods) + { + modsIgnoreOverride.Add(modName); + //Logger.Log($"IGNORE_OVERRIDE: {modName}"); + } + } + catch { } + } + if(node.HasNode("INTERVAL")) + { + try + { + ConfigNode _temp = new ConfigNode(); + _temp = node.GetNode("INTERVAL"); + + AvcInterval = Int32.Parse(_temp.GetValue("MinTimeBetweenAvcRuns")); + if(!_temp.HasValue("AvcRunsNext")) + { + CfgUpdated = true; + } + NextRun = DateTime.Parse(_temp.GetValue("AvcRunsNext")); + Logger.Log($"INTERVAL: {AvcInterval}"); + Logger.Log($"NextRun: {NextRun}"); + } + catch { } + } + if (DateTime.Compare(DateTime.Now, NextRun) >= 0 && AvcInterval > 0) + { + CfgUpdated = true; + } + + CfgLoaded = true; + Logger.Flush(); + } + + public static LocalRemotePriority OverridePriority { get; private set; } + public static LocalRemotePriority SimplePriority { get; private set; } +#if STRICT + public static bool StrictVersion { get; private set; } +#endif + public static bool CfgLoaded = false; + + public static List modsIgnoreOverride = new List(); + + public static Dictionary CompatibleVersions = new Dictionary(); + +#endregion } } \ No newline at end of file diff --git a/KSP-AVC/DropDownList.cs b/KSP-AVC/DropDownList.cs index 3c337fc..cd7e2cd 100644 --- a/KSP-AVC/DropDownList.cs +++ b/KSP-AVC/DropDownList.cs @@ -59,7 +59,7 @@ public class DropDownList : MonoBehaviour public void DrawButton(string label, Rect parent, float width) { this.ShowList = GUILayout.Toggle(this.ShowList, label, this.toggleStyle, GUILayout.Width(width)); - if (Event.current.type == EventType.repaint) + if (Event.current.type == EventType.Repaint) { this.SetPosition(GUILayoutUtility.GetLastRect(), parent); } diff --git a/KSP-AVC/FirstRunGui.cs b/KSP-AVC/FirstRunGui.cs index a4c4a2e..9b20081 100644 --- a/KSP-AVC/FirstRunGui.cs +++ b/KSP-AVC/FirstRunGui.cs @@ -58,7 +58,6 @@ protected void Awake() { Logger.Exception(ex); } - Logger.Log("FirstRunGui was created."); } protected void OnDestroy() diff --git a/KSP-AVC/GuiHelper.cs b/KSP-AVC/GuiHelper.cs new file mode 100644 index 0000000..14f140e --- /dev/null +++ b/KSP-AVC/GuiHelper.cs @@ -0,0 +1,220 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using System.Text.RegularExpressions; + +//Helper class to keep up an update method which checks for the key combination needed to open the GUI +namespace KSP_AVC +{ + public enum OverrideType { name, version, ignore, locked }; + + public class GuiHelper : MonoBehaviour + { + public static string userInput { get; set; } + + protected void Awake() + { + try + { + DontDestroyOnLoad(this); + } + catch (Exception ex) + { + Logger.Exception(ex); + } + this.name = "GuiHelper"; + Logger.Log("GuiHelper was created"); + } + + protected void Update() + { + bool modKey = GameSettings.MODIFIER_KEY.GetKey(); + if (modKey && Input.GetKeyDown(KeyCode.Alpha2)) + { + if (this.GetComponent()) + { + Destroy(this.GetComponent()); + return; + } + ToggleGUI(); + } + if (HighLogic.LoadedScene == GameScenes.SPACECENTER) + { + Destroy(this.gameObject); + } + } + + protected void OnDestroy() + { + Logger.Log("GuiHelper was destroyed"); + } + + public void ToggleGUI() + { + if(Configuration.OverrideIsDisabledGlobal) + { + this.gameObject.AddComponent(); + return; + } + if (!this.GetComponent()) + { + this.gameObject.AddComponent(); + return; + } + else + { + Destroy(this.GetComponent()); + } + } + + public static bool CompatibilityState(OverrideType type, Addon addon, string oldVersion = "") //requires -1 instead of * + { + switch (type) + { + case OverrideType.name: + { + return addon.IsForcedCompatibleByName; + } + + case OverrideType.version: + { + if (oldVersion != "") + { + oldVersion = oldVersion.Replace("*", "-1"); + bool b = (from d in Configuration.CompatibleVersions + where oldVersion == d.Key + where d.Value.compatWithVersion.Contains(AddonInfo.ActualKspVersion) + select d).Any(); + return b; + } + return addon.IsForcedCompatibleByVersion; + } + + case OverrideType.ignore: + { + return Configuration.modsIgnoreOverride.Contains(addon.Name); + } + case OverrideType.locked: + { + return addon.IsLockedByCreator; + } + + default: + { + return false; + } + } + } + + public static void UpdateCompatibilityState(OverrideType type, Addon addon = null, string versionInfo = "", bool remove = false) + { + switch (type) + { + case OverrideType.name: + { + if (!CompatibilityState(OverrideType.name, addon)) + { + Configuration.AddOverrideName(addon); + return; + } + Configuration.RemoveOverrideName(addon); + return; + } + + case OverrideType.version: + { + if (validateInput(versionInfo)) + { + userInput = ""; + List inputs = reformatInput(versionInfo); + var dictKeys = Configuration.CompatibleVersions.Keys; + + if (dictKeys.Contains(inputs[0]) && remove) + { + int j = inputs.Count(); + for (int i = 1; i < j; i++) //so far, the list will always have just two entries in this case but just to be sure, I've build the loop anyway + { + Configuration.RemoveOverrideVersion(inputs[0], inputs[i]); + } + return; + } + int m = inputs.Count(); + for (int i = 1; i < m; i++) + { + Configuration.AddOverrideVersion(inputs[0], inputs[i]); + } + return; + } + userInput = "INVALID"; + return; + } + + case OverrideType.ignore: + { + if (!CompatibilityState(OverrideType.ignore, addon)) + { + Configuration.AddToIgnore(addon); + return; + } + Configuration.RemoveFromIgnore(addon); + return; + } + + default: + { + Logger.Log("Unable to update compatibility override"); + return; + } + } + } + + private static bool validateInput(string userInput) + { + if (!Regex.IsMatch(userInput, @"[^\d\.\-\*\,\s]")) //matches any character which isn't going to be valid at all + { + string regexPatternMulti = @"(\d\.\d)\,\s?(\d\.\d)"; //just a rough pattern, should filter out most invalid inputs but definitly not all of them + string regexPatternSingle = @"(\d\.\d)"; //checks for at least 2 numbers, sparated by a dot + string regexPatternWildcard = @"\d\.\d\.\*"; //at least one digit + dot + asterisk + bool matchMulti = Regex.IsMatch(userInput, regexPatternMulti); + bool matchSingle = Regex.IsMatch(userInput, regexPatternSingle); + bool matchWildcard = Regex.IsMatch(userInput, regexPatternWildcard); + if (matchWildcard) + { + return true; + } + if (matchMulti) + { + return true; + } + if (matchSingle) + { + return true; + } + return false; + } + return false; + } + + //looks ridiculous stupid but I need a strict format ("old version","new version") for the version list + //funny results if invalid user input slips through the validation + private static List reformatInput(string userInput) + { + string[] splitted = userInput.Split(',').Select(x => x.Trim()).ToArray(); + List reformattedStrings = new List(); + int m = splitted.Length; + for (int i = 0; i < m; i++) + { + reformattedStrings.Add(splitted[i]); + } + if (reformattedStrings.Count == 1) //add the actual KSP version if just a single version number is given + { + VersionInfo actualKspVersion = new VersionInfo(Versioning.version_major, Versioning.version_minor, Versioning.Revision); + reformattedStrings.Add(actualKspVersion.ToString()); + } + + return reformattedStrings; + } + } +} diff --git a/KSP-AVC/InstallChecker.cs b/KSP-AVC/InstallChecker.cs new file mode 100644 index 0000000..a64062d --- /dev/null +++ b/KSP-AVC/InstallChecker.cs @@ -0,0 +1,101 @@ +/** + * Based on the InstallChecker from the Kethane mod for Kerbal Space Program. + * https://github.com/Majiir/Kethane/blob/b93b1171ec42b4be6c44b257ad31c7efd7ea1702/Plugin/InstallChecker.cs + * + * Original is (C) Copyright Majiir. + * CC0 Public Domain (http://creativecommons.org/publicdomain/zero/1.0/) + * http://forum.kerbalspaceprogram.com/threads/65395-CompatibilityChecker-Discussion-Thread?p=899895&viewfull=1#post899895 + * + * This file has been modified extensively and is released under the same license. + */ +using System; +using System.IO; +using System.Linq; +using System.Reflection; +using UnityEngine; + +namespace KSP_AVC +{ + [KSPAddon(KSPAddon.Startup.Instantly, true)] + internal class Startup : MonoBehaviour + { + private void Start() + { + string v = "n/a"; + AssemblyTitleAttribute attributes = (AssemblyTitleAttribute)Attribute.GetCustomAttribute(Assembly.GetExecutingAssembly(), typeof(AssemblyTitleAttribute), false); + string title = attributes?.Title; + if (title == null) + { + title = "TitleNotAvailable"; + } + v = Assembly.GetExecutingAssembly().FullName; + if (v == null) + { + v = "VersionNotAvailable"; + } + Logger.Log("[" + title + "] Version " + v); + } + } + + [KSPAddon(KSPAddon.Startup.MainMenu, true)] + internal class InstallChecker : MonoBehaviour + { + internal const string MODNAME = "KSP Addon Version Checker"; + internal const string FOLDERNAME = "KSP-AVC"; + internal const string FOLDERNAME2 = "ZeroMiniAVC"; + internal const string EXPECTEDPATH = FOLDERNAME + "/Plugins"; + internal const string EXPECTEDPATH2 = FOLDERNAME2 + "/Plugins"; + + protected void Start() + { + // Search for this mod's DLL existing in the wrong location. This will also detect duplicate copies because only one can be in the right place. + var assemblies = AssemblyLoader.loadedAssemblies.Where(a => a.assembly.GetName().Name == Assembly.GetExecutingAssembly().GetName().Name).Where(a => a.url != EXPECTEDPATH && a.url != EXPECTEDPATH2); + if (assemblies.Any()) + { + var badPaths = assemblies.Select(a => a.path).Select(p => Uri.UnescapeDataString(new Uri(Path.GetFullPath(KSPUtil.ApplicationRootPath)).MakeRelativeUri(new Uri(p)).ToString().Replace('/', Path.DirectorySeparatorChar))); + PopupDialog.SpawnPopupDialog + ( + new Vector2(0.5f, 0.5f), + new Vector2(0.5f, 0.5f), + "test", + "Incorrect " + MODNAME + " Installation", + MODNAME + " has been installed incorrectly and will not function properly. All files should be located in KSP/GameData/" + FOLDERNAME + ". Do not move any files from inside that folder.\n\nIncorrect path(s):\n" + String.Join("\n", badPaths.ToArray()), + "OK", + false, + HighLogic.UISkin + ); + Logger.Log("Incorrect " + MODNAME + " Installation: " + MODNAME + " has been installed incorrectly and will not function properly. All files should be located in KSP/GameData/" + EXPECTEDPATH + ". Do not move any files from inside that folder.\n\nIncorrect path(s):\n" + String.Join("\n", badPaths.ToArray()) + + ); + + } + + //// Check for Module Manager + //if (!AssemblyLoader.loadedAssemblies.Any(a => a.assembly.GetName().Name.StartsWith("ModuleManager") && a.url == "")) + //{ + // PopupDialog.SpawnPopupDialog("Missing Module Manager", + // modName + " requires the Module Manager mod in order to function properly.\n\nPlease download from http://forum.kerbalspaceprogram.com/threads/55219 and copy to the KSP/GameData/ directory.", + // "OK", false, HighLogic.Skin); + //} + + CleanupOldVersions(); + } + + /* + * Tries to fix the install if it was installed over the top of a previous version + */ + void CleanupOldVersions() + { + try + { + } + catch (Exception ex) + { + Logger.Error("-ERROR- " + this.GetType().FullName + "[" + this.GetInstanceID().ToString("X") + "][" + Time.time.ToString("0.00") + "]: " + + "Exception caught while cleaning up old files.\n" + ex.Message + "\n" + ex.StackTrace); + + } + } + } +} + diff --git a/KSP-AVC/IssueGui.cs b/KSP-AVC/IssueGui.cs index e42434a..c231771 100644 --- a/KSP-AVC/IssueGui.cs +++ b/KSP-AVC/IssueGui.cs @@ -42,6 +42,8 @@ public class IssueGui : MonoBehaviour private GUIStyle nameTitleStyle; private Rect position = new Rect(Screen.width, Screen.height, 0, 0); private GUIStyle titleStyle; + //private bool isInitialised = false; + #endregion @@ -86,7 +88,7 @@ protected void OnGUI() catch (Exception ex) { Logger.Exception(ex); - } + } } protected void Start() @@ -165,23 +167,42 @@ private void DrawActionListDownload(DropDownList list, Addon addon) Application.OpenURL(addon.RemoteInfo.Download); list.ShowList = false; } - if (Event.current.type == EventType.repaint) + if (Event.current.type == EventType.Repaint) { list.ToolTip.Text = GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) ? list.ToolTip.Text = addon.RemoteInfo.Download : String.Empty; } } + VersionInfo zero = new VersionInfo(); private void DrawCompatibilityIssues() { GUILayout.BeginVertical(this.boxStyle); GUILayout.Label("COMPATIBILITY ISSUES", this.nameTitleStyle); - foreach (var addon in AddonLibrary.Addons.Where(a => !a.IsCompatible)) + foreach (var addon in AddonLibrary.Addons.Where(a => !a.IsCompatible && !a.IsForcedCompatibleByVersion && !a.IsForcedCompatibleByName)) { - GUILayout.Label("The currently installed version of " + addon.Name + " was built to run on KSP " + addon.LocalInfo.KspVersion, this.messageStyle, GUILayout.MinWidth(575.0f)); + if (addon.LocalInfo.IsKspExcludedVersion) + { + GUILayout.Label("The currently installed version of " + addon.Name + " is not compatible with " + + AddonInfo.ActualKspVersion, this.messageStyle, GUILayout.MinWidth(575.0f)); + } + else + { + string built = ""; + if (addon.LocalInfo.KspVersionMinIsNull && addon.LocalInfo.KspVersionMaxIsNull) //|| addon.LocalInfo.KspVersion == addon.LocalInfo.KspVersionMin) + built = " was built to run on KSP " + addon.LocalInfo.KspVersion; + else + { + if (addon.LocalInfo.KspVersionMin == addon.LocalInfo.KspVersionMax) + built = " was built to run on KSP " + addon.LocalInfo.KspVersionMax; + else + built = " was built to run on KSP " + addon.LocalInfo.KspVersionMin + " - " + addon.LocalInfo.KspVersionMax; + } + GUILayout.Label("The currently installed version of " + addon.Name + built, this.messageStyle, GUILayout.MinWidth(575.0f)); + } } GUILayout.EndVertical(); } - + private void DrawUpdateHeadings() { GUILayout.BeginHorizontal(); @@ -216,6 +237,10 @@ private void DrawUpdateIssues() private void InitialiseStyles() { + //if (Configuration.UseKspSkin) + //{ + // GUI.skin = HighLogic.Skin; + //} this.boxStyle = new GUIStyle(HighLogic.Skin.box) { padding = new RectOffset(10, 10, 5, 5) @@ -267,6 +292,8 @@ private void InitialiseStyles() textColor = Color.white } }; + + //isInitialised = true; } private void Window(int id) @@ -277,7 +304,7 @@ private void Window(int id) { this.DrawUpdateIssues(); } - if (AddonLibrary.Addons.Any(a => !a.IsCompatible)) + if (AddonLibrary.Addons.Any(a => !a.IsCompatible && !a.IsForcedCompatibleByVersion && !a.IsForcedCompatibleByName)) { this.DrawCompatibilityIssues(); } diff --git a/KSP-AVC/KSP-AVC.csproj b/KSP-AVC/KSP-AVC.csproj index b4b809a..b7eeadc 100644 --- a/KSP-AVC/KSP-AVC.csproj +++ b/KSP-AVC/KSP-AVC.csproj @@ -9,7 +9,7 @@ Properties KSP_AVC KSP-AVC - v3.5 + v4.5 512 @@ -21,6 +21,7 @@ DEBUG;TRACE prompt 4 + false false @@ -30,6 +31,7 @@ TRACE prompt 4 + false false false @@ -37,10 +39,21 @@ + + True + True + AssemblyVersion.tt + + + + + + + @@ -53,24 +66,24 @@ - - ..\..\..\KSP-Environment\KSP_x64_Data\Managed\Assembly-CSharp.dll + False - - ..\..\Game\KSP_x64_Data\Managed\System.dll - False - - - ..\..\Game\KSP_x64_Data\Managed\System.Xml.dll - False - - - ..\..\..\KSP-Environment\KSP_x64_Data\Managed\UnityEngine.dll + False + + + + + + TextTemplatingFileGenerator + AssemblyVersion.cs + + + + - @@ -85,11 +98,25 @@ $(PostBuildEventDependsOn); PostBuildMacros; - xcopy "$(SolutionDir)Output\KSP-AVC\*" "$(SolutionDir)..\..\KSP-Environment\GameData\KSP-AVC\*" /E /Y -del "$(SolutionDir)Release\KSP-AVC\*" /Q -xcopy "$(SolutionDir)Documents\KSP-AVC\*" "$(SolutionDir)Release\KSP-AVC\Documents\*" /E /Y -7z.exe a -tzip -mx3 "$(SolutionDir)Release\KSP-AVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Output\KSP-AVC" -7z.exe a -tzip -mx3 "$(SolutionDir)Release\KSP-AVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Documents\KSP-AVC\*" + rem del $(KSPDIR)\GameData\KSP-AVC\KSP-AVC.dll + + + + +rem copy D:\Users\jbb\github\KSPAddonVersionChecker\Output\KSP-AVC\KSP-AVC.dll $(KSPDIR)\GameData\KSP-AVC + + +start /D D:\Users\jbb\github\AVC_Mods\KSPAddonVersionChecker /WAIT deploy.bat $(TargetDir) $(TargetFileName) + +if $(ConfigurationName) == Release ( + + start /D D:\Users\jbb\github\AVC_Mods\KSPAddonVersionChecker /WAIT buildRelease.bat $(TargetDir) $(TargetFileName) + +) + + + "$(DevEnvDir)\texttransform.exe" "$(ProjectDir)AssemblyVersion.tt" + + \ No newline at end of file diff --git a/KSP-AVC/KSP-AVC.csproj.orig b/KSP-AVC/KSP-AVC.csproj.orig new file mode 100644 index 0000000..f2e32c9 --- /dev/null +++ b/KSP-AVC/KSP-AVC.csproj.orig @@ -0,0 +1,136 @@ + + + + + Debug + AnyCPU + {F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C} + Library + Properties + KSP_AVC + KSP-AVC + v3.5 + 512 + + + + false + none + false + ..\Output\KSP-AVC\ + DEBUG;TRACE + prompt + 4 + false + + + none + true + ..\Output\KSP-AVC\ + TRACE + prompt + 4 + false + false + + + + + + + True + True + AssemblyVersion.tt + + + + + + + + + + + + + + + + + + + + + + + + R:\KSP_1.7.3_dev\KSP_x64_Data\Managed\Assembly-CSharp.dll + + + + + R:\KSP_1.7.3_dev\KSP_x64_Data\Managed\UnityEngine.dll + + + False + R:\KSP_1.7.3_dev\KSP_x64_Data\Managed\UnityEngine.UI.dll + + + + + TextTemplatingFileGenerator + AssemblyVersion.cs + + + + + + + + + + + + + + + + + $(PostBuildEventDependsOn); + PostBuildMacros; + + rem del R:\KSP_1.7.3_dev\GameData\KSP-AVC\KSP-AVC.dll + + + + +rem copy D:\Users\jbb\github\KSPAddonVersionChecker\Output\KSP-AVC\KSP-AVC.dll R:\KSP_1.7.3_dev\GameData\KSP-AVC + + +start /D D:\Users\jbb\github\KSPAddonVersionChecker /WAIT deploy.bat $(TargetDir) $(TargetFileName) + +if $(ConfigurationName) == Release ( + + start /D D:\Users\jbb\github\KSPAddonVersionChecker /WAIT buildRelease.bat $(TargetDir) $(TargetFileName) + +) + + + +set textTemplatingPath="%25ProgramFiles(x86)%25\Microsoft Visual Studio\2017\Community\Common7\IDE\texttransform.exe" + + + + + +%25textTemplatingPath%25 "$(ProjectDir)AssemblyVersion.tt" + + + + \ No newline at end of file diff --git a/KSP-AVC/Logger.cs b/KSP-AVC/Logger.cs index 0a2ca0e..0f898fe 100644 --- a/KSP-AVC/Logger.cs +++ b/KSP-AVC/Logger.cs @@ -22,6 +22,7 @@ using System.Collections.Generic; using System.IO; using System.Reflection; +using System.Linq; using UnityEngine; @@ -34,18 +35,23 @@ public class Logger : MonoBehaviour { #region Fields - private static readonly AssemblyName assemblyName; - private static readonly string fileName; + private static AssemblyName assemblyName; + private static string fileName; private static readonly List messages = new List(); - + private static string LogsPath = null; #endregion #region Constructors - static Logger() + static void LoggerInit() { + LogsPath = KSPUtil.ApplicationRootPath + "Logs"; + if (!Directory.Exists(LogsPath)) + Directory.CreateDirectory(LogsPath); + assemblyName = Assembly.GetExecutingAssembly().GetName(); - fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "log"); + //fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "log"); + fileName = LogsPath + "/" + assemblyName.Name + ".log"; File.Delete(fileName); lock (messages) @@ -69,6 +75,7 @@ static Logger() #region Methods: public + public static void Blank() { lock (messages) @@ -117,9 +124,9 @@ public static void Flush() foreach (var message in messages) { file.WriteLine(message.Length > 0 ? message.Length > 1 ? "[" + message[0] + "]: " + message[1] : message[0] : string.Empty); - if (message.Length > 0) + if (message.Length > 0 && !Environment.GetCommandLineArgs().Contains("-AVC-log-only")) //thanks @blowfish for suggesting the command line flag { - print(message.Length > 1 ? assemblyName.Name + " -> " + message[1] : assemblyName.Name + " -> " + message[0]); + //print(message.Length > 1 ? assemblyName.Name + " -> " + message[1] : assemblyName.Name + " -> " + message[0]); } } } @@ -127,6 +134,7 @@ public static void Flush() } } +#if false public static void Log(object obj) { lock (messages) @@ -152,6 +160,7 @@ public static void Log(object obj) } } } +#endif public static void Log(string name, object obj) { @@ -162,13 +171,15 @@ public static void Log(string name, object obj) if (obj is IEnumerable) { messages.Add(new[] {"Text " + DateTime.Now.TimeOfDay, name}); + foreach (var o in obj as IEnumerable) { - messages.Add(new[] {"\t", o.ToString()}); + messages.Add(new[] {"\t", o.ToString()}); } } else { + messages.Add(new[] { "Text " + DateTime.Now.TimeOfDay, name }); messages.Add(new[] {"Text " + DateTime.Now.TimeOfDay, obj.ToString()}); } } @@ -195,12 +206,13 @@ public static void Warning(string message) } } - #endregion +#endregion - #region Methods: protected +#region Methods: protected protected void Awake() { + LoggerInit(); DontDestroyOnLoad(this); } @@ -214,6 +226,6 @@ protected void OnDestroy() Flush(); } - #endregion +#endregion } } \ No newline at end of file diff --git a/KSP-AVC/Properties/AssemblyInfo.cs b/KSP-AVC/Properties/AssemblyInfo.cs index 47dea57..7d5d386 100644 --- a/KSP-AVC/Properties/AssemblyInfo.cs +++ b/KSP-AVC/Properties/AssemblyInfo.cs @@ -24,7 +24,7 @@ [assembly: AssemblyTitle("KSP-AVC")] [assembly: AssemblyProduct("KSP-AVC")] -[assembly: AssemblyCopyright("Copyright © 2015 CYBUTEK")] +[assembly: AssemblyCopyright("Copyright © 2015 CYBUTEK, Linuxgurugamer 2018")] [assembly: ComVisible(false)] [assembly: Guid("be1fd3ec-c1ba-47ec-9e16-f83da6fe87d5")] -[assembly: AssemblyVersion("1.1.6.2")] \ No newline at end of file +//[assembly: AssemblyVersion("1.1.6.2")] \ No newline at end of file diff --git a/KSP-AVC/Starter.cs b/KSP-AVC/Starter.cs index 4c69d2d..9c6d8f4 100644 --- a/KSP-AVC/Starter.cs +++ b/KSP-AVC/Starter.cs @@ -20,8 +20,9 @@ using System; using System.Linq; using System.Reflection; - +using System.IO; using UnityEngine; +using System.Threading; #endregion @@ -54,6 +55,7 @@ protected void Awake() { Logger.Exception(ex); } + Logger.Log("Starter was created."); } @@ -74,6 +76,11 @@ protected void OnDestroy() { Logger.Exception(ex); } + + if(Configuration.CfgUpdated) + { + Configuration.SaveCfg(); + } Logger.Log("Starter was destroyed."); } @@ -81,6 +88,23 @@ protected void Start() { try { + if (!Configuration.CfgLoaded) + { + Configuration.LoadCfg(); + } + if(Configuration.AvcInterval == -1) + { + ScreenMessages.PostScreenMessage("AVC disabled", 10); + Destroy(this); + return; + } + else if (DateTime.Compare(DateTime.Now, Configuration.NextRun) <= 0 && Configuration.AvcInterval != 0) + { + ScreenMessages.PostScreenMessage("AVC version check skipped", 10); + ScreenMessages.PostScreenMessage($"AVC runs next: {Configuration.NextRun}", 10); + Destroy(this); + return; + } if (new System.Version(Configuration.GetVersion()) < Assembly.GetExecutingAssembly().GetName().Version) { this.ShowUpdatedWindow(); @@ -151,10 +175,15 @@ private bool ShowIssuesWindow() { return false; } - if (AddonLibrary.Addons.Any(a => a.IsUpdateAvailable || !a.IsCompatible)) + if (!GetComponent()) // if (GameObject.Find("GuiHelper") == null) + { + this.gameObject.AddComponent(); + } + if (AddonLibrary.Addons.Any(a => a.IsUpdateAvailable || a.TriggerIssueGui)) { this.gameObject.AddComponent(); } + Destroy(this); return true; } diff --git a/KSP-AVC/Toolbar/ToolbarWindow.cs b/KSP-AVC/Toolbar/ToolbarWindow.cs index c84a6a5..08598e0 100644 --- a/KSP-AVC/Toolbar/ToolbarWindow.cs +++ b/KSP-AVC/Toolbar/ToolbarWindow.cs @@ -34,11 +34,17 @@ public class ToolbarWindow : MonoBehaviour private string addonList; private GUIStyle labelGreen; private GUIStyle labelYellow; + private GUIStyle labelCyan; private Rect position = new Rect(0.0f, 0.0f, 400.0f, 0.0f); - private Vector2 scrollPosition; + private Vector2 scrollPosition = new Vector2(0, 0); private bool showAddons; private bool useScrollView; private GUIStyle windowStyle; + private GameObject helper; + private GuiHelper InstanceGuiHelper; + private string overrideAvailable = "Compatibility Override GUI"; + private string overrideNotAvailable = "Wait for AVC processing..."; + private string buttonText; #endregion @@ -83,10 +89,19 @@ protected void Start() { Logger.Exception(ex); } + } protected void Update() { + if (Configuration.CfgLoaded && Configuration.AvcInterval == -1) + { + Destroy(this); + } + else if (Configuration.CfgLoaded && DateTime.Compare(DateTime.Now, Configuration.NextRun) <= 0 && Configuration.AvcInterval != 0) + { + Destroy(this); + } try { if (HighLogic.LoadedScene != GameScenes.LOADING && HighLogic.LoadedScene != GameScenes.MAINMENU) @@ -98,6 +113,17 @@ protected void Update() { Logger.Exception(ex); } + + if(helper == null) + { + helper = GameObject.Find("GuiHelper"); + buttonText = overrideNotAvailable; + if (helper != null) + { + InstanceGuiHelper = helper.GetComponent(); + buttonText = overrideAvailable; + } + } } #endregion @@ -115,6 +141,17 @@ private void CheckScrollViewUsage() this.position.height = Screen.height * 0.5f; } + private void OverrideGUI() + { + if (GUILayout.Button(buttonText)) + { + if (InstanceGuiHelper != null) + { + InstanceGuiHelper.ToggleGUI(); + } + } + } + private void CopyToClipboard() { if (!GUILayout.Button("Copy to Clipboard")) @@ -146,8 +183,9 @@ private void CopyToClipboard() var textEditor = new TextEditor { - content = new GUIContent(copyText) + text = copyText }; + textEditor.SelectAll(); textEditor.Copy(); } @@ -163,12 +201,25 @@ private void DrawAddonBoxEnd() GUILayout.EndVertical(); } } - + bool err = false; private void DrawAddonBoxStart() { if (this.useScrollView) { - this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, GUILayout.Height(Screen.height * 0.5f)); + try + { + + this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, GUILayout.Height(Screen.height * 0.5f)); + + } + catch /* (Exception ex ) */ + { + // Strange, the above call generates a single exception, not the first time called. But after that + // it's ok, so this will just bypass the error + + err = true; + return; + } } else { @@ -179,11 +230,17 @@ private void DrawAddonBoxStart() private void DrawAddonList() { this.DrawAddonBoxStart(); + if (err) + { + err = false; + return; + } this.DrawAddons(); this.DrawAddonBoxEnd(); GUILayout.Space(5.0f); this.CopyToClipboard(); + this.OverrideGUI(); GUILayout.Space(5.0f); } @@ -192,13 +249,14 @@ private void DrawAddons() this.addonList = String.Empty; foreach (var addon in AddonLibrary.Addons) { - var labelStyle = !addon.IsCompatible || addon.IsUpdateAvailable ? this.labelYellow : this.labelGreen; + var labelStyle = (addon.IsForcedCompatibleByVersion || addon.IsForcedCompatibleByName) && !addon.IsUpdateAvailable ? this.labelCyan : (!addon.IsCompatible || addon.IsUpdateAvailable) ? this.labelYellow : this.labelGreen; this.addonList += Environment.NewLine + addon.Name + " - " + addon.LocalInfo.Version; GUILayout.BeginHorizontal(); GUILayout.Label(addon.Name, labelStyle); GUILayout.FlexibleSpace(); - GUILayout.Label(addon.LocalInfo != null ? addon.LocalInfo.Version.ToString() : String.Empty, labelStyle); + GUILayout.Label(addon.LocalInfo.Version != null ? addon.LocalInfo.Version.ToString() : String.Empty, labelStyle); GUILayout.EndHorizontal(); + } } @@ -229,6 +287,14 @@ private void InitialiseStyles() textColor = Color.yellow } }; + + this.labelCyan = new GUIStyle + { + normal = + { + textColor = Color.cyan + } + }; } private void Window(int windowId) @@ -255,6 +321,6 @@ private void Window(int windowId) } } - #endregion +#endregion } } \ No newline at end of file diff --git a/KSP-AVC/Utils.cs b/KSP-AVC/Utils.cs index b95075f..562e713 100644 --- a/KSP-AVC/Utils.cs +++ b/KSP-AVC/Utils.cs @@ -31,7 +31,7 @@ public static class Utils { #region Fields - private static readonly string textureDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Textures"); + private static readonly string textureDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "../Textures"); #endregion @@ -54,4 +54,4 @@ public static Texture2D GetTexture(string file, int width, int height) #endregion } -} \ No newline at end of file +} diff --git a/KSP-AVC/VersionInfo.cs b/KSP-AVC/VersionInfo.cs index ef747b6..980d226 100644 --- a/KSP-AVC/VersionInfo.cs +++ b/KSP-AVC/VersionInfo.cs @@ -75,6 +75,17 @@ public bool Any public long Patch { get; set; } + public string Version + { + get + { + string v = this.Major.ToString() + "." + this.Minor.ToString() + "." + this.Patch.ToString(); + if (this.Build > 0) + v += "." + this.Build.ToString(); + return v; + } + } + #endregion #region Operators @@ -210,7 +221,7 @@ public void SetVersion(long major = 0, long minor = 0, long patch = 0, long buil public void SetVersion(string version) { - var sections = Regex.Replace(version, @"[^\d\.]", String.Empty).Split('.'); + var sections = Regex.Replace(version, @"[^\d\.\-]", String.Empty).Split('.'); switch (sections.Length) { diff --git a/MiniAVC-V2.version b/MiniAVC-V2.version new file mode 100644 index 0000000..7f86f04 --- /dev/null +++ b/MiniAVC-V2.version @@ -0,0 +1,25 @@ +{ + "NAME": "MiniAVC-V2 Plugin", + "URL": "http://ksp.spacetux.net/avc/MiniAVC-V2", + "DOWNLOAD": "https://github.com/linuxgurugamer/KSPAddonVersionChecker/releases", + "GITHUB": { + "USERNAME": "linuxgurugamer", + "REPOSITORY": "KSPAddonVersionChecker" + }, + "VERSION": { + "MAJOR": 2, + "MINOR": 0, + "PATCH": 0, + "BUILD": 1 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 12, + "PATCH": 2 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 12, + "PATCH": 0 + } +} diff --git a/MiniAVC/Addon.cs b/MiniAVC-V2/Addon.cs similarity index 65% rename from MiniAVC/Addon.cs rename to MiniAVC-V2/Addon.cs index 30949ed..948e946 100644 --- a/MiniAVC/Addon.cs +++ b/MiniAVC-V2/Addon.cs @@ -13,10 +13,12 @@ using System; using System.IO; -using System.Threading; +using System.Net; +//using System.Threading; using UnityEngine; +using UnityEngine.Networking; -namespace MiniAVC +namespace MiniAVC_V2 { public class Addon { @@ -59,9 +61,19 @@ public bool IsIgnored public bool IsUpdateAvailable { - get { return IsProcessingComplete && LocalInfo.Version != null && RemoteInfo.Version != null && RemoteInfo.Version > LocalInfo.Version && RemoteInfo.IsCompatibleKspVersion && RemoteInfo.IsCompatibleGitHubVersion; } - } + get + { + bool b = this.IsProcessingComplete && + this.LocalInfo.Version != null && + this.RemoteInfo.Version != null && + this.RemoteInfo.Version > this.LocalInfo.Version && + // this.RemoteInfo.IsCompatibleKspVersion && + this.RemoteInfo.IsCompatible && + this.RemoteInfo.IsCompatibleGitHubVersion; + return b; + } + } public AddonInfo LocalInfo { get; private set; } public string Name @@ -78,12 +90,14 @@ public AddonSettings Settings public void RunProcessLocalInfo(string file) { - ThreadPool.QueueUserWorkItem(ProcessLocalInfo, file); + ProcessLocalInfo(file); + //ThreadPool.QueueUserWorkItem(ProcessLocalInfo, file); } public void RunProcessRemoteInfo() { - ThreadPool.QueueUserWorkItem(ProcessRemoteInfo); + ProcessRemoteInfo(null); + //ThreadPool.QueueUserWorkItem(ProcessRemoteInfo); } private void FetchLocalInfo(string path) @@ -102,7 +116,44 @@ private void FetchLocalInfo(string path) private void FetchRemoteInfo() { - using (var www = new WWW(Uri.EscapeUriString(LocalInfo.Url))) + try + { + HttpWebRequest request = HttpWebRequest.Create(Uri.EscapeUriString(this.LocalInfo.Url)) as HttpWebRequest; + request.Method = WebRequestMethods.Http.Get; + request.Timeout = 10000; // milliseconds + HttpWebResponse response = request.GetResponse() as HttpWebResponse; + if (response.StatusCode == HttpStatusCode.OK) + { + Stream data = response.GetResponseStream(); + string html = String.Empty; + using (StreamReader sr = new StreamReader(data)) + { + html = sr.ReadToEnd(); + } + response.Close(); + this.SetRemoteInfo(html); + } + else + { + SetLocalInfoOnly(); + } + } + catch (WebException ex) + { + Logger.Log("Exception fetching data from: " + this.LocalInfo.Url); + if (ex.Status == WebExceptionStatus.ProtocolError) + { + Logger.Log("Status Code : " + ((int)((HttpWebResponse)ex.Response).StatusCode).ToString() + " - " + ((HttpWebResponse)ex.Response).StatusCode.ToString()); + Logger.Log("Status Description : " + ((HttpWebResponse)ex.Response).StatusDescription); + } + else + Logger.Exception(ex); + + this.SetLocalInfoOnly(); + } + +#if false + using (UnityWebRequest www = UnityWebRequest.Get(Uri.EscapeUriString(LocalInfo.Url))) { while (!www.isDone) { @@ -117,6 +168,7 @@ private void FetchRemoteInfo() SetLocalInfoOnly(); } } +#endif } private void ProcessLocalInfo(object state) @@ -181,11 +233,17 @@ private void SetLocalInfoOnly() Logger.Blank(); } - private void SetRemoteInfo(WWW www) +#if false + private void SetRemoteInfo(UnityWebRequest www) { - RemoteInfo = new AddonInfo(LocalInfo.Url, www.text); + SetRemoteInfo(www.url); + } +#endif + private void SetRemoteInfo(string json) + { + RemoteInfo = new AddonInfo(LocalInfo.Url, json); RemoteInfo.FetchRemoteData(); - +#if true if (LocalInfo.Version == RemoteInfo.Version) { Logger.Log("Identical remote version found: Using remote version information only."); @@ -194,6 +252,7 @@ private void SetRemoteInfo(WWW www) LocalInfo = RemoteInfo; } else +#endif { Logger.Log(LocalInfo); Logger.Log(RemoteInfo + "\n\tUpdateAvailable: " + IsUpdateAvailable); @@ -204,4 +263,4 @@ private void SetRemoteInfo(WWW www) IsProcessingComplete = true; } } -} \ No newline at end of file +} diff --git a/MiniAVC/AddonInfo.cs b/MiniAVC-V2/AddonInfo.cs similarity index 69% rename from MiniAVC/AddonInfo.cs rename to MiniAVC-V2/AddonInfo.cs index 7abe268..7dc5008 100644 --- a/MiniAVC/AddonInfo.cs +++ b/MiniAVC-V2/AddonInfo.cs @@ -1,4 +1,4 @@ -// Copyright (C) 2014 CYBUTEK +// Copyright (C)2014 CYBUTEK // // 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 @@ -15,11 +15,13 @@ using System.Collections.Generic; using System.Text; using System.Text.RegularExpressions; -using System.Threading; +using System.Net; +//using System.Threading; -using UnityEngine; +using System.IO; -namespace MiniAVC + +namespace MiniAVC_V2 { public class AddonInfo { @@ -30,6 +32,8 @@ public class AddonInfo private VersionInfo kspVersion; private VersionInfo kspVersionMax; private VersionInfo kspVersionMin; + private List kspExcludeVersions = null; + private List kspIncludeVersions = null; static AddonInfo() { @@ -71,7 +75,20 @@ public static VersionInfo ActualKspVersion public bool IsCompatible { - get { return IsCompatibleKspVersion || ((kspVersionMin != null || kspVersionMax != null) && IsCompatibleKspVersionMin && IsCompatibleKspVersionMax); } + get + { + if (kspIncludeVersions != null && this.IsKspIncludedVersion) + return true; + bool b = (this.IsCompatibleKspVersion && this.kspVersionMin == null && this.kspVersionMax == null) + || + ((this.kspVersionMin != null || this.kspVersionMax != null) && this.IsCompatibleKspVersionMin && this.IsCompatibleKspVersionMax); + if (b) + { + if (kspExcludeVersions != null && this.IsKspExcludedVersion) + b = false; + } + return b; + } } public bool IsCompatibleGitHubVersion @@ -108,6 +125,27 @@ public VersionInfo KspVersionMin { get { return (kspVersionMin ?? VersionInfo.MinValue); } } + public bool IsKspExcludedVersion + { + get + { + if (this.kspExcludeVersions == null) + return false; + bool b = this.kspExcludeVersions.Contains(actualKspVersion); + return b; + } + } + public bool IsKspIncludedVersion + { + get + { + if (this.kspIncludeVersions == null) + return false; + bool b = this.kspIncludeVersions.Contains(actualKspVersion); + return b; + } + } + public bool KspExcludeVersionIsNull { get { return this.kspExcludeVersions == null; } } public string Name { get; private set; } @@ -127,7 +165,7 @@ public void FetchRemoteData() public override string ToString() { - return path + + string str = path + "\n\tNAME: " + (String.IsNullOrEmpty(Name) ? "NULL (required)" : Name) + "\n\tURL: " + (String.IsNullOrEmpty(Url) ? "NULL" : Url) + "\n\tDOWNLOAD: " + (String.IsNullOrEmpty(Download) ? "NULL" : Download) + @@ -135,11 +173,21 @@ public override string ToString() "\n\tVERSION: " + (Version != null ? Version.ToString() : "NULL (required)") + "\n\tKSP_VERSION: " + KspVersion + "\n\tKSP_VERSION_MIN: " + (kspVersionMin != null ? kspVersionMin.ToString() : "NULL") + - "\n\tKSP_VERSION_MAX: " + (kspVersionMax != null ? kspVersionMax.ToString() : "NULL") + + "\n\tKSP_VERSION_MAX: " + (kspVersionMax != null ? kspVersionMax.ToString() : "NULL"); + if (kspExcludeVersions != null) + { + str += "\n\tKSP_VERSION_EXCLUDE:"; + foreach (var s in kspExcludeVersions) + { + str += "\n\t\t" + s; + } + } + str += "\n\tCompatibleKspVersion: " + IsCompatibleKspVersion + "\n\tCompatibleKspVersionMin: " + IsCompatibleKspVersionMin + "\n\tCompatibleKspVersionMax: " + IsCompatibleKspVersionMax + "\n\tCompatibleGitHubVersion: " + IsCompatibleGitHubVersion; + return str; } private static string FormatCompatibleUrl(string url) @@ -195,7 +243,7 @@ private static VersionInfo ParseVersion(Dictionary data) private void Parse(string json) { - var data = MiniAVC.Json.Deserialize(json) as Dictionary; + var data = MiniAVC_V2.Json.Deserialize(json) as Dictionary; if (data == null) { ParseError = true; @@ -236,6 +284,15 @@ private void Parse(string json) case "KSP_VERSION_MAX": kspVersionMax = GetVersion(data[key]); break; + case "KSP_VERSION_EXCLUDE": + kspExcludeVersions = new List(); + List ExcludeList = (List)data[key]; + foreach (System.Object el in ExcludeList) + { + var s = GetVersion(el); + kspExcludeVersions.Add(s); + } + break; } } } @@ -264,9 +321,47 @@ public GitHubInfo(object obj, AddonInfo addonInfo) public void FetchRemoteData() { + HttpWebResponse response = null; + try + { + + string uri = "https://api.github.com/repos/" + this.Username + "/" + this.Repository + "/releases"; + HttpWebRequest request = HttpWebRequest.Create(Uri.EscapeUriString(uri)) as HttpWebRequest; + + request.Proxy.Credentials = System.Net.CredentialCache.DefaultCredentials; + request.Accept = "text/html,application/xhtml+xm…plication/xml; q=0.9,*/*;q=0.8"; + request.UserAgent = "KSP-AVC"; + request.Timeout = 10000; // milliseconds + request.Method = WebRequestMethods.Http.Get; + response = request.GetResponse() as HttpWebResponse; + if (response.StatusCode == HttpStatusCode.OK) + { + Stream data = response.GetResponseStream(); + string html = String.Empty; + using (StreamReader sr = new StreamReader(data)) + { + html = sr.ReadToEnd(); + } + response.Close(); + ParseGitHubJson(html); + } + } + catch (WebException ex) + { + Logger.Log("Exception fetching data from Github: " + "https://api.github.com/repos/" + this.Username + "/" + this.Repository + "/releases"); + if (ex.Status == WebExceptionStatus.ProtocolError) + { + Logger.Log("Status Code : " + ((int)((HttpWebResponse)ex.Response).StatusCode).ToString() + " - " + ((HttpWebResponse)ex.Response).StatusCode.ToString()); + Logger.Log("Status Description : " + ((HttpWebResponse)ex.Response).StatusDescription); + } + else + Logger.Exception(ex); + } + +#if false try { - using (var www = new WWW("https://api.github.com/repos/" + Username + "/" + Repository + "/releases")) + using (UnityWebRequest www = UnityWebRequest.Get("https://api.github.com/repos/" + Username + "/" + Repository + "/releases")) { while (!www.isDone) { @@ -274,7 +369,7 @@ public void FetchRemoteData() } if (www.error == null) { - ParseGitHubJson(www.text); + ParseGitHubJson(www.url); } } } @@ -282,6 +377,7 @@ public void FetchRemoteData() { Logger.Exception(ex); } +#endif } public override string ToString() @@ -295,7 +391,7 @@ private void ParseGitHubJson(string json) { try { - var obj = MiniAVC.Json.Deserialize(json) as List; + var obj = MiniAVC_V2.Json.Deserialize(json) as List; if (obj == null || obj.Count == 0) { ParseError = true; diff --git a/MiniAVC/AddonLibrary.cs b/MiniAVC-V2/AddonLibrary.cs similarity index 69% rename from MiniAVC/AddonLibrary.cs rename to MiniAVC-V2/AddonLibrary.cs index c5f6730..0433242 100644 --- a/MiniAVC/AddonLibrary.cs +++ b/MiniAVC-V2/AddonLibrary.cs @@ -21,11 +21,11 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using System.Threading; +//using System.Threading; #endregion -namespace MiniAVC +namespace MiniAVC_V2 { public static class AddonLibrary { @@ -39,7 +39,8 @@ public static class AddonLibrary static AddonLibrary() { - ThreadPool.QueueUserWorkItem(ProcessAddonPopulation); + ProcessAddonPopulation(null); + //ThreadPool.QueueUserWorkItem(ProcessAddonPopulation); } #endregion @@ -89,12 +90,31 @@ private static void ProcessAddonPopulation(object state) { var threadAddons = new List(); var threadSettings = new List(); + var versionFileSettings = new Dictionary(); foreach (var rootPath in AssemblyLoader.loadedAssemblies.Where(a => a.name == "MiniAVC").Select(a => Path.GetDirectoryName(a.path))) { var settings = AddonSettings.Load(rootPath); threadSettings.Add(settings); - threadAddons.AddRange(Directory.GetFiles(rootPath, "*.version", SearchOption.AllDirectories).Select(p => new Addon(p, settings)).ToList()); + foreach (string versionFile in Directory.GetFiles(rootPath, "*.version", SearchOption.AllDirectories)) + { + // Check whether we've already seen this file + AddonSettings prevSettings; + if (versionFileSettings.TryGetValue(versionFile, out prevSettings)) + { + // Use the settings closest to the DLL (== longest path) + if (prevSettings.FileName.Length < settings.FileName.Length) + { + versionFileSettings[versionFile] = settings; + } + } + else + { + versionFileSettings.Add(versionFile, settings); + } + } } + threadAddons.AddRange(versionFileSettings.Select(kvp => new Addon(kvp.Key, kvp.Value))); + addons = threadAddons; Settings = threadSettings; Populated = true; @@ -107,4 +127,4 @@ private static void ProcessAddonPopulation(object state) #endregion } -} \ No newline at end of file +} diff --git a/MiniAVC/AddonSettings.cs b/MiniAVC-V2/AddonSettings.cs similarity index 96% rename from MiniAVC/AddonSettings.cs rename to MiniAVC-V2/AddonSettings.cs index 5c7b00c..414a613 100644 --- a/MiniAVC/AddonSettings.cs +++ b/MiniAVC-V2/AddonSettings.cs @@ -16,7 +16,7 @@ using System.Xml.Serialization; using UnityEngine; -namespace MiniAVC +namespace MiniAVC_V2 { public class AddonSettings { @@ -44,6 +44,7 @@ public bool FirstRun public static AddonSettings Load(string rootPath) { + Debug.Log("AddonSettings.Load, rootPath: " + rootPath); var filePath = Path.Combine(rootPath, "MiniAVC.xml"); if (!File.Exists(filePath)) diff --git a/MiniAVC-V2/AssemblyVersion.cs b/MiniAVC-V2/AssemblyVersion.cs new file mode 100644 index 0000000..46fbc93 --- /dev/null +++ b/MiniAVC-V2/AssemblyVersion.cs @@ -0,0 +1,9 @@ + + // This code was generated by a tool. Any changes made manually will be lost + // the next time this code is regenerated. + // + + using System.Reflection; + + [assembly: AssemblyVersion("2.0.0.1")] + [assembly: AssemblyFileVersion("2.0.0.1")] diff --git a/MiniAVC-V2/AssemblyVersion.tt b/MiniAVC-V2/AssemblyVersion.tt new file mode 100644 index 0000000..6ad1647 --- /dev/null +++ b/MiniAVC-V2/AssemblyVersion.tt @@ -0,0 +1,101 @@ +<#@ template debug="false" hostspecific="true" language="C#" #> +<#@ import namespace="System.IO" #> +<#@ output extension=".cs" #> + +<#@ assembly name="EnvDTE" #><# /* This assembly provides access to Visual Studio project properties. */ #> +<# + + // Instructions + // 1. Add a new Text Template to the project + // 2. Copy this file into the new template + // 3. Update the string: versionfile with the complete path to the .version file + // 4. Remove the following line from the file AssemblyInfo.cs (usually located in the "Property" folder inside your C# project): + // [assembly: AssemblyVersion("1.0.0.0")] + // 5. Add the following to the PreBuild steps: + // + // set textTemplatingPath="%ProgramFiles(x86)%\Microsoft Visual Studio\2017\Community\Common7\IDE\texttransform.exe" + // %textTemplatingPath% "$(ProjectDir)AssemblyVersion.tt" + + + int major = 0; + int minor = 0; + int build = 0; + int patch = 0; + bool versionSection = false; + + int i = 0; + int i2 = 0; + string s; + + + // For Visual Studio / MSBuild Build-Time Template Resolution + string RootDirectory = System.IO.Path.GetDirectoryName(Host.TemplateFile) + @"\..\"; + + // + // Update the following with the name of the .version file which is in the root directory + // + string versionfile = RootDirectory + "MiniAVC-V2.version"; + + if (!File.Exists(versionfile)) + { + Write("File: " + versionfile + " missing\n"); + } + + try + { + foreach (var line in File.ReadAllLines(versionfile)) + { + if (line != null) + { + if (!versionSection) + { + if (line.Contains("\"VERSION\"")) + versionSection = true; + } + else + { + if (line.Contains("}")) + versionSection = false; + i = line.IndexOf(":"); + i2 = line.IndexOf(","); + if (i2 == -1) + i2 = line.Length; + if (i >= 0 && i2 >= 0) + { + s = line.Substring(i + 1, i2 - i - 1); + + if (line.Contains("MAJOR")) + Int32.TryParse(s, out major); + + if (line.Contains("MINOR")) + Int32.TryParse(s, out minor); + + if (line.Contains("PATCH")) + Int32.TryParse(s, out patch); + + if (line.Contains("BUILD")) + Int32.TryParse(s, out build); + } + } + } + } + + } + catch + { + major = 1; + minor = 0; + patch = 0; + build = 0; + } + //Write("File done"); + + #> + // This code was generated by a tool. Any changes made manually will be lost + // the next time this code is regenerated. + // + + using System.Reflection; + + [assembly: AssemblyVersion("<#= major #>.<#= minor #>.<#= patch #>.<#= build #>")] + [assembly: AssemblyFileVersion("<#= major #>.<#= minor #>.<#= patch #>.<#= build #>")] diff --git a/MiniAVC/FirstRunGui.cs b/MiniAVC-V2/FirstRunGui.cs similarity index 99% rename from MiniAVC/FirstRunGui.cs rename to MiniAVC-V2/FirstRunGui.cs index 905d169..22cfead 100644 --- a/MiniAVC/FirstRunGui.cs +++ b/MiniAVC-V2/FirstRunGui.cs @@ -24,7 +24,7 @@ #endregion -namespace MiniAVC +namespace MiniAVC_V2 { public class FirstRunGui : MonoBehaviour { diff --git a/MiniAVC/IssueGui.cs b/MiniAVC-V2/IssueGui.cs similarity index 91% rename from MiniAVC/IssueGui.cs rename to MiniAVC-V2/IssueGui.cs index e65d68f..81cfdc0 100644 --- a/MiniAVC/IssueGui.cs +++ b/MiniAVC-V2/IssueGui.cs @@ -15,7 +15,7 @@ using UnityEngine; -namespace MiniAVC +namespace MiniAVC_V2 { public class IssueGui : MonoBehaviour { @@ -108,7 +108,15 @@ private void DrawNotCompatible() } GUILayout.BeginVertical(HighLogic.Skin.box); - GUILayout.Label($"Unsupported by KSP v{VersioningBase.GetVersionString()}, please use v{Addon.LocalInfo.KspVersion}.", titleStyle, GUILayout.Width(400.0f)); + if (Addon.LocalInfo.IsKspExcludedVersion) + { + GUILayout.Label("The currently installed version of " + Addon.Name + " is not compatible with " + + AddonInfo.ActualKspVersion, titleStyle, GUILayout.MinWidth(575.0f)); + } + else + { + GUILayout.Label($"Unsupported by KSP v{VersioningBase.GetVersionString()}, please use v{Addon.LocalInfo.KspVersionMin}.", titleStyle, GUILayout.Width(400.0f)); + } GUILayout.EndVertical(); } diff --git a/MiniAVC/Json.cs b/MiniAVC-V2/Json.cs similarity index 99% rename from MiniAVC/Json.cs rename to MiniAVC-V2/Json.cs index 4b867d1..eeaf619 100644 --- a/MiniAVC/Json.cs +++ b/MiniAVC-V2/Json.cs @@ -25,7 +25,7 @@ #endregion -namespace MiniAVC +namespace MiniAVC_V2 { /* * Copyright (c) 2013 Calvin Rien diff --git a/MiniAVC/Logger.cs b/MiniAVC-V2/Logger.cs similarity index 83% rename from MiniAVC/Logger.cs rename to MiniAVC-V2/Logger.cs index 180b4a3..e0eebf3 100644 --- a/MiniAVC/Logger.cs +++ b/MiniAVC-V2/Logger.cs @@ -27,23 +27,25 @@ #endregion -namespace MiniAVC +namespace MiniAVC_V2 { [KSPAddon(KSPAddon.Startup.Instantly, false)] public class Logger : MonoBehaviour { #region Fields - private static readonly AssemblyName assemblyName; - private static readonly string fileName; - + private static AssemblyName assemblyName; + private static string fileName; + private static string LogsPath = null; private static readonly List messages = new List(); #endregion #region Constructors - static Logger() + // Following was originally a constructor, Unity 5 doesn't like some of what's happening, so + // it's now called from the Awake method + static void LoggerInit2() { assemblyName = Assembly.GetExecutingAssembly().GetName(); fileName = assemblyName.Name + ".log"; @@ -53,7 +55,24 @@ static Logger() messages.Add(new[] {"Assembly: " + Assembly.GetExecutingAssembly().Location}); Blank(); } + static void LoggerInit() + { + LogsPath = KSPUtil.ApplicationRootPath + "Logs"; + if (!Directory.Exists(LogsPath)) + Directory.CreateDirectory(LogsPath); + assemblyName = Assembly.GetExecutingAssembly().GetName(); + //fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "log"); + fileName = LogsPath + "/" + assemblyName.Name + ".log"; + //File.Delete(fileName); + + lock (messages) + { + messages.Add(new[] { "Executing: " + assemblyName.Name + " - " + assemblyName.Version }); + messages.Add(new[] { "Assembly: " + Assembly.GetExecutingAssembly().Location }); + } + Blank(); + } #endregion #region Destructors @@ -199,6 +218,7 @@ public static void Warning(string message) protected void Awake() { + LoggerInit(); DontDestroyOnLoad(this); } diff --git a/MiniAVC-V2/MiniAVC-V2.csproj b/MiniAVC-V2/MiniAVC-V2.csproj new file mode 100644 index 0000000..db8935a --- /dev/null +++ b/MiniAVC-V2/MiniAVC-V2.csproj @@ -0,0 +1,102 @@ + + + + + Debug + AnyCPU + {F1351BAB-76F1-41DE-B01C-496163CB44D8} + Library + Properties + MiniAVC_V2 + MiniAVC-V2 + v4.5 + 512 + + + + true + full + false + bin\Debug\ + DEBUG;TRACE + prompt + 4 + false + + + none + true + ..\Output\MiniAVC\ + TRACE + prompt + 4 + false + + + + + + + True + True + AssemblyVersion.tt + + + + + + + + + + + + + + + False + + + False + + + + + + + TextTemplatingFileGenerator + AssemblyVersion.cs + + + + + + + + + + + + + + + + + $(PostBuildEventDependsOn); + PostBuildMacros; + + + + + + "$(DevEnvDir)\texttransform.exe" "$(ProjectDir)AssemblyVersion.tt" + + + + \ No newline at end of file diff --git a/MiniAVC/MiniAVC.csproj b/MiniAVC-V2/MiniAVC.csproj.173 similarity index 74% rename from MiniAVC/MiniAVC.csproj rename to MiniAVC-V2/MiniAVC.csproj.173 index 1940039..eb45edd 100644 --- a/MiniAVC/MiniAVC.csproj +++ b/MiniAVC-V2/MiniAVC.csproj.173 @@ -34,6 +34,11 @@ + + True + True + AssemblyVersion.tt + @@ -42,26 +47,28 @@ + - ..\..\..\KSP-Environment\KSP_x64_Data\Managed\Assembly-CSharp.dll - False - - - ..\..\Game\KSP_x64_Data\Managed\System.dll - False - - - ..\..\Game\KSP_x64_Data\Managed\System.Xml.dll - False + R:\KSP_1.7.3_dev\KSP_x64_Data\Managed\Assembly-CSharp.dll + + - ..\..\..\KSP-Environment\KSP_x64_Data\Managed\UnityEngine.dll - False + R:\KSP_1.7.3_dev\KSP_x64_Data\Managed\UnityEngine.dll + + + TextTemplatingFileGenerator + AssemblyVersion.cs + + + + + @@ -76,11 +83,15 @@ $(PostBuildEventDependsOn); PostBuildMacros; - xcopy "$(SolutionDir)Output\MiniAVC\*" "$(SolutionDir)..\Game\GameData\MiniAVC\*" /E /Y -del "$(SolutionDir)Release\MiniAVC\*" /Q -xcopy "$(SolutionDir)Documents\MiniAVC\*" "$(SolutionDir)Release\MiniAVC\Documents\*" /E /Y -7z.exe a -tzip -mx3 "$(SolutionDir)Release\MiniAVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Output\MiniAVC" -7z.exe a -tzip -mx3 "$(SolutionDir)Release\MiniAVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Documents\MiniAVC\*" + + + + + +set textTemplatingPath="%25ProgramFiles(x86)%25\Microsoft Visual Studio\2017\Community\Common7\IDE\texttransform.exe" + +%25textTemplatingPath%25 "$(ProjectDir)AssemblyVersion.tt" + + \ No newline at end of file diff --git a/MiniAVC/Properties/AssemblyInfo.cs b/MiniAVC-V2/Properties/AssemblyInfo.cs similarity index 89% rename from MiniAVC/Properties/AssemblyInfo.cs rename to MiniAVC-V2/Properties/AssemblyInfo.cs index 1c5b2c4..f23d757 100644 --- a/MiniAVC/Properties/AssemblyInfo.cs +++ b/MiniAVC-V2/Properties/AssemblyInfo.cs @@ -24,7 +24,7 @@ [assembly: AssemblyTitle("MiniAVC")] [assembly: AssemblyProduct("MiniAVC")] -[assembly: AssemblyCopyright("Copyright © CYBUTEK 2014")] +[assembly: AssemblyCopyright("Copyright © CYBUTEK 2014, Linuxgurugamer 2018")] [assembly: ComVisible(false)] [assembly: Guid("d3138342-d8a8-4ab3-96e7-e7f086c13212")] -[assembly: AssemblyVersion("1.0.3.3")] \ No newline at end of file +//[assembly: AssemblyVersion("1.0.3.3")] \ No newline at end of file diff --git a/MiniAVC/Starter.cs b/MiniAVC-V2/Starter.cs similarity index 81% rename from MiniAVC/Starter.cs rename to MiniAVC-V2/Starter.cs index 0346ce4..04a5503 100644 --- a/MiniAVC/Starter.cs +++ b/MiniAVC-V2/Starter.cs @@ -21,9 +21,10 @@ #endregion Using Directives -namespace MiniAVC +namespace MiniAVC_V2 { [KSPAddon(KSPAddon.Startup.Instantly, false)] +// [KSPAddon(KSPAddon.Startup.MainMenu, false)] public class Starter : MonoBehaviour { #region Fields @@ -55,17 +56,41 @@ protected void Awake() Destroy(this); return; } + + } catch (Exception ex) { Logger.Exception(ex); } - Logger.Log("Starter was created."); + } + + protected void Start() + { + if (!UpdateFrequency.ConfigLoaded) + { + UpdateFrequency.LoadConfig(); + if (UpdateFrequency.DisableCheck) + { + ScreenMessages.PostScreenMessage("Mini-AVC disabled", 10); + Destroy(this); + return; + } + if (UpdateFrequency.SkipRun) + { + ScreenMessages.PostScreenMessage("Mini-AVC version check skipped", 10); + ScreenMessages.PostScreenMessage($"Mini-AVC runs next: {UpdateFrequency.NextRun}", 10); + Destroy(this); + } + } } protected void OnDestroy() { - Logger.Log("Starter was destroyed."); + if (UpdateFrequency.ConfigLoaded) + { + UpdateFrequency.SaveConfig(); + } } protected void Update() diff --git a/MiniAVC/ToolTipGui.cs b/MiniAVC-V2/ToolTipGui.cs similarity index 99% rename from MiniAVC/ToolTipGui.cs rename to MiniAVC-V2/ToolTipGui.cs index 4097ae0..26f3e65 100644 --- a/MiniAVC/ToolTipGui.cs +++ b/MiniAVC-V2/ToolTipGui.cs @@ -23,7 +23,7 @@ #endregion -namespace MiniAVC +namespace MiniAVC_V2 { public class ToolTipGui : MonoBehaviour { diff --git a/MiniAVC-V2/UpdateFrequency.cs b/MiniAVC-V2/UpdateFrequency.cs new file mode 100644 index 0000000..b938d27 --- /dev/null +++ b/MiniAVC-V2/UpdateFrequency.cs @@ -0,0 +1,94 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using UnityEngine; +using System.IO; + +namespace MiniAVC_V2 +{ + class UpdateFrequency + { + public static bool ConfigLoaded { get; private set; } + public static int AvcInterval { get; private set; } + public static DateTime NextRun { get; private set; } + static string configPath = KSPUtil.ApplicationRootPath + "GameData/MiniAVCUpdateFrequency.dat"; + + public static bool SkipRun + { + get + { + if (DateTime.Compare(DateTime.Now, NextRun) <= 0 && AvcInterval != 0) + { + return true; + } + return false; + } + } + + public static bool DisableCheck + { + get + { + if (AvcInterval == -1) + { + return true; + } + return false; + } + } + + public static void LoadConfig() + { + if (!File.Exists(configPath)) + { + Logger.Log($"Config not found: {configPath}"); + return; + } + + ConfigNode LoadNodeFromFile = ConfigNode.Load(configPath); + ConfigNode node = LoadNodeFromFile.GetNode("MINI-AVC"); + + var nodes = node.GetNodes(); + if(node.HasNode("UPDATE_FREQUENCY")) + { + try + { + ConfigNode _temp = new ConfigNode(); + _temp = node.GetNode("UPDATE_FREQUENCY"); + + AvcInterval = Int32.Parse(_temp.GetValue("MinTimeBetweenAvcRuns")); + if (_temp.HasValue("AvcRunsNext")) + { + NextRun = DateTime.Parse(_temp.GetValue("AvcRunsNext")); + } + } + catch { } + } + ConfigLoaded = true; + Logger.Log("Config loaded"); + } + + public static void SaveConfig() + { + ConfigNode cfgnode = new ConfigNode(); + ConfigNode KSPAVC = cfgnode.AddNode("MINI-AVC"); + + ConfigNode Interval = KSPAVC.AddNode("UPDATE_FREQUENCY"); + { + Interval.AddValue("MinTimeBetweenAvcRuns", AvcInterval.ToString() + " //Timespan between AVC runs in hours (-1 = Disable MiniAVC, 0 = Run on each game start)"); + + if (DateTime.Compare(DateTime.Now, NextRun) >= 0 && AvcInterval > 0) + { + Interval.AddValue("AvcRunsNext", DateTime.Now.AddHours(AvcInterval).ToString()); + } + else + { + Interval.AddValue("AvcRunsNext", NextRun.ToString()); + } + } + cfgnode.Save(configPath); + Logger.Log("Config saved!"); + } + } +} diff --git a/MiniAVC/VersionInfo.cs b/MiniAVC-V2/VersionInfo.cs similarity index 89% rename from MiniAVC/VersionInfo.cs rename to MiniAVC-V2/VersionInfo.cs index 7829be4..b0f584b 100644 --- a/MiniAVC/VersionInfo.cs +++ b/MiniAVC-V2/VersionInfo.cs @@ -22,7 +22,7 @@ #endregion -namespace MiniAVC +namespace MiniAVC_V2 { public class VersionInfo : IComparable { @@ -33,26 +33,39 @@ public VersionInfo(long major = 0, long minor = 0, long patch = 0, long build = this.SetVersion(major, minor, patch, build); } + Int64 SafeParseInt64(string s) + { + try + { + return Int64.Parse(s); + } + catch (Exception e) + { + Logger.Log("SafeParseInt64, exception: string: " + e); + return 0; + } + } + public VersionInfo(string version) { var sections = Regex.Replace(version, @"[^\d\.]", String.Empty).Split('.'); - + switch (sections.Length) { case 1: - this.SetVersion(Int64.Parse(sections[0])); + this.SetVersion(SafeParseInt64(sections[0])); return; case 2: - this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1])); + this.SetVersion(SafeParseInt64(sections[0]), SafeParseInt64(sections[1])); return; case 3: - this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2])); + this.SetVersion(SafeParseInt64(sections[0]), SafeParseInt64(sections[1]), SafeParseInt64(sections[2])); return; case 4: - this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2]), Int64.Parse(sections[3])); + this.SetVersion(SafeParseInt64(sections[0]), SafeParseInt64(sections[1]), SafeParseInt64(sections[2]), SafeParseInt64(sections[3])); return; default: diff --git a/MiniAVCUpdateFrequency.dat_example b/MiniAVCUpdateFrequency.dat_example new file mode 100644 index 0000000..d9cd475 --- /dev/null +++ b/MiniAVCUpdateFrequency.dat_example @@ -0,0 +1,11 @@ +//Rename this file to MiniAVCUpdateFrequency.dat and put it into the GameData folder +//If you don't feel confident in the DateTime format, just edit the "MinTimeBetweenAvcRuns" value and MiniAVC creates the proper timestamp on the next launch +//If you change the timespan, you should always delete the "AvcRunsNext" entry. +MINI-AVC +{ + UPDATE_FREQUENCY + { + MinTimeBetweenAvcRuns = 0 //Timespan between AVC runs in hours (-1 = Disable MiniAVC, 0 = Run on each game start) + AvcRunsNext = 1/1/0001 12:00:00 AM + } +} diff --git a/Output/AVCToolkit/AVCToolkit.exe b/Output/AVCToolkit/AVCToolkit.exe deleted file mode 100644 index 800173d..0000000 Binary files a/Output/AVCToolkit/AVCToolkit.exe and /dev/null differ diff --git a/Output/KSP-AVC/KSP-AVC.dll b/Output/KSP-AVC/KSP-AVC.dll deleted file mode 100644 index c95cced..0000000 Binary files a/Output/KSP-AVC/KSP-AVC.dll and /dev/null differ diff --git a/Output/MiniAVC/MiniAVC.dll b/Output/MiniAVC/MiniAVC.dll deleted file mode 100644 index e4c4b74..0000000 Binary files a/Output/MiniAVC/MiniAVC.dll and /dev/null differ diff --git a/TODO.txt b/TODO.txt new file mode 100644 index 0000000..90f12a1 --- /dev/null +++ b/TODO.txt @@ -0,0 +1,3 @@ +update ZeroMiniAVC to delete the new versions of MiniAVC +update MiniAVC to delete the old renamed versions of the old one +Change name of MiniAVC assembly to MiniAVC-v2 \ No newline at end of file diff --git a/TestCases/KspMaxVersion.version b/TestCases/KspMaxVersion.version new file mode 100644 index 0000000..a9c6fc0 --- /dev/null +++ b/TestCases/KspMaxVersion.version @@ -0,0 +1,23 @@ +{ + "NAME":"KspVersion & KspMaxVersion", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMaxVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":2 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} \ No newline at end of file diff --git a/TestCases/KspMaxVersion1.version b/TestCases/KspMaxVersion1.version new file mode 100644 index 0000000..ca06556 --- /dev/null +++ b/TestCases/KspMaxVersion1.version @@ -0,0 +1,23 @@ +{ + "NAME":"KspVersion & KspMaxVersion, Update Available", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMaxVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/KspMaxVersion2.version b/TestCases/KspMaxVersion2.version new file mode 100644 index 0000000..353ba30 --- /dev/null +++ b/TestCases/KspMaxVersion2.version @@ -0,0 +1,23 @@ +{ + "NAME":"KspVersion & KspMaxVersion, No Update Available", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMaxVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":3, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/KspMinMaxVersion.version b/TestCases/KspMinMaxVersion.version new file mode 100644 index 0000000..433e5c3 --- /dev/null +++ b/TestCases/KspMinMaxVersion.version @@ -0,0 +1,29 @@ +{ + "NAME":"KspMinVersion & KspMaxVersion", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMinMaxVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":2 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/KspMinMaxVersion1.version b/TestCases/KspMinMaxVersion1.version new file mode 100644 index 0000000..ecdbec4 --- /dev/null +++ b/TestCases/KspMinMaxVersion1.version @@ -0,0 +1,29 @@ +{ + "NAME":"KspMinVersion & KspMaxVersion, Update Available", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMinMaxVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} \ No newline at end of file diff --git a/TestCases/KspMinMaxVersion2.version b/TestCases/KspMinMaxVersion2.version new file mode 100644 index 0000000..9cd7913 --- /dev/null +++ b/TestCases/KspMinMaxVersion2.version @@ -0,0 +1,29 @@ +{ + "NAME":"KspMinVersion & KspMaxVersion, No Update Available, Max too low", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMinMaxVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/KspMinMaxVersion3.version b/TestCases/KspMinMaxVersion3.version new file mode 100644 index 0000000..631dd68 --- /dev/null +++ b/TestCases/KspMinMaxVersion3.version @@ -0,0 +1,29 @@ +{ + "NAME":"KspMinVersion & KspMaxVersion, No Update Available, Min too high", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMinMaxVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":4, + "PATCH":2 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":5, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/KspMinVersion.version b/TestCases/KspMinVersion.version new file mode 100644 index 0000000..aee857a --- /dev/null +++ b/TestCases/KspMinVersion.version @@ -0,0 +1,23 @@ +{ + "NAME":"KspVersion & KspMinVersion", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMinVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":2 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/KspMinVersion1.version b/TestCases/KspMinVersion1.version new file mode 100644 index 0000000..32ec8cc --- /dev/null +++ b/TestCases/KspMinVersion1.version @@ -0,0 +1,23 @@ +{ + "NAME":"KspVersion & KspMinVersion, Update Available", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMinVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/KspMinVersion2.version b/TestCases/KspMinVersion2.version new file mode 100644 index 0000000..e821ee6 --- /dev/null +++ b/TestCases/KspMinVersion2.version @@ -0,0 +1,23 @@ +{ + "NAME":"KspVersion & KspMinVersion, No Update Available", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspMinVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":5, + "PATCH":0 + } +} \ No newline at end of file diff --git a/Output/KSP-AVC/KSP-AVC.version b/TestCases/KspVersion.version similarity index 50% rename from Output/KSP-AVC/KSP-AVC.version rename to TestCases/KspVersion.version index cbba7ee..12da459 100644 --- a/Output/KSP-AVC/KSP-AVC.version +++ b/TestCases/KspVersion.version @@ -1,6 +1,6 @@ { - "NAME":"KSP-AVC Plugin", - "URL":"http://ksp-avc.cybutek.net/version.php?id=2", + "NAME":"KspVersion", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspVersion.version", "VERSION": { "MAJOR":1, @@ -11,7 +11,7 @@ "KSP_VERSION": { "MAJOR":1, - "MINOR":2, - "PATCH":0 + "MINOR":4, + "PATCH":1 } } \ No newline at end of file diff --git a/TestCases/KspVersion1.version b/TestCases/KspVersion1.version new file mode 100644 index 0000000..1517f34 --- /dev/null +++ b/TestCases/KspVersion1.version @@ -0,0 +1,17 @@ +{ + "NAME":"KspVersion, Update Available", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} \ No newline at end of file diff --git a/TestCases/KspVersion2.version b/TestCases/KspVersion2.version new file mode 100644 index 0000000..99da0af --- /dev/null +++ b/TestCases/KspVersion2.version @@ -0,0 +1,17 @@ +{ + "NAME":"KspVersion, No Update Available", + "URL":"file://D:/Users/jbb/github/KSPAddonVersionChecker/TestCases/KspVersion.version", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":0 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/AdjustableModPanel.version b/TestCases/mods versions/AdjustableModPanel.version new file mode 100644 index 0000000..b3a7bf2 --- /dev/null +++ b/TestCases/mods versions/AdjustableModPanel.version @@ -0,0 +1,30 @@ +{ + "NAME": "Adjustable Mod Panel", + "DOWNLOAD": "https://github.com/radistmorse/KSPAdjustableModPanel/releases", + "URL": "https://raw.githubusercontent.com/radistmorse/KSPAdjustableModPanel/master/AdjustableModPanel.version", + "GITHUB": { + "USERNAME": "radistmorse", + "REPOSITORY": "KSPAdjustableModPanel" + }, + "VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0, + "BUILD": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/AutoAction.version b/TestCases/mods versions/AutoAction.version new file mode 100644 index 0000000..80f41c1 --- /dev/null +++ b/TestCases/mods versions/AutoAction.version @@ -0,0 +1,36 @@ +{ + "NAME": "AutoAction", + "URL": "http://ksp-avc.cybutek.net/version.php?id=373", + "DOWNLOAD": "https://github.com/formicant/AutoAction/releases", + "GITHUB": + { + "USERNAME": "formicant", + "REPOSITORY": "AutoAction", + "ALLOW_PRE_RELEASE": false, + }, + "VERSION": + { + "MAJOR": 1, + "MINOR": 9, + "PATCH": 4, + "BUILD": 0 + }, + "KSP_VERSION": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + "KSP_VERSION_MIN": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, +} diff --git a/TestCases/mods versions/B9PartSwitch.version b/TestCases/mods versions/B9PartSwitch.version new file mode 100644 index 0000000..d7181ea --- /dev/null +++ b/TestCases/mods versions/B9PartSwitch.version @@ -0,0 +1,19 @@ +{ + "NAME" : "B9 Part Switch", + "DOWNLOAD" : "https://github.com/blowfishpro/B9PartSwitch/releases", + "URL" : "https://s3.amazonaws.com/blowfish-ksp-b9partswitch-avc/ksp-1.3.1/B9PartSwitch.version", + "GITHUB" : { + "USERNAME" : "blowfishpro", + "REPOSITORY" : "B9PartSwitch" + }, + "VERSION" : { + "MAJOR" : 2, + "MINOR" : 0, + "PATCH" : 0 + }, + "KSP_VERSION" : { + "MAJOR" : 1, + "MINOR" : 3, + "PATCH" : 1 + } +} diff --git a/TestCases/mods versions/BasicOrbit.version b/TestCases/mods versions/BasicOrbit.version new file mode 100644 index 0000000..f978fc2 --- /dev/null +++ b/TestCases/mods versions/BasicOrbit.version @@ -0,0 +1,31 @@ +{ + "NAME":"Basic Orbit", + "URL":"https://raw.githubusercontent.com/DMagic1/KSP_BasicOrbit/master/GameData/BasicOrbit/BasicOrbit.version", + "DOWNLOAD":"https://github.com/DMagic1/KSP_BasicOrbit/releases", + "GITHUB":{ + "USERNAME":"DMagic1", + "REPOSITORY":"KSP_BasicOrbit", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":1, + "MINOR":0, + "PATCH":8, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } + } \ No newline at end of file diff --git a/TestCases/mods versions/Bluedog_DB.version b/TestCases/mods versions/Bluedog_DB.version new file mode 100644 index 0000000..5b4dfec --- /dev/null +++ b/TestCases/mods versions/Bluedog_DB.version @@ -0,0 +1,26 @@ +{ + "NAME": "Bluedog Design Bureau", + "DOWNLOAD": "https://github.com/CobaltWolf/Bluedog-Design-Bureau/releases", + "URL": "https://raw.githubusercontent.com/CobaltWolf/Bluedog-Design-Bureau/master/Gamedata/Bluedog_DB/Bluedog_DB.version", + "VERSION": { + "MAJOR": 1, + "MINOR": 1, + "PATCH": 6, + "BUILD": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 99 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/CCK.version b/TestCases/mods versions/CCK.version new file mode 100644 index 0000000..062f2c5 --- /dev/null +++ b/TestCases/mods versions/CCK.version @@ -0,0 +1,31 @@ +{ + "DOWNLOAD": "https://github.com/BobPalmer/CommunityCategoryKit/releases", + "GITHUB": { + "ALLOW_PRE_RELEASE": false, + "REPOSITORY": "CommunityCategoryKit", + "USERNAME": "BobPalmer" + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":9 + }, + "NAME": "Community Category Kit", + "URL": "https://raw.githubusercontent.com/BobPalmer/CommunityCategoryKit/master/FOR_RELEASE/GameData/CommunityCategoryKit/CCK.version", + "VERSION": { + "BUILD": 0, + "MAJOR": 3, + "MINOR": 0, + "PATCH": 0 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/CRP.version b/TestCases/mods versions/CRP.version new file mode 100644 index 0000000..a585c77 --- /dev/null +++ b/TestCases/mods versions/CRP.version @@ -0,0 +1,31 @@ +{ + "NAME":"Community Resource Pack", + "URL":"https://raw.githubusercontent.com/BobPalmer/CommunityResourcePack/master/FOR_RELEASE/GameData/CommunityResourcePack/CRP.version", + "DOWNLOAD":"https://github.com/BobPalmer/CommunityResourcePack/releases", + "GITHUB":{ + "USERNAME":"BobPalmer", + "REPOSITORY":"CommunityResourcePack", + "ALLOW_PRE_RELEASE":false + }, + "VERSION":{ + "MAJOR":0, + "MINOR":10, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":9 + } + } diff --git a/TestCases/mods versions/Chatterer.version b/TestCases/mods versions/Chatterer.version new file mode 100644 index 0000000..ea11e69 --- /dev/null +++ b/TestCases/mods versions/Chatterer.version @@ -0,0 +1,29 @@ +{ + "NAME":"Chatterer", + "URL":"http://ksp-avc.cybutek.net/version.php?id=27", + "VERSION": + { + "MAJOR":0, + "MINOR":9, + "PATCH":94, + "BUILD":2077 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":3, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":99 + }, +} \ No newline at end of file diff --git a/TestCases/mods versions/ClickThroughBlocker.version b/TestCases/mods versions/ClickThroughBlocker.version new file mode 100644 index 0000000..ec10738 --- /dev/null +++ b/TestCases/mods versions/ClickThroughBlocker.version @@ -0,0 +1,23 @@ +{ + + "NAME": "ClickThroughBlocker", + "URL" : "https://raw.githubusercontent.com/linuxgurugamer/ClickThroughBlocker/master/ClickThroughBlocker.version", + "DOWNLOAD" : "https://github.com/linuxgurugamer/ClickThroughBlocker/releases", + "GITHUB" : + { + "USERNAME" : "linuxgurugamer", + "REPOSITORY" : "ClickThroughBlocker" + }, + "URL": "http://ksp-avc.cybutek.net/version.php?id=546", + "VERSION": { + "MAJOR": 0, + "MINOR": 1, + "PATCH": 6, + "BUILD": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/ColorCodedCanisters.version b/TestCases/mods versions/ColorCodedCanisters.version new file mode 100644 index 0000000..ba400b6 --- /dev/null +++ b/TestCases/mods versions/ColorCodedCanisters.version @@ -0,0 +1,15 @@ +{ + "NAME": "Color Coded Canisters", + "URL": "http://ksp.necrobones.com/files/ColorCodedCanisters/ColorCodedCanisters.version", + "DOWNLOAD": "http://spacedock.info/mod/91/Color%20Coded%20Canisters", + "VERSION": { + "MAJOR": 2, + "MINOR": 0, + "PATCH": 1 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + } +} diff --git a/TestCases/mods versions/ContractConfigurator.version b/TestCases/mods versions/ContractConfigurator.version new file mode 100644 index 0000000..10d1e27 --- /dev/null +++ b/TestCases/mods versions/ContractConfigurator.version @@ -0,0 +1,32 @@ +{ + "NAME":"Contract Configurator", + "URL":"https://raw.githubusercontent.com/jrossignol/ContractConfigurator/master/GameData/ContractConfigurator/ContractConfigurator.version", + "DOWNLOAD":"https://github.com/jrossignol/ContractConfigurator/releases", + "CHANGE_LOG_URL":"https://raw.githubusercontent.com/jrossignol/ContractConfigurator/1.24.0/CHANGES.txt", + "GITHUB":{ + "USERNAME":"jrossignol", + "REPOSITORY":"ContractConfigurator", + "ALLOW_PRE_RELEASE":false + }, + "VERSION":{ + "MAJOR":1, + "MINOR":24, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } + } diff --git a/TestCases/mods versions/ContractRewardModifier.version b/TestCases/mods versions/ContractRewardModifier.version new file mode 100644 index 0000000..7018fde --- /dev/null +++ b/TestCases/mods versions/ContractRewardModifier.version @@ -0,0 +1,31 @@ +{ + "NAME":"Contract Reward Modifier", + "URL":"https://raw.githubusercontent.com/DMagic1/Contract-Modifier/master/GameData/ContractRewardModifier/ContractRewardModifier.version", + "DOWNLOAD":"http://spacedock.info/mod/132/Contract%20Reward%20Modifier/download/2.6", + "GITHUB":{ + "USERNAME":"DMagic1", + "REPOSITORY":"Contract-Modifier", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":1, + "MINOR":0, + "PATCH":2, + "BUILD":6 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } + } diff --git a/TestCases/mods versions/CrewLight.version b/TestCases/mods versions/CrewLight.version new file mode 100644 index 0000000..13f6144 --- /dev/null +++ b/TestCases/mods versions/CrewLight.version @@ -0,0 +1,30 @@ +{ + "NAME":"Crew Light", + "URL":"https://raw.githubusercontent.com/Li0n-0/CrewLight/master/GameData/CrewLight/CrewLight.version", + "DOWNLOAD":"https://github.com/Li0n-0/CrewLight/releases", + "VERSION": + { + "MAJOR":1, + "MINOR":13, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/DiscontinuedParts.version b/TestCases/mods versions/DiscontinuedParts.version new file mode 100644 index 0000000..d9cabf1 --- /dev/null +++ b/TestCases/mods versions/DiscontinuedParts.version @@ -0,0 +1,15 @@ +{ + "NAME": "Discontinued Parts", + "URL": "http://ksp.necrobones.com/files/DiscontinuedParts/DiscontinuedParts.version", + "DOWNLOAD": "http://spacedock.info/mod/137/Discontinued%20Parts", + "VERSION": { + "MAJOR": 0, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 0, + "PATCH": 5 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/EVAStruts.version b/TestCases/mods versions/EVAStruts.version new file mode 100644 index 0000000..e94f151 --- /dev/null +++ b/TestCases/mods versions/EVAStruts.version @@ -0,0 +1,31 @@ +{ + "NAME":"EVA Struts", + "URL":"https://raw.githubusercontent.com/DMagic1/KSP_EVA_Struts/master/GameData/EVAStruts/EVAStruts.version", + "DOWNLOAD":"https://github.com/DMagic1/KSP_EVA_Strut/releases", + "GITHUB":{ + "USERNAME":"DMagic1", + "REPOSITORY":"KSP_EVA_Struts", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":1, + "MINOR":0, + "PATCH":5, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } + } \ No newline at end of file diff --git a/TestCases/mods versions/EVATransfer.version b/TestCases/mods versions/EVATransfer.version new file mode 100644 index 0000000..b0962c0 --- /dev/null +++ b/TestCases/mods versions/EVATransfer.version @@ -0,0 +1,31 @@ +{ + "NAME":"EVA Transfer", + "URL":"https://raw.githubusercontent.com/DMagic1/KSP-EVA-Transfer/master/GameData/EVATransfer/EVATransfer.version", + "DOWNLOAD":"https://github.com/DMagic1/KSP-EVA-Transfer/releases", + "GITHUB":{ + "USERNAME":"DMagic1", + "REPOSITORY":"KSP-EVA-Transfer", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":1, + "MINOR":0, + "PATCH":8, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } + } \ No newline at end of file diff --git a/TestCases/mods versions/EasyVesselSwitch.version b/TestCases/mods versions/EasyVesselSwitch.version new file mode 100644 index 0000000..5e8fcaa --- /dev/null +++ b/TestCases/mods versions/EasyVesselSwitch.version @@ -0,0 +1,27 @@ +{ + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/ihsoft/EasyVesselSwitch/master/CHANGELOG.md", + "DOWNLOAD": "http://kerbal.curseforge.com/projects/easy-vessel-switch-evs", + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "NAME": "Easy Vessel Switch", + "URL": "https://raw.githubusercontent.com/ihsoft/EasyVesselSwitch/master/EasyVesselSwitch.version", + "VERSION": { + "BUILD": 41793, + "MAJOR": 1, + "MINOR": 6, + "PATCH": 6640 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/EditorExtensionsRedux.version b/TestCases/mods versions/EditorExtensionsRedux.version new file mode 100644 index 0000000..c999a17 --- /dev/null +++ b/TestCases/mods versions/EditorExtensionsRedux.version @@ -0,0 +1,30 @@ +{ + "NAME":"EditorExtensionsRedux", + "URL":"http://ksp-avc.cybutek.net/version.php?id=236", + "DOWNLOAD":"https://kerbalstuff.com/mod/1342/EditorExtensionsRedux/download", + "VERSION": + { + "MAJOR":3, + "MINOR":3, + "PATCH":19, + "BUILD":2 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/EnvironmentalVisualEnhancements.version b/TestCases/mods versions/EnvironmentalVisualEnhancements.version new file mode 100644 index 0000000..e551c8f --- /dev/null +++ b/TestCases/mods versions/EnvironmentalVisualEnhancements.version @@ -0,0 +1,31 @@ +{ + "NAME": "Environmental Visual Enhancements", + "URL": "https://raw.githubusercontent.com/WazWaz/EnvironmentalVisualEnhancements/master/EnvironmentalVisualEnhancements.version", + "DOWNLOAD" : "https://github.com/WazWaz/EnvironmentalVisualEnhancements/releases", + "GITHUB": { + "USERNAME": "WazWaz", + "REPOSITORY": "EnvironmentalVisualEnhancements", + "ALLOW_PRE_RELEASE": false + }, + "VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0, + "BUILD": 1 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + } +} diff --git a/TestCases/mods versions/FlexoDocking.version b/TestCases/mods versions/FlexoDocking.version new file mode 100644 index 0000000..d39a9d8 --- /dev/null +++ b/TestCases/mods versions/FlexoDocking.version @@ -0,0 +1,31 @@ +{ + "NAME":"Flexible Docking", + "URL":"https://raw.githubusercontent.com/DMagic1/KSP_Flexible_Docking/master/GameData/FlexoDocking/FlexoDocking.version", + "DOWNLOAD":"https://github.com/DMagic1/KSP_Flexible_Docking/releases", + "GITHUB":{ + "USERNAME":"DMagic1", + "REPOSITORY":"KSP_Flexible_Docking", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":1, + "MINOR":0, + "PATCH":6, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } + } \ No newline at end of file diff --git a/TestCases/mods versions/FuelTankExpansion.version b/TestCases/mods versions/FuelTankExpansion.version new file mode 100644 index 0000000..7148771 --- /dev/null +++ b/TestCases/mods versions/FuelTankExpansion.version @@ -0,0 +1,25 @@ +{ + "NAME": "MunarIndustries Fuel Tank Expansion", + "URL": "https://raw.githubusercontent.com/linuxgurugamer/ModularFuelTankExpansion/master/GameData/MunarIndustries/FuelTankExpansion.version", + "VERSION": { + "MAJOR": 0, + "MINOR": 9, + "PATCH": 6, + "BUILD": 1 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + } +} diff --git a/TestCases/mods versions/FuelTanksPlus.version b/TestCases/mods versions/FuelTanksPlus.version new file mode 100644 index 0000000..1482ef0 --- /dev/null +++ b/TestCases/mods versions/FuelTanksPlus.version @@ -0,0 +1,15 @@ +{ + "NAME": "Fuel Tanks Plus", + "URL": "http://ksp.necrobones.com/files/FuelTanksPlus/FuelTanksPlus.version", + "DOWNLOAD": "http://spacedock.info/mod/92/Fuel%20Tanks%20Plus", + "VERSION": { + "MAJOR": 2, + "MINOR": 0, + "PATCH": 2 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/HyperEdit.version b/TestCases/mods versions/HyperEdit.version new file mode 100644 index 0000000..1fc47ea --- /dev/null +++ b/TestCases/mods versions/HyperEdit.version @@ -0,0 +1,26 @@ +{ + "NAME": "HyperEdit", + "URL": "https://raw.githubusercontent.com/Ezriilc/HyperEdit/master/HyperEdit.version", + "DOWNLOAD": "http://www.kerbaltek.com/hyperedit", + "VERSION": { + "MAJOR": 1, + "MINOR": 5, + "PATCH": 6, + "BUILD": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 1 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 1 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 3, + "PATCH": 99 + } +} diff --git a/TestCases/mods versions/KAS.version b/TestCases/mods versions/KAS.version new file mode 100644 index 0000000..e63263f --- /dev/null +++ b/TestCases/mods versions/KAS.version @@ -0,0 +1,31 @@ +{ + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/ihsoft/KAS/master/changelog.md", + "DOWNLOAD": "http://forum.kerbalspaceprogram.com/threads/92514", + "GITHUB": { + "REPOSITORY": "KAS", + "USERNAME": "ihsoft" + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "NAME": "Kerbal Attachment System", + "URL": "https://raw.githubusercontent.com/ihsoft/KAS/master/kas.version", + "VERSION": { + "BUILD": 0, + "MAJOR": 0, + "MINOR": 6, + "PATCH": 4 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/KIS.version b/TestCases/mods versions/KIS.version new file mode 100644 index 0000000..1bbd8e8 --- /dev/null +++ b/TestCases/mods versions/KIS.version @@ -0,0 +1,27 @@ +{ + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/ihsoft/KIS/master/CHANGELOG.md", + "DOWNLOAD": "http://forum.kerbalspaceprogram.com/index.php?/topic/149848-12-kerbal-inventory-system-kis-v131/", + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "NAME": "Kerbal Inventory System", + "URL": "https://raw.githubusercontent.com/ihsoft/KIS/master/KIS.version", + "VERSION": { + "BUILD": 40620, + "MAJOR": 1, + "MINOR": 10, + "PATCH": 6640 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/KWRocketryRebalanced.version b/TestCases/mods versions/KWRocketryRebalanced.version new file mode 100644 index 0000000..066692b --- /dev/null +++ b/TestCases/mods versions/KWRocketryRebalanced.version @@ -0,0 +1,18 @@ +{ + "NAME":"KWRocketryRebalanced", + "URL":"https://raw.githubusercontent.com/linuxgurugamer/KWRocketryRedux/Rebalanced/KWRocketryRebalanced/GameData/KWRocketry/KWRocketryRebalanced.version", + + "VERSION": + { + "MAJOR": 3, + "MINOR": 2, + "PATCH": 5, + "BUILD": 2 + }, + "KSP_VERSION": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + } +} diff --git a/TestCases/mods versions/KerbalAcademy.version b/TestCases/mods versions/KerbalAcademy.version new file mode 100644 index 0000000..19fd28c --- /dev/null +++ b/TestCases/mods versions/KerbalAcademy.version @@ -0,0 +1,35 @@ +{ + "NAME" : "Contract Pack: Kerbal Academy", + "URL" : "https://github.com/severedsolo/KerbalAcademy/blob/master/KerbalAcademy.version", + "DOWNLOAD" : "https://github.com/severedsolo/KerbalAcademy/releases", + "GITHUB" : + { + "USERNAME" : "severedsolo", + "REPOSITORY" : "KerbalAcademy" + }, + "VERSION" : + { + "MAJOR" : 1, + "MINOR" : 1, + "PATCH" : 7, + "BUILD" : 0 + }, + "KSP_VERSION" : + { + "MAJOR" : 1, + "MINOR" : 2, + "PATCH" : 2 + }, + "KSP_VERSION_MIN" : + { + "MAJOR" : 1, + "MINOR" : 1, + "PATCH" : 3 + }, + "KSP_VERSION_MAX" : + { + "MAJOR" : 1, + "MINOR" : 99, + "PATCH" : 99 + } +} diff --git a/TestCases/mods versions/KerbalAlarmClock.version b/TestCases/mods versions/KerbalAlarmClock.version new file mode 100644 index 0000000..5fbc9b1 --- /dev/null +++ b/TestCases/mods versions/KerbalAlarmClock.version @@ -0,0 +1,26 @@ +{ + "NAME": "Kerbal Alarm Clock", + "URL": "https://raw.githubusercontent.com/TriggerAu/KerbalAlarmClock/master/KerbalAlarmClock/KerbalAlarmClock.version", + "DOWNLOAD" : "https://github.com/TriggerAu/KerbalAlarmClock/releases", + "VERSION": { + "MAJOR": 3, + "MINOR": 9, + "PATCH": 0, + "BUILD": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + } +} diff --git a/TestCases/mods versions/KerbalEngineer.version b/TestCases/mods versions/KerbalEngineer.version new file mode 100644 index 0000000..c7a52ee --- /dev/null +++ b/TestCases/mods versions/KerbalEngineer.version @@ -0,0 +1,29 @@ +{ + "NAME":"Kerbal Engineer Redux", + "URL":"http://ksp-avc.cybutek.net/version.php?id=6", + "VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":4, + "BUILD":3 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":2, + "PATCH":9 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":9 + } +} diff --git a/TestCases/mods versions/MagiCore.version b/TestCases/mods versions/MagiCore.version new file mode 100644 index 0000000..3928df9 --- /dev/null +++ b/TestCases/mods versions/MagiCore.version @@ -0,0 +1,29 @@ +{ + "NAME":"MagiCore", + "URL":"https://raw.githubusercontent.com/magico13/MagiCore/master/GameData/MagiCore/MagiCore.version", + "VERSION": + { + "MAJOR":1, + "MINOR":3, + "PATCH":1, + "BUILD":0 + }, + "GITHUB": + { + "USERNAME":"magico13", + "REPOSITORY":"MagiCore", + "ALLOW_PRE_RELEASE":false, + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":2, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } +} diff --git a/TestCases/mods versions/ManeuverNodeEvolved.version b/TestCases/mods versions/ManeuverNodeEvolved.version new file mode 100644 index 0000000..c5b1ba0 --- /dev/null +++ b/TestCases/mods versions/ManeuverNodeEvolved.version @@ -0,0 +1,31 @@ +{ + "NAME":"Maeneuver Node Evolved", + "URL":"https://raw.githubusercontent.com/DMagic1/KSP_Better_Maneuvering/master/GameData/ManeuverNodeEvolved/ManeuverNodeEvolved.version", + "DOWNLOAD":"https://github.com/DMagic1/KSP_Better_Maneuvering/releases", + "GITHUB":{ + "USERNAME":"DMagic1", + "REPOSITORY":"KSP_Better_Maneuvering", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":1, + "MINOR":0, + "PATCH":4, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } + } \ No newline at end of file diff --git a/TestCases/mods versions/ModularRocketSystems.version b/TestCases/mods versions/ModularRocketSystems.version new file mode 100644 index 0000000..4775445 --- /dev/null +++ b/TestCases/mods versions/ModularRocketSystems.version @@ -0,0 +1,15 @@ +{ + "NAME": "Modular Rocket Systems", + "URL": "http://ksp.necrobones.com/files/ModRocketSys/ModularRocketSystems.version", + "DOWNLOAD": "http://spacedock.info/mod/86/Modular%20Rocket%20Systems", + "VERSION": { + "MAJOR": 1, + "MINOR": 13, + "PATCH": 2 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 2, + "PATCH": 0 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/OldPartsReduxAlpha.version b/TestCases/mods versions/OldPartsReduxAlpha.version new file mode 100644 index 0000000..6796c75 --- /dev/null +++ b/TestCases/mods versions/OldPartsReduxAlpha.version @@ -0,0 +1,31 @@ +{ + "NAME":"Old Parts Redux Alpha", + "URL":"https://spacedock.info/mod/1744/Old%20Parts%20Redux", + "DOWNLOAD":"https://spacedock.info/mod/1744/Old%20Parts%20Redux/download/0.6.3", + }, + "VERSION": + { + "MAJOR":1, + "MINOR":0, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":9 + } +} diff --git a/TestCases/mods versions/PatchManager.version b/TestCases/mods versions/PatchManager.version new file mode 100644 index 0000000..c8c6f1d --- /dev/null +++ b/TestCases/mods versions/PatchManager.version @@ -0,0 +1,23 @@ +{ + "NAME": "PatchManager", + "URL": "https://raw.githubusercontent.com/linuxgurugamer/PatchManager/master/PatchManager.version", + "DOWNLOAD" : "https://github.com/linuxgurugamer/PatchManager/releases", + "GITHUB" : + { + "USERNAME" : "linuxgurugamer", + "REPOSITORY" : "PatchManager" + }, + + "URL": "https://raw.githubusercontent.com/linuxgurugamer/PatchManager/master/PatchManager.version", + "VERSION": { + "MAJOR": 0, + "MINOR": 0, + "PATCH": 15, + "BUILD": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + } +} diff --git a/TestCases/mods versions/PhysicsRangeExtender.version b/TestCases/mods versions/PhysicsRangeExtender.version new file mode 100644 index 0000000..599160a --- /dev/null +++ b/TestCases/mods versions/PhysicsRangeExtender.version @@ -0,0 +1,26 @@ +{ + "NAME": "PhysicsRangeExtender", + "URL":"https://github.com/jrodrigv/PhysicsRangeExtender/raw/master/PhysicsRangeExtender/Distribution/GameData/PhysicsRangeExtender/PhysicsRangeExtender.version", + "DOWNLOAD":"https://github.com/jrodrigv/PhysicsRangeExtender/releases/tag/1.6.0", + "CHANGE_LOG_URL":"https://github.com/jrodrigv/PhysicsRangeExtender/raw/master/PhysicsRangeExtender/Distribution/GameData/PhysicsRangeExtender/ChangeLog.txt", + "VERSION": { + "MAJOR": 1, + "MINOR": 6, + "PATCH": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/RSSeaDragon.version b/TestCases/mods versions/RSSeaDragon.version new file mode 100644 index 0000000..67536fb --- /dev/null +++ b/TestCases/mods versions/RSSeaDragon.version @@ -0,0 +1,15 @@ +{ + "NAME": "Real Scale Sea Dragon", + "URL": "http://ksp.necrobones.com/files/RSSeaDragon/RSSeaDragon.version", + "DOWNLOAD": "http://spacedock.info/mod/440/Real%20Scale%20Sea%20Dragon", + "VERSION": { + "MAJOR": 0, + "MINOR": 3, + "PATCH": 4 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 1, + "PATCH": 0 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/RasterPropMonitor.version b/TestCases/mods versions/RasterPropMonitor.version new file mode 100644 index 0000000..720bc57 --- /dev/null +++ b/TestCases/mods versions/RasterPropMonitor.version @@ -0,0 +1,21 @@ +{ + "NAME": "RasterPropMonitor", + "URL": "https://raw.githubusercontent.com/Mihara/RasterPropMonitor/master/GameData/JSI/RasterPropMonitor/RasterPropMonitor.version", + "DOWNLOAD": "https://github.com/Mihara/RasterPropMonitor/releases", + "VERSION": { + "MAJOR": 0, + "MINOR": 30, + "PATCH": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + "KSP_VERSION_MIN": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + } +} diff --git a/TestCases/mods versions/RealChute.version b/TestCases/mods versions/RealChute.version new file mode 100644 index 0000000..4dc75b3 --- /dev/null +++ b/TestCases/mods versions/RealChute.version @@ -0,0 +1,33 @@ +{ + "NAME": "RealChute", + "URL": "https://raw.githubusercontent.com/StupidChris/RealChute/master/Output/GameData/RealChute/RealChute.version", + + "VERSION": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 6, + "BUILD": 0 + }, + + "KSP_VERSION": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + + "KSP_VERSION_MIN": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 0 + }, + + "KSP_VERSION_MAX": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 99 + } +} diff --git a/TestCases/mods versions/RealScaleBoosters.version b/TestCases/mods versions/RealScaleBoosters.version new file mode 100644 index 0000000..e497f2f --- /dev/null +++ b/TestCases/mods versions/RealScaleBoosters.version @@ -0,0 +1,15 @@ +{ + "NAME": "Real Scale Boosters", + "URL": "http://ksp.necrobones.com/files/RealScaleBoosters/RealScaleBoosters.version", + "DOWNLOAD": "http://spacedock.info/mod/90/Real%20Scale%20Boosters", + "VERSION": { + "MAJOR": 0, + "MINOR": 16, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 2, + "PATCH": 0 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/RealScaleBoostersStockalike.version b/TestCases/mods versions/RealScaleBoostersStockalike.version new file mode 100644 index 0000000..4934014 --- /dev/null +++ b/TestCases/mods versions/RealScaleBoostersStockalike.version @@ -0,0 +1,15 @@ +{ + "NAME": "RSB Stockalike", + "URL": "http://ksp.necrobones.com/files/RealScaleBoosters/RealScaleBoostersStockalike.version", + "DOWNLOAD": "http://ksp.necrobones.com/files/RealScaleBoosters/", + "VERSION": { + "MAJOR": 0, + "MINOR": 4, + "PATCH": 0 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 1, + "PATCH": 0 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/RealTimeClock2.version b/TestCases/mods versions/RealTimeClock2.version new file mode 100644 index 0000000..3be2cf8 --- /dev/null +++ b/TestCases/mods versions/RealTimeClock2.version @@ -0,0 +1,30 @@ +{ + "NAME":"Real Time Clock 2", + "URL":"https://raw.githubusercontent.com/Li0n-0/Real-Time-Clock-2/master/GameData/RealTimeClock2/RealTimeClock2.version", + "DOWNLOAD":"https://github.com/Li0n-0/Real-Time-Clock-2/releases", + "VERSION": + { + "MAJOR":1, + "MINOR":7, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/RemoteTech.version b/TestCases/mods versions/RemoteTech.version new file mode 100644 index 0000000..83ed161 --- /dev/null +++ b/TestCases/mods versions/RemoteTech.version @@ -0,0 +1,33 @@ +{ + "NAME": "RemoteTech", + "URL": "https://raw.githubusercontent.com/RemoteTechnologiesGroup/RemoteTech/master/GameData/RemoteTech/RemoteTech.version", + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/RemoteTechnologiesGroup/RemoteTech/master/CHANGES.md", + "DOWNLOAD": "http://spacedock.info/mod/520/RemoteTech", + "GITHUB": + { + "USERNAME": "RemoteTechnologiesGroup", + "REPOSITORY": "RemoteTech", + "ALLOW_PRE_RELEASE": false + }, + "VERSION":{ + "MAJOR":1, + "MINOR":8, + "PATCH":10, + "BUILD":1 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} diff --git a/TestCases/mods versions/SCANsat.version b/TestCases/mods versions/SCANsat.version new file mode 100644 index 0000000..6d56623 --- /dev/null +++ b/TestCases/mods versions/SCANsat.version @@ -0,0 +1,31 @@ +{ + "NAME":"SCANsat", + "URL":"https://raw.githubusercontent.com/S-C-A-N/SCANsat/release/SCANassets/SCANsat.version", + "DOWNLOAD":"https://github.com/S-C-A-N/SCANsat/releases", + "GITHUB":{ + "USERNAME":"S-C-A-N", + "REPOSITORY":"SCANsat", + "ALLOW_PRE_RELEASE":false + }, + "VERSION":{ + "MAJOR":1, + "MINOR":1, + "PATCH":8, + "BUILD":5 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } +} diff --git a/TestCases/mods versions/SR.version b/TestCases/mods versions/SR.version new file mode 100644 index 0000000..d5efb6b --- /dev/null +++ b/TestCases/mods versions/SR.version @@ -0,0 +1,27 @@ +{ + "NAME":"StageRecovery", + "URL":"https://raw.githubusercontent.com/magico13/StageRecovery/master/GameData/StageRecovery/SR.version", + "DOWNLOAD":"http://forum.kerbalspaceprogram.com/index.php?/topic/78226-1", + "CHANGE_LOG_URL":"https://raw.githubusercontent.com/magico13/StageRecovery/master/GameData/StageRecovery/SR-Readme.txt", + "VERSION":{ + "MAJOR":1, + "MINOR":8, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } +} diff --git a/TestCases/mods versions/SafeChute.version b/TestCases/mods versions/SafeChute.version new file mode 100644 index 0000000..bae0674 --- /dev/null +++ b/TestCases/mods versions/SafeChute.version @@ -0,0 +1,6 @@ +{"NAME":"SafeChute", +"URL":"https://raw.githubusercontent.com/henrybauer/SafeChute/master/SafeChute.version", +"DOWNLOAD":"http://forum.kerbalspaceprogram.com/threads/100855", +"VERSION":{"MAJOR":2,"MINOR":1,"PATCH":10,"BUILD":0}, +"KSP_VERSION":{"MAJOR":1,"MINOR":4,"PATCH":1} +} diff --git a/TestCases/mods versions/TimeControl.version b/TestCases/mods versions/TimeControl.version new file mode 100644 index 0000000..0465509 --- /dev/null +++ b/TestCases/mods versions/TimeControl.version @@ -0,0 +1,27 @@ +{ + "NAME": "TimeControl", + "URL": "http://ksp-avc.cybutek.net/version.php?id=310", + "DOWNLOAD": "https://github.com/ntwest/TimeControl/releases", + "CHANGE_LOG_URL": "https://github.com/ntwest/TimeControl/blob/master/CHANGELOG.md", + "VERSION": { + "MAJOR": 2, + "MINOR": 9, + "PATCH": 0, + "BUILD": 0 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/ToolbarControl.version b/TestCases/mods versions/ToolbarControl.version new file mode 100644 index 0000000..a66255c --- /dev/null +++ b/TestCases/mods versions/ToolbarControl.version @@ -0,0 +1,23 @@ +{ + "NAME" : "ToolbarControl", + "URL" : "https://raw.githubusercontent.com/linuxgurugamer/ToolbarControl/master/ToolbarControl.version", + "DOWNLOAD" : "https://github.com/linuxgurugamer/ToolbarControl/releases", + "GITHUB" : + { + "USERNAME" : "linuxgurugamer", + "REPOSITORY" : "ToolbarControl" + }, + "VERSION" : + { + "MAJOR" : 0, + "MINOR" : 1, + "PATCH" : 5, + "BUILD" : 6 + }, + "KSP_VERSION": + { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + } +} diff --git a/TestCases/mods versions/TrackingStationEvolved.version b/TestCases/mods versions/TrackingStationEvolved.version new file mode 100644 index 0000000..894ce5a --- /dev/null +++ b/TestCases/mods versions/TrackingStationEvolved.version @@ -0,0 +1,31 @@ +{ + "NAME":"Tracking Station Evolved", + "URL":"https://raw.githubusercontent.com/DMagic1/KSP_BetterTracking/master/GameData/TrackingStationEvolved/TrackingStationEvolved.version", + "DOWNLOAD":"https://github.com/DMagic1/KSP_BetterTracking/releases", + "GITHUB":{ + "USERNAME":"DMagic1", + "REPOSITORY":"KSP_BetterTracking", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":1, + "MINOR":0, + "PATCH":2, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":8 + } + } \ No newline at end of file diff --git a/TestCases/mods versions/TweakScale.version b/TestCases/mods versions/TweakScale.version new file mode 100644 index 0000000..56d50cb --- /dev/null +++ b/TestCases/mods versions/TweakScale.version @@ -0,0 +1,33 @@ +{ + "NAME":"TweakScale", + "URL":"https://github.com/pellinor0/TweakScale/blob/master/GameData/TweakScale/TweakScale.version", + "DOWNLOAD":"http://spacedock.info/mod/127/TweakScale/", + "GITHUB":{ + "USERNAME":"Pellinor", + "REPOSITORY":"TweakScale", + "ALLOW_PRE_RELEASE":false, + }, + "VERSION":{ + "MAJOR":2, + "MINOR":3, + "PATCH":10, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":99 + } +} diff --git a/TestCases/mods versions/USI-LS.version b/TestCases/mods versions/USI-LS.version new file mode 100644 index 0000000..9f94437 --- /dev/null +++ b/TestCases/mods versions/USI-LS.version @@ -0,0 +1,31 @@ +{ + "NAME":"USI-LS", + "URL":"https://raw.githubusercontent.com/BobPalmer/USI-LS/master/FOR_RELEASE/GameData/UmbraSpaceIndustries/LifeSupport/USI-LS.version", + "DOWNLOAD":"https://github.com/BobPalmer/USI-LS/releases", + "GITHUB":{ + "USERNAME":"BobPalmer", + "REPOSITORY":"USI-LS", + "ALLOW_PRE_RELEASE":false + }, + "VERSION":{ + "MAJOR":0, + "MINOR":9, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":9 + } + } diff --git a/TestCases/mods versions/USITools.version b/TestCases/mods versions/USITools.version new file mode 100644 index 0000000..1ec62e5 --- /dev/null +++ b/TestCases/mods versions/USITools.version @@ -0,0 +1,31 @@ +{ + "NAME":"USI Tools", + "URL":"https://raw.githubusercontent.com/BobPalmer/UmbraSpaceIndustries/master/FOR_RELEASE/GameData/000_USITools/USITools.version", + "DOWNLOAD":"https://github.com/BobPalmer/UmbraSpaceIndustries/releases", + "GITHUB":{ + "USERNAME":"BobPalmer", + "REPOSITORY":"UmbraSpaceIndustries", + "ALLOW_PRE_RELEASE":false + }, + "VERSION":{ + "MAJOR":0, + "MINOR":12, + "PATCH":0, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":1 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":9 + } + } \ No newline at end of file diff --git a/TestCases/mods versions/UniversalStorage.version b/TestCases/mods versions/UniversalStorage.version new file mode 100644 index 0000000..b92b618 --- /dev/null +++ b/TestCases/mods versions/UniversalStorage.version @@ -0,0 +1 @@ +{"NAME":"Universal Storage","URL":"http://ksp-avc.cybutek.net/version.php?id=365","DOWNLOAD":"http://spacedock.info/mod/329/Universal%20Storage","CHANGE_LOG_URL":"http://spacedock.info/mod/329/Universal%20Storage","VERSION":{"MAJOR":1,"MINOR":4,"PATCH":0,"BUILD":0},"KSP_VERSION":{"MAJOR":1,"MINOR":4,"PATCH":0},"KSP_VERSION_MIN":{"MAJOR":1,"MINOR":2,"PATCH":1},"KSP_VERSION_MAX":{"MAJOR":1,"MINOR":4,"PATCH":99}} \ No newline at end of file diff --git a/TestCases/mods versions/UniversalStorageStockResourceFuelCell.version b/TestCases/mods versions/UniversalStorageStockResourceFuelCell.version new file mode 100644 index 0000000..a4b31a6 --- /dev/null +++ b/TestCases/mods versions/UniversalStorageStockResourceFuelCell.version @@ -0,0 +1,29 @@ +{ + "NAME":"Universal Storage - Stock Resource Fuel Cell", + "DOWNLOAD":"https://github.com/QuickBASIC/UniversalStorageStockResourceFuelCell/releases", + "VERSION": + { + "MAJOR":0, + "MINOR":1, + "PATCH":4, + "BUILD":1 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":1, + "PATCH":3 + }, + "KSP_VERSION_MIN": + { + "MAJOR":1, + "MINOR":1, + "PATCH":3 + }, + "KSP_VERSION_MAX": + { + "MAJOR":1, + "MINOR":4, + "PATCH":99 + } +} diff --git a/TestCases/mods versions/WaypointManager.version b/TestCases/mods versions/WaypointManager.version new file mode 100644 index 0000000..507786a --- /dev/null +++ b/TestCases/mods versions/WaypointManager.version @@ -0,0 +1,32 @@ +{ + "NAME":"Waypoint Manager", + "URL":"https://raw.githubusercontent.com/jrossignol/WaypointManager/master/GameData/WaypointManager/WaypointManager.version", + "DOWNLOAD":"https://github.com/jrossignol/WaypointManager/releases", + "CHANGE_LOG_URL":"https://raw.githubusercontent.com/jrossignol/WaypointManager/2.7.2/CHANGES.txt", + "GITHUB":{ + "USERNAME":"jrossignol", + "REPOSITORY":"WaypointManager", + "ALLOW_PRE_RELEASE":false + }, + "VERSION":{ + "MAJOR":2, + "MINOR":7, + "PATCH":2, + "BUILD":0 + }, + "KSP_VERSION":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MIN":{ + "MAJOR":1, + "MINOR":4, + "PATCH":0 + }, + "KSP_VERSION_MAX":{ + "MAJOR":1, + "MINOR":4, + "PATCH":99 + } + } diff --git a/TestCases/mods versions/[x] Science!.version b/TestCases/mods versions/[x] Science!.version new file mode 100644 index 0000000..07d6bf8 --- /dev/null +++ b/TestCases/mods versions/[x] Science!.version @@ -0,0 +1,18 @@ +{ + "NAME":"[x] Science!", + "URL":"https://themoose.co.uk/ksp/%5Bx%5D%20Science!.version", + "DOWNLOAD":"https://themoose.co.uk/ksp/downloads.html", + "CHANGE_LOG_URL":"https://themoose.co.uk/ksp/CHANGES.md", + "VERSION": + { + "MAJOR":5, + "MINOR":13, + "PATCH":0 + }, + "KSP_VERSION": + { + "MAJOR":1, + "MINOR":4, + "PATCH":1 + } +} \ No newline at end of file diff --git a/TestCases/mods versions/kOS.version b/TestCases/mods versions/kOS.version new file mode 100644 index 0000000..c97835b --- /dev/null +++ b/TestCases/mods versions/kOS.version @@ -0,0 +1,32 @@ +{ + "NAME": "kOS", + "URL": "https://raw.githubusercontent.com/KSP-KOS/KOS/master/Resources/GameData/kOS/kOS.version", + "DOWNLOAD": "TODO - when release...", + "CHANGE_LOG_URL": "https://raw.githubusercontent.com/KSP-KOS/KOS/master/CHANGELOG.md", + "GITHUB": { + "USERNAME":"KSP-KOS", + "REPOSITORY":"KOS", + "ALLOW_PRE_RELEASE":false + }, + "VERSION": { + "MAJOR": 1, + "MINOR": 1, + "PATCH": 5, + "BUILD": 2 + }, + "KSP_VERSION": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + "KSP_VERSION_MIN": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + }, + "KSP_VERSION_MAX": { + "MAJOR": 1, + "MINOR": 4, + "PATCH": 1 + } +} diff --git a/buildRelease.bat b/buildRelease.bat new file mode 100644 index 0000000..92b2580 --- /dev/null +++ b/buildRelease.bat @@ -0,0 +1,75 @@ + +@echo off + +rem Put the following text into the Post-build event command line: +rem without the "rem": + +rem start /D D:\Users\jbb\github\IFI-Life-Support /WAIT deploy.bat $(TargetDir) $(TargetFileName) +rem +rem if $(ConfigurationName) == Release ( +rem +rem start /D D:\Users\jbb\github\IFI-Life-Support /WAIT buildRelease.bat $(TargetDir) $(TargetFileName) +rem +rem ) + + +rem Set variables here + +rem H is the destination game folder +rem GAMEDIR is the name of the mod folder (usually the mod name) +rem GAMEDATA is the name of the local GameData +rem VERSIONFILE is the name of the version file, usually the same as GAMEDATA, +rem but not always +rem LICENSE is the license file +rem README is the readme file + +set GAMEDIR=KSP-AVC +set GAMEDATA="GameData\" +set VERSIONFILE=%GAMEDIR%.version +set LICENSE=License.txt +set README=ReadMe.md + +set RELEASEDIR=d:\Users\jbb\release +set ZIP="c:\Program Files\7-zip\7z.exe" + +rem Copy files to GameData locations + +copy /Y "%1%2" "%GAMEDATA%\%GAMEDIR%\Plugins" +copy /Y %VERSIONFILE% %GAMEDATA%\%GAMEDIR% +copy /Y ..\MiniAVC.dll %GAMEDATA%\%GAMEDIR% + +if "%LICENSE%" NEQ "" copy /y %LICENSE% %GAMEDATA%\%GAMEDIR% +if "%README%" NEQ "" copy /Y %README% %GAMEDATA%\%GAMEDIR% + +rem Get Version info + +copy %VERSIONFILE% tmp.version +set VERSIONFILE=tmp.version +rem The following requires the JQ program, available here: https://stedolan.github.io/jq/download/ +c:\local\jq-win64 ".VERSION.MAJOR" %VERSIONFILE% >tmpfile +set /P major=tmpfile +set /P minor=tmpfile +set /P patch=tmpfile +set /P build=