├── .gitattributes ├── .gitignore ├── AVCToolkit ├── AVCToolkit.csproj ├── AddonInfo.cs ├── GitHubInfo.cs ├── Json │ ├── IJsonObject.cs │ ├── JsonFieldAttribute.cs │ ├── JsonObject.cs │ └── JsonSerialiser.cs ├── Program.cs ├── Properties │ └── AssemblyInfo.cs └── VersionInfo.cs ├── Artwork ├── DropDownActive.psd ├── DropDownBackground.psd ├── DropDownHover.psd ├── DropDownNormal.psd ├── DropDownOnHover.psd ├── DropDownOnNormal.psd └── OverlayBackground.psd ├── Documents ├── KSP-AVC │ ├── CHANGES.txt │ ├── LICENSE.txt │ └── README.htm └── MiniAVC │ ├── CHANGES.txt │ ├── LICENSE.txt │ ├── README.htm │ └── README.md ├── KSP-AVC.sln ├── KSP-AVC.sln.DotSettings ├── KSP-AVC ├── Addon.cs ├── AddonInfo.cs ├── AddonLibrary.cs ├── ChangeLogGui.cs ├── CheckerProgressGui.cs ├── Configuration.cs ├── DropDownList.cs ├── FirstRunGui.cs ├── IssueGui.cs ├── Json.cs ├── KSP-AVC.csproj ├── Logger.cs ├── Properties │ └── AssemblyInfo.cs ├── Starter.cs ├── ToolTipGui.cs ├── Toolbar │ └── ToolbarWindow.cs ├── Utils.cs └── VersionInfo.cs ├── MiniAVC ├── Addon.cs ├── AddonInfo.cs ├── AddonLibrary.cs ├── AddonSettings.cs ├── FirstRunGui.cs ├── IssueGui.cs ├── Json.cs ├── Logger.cs ├── MiniAVC.csproj ├── Properties │ └── AssemblyInfo.cs ├── Starter.cs ├── ToolTipGui.cs └── VersionInfo.cs └── Output ├── AVCToolkit └── AVCToolkit.exe ├── KSP-AVC ├── KSP-AVC.dll ├── KSP-AVC.version └── Textures │ ├── DropDownActive.png │ ├── DropDownBackground.png │ ├── DropDownHover.png │ ├── DropDownNormal.png │ ├── DropDownOnHover.png │ ├── DropDownOnNormal.png │ └── OverlayBackground.png └── MiniAVC └── MiniAVC.dll /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Bb]in/ 3 | [Oo]bj/ 4 | 5 | # mstest test results 6 | TestResults 7 | 8 | ## Ignore Visual Studio temporary files, build results, and 9 | ## files generated by popular Visual Studio add-ons. 10 | 11 | # User-specific files 12 | *.suo 13 | *.user 14 | *.sln.docstates 15 | 16 | # Build results 17 | [Dd]ebug/ 18 | x64/ 19 | *_i.c 20 | *_p.c 21 | *.ilk 22 | *.meta 23 | *.obj 24 | *.pch 25 | *.pdb 26 | *.pgc 27 | *.pgd 28 | *.rsp 29 | *.sbr 30 | *.tlb 31 | *.tli 32 | *.tlh 33 | *.tmp 34 | *.log 35 | *.vspscc 36 | *.vssscc 37 | .builds 38 | 39 | # Visual C++ cache files 40 | ipch/ 41 | *.aps 42 | *.ncb 43 | *.opensdf 44 | *.sdf 45 | 46 | # Visual Studio profiler 47 | *.psess 48 | *.vsp 49 | *.vspx 50 | 51 | # Guidance Automation Toolkit 52 | *.gpState 53 | 54 | # ReSharper is a .NET coding add-in 55 | _ReSharper* 56 | 57 | # Mindbench SASS cache 58 | .sass-cache/ 59 | 60 | # NCrunch 61 | *.ncrunch* 62 | .*crunch*.local.xml 63 | 64 | # Installshield output folder 65 | [Ee]xpress 66 | 67 | # DocProject is a documentation generator add-in 68 | DocProject/buildhelp/ 69 | DocProject/Help/*.HxT 70 | DocProject/Help/*.HxC 71 | DocProject/Help/*.hhc 72 | DocProject/Help/*.hhk 73 | DocProject/Help/*.hhp 74 | DocProject/Help/Html2 75 | DocProject/Help/html 76 | 77 | # Click-Once directory 78 | publish 79 | 80 | # Publish Web Output 81 | *.Publish.xml 82 | 83 | # NuGet Packages Directory 84 | packages 85 | 86 | # Windows Azure Build Output 87 | csx 88 | *.build.csdef 89 | 90 | # Windows Store app package directory 91 | AppPackages/ 92 | 93 | # Others 94 | sql 95 | TestResults 96 | [Tt]est[Rr]esult* 97 | *.Cache 98 | ClientBin 99 | [Ss]tyle[Cc]op.* 100 | ~$* 101 | *.dbmdl 102 | Generated_Code #added for RIA/Silverlight projects 103 | .vs 104 | 105 | # Backup & report files from converting an old project file to a newer 106 | # Visual Studio version. Backup files are not needed, because we have git ;-) 107 | _UpgradeReport_Files/ 108 | Backup*/ 109 | UpgradeLog*.XML 110 | 111 | # SQL Server files 112 | App_Data/*.mdf 113 | App_Data/*.ldf 114 | 115 | *.zip 116 | *.bat 117 | [Gg]ame/ 118 | [Rr]elease/ -------------------------------------------------------------------------------- /AVCToolkit/AVCToolkit.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {FD522EDB-A592-41C8-9342-C3629C18A6AD} 8 | Exe 9 | Properties 10 | AVCToolkit 11 | AVCToolkit 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | AnyCPU 18 | true 19 | full 20 | false 21 | ..\Output\AVCToolkit\ 22 | DEBUG;TRACE 23 | prompt 24 | 4 25 | 26 | 27 | AnyCPU 28 | none 29 | true 30 | ..\Output\AVCToolkit\ 31 | TRACE 32 | prompt 33 | 4 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | $(PostBuildEventDependsOn); 62 | PostBuildMacros; 63 | 64 | del "$(SolutionDir)Release\AVCToolkit\*" /Q 65 | xcopy "$(SolutionDir)Documents\AVCToolkit\*" "$(SolutionDir)Release\AVCToolkit\Documents\*" /E /Y 66 | 7z.exe a -tzip -mx3 "$(SolutionDir)Release\AVCToolkit\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Output\AVCToolkit" 67 | 7z.exe a -tzip -mx3 "$(SolutionDir)Release\AVCToolkit\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Documents\AVCToolkit\*" 68 | 69 | 70 | del "$(TargetDir)*" /Q 71 | 72 | 79 | -------------------------------------------------------------------------------- /AVCToolkit/AddonInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using AVCToolkit.Json; 21 | 22 | #endregion 23 | 24 | namespace AVCToolkit 25 | { 26 | public class AddonInfo 27 | { 28 | #region Fields 29 | 30 | private GitHubInfo gitHub = new GitHubInfo(); 31 | 32 | #endregion 33 | 34 | #region Properties 35 | 36 | [JsonField("CHANGE_LOG", Order = 4)] 37 | public string ChangeLog { get; set; } 38 | 39 | [JsonField("CHANGE_LOG_URL", Order = 5)] 40 | public string ChangeLogUrl { get; set; } 41 | 42 | [JsonField("DOWNLOAD", Order = 3)] 43 | public string Download { get; set; } 44 | 45 | [JsonField("GITHUB", Order = 6)] 46 | public GitHubInfo GitHub 47 | { 48 | get { return this.gitHub; } 49 | set { this.gitHub = value; } 50 | } 51 | 52 | [JsonField("KSP_VERSION", Order = 8)] 53 | public VersionInfo KspVersion { get; set; } 54 | 55 | [JsonField("KSP_VERSION_MAX", Order = 10)] 56 | public VersionInfo KspVersionMax { get; set; } 57 | 58 | [JsonField("KSP_VERSION_MIN", Order = 9)] 59 | public VersionInfo KspVersionMin { get; set; } 60 | 61 | [JsonField("NAME", Order = 1)] 62 | public string Name { get; set; } 63 | 64 | [JsonField("URL", Order = 2)] 65 | public string Url { get; set; } 66 | 67 | [JsonField("VERSION", Order = 7)] 68 | public VersionInfo Version { get; set; } 69 | 70 | #endregion 71 | } 72 | } -------------------------------------------------------------------------------- /AVCToolkit/GitHubInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using AVCToolkit.Json; 21 | 22 | #endregion 23 | 24 | namespace AVCToolkit 25 | { 26 | public class GitHubInfo 27 | { 28 | #region Properties 29 | 30 | [JsonField("ALLOW_PRE_RELEASE", Order = 3)] 31 | public bool? AllowPreRelease { get; set; } 32 | 33 | [JsonField("REPOSITORY", Order = 2)] 34 | public string Repository { get; set; } 35 | 36 | [JsonField("USERNAME", Order = 1)] 37 | public string Username { get; set; } 38 | 39 | #endregion 40 | } 41 | } -------------------------------------------------------------------------------- /AVCToolkit/Json/IJsonObject.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | namespace AVCToolkit.Json 19 | { 20 | public interface IJsonObject 21 | { 22 | #region Methods: public 23 | 24 | JsonObject ToJsonObject(); 25 | 26 | #endregion 27 | } 28 | } -------------------------------------------------------------------------------- /AVCToolkit/Json/JsonFieldAttribute.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | 22 | #endregion 23 | 24 | namespace AVCToolkit.Json 25 | { 26 | [AttributeUsage(AttributeTargets.Property)] 27 | public class JsonFieldAttribute : Attribute 28 | { 29 | #region Constructors 30 | 31 | public JsonFieldAttribute(string name) 32 | { 33 | this.Name = name; 34 | } 35 | 36 | #endregion 37 | 38 | #region Properties 39 | 40 | public string Name { get; private set; } 41 | 42 | public int Order { get; set; } 43 | 44 | #endregion 45 | } 46 | } -------------------------------------------------------------------------------- /AVCToolkit/Json/JsonObject.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System.Collections.Generic; 21 | using System.Linq; 22 | 23 | #endregion 24 | 25 | namespace AVCToolkit.Json 26 | { 27 | public class JsonObject 28 | { 29 | #region Fields 30 | 31 | private readonly Dictionary fields = new Dictionary(); 32 | 33 | #endregion 34 | 35 | #region Constructors 36 | 37 | public JsonObject(object obj) 38 | { 39 | foreach (var property in obj.GetType().GetProperties().Where(p => p.IsDefined(typeof(JsonFieldAttribute), true)).ToList().OrderBy(p => (p.GetCustomAttributes(typeof(JsonFieldAttribute), true).First() as JsonFieldAttribute).Order)) 40 | { 41 | var name = (property.GetCustomAttributes(typeof(JsonFieldAttribute), true).First() as JsonFieldAttribute).Name; 42 | var value = property.GetValue(obj, null); 43 | 44 | this.fields.Add(name, value); 45 | } 46 | } 47 | 48 | #endregion 49 | 50 | #region Properties 51 | 52 | public int Count 53 | { 54 | get { return this.fields.Count; } 55 | } 56 | 57 | public Dictionary Fields 58 | { 59 | get { return this.fields; } 60 | } 61 | 62 | public bool HasVisibleFields 63 | { 64 | get { return this.fields.Any(f => f.Value != null); } 65 | } 66 | 67 | #endregion 68 | } 69 | } -------------------------------------------------------------------------------- /AVCToolkit/Json/JsonSerialiser.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | using AVCToolkit.Json; 24 | 25 | #endregion 26 | 27 | namespace AVCToolkit 28 | { 29 | public static class JsonSerialiser 30 | { 31 | #region Methods: public 32 | 33 | public static string Serialise(object obj) 34 | { 35 | var jsonObject = new JsonObject(obj); 36 | var json = "{"; 37 | 38 | var first = true; 39 | foreach (var field in jsonObject.Fields) 40 | { 41 | var jsonField = SerialiseField(field); 42 | if (jsonField == String.Empty) 43 | { 44 | continue; 45 | } 46 | if (!first) 47 | { 48 | json += ","; 49 | } 50 | json += jsonField; 51 | first = false; 52 | } 53 | 54 | return json + "}"; 55 | } 56 | 57 | #endregion 58 | 59 | #region Methods: private 60 | 61 | private static bool IsPrimitive(object value) 62 | { 63 | return value is byte || 64 | value is sbyte || 65 | value is short || 66 | value is ushort || 67 | value is int || 68 | value is uint || 69 | value is long || 70 | value is ulong || 71 | value is float || 72 | value is double || 73 | value is decimal || 74 | value is bool; 75 | } 76 | 77 | private static string SerialiseField(KeyValuePair field) 78 | { 79 | if (field.Value == null) 80 | { 81 | return String.Empty; 82 | } 83 | 84 | if (IsPrimitive(field.Value)) 85 | { 86 | return "\"" + field.Key + "\":" + field.Value; 87 | } 88 | 89 | var jsonObject = new JsonObject(field.Value); 90 | if (jsonObject.Count > 0) 91 | { 92 | if (jsonObject.HasVisibleFields) 93 | { 94 | return "\"" + field.Key + "\":" + Serialise(field.Value); 95 | } 96 | return String.Empty; 97 | } 98 | 99 | return "\"" + field.Key + "\":\"" + field.Value + "\""; 100 | } 101 | 102 | #endregion 103 | } 104 | } -------------------------------------------------------------------------------- /AVCToolkit/Program.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Globalization; 22 | using System.IO; 23 | 24 | #endregion 25 | 26 | namespace AVCToolkit 27 | { 28 | internal class Program 29 | { 30 | #region Fields 31 | 32 | private static readonly AddonInfo addon = new AddonInfo(); 33 | private static string output; 34 | 35 | #endregion 36 | 37 | #region Methods: private 38 | 39 | private static void Main(string[] args) 40 | { 41 | for (var i = 0; i < args.Length; i++) 42 | { 43 | switch (args[i].ToLower(CultureInfo.InvariantCulture)) 44 | { 45 | case "-name": 46 | if (i++ < args.Length) 47 | { 48 | addon.Name = args[i]; 49 | } 50 | break; 51 | 52 | case "-url": 53 | if (i++ < args.Length) 54 | { 55 | addon.Url = args[i]; 56 | } 57 | break; 58 | 59 | case "-download": 60 | if (i++ < args.Length) 61 | { 62 | addon.Download = args[i]; 63 | } 64 | break; 65 | 66 | case "-change_log": 67 | if (i++ < args.Length) 68 | { 69 | addon.ChangeLog = args[i]; 70 | } 71 | break; 72 | 73 | case "-change_log_url": 74 | if (i++ < args.Length) 75 | { 76 | addon.ChangeLogUrl = args[i]; 77 | } 78 | break; 79 | 80 | case "-github.username": 81 | if (i++ < args.Length) 82 | { 83 | addon.GitHub.Username = args[i]; 84 | } 85 | break; 86 | 87 | case "-github.repository": 88 | if (i++ < args.Length) 89 | { 90 | addon.GitHub.Repository = args[i]; 91 | } 92 | break; 93 | 94 | case "-github.allow_pre_release": 95 | if (i++ < args.Length) 96 | { 97 | addon.GitHub.AllowPreRelease = Boolean.Parse(args[i]); 98 | } 99 | break; 100 | 101 | case "-version": 102 | if (i++ < args.Length) 103 | { 104 | addon.Version = new VersionInfo(args[i]); 105 | } 106 | break; 107 | 108 | case "-ksp_version": 109 | if (i++ < args.Length) 110 | { 111 | addon.KspVersion = new VersionInfo(args[i]); 112 | } 113 | break; 114 | 115 | case "-ksp_version_min": 116 | if (i++ < args.Length) 117 | { 118 | addon.KspVersionMin = new VersionInfo(args[i]); 119 | } 120 | break; 121 | 122 | case "-ksp_version_max": 123 | if (i++ < args.Length) 124 | { 125 | addon.KspVersionMax = new VersionInfo(args[i]); 126 | } 127 | break; 128 | 129 | case "-output": 130 | if (i++ < args.Length) 131 | { 132 | output = args[i]; 133 | } 134 | break; 135 | } 136 | } 137 | 138 | if (!String.IsNullOrEmpty(output)) 139 | { 140 | using (var stream = new StreamWriter(output)) 141 | { 142 | stream.Write(JsonSerialiser.Serialise(addon)); 143 | } 144 | } 145 | 146 | Console.WriteLine(JsonSerialiser.Serialise(addon)); 147 | } 148 | 149 | #endregion 150 | } 151 | } -------------------------------------------------------------------------------- /AVCToolkit/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System.Reflection; 21 | using System.Runtime.InteropServices; 22 | 23 | #endregion 24 | 25 | // General Information about an assembly is controlled through the following 26 | // set of attributes. Change these attribute values to modify the information 27 | // associated with an assembly. 28 | 29 | [assembly: AssemblyTitle("AVCToolkit")] 30 | [assembly: AssemblyProduct("AVCToolkit")] 31 | [assembly: AssemblyCopyright("Copyright © 2014 CYBUTEK")] 32 | 33 | // Setting ComVisible to false makes the types in this assembly not visible 34 | // to COM components. If you need to access a type in this assembly from 35 | // COM, set the ComVisible attribute to true on that type. 36 | 37 | [assembly: ComVisible(false)] 38 | 39 | // The following GUID is for the ID of the typelib if this project is exposed to COM 40 | 41 | [assembly: Guid("73a52241-684b-4817-b305-31f3b8a4a92f")] 42 | 43 | // Version information for an assembly consists of the following four values: 44 | // 45 | // Major Version 46 | // Minor Version 47 | // Build Number 48 | // Revision 49 | // 50 | // You can specify all the values or you can default the Build and Revision Numbers 51 | // by using the '*' as shown below: 52 | // [assembly: AssemblyVersion("1.0.*")] 53 | 54 | [assembly: AssemblyVersion("1.0.0.0")] -------------------------------------------------------------------------------- /AVCToolkit/VersionInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Text.RegularExpressions; 22 | 23 | using AVCToolkit.Json; 24 | 25 | #endregion 26 | 27 | namespace AVCToolkit 28 | { 29 | public class VersionInfo : IComparable 30 | { 31 | #region Constructors 32 | 33 | public VersionInfo(long major = 0, long minor = 0, long patch = 0, long build = 0) 34 | { 35 | this.SetVersion(major, minor, patch, build); 36 | } 37 | 38 | public VersionInfo(string version) 39 | { 40 | var sections = Regex.Replace(version, @"[^\d\.]", String.Empty).Split('.'); 41 | 42 | switch (sections.Length) 43 | { 44 | case 1: 45 | this.SetVersion(Int64.Parse(sections[0])); 46 | return; 47 | 48 | case 2: 49 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1])); 50 | return; 51 | 52 | case 3: 53 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2])); 54 | return; 55 | 56 | case 4: 57 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2]), Int64.Parse(sections[3])); 58 | return; 59 | 60 | default: 61 | this.SetVersion(); 62 | return; 63 | } 64 | } 65 | 66 | #endregion 67 | 68 | #region Properties 69 | 70 | public static VersionInfo MaxValue 71 | { 72 | get { return new VersionInfo(Int64.MaxValue, Int64.MaxValue, Int64.MaxValue, Int64.MaxValue); } 73 | } 74 | 75 | public static VersionInfo MinValue 76 | { 77 | get { return new VersionInfo(); } 78 | } 79 | 80 | [JsonField("BUILD", Order = 4)] 81 | public long Build { get; set; } 82 | 83 | [JsonField("MAJOR", Order = 1)] 84 | public long Major { get; set; } 85 | 86 | [JsonField("MINOR", Order = 2)] 87 | public long Minor { get; set; } 88 | 89 | [JsonField("PATCH", Order = 3)] 90 | public long Patch { get; set; } 91 | 92 | #endregion 93 | 94 | #region Operators 95 | 96 | public static bool operator ==(VersionInfo v1, VersionInfo v2) 97 | { 98 | return Equals(v1, v2); 99 | } 100 | 101 | public static bool operator >(VersionInfo v1, VersionInfo v2) 102 | { 103 | return v1.CompareTo(v2) > 0; 104 | } 105 | 106 | public static bool operator >=(VersionInfo v1, VersionInfo v2) 107 | { 108 | return v1.CompareTo(v2) >= 0; 109 | } 110 | 111 | public static implicit operator Version(VersionInfo version) 112 | { 113 | return new Version(Convert.ToInt32(version.Major), Convert.ToInt32(version.Minor), Convert.ToInt32(version.Patch), Convert.ToInt32(version.Build)); 114 | } 115 | 116 | public static implicit operator VersionInfo(Version version) 117 | { 118 | return new VersionInfo(version.Major, version.Minor, version.Build, version.Revision); 119 | } 120 | 121 | public static bool operator !=(VersionInfo v1, VersionInfo v2) 122 | { 123 | return !Equals(v1, v2); 124 | } 125 | 126 | public static bool operator <(VersionInfo v1, VersionInfo v2) 127 | { 128 | return v1.CompareTo(v2) < 0; 129 | } 130 | 131 | public static bool operator <=(VersionInfo v1, VersionInfo v2) 132 | { 133 | return v1.CompareTo(v2) <= 0; 134 | } 135 | 136 | #endregion 137 | 138 | #region Methods: public 139 | 140 | public int CompareTo(object obj) 141 | { 142 | if (obj == null) 143 | { 144 | return 1; 145 | } 146 | 147 | var other = obj as VersionInfo; 148 | if (other == null) 149 | { 150 | throw new ArgumentException("Not a VersionInfo object."); 151 | } 152 | 153 | var major = this.Major.CompareTo(other.Major); 154 | if (major != 0) 155 | { 156 | return major; 157 | } 158 | 159 | var minor = this.Minor.CompareTo(other.Minor); 160 | if (minor != 0) 161 | { 162 | return minor; 163 | } 164 | 165 | var patch = this.Patch.CompareTo(other.Patch); 166 | return patch != 0 ? patch : this.Build.CompareTo(other.Build); 167 | } 168 | 169 | public override bool Equals(object obj) 170 | { 171 | if (ReferenceEquals(null, obj)) 172 | { 173 | return false; 174 | } 175 | if (ReferenceEquals(this, obj)) 176 | { 177 | return true; 178 | } 179 | return obj.GetType() == this.GetType() && this.Equals((VersionInfo)obj); 180 | } 181 | 182 | public override int GetHashCode() 183 | { 184 | unchecked 185 | { 186 | var hashCode = this.Major.GetHashCode(); 187 | hashCode = (hashCode * 397) ^ this.Minor.GetHashCode(); 188 | hashCode = (hashCode * 397) ^ this.Patch.GetHashCode(); 189 | hashCode = (hashCode * 397) ^ this.Build.GetHashCode(); 190 | return hashCode; 191 | } 192 | } 193 | 194 | public void SetVersion(long major = 0, long minor = 0, long patch = 0, long build = 0) 195 | { 196 | this.Major = major; 197 | this.Minor = minor; 198 | this.Patch = patch; 199 | this.Build = build; 200 | } 201 | 202 | public override string ToString() 203 | { 204 | if (this.Build > 0) 205 | { 206 | return String.Format("{0}.{1}.{2}.{3}", this.Major, this.Minor, this.Patch, this.Build); 207 | } 208 | return this.Patch > 0 ? String.Format("{0}.{1}.{2}", this.Major, this.Minor, this.Patch) : String.Format("{0}.{1}", this.Major, this.Minor); 209 | } 210 | 211 | #endregion 212 | 213 | #region Methods: protected 214 | 215 | protected bool Equals(VersionInfo other) 216 | { 217 | return this.Major.Equals(other.Major) && this.Minor.Equals(other.Minor) && this.Patch.Equals(other.Patch) && this.Build.Equals(other.Build); 218 | } 219 | 220 | #endregion 221 | } 222 | } -------------------------------------------------------------------------------- /Artwork/DropDownActive.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Artwork/DropDownActive.psd -------------------------------------------------------------------------------- /Artwork/DropDownBackground.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Artwork/DropDownBackground.psd -------------------------------------------------------------------------------- /Artwork/DropDownHover.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Artwork/DropDownHover.psd -------------------------------------------------------------------------------- /Artwork/DropDownNormal.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Artwork/DropDownNormal.psd -------------------------------------------------------------------------------- /Artwork/DropDownOnHover.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Artwork/DropDownOnHover.psd -------------------------------------------------------------------------------- /Artwork/DropDownOnNormal.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Artwork/DropDownOnNormal.psd -------------------------------------------------------------------------------- /Artwork/OverlayBackground.psd: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Artwork/OverlayBackground.psd -------------------------------------------------------------------------------- /Documents/KSP-AVC/CHANGES.txt: -------------------------------------------------------------------------------- 1 | 1.1.6.2 2 | Build on KSP 1.2.0.1586 3 | Fixed: URLs are escaped before being processed. 4 | Fixed: UI is destroyed upon entering the Space Centre. This mitigates issues that may cause the progress window to remain visible indefinitely. 5 | 6 | 1.1.6.1 7 | Build on KSP 1.1.0.1230 8 | 9 | 1.1.6.0 10 | Built on KSP Experimental 1.1.0.1171 11 | Added: 10-second timeout on invalid URLs. 12 | Added: DevHelper GUI avoidence. 13 | 14 | 1.1.5.0 15 | Added: Remote version files take priority when local/remote add-on versions are the same. 16 | Added: 'Any' type versions are now fully supported. 17 | Added: Wildcards for version fields with '-1'. 18 | Added: New informational toolbar to the top left of the screen, replacing the drop down button. 19 | Added: Toolbar display's the number of installed add-ons that are KSP-AVC ready. 20 | Added: Toolbar has a dynamic list that will allow scrolling when taller than half the game screen height. 21 | Added: Toolbar has a 'Copy to Clipboard' button that will copy the list and environment information (KSP/Unity/OS) to the clipboard. 22 | 23 | 1.1.4.3 24 | Updated for KSP v0.25.0 25 | Fixed: Typo in AddonInfo.ToString() 26 | Fixed: Bug with empty version files which would cause the top drop down to not work. 27 | 28 | 1.1.4.2 29 | Changed: Done a lot of under the hood refactoring. 30 | Fixed: Bug that would freeze the computer when checking many add-ons. 31 | Fixed: Bug that caused the compatibility display to show as a long thin window. 32 | 33 | 1.1.4.1 34 | Fixed: Log spam. 35 | Fixed: Checking window staying open after displaying the first run / updated window. 36 | 37 | 1.1.4.0 38 | Added: Drop down action menu support allowing for multiple actions per add-on. 39 | Added: Change log support, allowing the player to view the add-on's change log. 40 | Added: Drop down list showing all KSP-AVC ready add-ons on loading and main menu. 41 | Changed: Versions will always have the minimum formatting of 'x.x'. 42 | Fixed: Issue with non-RAW GitHub version file hosting, extending the url formatter. 43 | Fixed: Bug where it would do a re-check when reloading the database. 44 | 45 | 1.1.3.1 46 | Fixed: Game breaking bug. 47 | 48 | 1.1.3.0 49 | Added: GitHub latest release checking. 50 | Added: Version file reading is now case insensitive. 51 | Fixed: Bug in version equality checking. (Now using a custom VersionInfo object). 52 | 53 | 1.1.2.0 54 | Added: Tooltip when hovering over the download button showing the destination URL. 55 | Fixed: Certain situations would cause the root directory to be incorrect. 56 | Fixed: File not found handling solving the lock whilst on the checking display. 57 | 58 | 1.1.1.0 59 | Added: Blanket exception handling and logging. 60 | Added: Logger will flush on destruction and GC finaliser. 61 | Added: Check to remove '/tree/' from github urls. 62 | Changed: Remote checking back to WWW because WebRequest in Mono does not support TLS/SSL. 63 | Changed: Version file search is now limited to just the GameData directory. 64 | Fixed: Possible null refs caused by invalid remote urls. 65 | 66 | 1.1.0.0 67 | Complete re-write of the core code. 68 | Added: Replaced LitJson with embeded MiniJson for compatibility and to reduce dependancies. 69 | Added: Better utilisation of multi-threading. 70 | Added: Check progress window which will show whilst processing. 71 | Changed: Remote version file fetching now uses WebRequest instead of Unity's archaic WWW. 72 | Fixed: Version formatting bug where it did not recognise build numbers in certain cases. 73 | 74 | 1.0.4.0 75 | Added: Url check to fix problems caused by non-raw github .version files. 76 | Added: Logging system now also saves into the standard ksp log file. 77 | Changed: Extended logging system now saves with the associated '.dll' file. 78 | 79 | 1.0.3.0 80 | Updated for KSP version 0.24.2. 81 | Added: Extended logging system that saves to "KSP-AVC.log". 82 | Added: First run checker which will show to indicate a successful install. 83 | Changed: Window is now centred on the screen. 84 | 85 | 1.0.2.0 86 | Updated for KSP version 0.24. 87 | Fixed a small bug with parsing KSP versions. 88 | 89 | 1.0.1.0 90 | Added minimum and maximum KSP version support. 91 | Updates will only be shown if the remote version is compatible with the installed version of KSP. -------------------------------------------------------------------------------- /Documents/KSP-AVC/README.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | KSP-AVC Plugin - README 6 | 7 | 112 | 113 | 114 |
115 |
KSP Add-on Version Checker
116 | 117 |
118 |

Developer

119 |

CYBUTEK

120 |
121 | 122 |
123 |

KSP-AVC Ready

124 |

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

128 |
129 | 130 |
131 |

Description

132 |

133 | 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. 134 |

135 |
136 | 137 |
138 |

Installation

139 |
    140 |
  • Copy the 'KSP-AVC' folder into the 'GameData' folder located within your Kerbal Space Program installation directory.
  • 141 |
142 |
143 | 144 |
145 |

Version File Breakdown

146 |

147 |

    148 |
  • NAME - Required
    149 | The display name for the add-on.
    150 |
  • 151 |
  • URL - Optional
    152 | Location of a remote version file for update checking. 153 |
  • 154 |
  • DOWNLOAD - Optional
    155 | Web address where the latest version can be downloaded.
    156 | This is only used from the remote version file. 157 |
  • 158 |
  • CHANGE_LOG - Optional
    159 | The complete or incremental change log for the add-on.
    160 | This is only used from the remote version file. 161 |
  • 162 |
  • CHANGE_LOG_URL - Optional
    163 | Populates the CHANGE_LOG field using the file at this url.
    164 | This is only used from the remote version file. 165 |
  • 166 |
  • GITHUB - Optional
    167 | Allows KSP-AVC to do release checks with GitHub including setting a download location if one is not specified.
    168 | If the latest release version is not equal to the version in the file, an update notification will not appear.
    169 | This is only used from the remote version file. 170 |
      171 |
    • USERNAME - Required
      172 | Your GitHub username. 173 |
    • 174 |
    • REPOSITORY - Required
      175 | The name of the source repository. 176 |
    • 177 |
    • ALLOW_PRE_RELEASE - Optional
      178 | Include pre-releases in the latest release search.
      179 | The default value is false. 180 |
    • 181 |
    182 |
  • 183 |
  • VERSION - Required
    184 | The version of the add-on. 185 |
  • 186 |
  • KSP_VERSION - Optional, Required for MIN/MAX
    187 | Version of KSP that the add-on was made to support. 188 |
  • 189 |
  • KSP_VERSION_MIN - Optional
    190 | Minimum version of KSP that the add-on supports.
    191 | Requires KSP_VERSION field to work. 192 |
  • 193 |
  • KSP_VERSION_MAX - Optional
    194 | Maximum version of KSP that the add-on supports.
    195 | Requires KSP_VERSION field to work. 196 |
  • 197 |
198 |
199 | For simple management of your version files you can use the KSP-AVC Online website at: ksp-avc.cybutek.net. 200 |

201 |
202 | 203 |
204 |

Version File Example

205 |

206 | {
207 |     "NAME":"KSP-AVC",
208 |     "URL":"http://ksp-avc.cybutek.net/version.php?id=2",
209 |     "DOWNLOAD":"http://kerbal.curseforge.com/ksp-mods/220462-ksp-avc-add-on-version-checker",
210 |     "GITHUB":
211 |     {
212 |         "USERNAME":"YourGitHubUserName",
213 |         "REPOSITORY":"YourGitHubRepository",
214 |         "ALLOW_PRE_RELEASE":false,
215 |     },
216 |     "VERSION":
217 |     {
218 |         "MAJOR":1,
219 |         "MINOR":1,
220 |         "PATCH":0,
221 |         "BUILD":0
222 |     },
223 |     "KSP_VERSION":
224 |     {
225 |         "MAJOR":0,
226 |         "MINOR":24,
227 |         "PATCH":2
228 |     },
229 |     "KSP_VERSION_MIN":
230 |     {
231 |         "MAJOR":0,
232 |         "MINOR":24,
233 |         "PATCH":0
234 |     },
235 |     "KSP_VERSION_MAX":
236 |     {
237 |         "MAJOR":0,
238 |         "MINOR":24,
239 |         "PATCH":2
240 |     }
241 | } 242 |

243 |
244 | 245 |
246 |

Change Log

247 | 248 |
249 | 250 |
251 |

Software License

252 |

253 | Licensed under the GNU General Public License v3. 254 |

255 |
256 | 257 | 258 |
259 | 260 |
261 | README design by CYBUTEK (GPLv3) 262 |
263 | 264 | -------------------------------------------------------------------------------- /Documents/MiniAVC/CHANGES.txt: -------------------------------------------------------------------------------- 1 | 1.0.3.3 2 | Build on KSP 1.2.0.1586 3 | Fixed: URLs are escaped before being processed. 4 | 5 | 1.0.3.2 6 | Built on KSP 1.1.0.1230 7 | 8 | 1.0.3.1 9 | Built on KSP Experimental 1.1.0.1171 10 | 11 | 1.0.3.0 12 | Added: Remote version files take priority when local/remote add-on versions are the same. 13 | Added: 'Any' type versions are now fully supported. 14 | Added: Wildcards for version fields with '-1'. 15 | 16 | 1.0.2.4 17 | Updated for KSP v0.25.0 18 | Fixed: Typo in AddonInfo.ToString() 19 | Fixed: Bug with empty version files. 20 | 21 | 1.0.2.3 22 | Changed: Done a lot of under the hood refactoring. 23 | Fixed: Bug that would freeze the computer when checking many add-ons. 24 | 25 | 1.0.2.2 26 | Changed: Versions will always have the minimum formatting of 'x.x'. 27 | Fixed: Issue with non-RAW GitHub version file hosting, extending the url formatter. 28 | 29 | 1.0.2.1 30 | Added: Some extra exception handling and cleaned up some of the code. 31 | 32 | 1.0.2.0 33 | Added: GitHub latest release checking. 34 | Added: Version file reading is now case insensitive. 35 | Fixed: Bug in version equality checking. (Now using a custom VersionInfo object). 36 | 37 | 1.0.1.1 38 | Fixed: Bug where it did not do the allow check. 39 | 40 | 1.0.1.0 41 | Added: Tooltip when hovering over the download button showing the destination URL. 42 | Added: File not found handling. 43 | 44 | 1.0.0.0 45 | Initial release of MiniAVC based on the core KSP-AVC Plugin v1.1.1 system. -------------------------------------------------------------------------------- /Documents/MiniAVC/README.htm: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | MiniAVC - README 6 | 7 | 112 | 113 | 114 |
115 |
MiniAVC Add-on Version Checker
116 | 117 |
118 |

Developer

119 |

CYBUTEK

120 |
121 | 122 |
123 |

KSP-AVC Ready

124 |

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

128 |
129 | 130 |
131 |

Description

132 |

133 | This plugin checks inside its current directory and all contained directories for version files. It's use is for mods to make use of the KSP-AVC system without requiring the player to have the full KSP-AVC Plugin installed. The MiniAVC.dll plugin is safe to be bundled with mods and will negotiate between all other instances of MiniAVC to run the latest version. If an installation of KSP-AVC Plugin is found, the MiniAVC system will be disabled to let KSP-AVC take over. MiniAVC can check for both updates and game version compatibility, the same way as KSP-AVC Plugin does. The biggest difference is that because MiniAVC is a bundleable plugin, it will ask the player on the first run whether to allow update checking. If the user does not wish your add-on to check for updates, the remote checking functionality will be disabled. This will not completely turn off MiniAVC as it can still run in local mode to notify the player of any game version compatibility issues. 134 |

135 |
136 | 137 |
138 |

Installation

139 |
    140 |
  • Bundle the MiniAVC.dll file into your packaged add-on directory along with your version file.
  • 141 |
  • If your add-on contains multiple version files, place it at the lowest directory level which will cover all the version files, but do not place it in GameData.
  • 142 |
143 |
144 | 145 |
146 |

Community Add-on Rule 5.5

147 |

148 | The rule states that, "Add-ons that contact another network or computer system must tell users exactly what it's sending or receiving in a clear and obvious way in all locations it is offered for download." This means that if you bundle MiniAVC with your add-on, you must clearly notify players before downloading that it contains MiniAVC and how it works. 149 | 150 |

BB Code
151 | This mod includes version checking using [URL=http://forum.kerbalspaceprogram.com/threads/79745]MiniAVC[/URL]. If you opt-in, it will use the internet to check whether there is a new version available. Data is only read from the internet and no personal information is sent. For a more comprehensive version checking experience, please download the [URL=http://forum.kerbalspaceprogram.com/threads/79745]KSP-AVC Plugin[/URL]. 152 |
153 |
HTML
154 | This mod includes version checking using <a href="http://forum.kerbalspaceprogram.com/threads/79745">MiniAVC</a>. If you opt-in, it will use the internet to check whether there is a new version available. Data is only read from the internet and no personal information is sent. For a more comprehensive version checking experience, please download the <a href="http://forum.kerbalspaceprogram.com/threads/79745">KSP-AVC Plugin</a>. 155 |
156 |

157 |
158 | 159 |
160 |

Version File Breakdown

161 |

162 |

    163 |
  • NAME - Required
    164 | The display name for the add-on.
    165 |
  • 166 |
  • URL - Optional
    167 | Location of a remote version file for update checking. 168 |
  • 169 |
  • DOWNLOAD - Optional
    170 | Web address where the latest version can be downloaded.
    171 | This is only used from the remote version file. 172 |
  • 173 |
  • CHANGE_LOG - Optional
    174 | The complete or incremental change log for the add-on.
    175 | This is only used from the remote version file. 176 |
  • 177 |
  • CHANGE_LOG_URL - Optional
    178 | Populates the CHANGE_LOG field using the file at this url.
    179 | This is only used from the remote version file. 180 |
  • 181 |
  • GITHUB - Optional
    182 | Allows KSP-AVC to do release checks with GitHub including setting a download location if one is not specified.
    183 | If the latest release version is not equal to the version in the file, an update notification will not appear.
    184 | This is only used from the remote version file. 185 |
      186 |
    • USERNAME - Required
      187 | Your GitHub username. 188 |
    • 189 |
    • REPOSITORY - Required
      190 | The name of the source repository. 191 |
    • 192 |
    • ALLOW_PRE_RELEASE - Optional
      193 | Include pre-releases in the latest release search.
      194 | The default value is false. 195 |
    • 196 |
    197 |
  • 198 |
  • VERSION - Required
    199 | The version of the add-on. 200 |
  • 201 |
  • KSP_VERSION - Optional, Required for MIN/MAX
    202 | Version of KSP that the add-on was made to support. 203 |
  • 204 |
  • KSP_VERSION_MIN - Optional
    205 | Minimum version of KSP that the add-on supports.
    206 | Requires KSP_VERSION field to work. 207 |
  • 208 |
  • KSP_VERSION_MAX - Optional
    209 | Maximum version of KSP that the add-on supports.
    210 | Requires KSP_VERSION field to work. 211 |
  • 212 |
213 |
214 | For simple management of your version files you can use the KSP-AVC Online website at: ksp-avc.cybutek.net. 215 |

216 |
217 | 218 |
219 |

Version File Example

220 |

221 | {
222 |     "NAME":"KSP-AVC",
223 |     "URL":"http://ksp-avc.cybutek.net/version.php?id=2",
224 |     "DOWNLOAD":"http://kerbal.curseforge.com/ksp-mods/220462-ksp-avc-add-on-version-checker",
225 |     "GITHUB":
226 |     {
227 |         "USERNAME":"YourGitHubUserName",
228 |         "REPOSITORY":"YourGitHubRepository",
229 |         "ALLOW_PRE_RELEASE":false,
230 |     },
231 |     "VERSION":
232 |     {
233 |         "MAJOR":1,
234 |         "MINOR":1,
235 |         "PATCH":0,
236 |         "BUILD":0
237 |     },
238 |     "KSP_VERSION":
239 |     {
240 |         "MAJOR":0,
241 |         "MINOR":24,
242 |         "PATCH":2
243 |     },
244 |     "KSP_VERSION_MIN":
245 |     {
246 |         "MAJOR":0,
247 |         "MINOR":24,
248 |         "PATCH":0
249 |     },
250 |     "KSP_VERSION_MAX":
251 |     {
252 |         "MAJOR":0,
253 |         "MINOR":24,
254 |         "PATCH":2
255 |     }
256 | } 257 |

258 |
259 | 260 |
261 |

Change Log

262 | 263 |
264 | 265 |
266 |

Software License

267 |

268 | Licensed under the GNU General Public License v3. 269 |

270 |
271 | 272 | 273 |
274 | 275 |
276 | README design by CYBUTEK (GPLv3) 277 |
278 | 279 | -------------------------------------------------------------------------------- /Documents/MiniAVC/README.md: -------------------------------------------------------------------------------- 1 | # MiniAVC Add-on Version Checker 2 | 3 | ## Developer 4 | 5 | Cybutek 6 | 7 | 8 | ## KSP-AVC Ready 9 | 10 | KSP Add-on Version Checker is a standardised system for versioning mods. You can get more information on the 11 | [forum thread](http://forum.kerbalspaceprogram.com/threads/79745) 12 | 13 | 14 | ## Description 15 | 16 | This plugin checks inside its current directory and all contained directories for version files. It's use is for mods to make use of the KSP-AVC system without requiring the player to have the full KSP-AVC Plugin installed. The MiniAVC.dll plugin is safe to be bundled with mods and will negotiate between all other instances of MiniAVC to run the latest version. If an installation of KSP-AVC Plugin is found, the MiniAVC system will be disabled to let KSP-AVC take over. MiniAVC can check for both updates and game version compatibility, the same way as KSP-AVC Plugin does. The biggest difference is that because MiniAVC is a bundleable plugin, it will ask the player on the first run whether to allow update checking. If the user does not wish your add-on to check for updates, the remote checking functionality will be disabled. This will not completely turn off MiniAVC as it can still run in local mode to notify the player of any game version compatibility issues. 17 | 18 | 19 | ## Installation 20 | 21 | - Bundle the MiniAVC.dll file into your packaged add-on directory along with your version file. 22 | - If your add-on contains multiple version files, place it at the lowest directory level which will cover all the version files, but do not place it in GameData. 23 | 24 | 25 | ## Community Add-on Rule 5.5 26 | 27 | The rule states that, "Add-ons that contact another network or computer system must tell users exactly what it's sending or receiving in a clear and obvious way in all locations it is offered for download." This means that if you bundle MiniAVC with your add-on, you must clearly notify players before downloading that it contains MiniAVC and how it works. 28 | 29 | ### BB Code 30 | ``` 31 | This mod includes version checking using [URL=http://forum.kerbalspaceprogram.com/threads/79745]MiniAVC[/URL]. If you opt-in, it will use the internet to check whether there is a new version available. Data is only read from the internet and no personal information is sent. For a more comprehensive version checking experience, please download the [URL=http://forum.kerbalspaceprogram.com/threads/79745]KSP-AVC Plugin[/URL]. 32 | ``` 33 | ### HTML 34 | ```html 35 | This mod includes version checking using MiniAVC. If you opt-in, it will use the internet to check whether there is a new version available. Data is only read from the internet and no personal information is sent. For a more comprehensive version checking experience, please download the KSP-AVC Plugin. 36 | ``` 37 | 38 | ## Version File Breakdown 39 | 40 | - **NAME** - Required 41 | 42 | The display name for the add-on. 43 | 44 | - **URL** - Optional 45 | 46 | Location of a remote version file for update checking. 47 | 48 | - **DOWNLOAD** - Optional 49 | 50 | Web address where the latest version can be downloaded. 51 | *This is only used from the remote version file.* 52 | 53 | - **CHANGE_LOG** - Optional 54 | 55 | The complete or incremental change log for the add-on. 56 | This is only used from the remote version file. 57 | 58 | - **CHANGE_LOG_URL** - Optional 59 | 60 | Populates the CHANGE_LOG field using the file at this url. 61 | *This is only used from the remote version file.* 62 | 63 | - **GITHUB** - Optional 64 | 65 | Allows KSP-AVC to do release checks with GitHub including setting a download location if one is not specified. 66 | If the latest release version is not equal to the version in the file, an update notification will not appear. 67 | *This is only used from the remote version file.* 68 | 69 | - **USERNAME** - Required 70 | 71 | Your GitHub username. 72 | 73 | - **REPOSITORY** - Required 74 | 75 | The name of the source repository. 76 | 77 | - **ALLOW_PRE_RELEASE** - Optional 78 | 79 | Include pre-releases in the latest release search. 80 | 81 | *The default value is false.* 82 | 83 | - **VERSION** - Required 84 | 85 | The version of the add-on. 86 | - **KSP_VERSION** - Optional, Required for MIN/MAX 87 | 88 | Version of KSP that the add-on was made to support. 89 | - **KSP_VERSION_MIN** - Optional 90 | 91 | Minimum version of KSP that the add-on supports. 92 | 93 | *Requires KSP_VERSION field to work.* 94 | 95 | - **KSP_VERSION_MAX** - Optional 96 | 97 | Maximum version of KSP that the add-on supports. 98 | *Requires KSP_VERSION field to work.* 99 | 100 | For simple management of your version files you can use the KSP-AVC Online website at: [ksp-avc.cybutek.net](http://ksp-avc.cybutek.net/) 101 | 102 | ## Version File Example 103 | 104 | ```json 105 | { 106 | "NAME":"KSP-AVC", 107 | "URL":"http://ksp-avc.cybutek.net/version.php?id=2", 108 | "DOWNLOAD":"http://kerbal.curseforge.com/ksp-mods/220462-ksp-avc-add-on-version-checker", 109 | "GITHUB": 110 | { 111 | "USERNAME":"YourGitHubUserName", 112 | "REPOSITORY":"YourGitHubRepository", 113 | "ALLOW_PRE_RELEASE":false, 114 | }, 115 | "VERSION": 116 | { 117 | "MAJOR":1, 118 | "MINOR":1, 119 | "PATCH":0, 120 | "BUILD":0 121 | }, 122 | "KSP_VERSION": 123 | { 124 | "MAJOR":0, 125 | "MINOR":24, 126 | "PATCH":2 127 | }, 128 | "KSP_VERSION_MIN": 129 | { 130 | "MAJOR":0, 131 | "MINOR":24, 132 | "PATCH":0 133 | }, 134 | "KSP_VERSION_MAX": 135 | { 136 | "MAJOR":0, 137 | "MINOR":24, 138 | "PATCH":2 139 | } 140 | } 141 | ``` 142 | 143 | ## Changelog 144 | 145 | See [CHANGES.txt](CHANGES.txt) 146 | 147 | ## Software License 148 | 149 | Licensed under the [GNU General Public License v3](LICENSE.txt). 150 | -------------------------------------------------------------------------------- /KSP-AVC.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 12.00 3 | # Visual Studio 15 4 | VisualStudioVersion = 15.0.27428.2015 5 | MinimumVisualStudioVersion = 10.0.40219.1 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "KSP-AVC", "KSP-AVC\KSP-AVC.csproj", "{F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "MiniAVC", "MiniAVC\MiniAVC.csproj", "{F1351BAB-76F1-41DE-B01C-496163CB44D8}" 9 | EndProject 10 | Global 11 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 12 | Debug|Any CPU = Debug|Any CPU 13 | Release|Any CPU = Release|Any CPU 14 | EndGlobalSection 15 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 16 | {F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 17 | {F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C}.Debug|Any CPU.Build.0 = Debug|Any CPU 18 | {F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C}.Release|Any CPU.ActiveCfg = Release|Any CPU 19 | {F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C}.Release|Any CPU.Build.0 = Release|Any CPU 20 | {F1351BAB-76F1-41DE-B01C-496163CB44D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 21 | {F1351BAB-76F1-41DE-B01C-496163CB44D8}.Debug|Any CPU.Build.0 = Debug|Any CPU 22 | {F1351BAB-76F1-41DE-B01C-496163CB44D8}.Release|Any CPU.ActiveCfg = Release|Any CPU 23 | {F1351BAB-76F1-41DE-B01C-496163CB44D8}.Release|Any CPU.Build.0 = Release|Any CPU 24 | EndGlobalSection 25 | GlobalSection(SolutionProperties) = preSolution 26 | HideSolutionNode = FALSE 27 | EndGlobalSection 28 | GlobalSection(ExtensibilityGlobals) = postSolution 29 | SolutionGuid = {2E4A6C1E-3FD6-448A-9441-8A631D0B15AA} 30 | EndGlobalSection 31 | EndGlobal 32 | -------------------------------------------------------------------------------- /KSP-AVC.sln.DotSettings: -------------------------------------------------------------------------------- 1 |  2 | GUI -------------------------------------------------------------------------------- /KSP-AVC/Addon.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.IO; 22 | using System.Threading; 23 | 24 | using UnityEngine; 25 | 26 | #endregion 27 | 28 | namespace KSP_AVC 29 | { 30 | public class Addon 31 | { 32 | #region Constructors 33 | 34 | public Addon(string path) 35 | { 36 | this.RunProcessLocalInfo(path); 37 | } 38 | 39 | #endregion 40 | 41 | #region Properties 42 | 43 | public bool HasError { get; private set; } 44 | 45 | public bool IsCompatible 46 | { 47 | get { return this.IsLocalReady && this.LocalInfo.IsCompatible; } 48 | } 49 | 50 | public bool IsLocalReady { get; private set; } 51 | 52 | public bool IsProcessingComplete { get; private set; } 53 | 54 | public bool IsRemoteReady { get; private set; } 55 | 56 | public bool IsUpdateAvailable 57 | { 58 | get { return this.IsProcessingComplete && this.LocalInfo.Version != null && this.RemoteInfo.Version != null && this.RemoteInfo.Version > this.LocalInfo.Version && this.RemoteInfo.IsCompatibleKspVersion && this.RemoteInfo.IsCompatibleGitHubVersion; } 59 | } 60 | 61 | public AddonInfo LocalInfo { get; private set; } 62 | 63 | public string Name 64 | { 65 | get { return this.LocalInfo.Name; } 66 | } 67 | 68 | public AddonInfo RemoteInfo { get; private set; } 69 | 70 | #endregion 71 | 72 | #region Methods: public 73 | 74 | public void RunProcessLocalInfo(string path) 75 | { 76 | ThreadPool.QueueUserWorkItem(this.ProcessLocalInfo, path); 77 | } 78 | 79 | public void RunProcessRemoteInfo() 80 | { 81 | ThreadPool.QueueUserWorkItem(this.ProcessRemoteInfo); 82 | } 83 | 84 | #endregion 85 | 86 | #region Methods: private 87 | 88 | private void FetchLocalInfo(string path) 89 | { 90 | using (var stream = new StreamReader(File.OpenRead(path))) 91 | { 92 | this.LocalInfo = new AddonInfo(path, stream.ReadToEnd(), AddonInfo.RemoteType.AVC); 93 | this.IsLocalReady = true; 94 | 95 | if (this.LocalInfo.ParseError) 96 | { 97 | this.SetHasError(); 98 | } 99 | } 100 | } 101 | 102 | private void FetchRemoteInfo() 103 | { 104 | const float timeoutSeconds = 10.0f; 105 | float startTime = Time.time; 106 | float currentTime = startTime; 107 | 108 | if (string.IsNullOrEmpty(this.LocalInfo.Url) == false) 109 | { 110 | using (var www = new WWW(Uri.EscapeUriString(this.LocalInfo.Url))) 111 | { 112 | while ((!www.isDone) && ((currentTime - startTime) < timeoutSeconds)) 113 | { 114 | Thread.Sleep(100); 115 | currentTime = Time.time; 116 | } 117 | if ((www.error == null) && ((currentTime - startTime) < timeoutSeconds)) 118 | { 119 | this.SetRemoteAvcInfo(www); 120 | } 121 | else 122 | { 123 | this.SetLocalInfoOnly(); 124 | } 125 | } 126 | } 127 | else 128 | { 129 | this.SetLocalInfoOnly(); 130 | } 131 | } 132 | 133 | private void ProcessLocalInfo(object state) 134 | { 135 | try 136 | { 137 | var path = (string)state; 138 | if (File.Exists(path)) 139 | { 140 | this.FetchLocalInfo(path); 141 | this.RunProcessRemoteInfo(); 142 | } 143 | else 144 | { 145 | Logger.Log("File Not Found: " + path); 146 | this.SetHasError(); 147 | } 148 | } 149 | catch (Exception ex) 150 | { 151 | Logger.Exception(ex); 152 | this.SetHasError(); 153 | } 154 | } 155 | 156 | private void ProcessRemoteInfo(object state) 157 | { 158 | try 159 | { 160 | if (String.IsNullOrEmpty(this.LocalInfo.Url) && String.IsNullOrEmpty(this.LocalInfo.KerbalStuffUrl)) 161 | { 162 | this.SetLocalInfoOnly(); 163 | return; 164 | } 165 | 166 | this.FetchRemoteInfo(); 167 | } 168 | catch (Exception ex) 169 | { 170 | Logger.Exception(ex); 171 | this.SetLocalInfoOnly(); 172 | } 173 | } 174 | 175 | private void SetHasError() 176 | { 177 | this.HasError = true; 178 | this.IsProcessingComplete = true; 179 | } 180 | 181 | private void SetLocalInfoOnly() 182 | { 183 | this.RemoteInfo = this.LocalInfo; 184 | this.IsRemoteReady = true; 185 | this.IsProcessingComplete = true; 186 | Logger.Log(this.LocalInfo); 187 | Logger.Blank(); 188 | } 189 | 190 | private void SetRemoteAvcInfo(WWW www) 191 | { 192 | this.RemoteInfo = new AddonInfo(this.LocalInfo.Url, www.text, AddonInfo.RemoteType.AVC); 193 | this.RemoteInfo.FetchRemoteData(); 194 | 195 | if (this.LocalInfo.Version == this.RemoteInfo.Version) 196 | { 197 | Logger.Log("Identical remote version found: Using remote version information only."); 198 | Logger.Log(this.RemoteInfo); 199 | Logger.Blank(); 200 | this.LocalInfo = this.RemoteInfo; 201 | } 202 | else 203 | { 204 | Logger.Log(this.LocalInfo); 205 | Logger.Log(this.RemoteInfo + "\n\tUpdateAvailable: " + this.IsUpdateAvailable); 206 | Logger.Blank(); 207 | } 208 | 209 | this.IsRemoteReady = true; 210 | this.IsProcessingComplete = true; 211 | } 212 | 213 | private void SetRemoteKerbalStuffInfo(WWW www) 214 | { 215 | this.RemoteInfo = new AddonInfo(this.LocalInfo.KerbalStuffUrl, www.text, AddonInfo.RemoteType.KerbalStuff); 216 | 217 | if (this.LocalInfo.Version == this.RemoteInfo.Version) 218 | { 219 | Logger.Log("Identical remote version found: Using remote version information only."); 220 | Logger.Log(this.RemoteInfo); 221 | Logger.Blank(); 222 | this.LocalInfo = this.RemoteInfo; 223 | } 224 | else 225 | { 226 | Logger.Log(this.LocalInfo); 227 | Logger.Log(this.RemoteInfo + "\n\tUpdateAvailable: " + this.IsUpdateAvailable); 228 | Logger.Blank(); 229 | } 230 | 231 | this.IsRemoteReady = true; 232 | this.IsProcessingComplete = true; 233 | } 234 | 235 | #endregion 236 | } 237 | } -------------------------------------------------------------------------------- /KSP-AVC/AddonLibrary.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.IO; 23 | using System.Linq; 24 | using System.Reflection; 25 | using System.Threading; 26 | 27 | #endregion 28 | 29 | namespace KSP_AVC 30 | { 31 | public static class AddonLibrary 32 | { 33 | #region Fields 34 | 35 | private static readonly string rootPath; 36 | private static List addons; 37 | 38 | #endregion 39 | 40 | #region Constructors 41 | 42 | static AddonLibrary() 43 | { 44 | rootPath = GetRootPath(); 45 | Logger.Log("Checking Root: " + rootPath); 46 | ThreadPool.QueueUserWorkItem(ProcessAddonPopulation); 47 | } 48 | 49 | #endregion 50 | 51 | #region Properties 52 | 53 | public static IEnumerable Addons 54 | { 55 | get { return (addons != null) ? addons.Where(a => !a.HasError).ToList() : null; } 56 | } 57 | 58 | public static bool Populated { get; private set; } 59 | 60 | public static int ProcessCount 61 | { 62 | get { return (addons != null) ? addons.Count(a => a.IsProcessingComplete) : 0; } 63 | } 64 | 65 | public static IEnumerable Processed 66 | { 67 | get { return (addons != null) ? addons.Where(a => !a.HasError && a.IsProcessingComplete) : null; } 68 | } 69 | 70 | public static bool ProcessingComplete 71 | { 72 | get { return addons != null && addons.All(a => a.IsProcessingComplete); } 73 | } 74 | 75 | public static int TotalCount 76 | { 77 | get { return (addons != null) ? addons.Count : 0; } 78 | } 79 | 80 | #endregion 81 | 82 | #region Methods: private 83 | 84 | private static string GetRootPath() 85 | { 86 | var rootPath = Assembly.GetExecutingAssembly().Location; 87 | var gameDataIndex = rootPath.IndexOf("GameData", StringComparison.CurrentCultureIgnoreCase); 88 | return Path.Combine(rootPath.Remove(gameDataIndex, rootPath.Length - gameDataIndex), "GameData"); 89 | } 90 | 91 | private static void ProcessAddonPopulation(object state) 92 | { 93 | try 94 | { 95 | Populated = false; 96 | addons = Directory.GetFiles(rootPath, "*.version", SearchOption.AllDirectories).Select(path => new Addon(path)).ToList(); 97 | Populated = true; 98 | } 99 | catch (Exception ex) 100 | { 101 | Logger.Exception(ex); 102 | } 103 | } 104 | 105 | #endregion 106 | } 107 | } -------------------------------------------------------------------------------- /KSP-AVC/ChangeLogGui.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | 22 | using UnityEngine; 23 | 24 | #endregion 25 | 26 | namespace KSP_AVC 27 | { 28 | public class ChangeLogGui : MonoBehaviour 29 | { 30 | #region Fields 31 | 32 | private GUIStyle closeStyle; 33 | private GUIStyle labelStyle; 34 | private Rect position = new Rect(0, 0, Screen.width, Screen.height); 35 | private Vector2 scrollPosition; 36 | 37 | #endregion 38 | 39 | #region Properties 40 | 41 | public string Name { get; set; } 42 | 43 | public string Text { get; set; } 44 | 45 | #endregion 46 | 47 | #region Methods: protected 48 | 49 | protected void Awake() 50 | { 51 | try 52 | { 53 | DontDestroyOnLoad(this); 54 | } 55 | catch (Exception ex) 56 | { 57 | Logger.Exception(ex); 58 | } 59 | Logger.Log("ChangeLogGui was created."); 60 | } 61 | 62 | protected void OnDestroy() 63 | { 64 | Logger.Log("ChangeLogGui was destroyed."); 65 | } 66 | 67 | protected void OnGUI() 68 | { 69 | try 70 | { 71 | GUI.skin = null; 72 | this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, this.Name + " - Change Log", HighLogic.Skin.window); 73 | } 74 | catch (Exception ex) 75 | { 76 | Logger.Exception(ex); 77 | } 78 | } 79 | 80 | protected void Start() 81 | { 82 | try 83 | { 84 | this.InitialiseStyles(); 85 | } 86 | catch (Exception ex) 87 | { 88 | Logger.Exception(ex); 89 | } 90 | } 91 | 92 | #endregion 93 | 94 | #region Methods: private 95 | 96 | private void InitialiseStyles() 97 | { 98 | this.closeStyle = new GUIStyle(HighLogic.Skin.button) 99 | { 100 | normal = 101 | { 102 | textColor = Color.white 103 | }, 104 | }; 105 | 106 | this.labelStyle = new GUIStyle(HighLogic.Skin.label) 107 | { 108 | normal = 109 | { 110 | textColor = Color.white 111 | }, 112 | fontStyle = FontStyle.Bold, 113 | stretchWidth = true, 114 | stretchHeight = true, 115 | wordWrap = true 116 | }; 117 | } 118 | 119 | private void Window(int id) 120 | { 121 | try 122 | { 123 | GUI.skin = HighLogic.Skin; 124 | this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, false, true); 125 | GUI.skin = null; 126 | GUILayout.Label(this.Text, this.labelStyle); 127 | GUILayout.EndScrollView(); 128 | 129 | if (GUILayout.Button("CLOSE", this.closeStyle)) 130 | { 131 | Destroy(this); 132 | } 133 | } 134 | catch (Exception ex) 135 | { 136 | Logger.Exception(ex); 137 | } 138 | } 139 | 140 | #endregion 141 | } 142 | } -------------------------------------------------------------------------------- /KSP-AVC/CheckerProgressGui.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Linq; 22 | 23 | using UnityEngine; 24 | 25 | #endregion 26 | 27 | namespace KSP_AVC 28 | { 29 | public class CheckerProgressGui : MonoBehaviour 30 | { 31 | #region Fields 32 | 33 | private bool hasCentred; 34 | private string message = String.Empty; 35 | private Rect position = new Rect(Screen.width, Screen.height, 0, 0); 36 | 37 | private GUIStyle titleStyle; 38 | 39 | #endregion 40 | 41 | #region Methods: protected 42 | 43 | protected void Awake() 44 | { 45 | try 46 | { 47 | DontDestroyOnLoad(this); 48 | } 49 | catch (Exception ex) 50 | { 51 | Logger.Exception(ex); 52 | } 53 | Logger.Log("CheckerProgressGui was created."); 54 | } 55 | 56 | protected void OnDestroy() 57 | { 58 | Logger.Log("CheckerProgressGui was destroyed."); 59 | } 60 | 61 | protected void OnGUI() 62 | { 63 | try 64 | { 65 | this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KSP Add-on Version Checker", HighLogic.Skin.window); 66 | this.CentreWindow(); 67 | } 68 | catch (Exception ex) 69 | { 70 | Logger.Exception(ex); 71 | } 72 | } 73 | 74 | protected void Start() 75 | { 76 | try 77 | { 78 | this.InitialiseStyles(); 79 | } 80 | catch (Exception ex) 81 | { 82 | Logger.Exception(ex); 83 | } 84 | } 85 | 86 | protected void Update() 87 | { 88 | try 89 | { 90 | this.message = AddonLibrary.Populated 91 | ? "Checked " + AddonLibrary.ProcessCount + " of " + AddonLibrary.TotalCount + " add-ons." 92 | : "Populating Library..."; 93 | } 94 | catch (Exception ex) 95 | { 96 | Logger.Exception(ex); 97 | } 98 | } 99 | 100 | #endregion 101 | 102 | #region Methods: private 103 | 104 | private void CentreWindow() 105 | { 106 | if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) 107 | { 108 | return; 109 | } 110 | this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); 111 | this.hasCentred = true; 112 | } 113 | 114 | private void InitialiseStyles() 115 | { 116 | this.titleStyle = new GUIStyle(HighLogic.Skin.label) 117 | { 118 | normal = 119 | { 120 | textColor = Color.white 121 | }, 122 | fontSize = 13, 123 | fontStyle = FontStyle.Bold, 124 | alignment = TextAnchor.MiddleCenter, 125 | stretchWidth = true 126 | }; 127 | } 128 | 129 | private void Window(int id) 130 | { 131 | try 132 | { 133 | GUILayout.BeginVertical(HighLogic.Skin.box); 134 | GUILayout.Label(this.message, this.titleStyle, GUILayout.Width(300.0f)); 135 | GUILayout.EndVertical(); 136 | } 137 | catch (Exception ex) 138 | { 139 | Logger.Exception(ex); 140 | } 141 | } 142 | 143 | #endregion 144 | } 145 | } -------------------------------------------------------------------------------- /KSP-AVC/Configuration.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.IO; 22 | using System.Reflection; 23 | using System.Xml.Serialization; 24 | 25 | #endregion 26 | 27 | namespace KSP_AVC 28 | { 29 | public class Configuration 30 | { 31 | #region Fields 32 | 33 | private static readonly string fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "xml"); 34 | 35 | #endregion 36 | 37 | #region Constructors 38 | 39 | static Configuration() 40 | { 41 | Instance = new Configuration 42 | { 43 | FirstRun = true, 44 | Version = Assembly.GetExecutingAssembly().GetName().Version.ToString() 45 | }; 46 | Load(); 47 | } 48 | 49 | #endregion 50 | 51 | #region Properties 52 | 53 | public static Configuration Instance { get; private set; } 54 | 55 | public bool FirstRun { get; set; } 56 | 57 | public string Version { get; set; } 58 | 59 | #endregion 60 | 61 | #region Methods: public 62 | 63 | public static bool GetFirstRun() 64 | { 65 | return Instance.FirstRun; 66 | } 67 | 68 | public static string GetVersion() 69 | { 70 | return Instance.Version; 71 | } 72 | 73 | public static void Load() 74 | { 75 | try 76 | { 77 | if (!File.Exists(fileName)) 78 | { 79 | return; 80 | } 81 | 82 | using (var stream = new FileStream(fileName, FileMode.Open)) 83 | { 84 | var xml = new XmlSerializer(Instance.GetType()); 85 | Instance = xml.Deserialize(stream) as Configuration; 86 | stream.Close(); 87 | } 88 | } 89 | catch (Exception ex) 90 | { 91 | Logger.Exception(ex); 92 | } 93 | } 94 | 95 | public static void Save() 96 | { 97 | try 98 | { 99 | using (var stream = new FileStream(fileName, FileMode.Create)) 100 | { 101 | var xml = new XmlSerializer(Instance.GetType()); 102 | xml.Serialize(stream, Instance); 103 | stream.Close(); 104 | } 105 | } 106 | catch (Exception ex) 107 | { 108 | Logger.Exception(ex); 109 | } 110 | } 111 | 112 | public static void SetFirstRun(bool value) 113 | { 114 | Instance.FirstRun = value; 115 | Save(); 116 | } 117 | 118 | public static void SetVersion(string value) 119 | { 120 | Instance.Version = value; 121 | Save(); 122 | } 123 | 124 | #endregion 125 | } 126 | } -------------------------------------------------------------------------------- /KSP-AVC/DropDownList.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.IO; 22 | using System.Reflection; 23 | 24 | using UnityEngine; 25 | 26 | #endregion 27 | 28 | namespace KSP_AVC 29 | { 30 | public class DropDownList : MonoBehaviour 31 | { 32 | #region Fields 33 | 34 | private readonly string textureDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Textures"); 35 | 36 | private Rect listPosition; 37 | private GUIStyle listStyle; 38 | private Rect togglePosition; 39 | private GUIStyle toggleStyle; 40 | 41 | #endregion 42 | 43 | #region Properties 44 | 45 | public Addon Addon { get; set; } 46 | 47 | public Action DrawAddonCallback { get; set; } 48 | 49 | public Action DrawCallback { get; set; } 50 | 51 | public bool ShowList { get; set; } 52 | 53 | public ToolTipGui ToolTip { get; set; } 54 | 55 | #endregion 56 | 57 | #region Methods: public 58 | 59 | public void DrawButton(string label, Rect parent, float width) 60 | { 61 | this.ShowList = GUILayout.Toggle(this.ShowList, label, this.toggleStyle, GUILayout.Width(width)); 62 | if (Event.current.type == EventType.repaint) 63 | { 64 | this.SetPosition(GUILayoutUtility.GetLastRect(), parent); 65 | } 66 | } 67 | 68 | #endregion 69 | 70 | #region Methods: protected 71 | 72 | protected void Awake() 73 | { 74 | try 75 | { 76 | DontDestroyOnLoad(this); 77 | this.InitialiseStyles(); 78 | this.ToolTip = this.gameObject.AddComponent(); 79 | } 80 | catch (Exception ex) 81 | { 82 | Logger.Exception(ex); 83 | } 84 | } 85 | 86 | protected void OnDestroy() 87 | { 88 | try 89 | { 90 | if (this.ToolTip != null) 91 | { 92 | Destroy(this.ToolTip); 93 | } 94 | } 95 | catch (Exception ex) 96 | { 97 | Logger.Exception(ex); 98 | } 99 | } 100 | 101 | protected void OnGUI() 102 | { 103 | try 104 | { 105 | if (!this.ShowList) 106 | { 107 | if (this.ToolTip != null && !String.IsNullOrEmpty(this.ToolTip.Text)) 108 | { 109 | this.ToolTip.Text = String.Empty; 110 | } 111 | return; 112 | } 113 | this.listPosition = GUILayout.Window(this.GetInstanceID(), this.listPosition, this.Window, String.Empty, this.listStyle); 114 | } 115 | catch (Exception ex) 116 | { 117 | Logger.Exception(ex); 118 | } 119 | } 120 | 121 | protected void Update() 122 | { 123 | try 124 | { 125 | if (!Input.GetMouseButtonDown(0) && !Input.GetMouseButtonDown(1) && !Input.GetMouseButtonDown(2)) 126 | { 127 | return; 128 | } 129 | 130 | if (!this.listPosition.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y)) && !this.togglePosition.Contains(new Vector2(Input.mousePosition.x, Screen.height - Input.mousePosition.y))) 131 | { 132 | this.ShowList = false; 133 | } 134 | } 135 | catch (Exception ex) 136 | { 137 | Logger.Exception(ex); 138 | } 139 | } 140 | 141 | #endregion 142 | 143 | #region Methods: private 144 | 145 | private Texture2D GetTexture(string file, int width, int height) 146 | { 147 | try 148 | { 149 | var texture = new Texture2D(width, height, TextureFormat.ARGB32, false); 150 | texture.LoadImage(File.ReadAllBytes(Path.Combine(this.textureDirectory, file))); 151 | return texture; 152 | } 153 | catch (Exception ex) 154 | { 155 | Logger.Exception(ex); 156 | return null; 157 | } 158 | } 159 | 160 | private void InitialiseStyles() 161 | { 162 | this.listStyle = new GUIStyle 163 | { 164 | normal = 165 | { 166 | background = this.GetTexture("DropDownBackground.png", 35, 25) 167 | }, 168 | border = new RectOffset(5, 5, 0, 5), 169 | padding = new RectOffset(3, 3, 3, 3) 170 | }; 171 | 172 | this.toggleStyle = new GUIStyle 173 | { 174 | normal = 175 | { 176 | background = this.GetTexture("DropDownNormal.png", 35, 25), 177 | textColor = Color.white 178 | }, 179 | hover = 180 | { 181 | background = this.GetTexture("DropDownHover.png", 35, 25), 182 | textColor = Color.white 183 | }, 184 | active = 185 | { 186 | background = this.GetTexture("DropDownActive.png", 35, 25), 187 | textColor = Color.white 188 | }, 189 | onNormal = 190 | { 191 | background = this.GetTexture("DropDownOnNormal.png", 35, 25), 192 | textColor = Color.white 193 | }, 194 | onHover = 195 | { 196 | background = this.GetTexture("DropDownOnHover.png", 35, 25), 197 | textColor = Color.white 198 | }, 199 | border = new RectOffset(5, 25, 5, 5), 200 | margin = new RectOffset(0, 0, 3, 3), 201 | padding = new RectOffset(5, 30, 5, 5), 202 | fixedHeight = 25.0f, 203 | fontStyle = FontStyle.Bold, 204 | alignment = TextAnchor.MiddleCenter 205 | }; 206 | } 207 | 208 | private void SetPosition(Rect toggle, Rect parent) 209 | { 210 | this.togglePosition = toggle; 211 | this.togglePosition.x += parent.x; 212 | this.togglePosition.y += parent.y; 213 | this.listPosition.x = this.togglePosition.x; 214 | this.listPosition.y = this.togglePosition.y + this.togglePosition.height; 215 | this.listPosition.width = this.togglePosition.width; 216 | } 217 | 218 | private void Window(int windowId) 219 | { 220 | try 221 | { 222 | GUI.BringWindowToFront(windowId); 223 | GUI.BringWindowToFront(this.ToolTip.GetInstanceID()); 224 | 225 | if (this.DrawCallback != null) 226 | { 227 | this.DrawCallback(this); 228 | } 229 | else if (this.DrawAddonCallback != null) 230 | { 231 | this.DrawAddonCallback(this, this.Addon); 232 | } 233 | } 234 | catch (Exception ex) 235 | { 236 | Logger.Exception(ex); 237 | } 238 | } 239 | 240 | #endregion 241 | } 242 | } -------------------------------------------------------------------------------- /KSP-AVC/FirstRunGui.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Reflection; 22 | 23 | using UnityEngine; 24 | 25 | #endregion 26 | 27 | namespace KSP_AVC 28 | { 29 | public class FirstRunGui : MonoBehaviour 30 | { 31 | #region Fields 32 | 33 | private readonly VersionInfo version = Assembly.GetExecutingAssembly().GetName().Version; 34 | private GUIStyle buttonStyle; 35 | private bool hasCentred; 36 | private string message; 37 | private Rect position = new Rect(Screen.width, Screen.height, 0, 0); 38 | private string title; 39 | private GUIStyle titleStyle; 40 | 41 | #endregion 42 | 43 | #region Properties 44 | 45 | public bool HasBeenUpdated { get; set; } 46 | 47 | #endregion 48 | 49 | #region Methods: protected 50 | 51 | protected void Awake() 52 | { 53 | try 54 | { 55 | DontDestroyOnLoad(this); 56 | } 57 | catch (Exception ex) 58 | { 59 | Logger.Exception(ex); 60 | } 61 | Logger.Log("FirstRunGui was created."); 62 | } 63 | 64 | protected void OnDestroy() 65 | { 66 | Logger.Log("FirstRunGui was destroyed."); 67 | } 68 | 69 | protected void OnGUI() 70 | { 71 | try 72 | { 73 | this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, this.title, HighLogic.Skin.window); 74 | this.CentreWindow(); 75 | } 76 | catch (Exception ex) 77 | { 78 | Logger.Exception(ex); 79 | } 80 | } 81 | 82 | protected void Start() 83 | { 84 | try 85 | { 86 | this.InitialiseStyles(); 87 | this.title = "KSP-AVC Plugin - " + (this.HasBeenUpdated ? "Updated" : "Installed"); 88 | this.message = (this.HasBeenUpdated ? "You have successfully updated KSP-AVC to v" : "You have successfully installed KSP-AVC v") + this.version; 89 | } 90 | catch (Exception ex) 91 | { 92 | Logger.Exception(ex); 93 | } 94 | } 95 | 96 | #endregion 97 | 98 | #region Methods: private 99 | 100 | private void CentreWindow() 101 | { 102 | if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) 103 | { 104 | return; 105 | } 106 | this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); 107 | this.hasCentred = true; 108 | } 109 | 110 | private void InitialiseStyles() 111 | { 112 | this.titleStyle = new GUIStyle(HighLogic.Skin.label) 113 | { 114 | normal = 115 | { 116 | textColor = Color.white 117 | }, 118 | fontSize = 13, 119 | fontStyle = FontStyle.Bold, 120 | alignment = TextAnchor.MiddleCenter, 121 | stretchWidth = true 122 | }; 123 | 124 | this.buttonStyle = new GUIStyle(HighLogic.Skin.button) 125 | { 126 | normal = 127 | { 128 | textColor = Color.white 129 | } 130 | }; 131 | } 132 | 133 | private void Window(int id) 134 | { 135 | try 136 | { 137 | GUILayout.BeginVertical(HighLogic.Skin.box); 138 | GUILayout.Label(this.message, this.titleStyle, GUILayout.Width(350.0f)); 139 | GUILayout.EndVertical(); 140 | if (GUILayout.Button("CLOSE", this.buttonStyle)) 141 | { 142 | Destroy(this); 143 | } 144 | GUI.DragWindow(); 145 | } 146 | catch (Exception ex) 147 | { 148 | Logger.Exception(ex); 149 | } 150 | } 151 | 152 | #endregion 153 | } 154 | } -------------------------------------------------------------------------------- /KSP-AVC/IssueGui.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.Linq; 23 | 24 | using UnityEngine; 25 | 26 | #endregion 27 | 28 | namespace KSP_AVC 29 | { 30 | public class IssueGui : MonoBehaviour 31 | { 32 | #region Fields 33 | 34 | private readonly Dictionary actionLists = new Dictionary(); 35 | 36 | private GUIStyle boxStyle; 37 | private GUIStyle buttonStyle; 38 | private bool hasCentred; 39 | private GUIStyle labelStyle; 40 | private GUIStyle messageStyle; 41 | private GUIStyle nameLabelStyle; 42 | private GUIStyle nameTitleStyle; 43 | private Rect position = new Rect(Screen.width, Screen.height, 0, 0); 44 | private GUIStyle titleStyle; 45 | 46 | #endregion 47 | 48 | #region Methods: protected 49 | 50 | protected void Awake() 51 | { 52 | try 53 | { 54 | DontDestroyOnLoad(this); 55 | } 56 | catch (Exception ex) 57 | { 58 | Logger.Exception(ex); 59 | } 60 | Logger.Log("IssueGui was created."); 61 | } 62 | 63 | protected void OnDestroy() 64 | { 65 | try 66 | { 67 | foreach (var dropDownList in this.actionLists.Values) 68 | { 69 | Destroy(dropDownList); 70 | } 71 | } 72 | catch (Exception ex) 73 | { 74 | Logger.Exception(ex); 75 | } 76 | Logger.Log("IssueGui was destroyed."); 77 | } 78 | 79 | protected void OnGUI() 80 | { 81 | try 82 | { 83 | this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "KSP Add-on Version Checker - Issue Monitor", HighLogic.Skin.window); 84 | this.CentreWindow(); 85 | } 86 | catch (Exception ex) 87 | { 88 | Logger.Exception(ex); 89 | } 90 | } 91 | 92 | protected void Start() 93 | { 94 | try 95 | { 96 | this.InitialiseStyles(); 97 | } 98 | catch (Exception ex) 99 | { 100 | Logger.Exception(ex); 101 | } 102 | } 103 | 104 | #endregion 105 | 106 | #region Methods: private 107 | 108 | private void CentreWindow() 109 | { 110 | if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) 111 | { 112 | return; 113 | } 114 | this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); 115 | this.hasCentred = true; 116 | } 117 | 118 | private DropDownList CreateActionList(Addon addon) 119 | { 120 | var actionList = this.gameObject.AddComponent(); 121 | actionList.Addon = addon; 122 | actionList.DrawAddonCallback = this.DrawActionList; 123 | this.actionLists.Add(addon, actionList); 124 | return actionList; 125 | } 126 | 127 | private void DrawActionButton(Addon addon) 128 | { 129 | if (String.IsNullOrEmpty(addon.RemoteInfo.Download) && String.IsNullOrEmpty(addon.RemoteInfo.ChangeLog)) 130 | { 131 | return; 132 | } 133 | 134 | (this.actionLists.ContainsKey(addon) ? this.actionLists[addon] : this.CreateActionList(addon)).DrawButton("ACTIONS", this.position, 125.0f); 135 | } 136 | 137 | private void DrawActionList(DropDownList list, Addon addon) 138 | { 139 | this.DrawActionListChangeLog(list, addon); 140 | this.DrawActionListDownload(list, addon); 141 | } 142 | 143 | private void DrawActionListChangeLog(DropDownList list, Addon addon) 144 | { 145 | if (String.IsNullOrEmpty(addon.RemoteInfo.ChangeLog) || !GUILayout.Button("Change Log", this.buttonStyle)) 146 | { 147 | return; 148 | } 149 | 150 | var changeLogGui = this.gameObject.AddComponent(); 151 | changeLogGui.Name = addon.RemoteInfo.Name; 152 | changeLogGui.Text = addon.RemoteInfo.ChangeLog; 153 | list.ShowList = false; 154 | } 155 | 156 | private void DrawActionListDownload(DropDownList list, Addon addon) 157 | { 158 | if (String.IsNullOrEmpty(addon.RemoteInfo.Download)) 159 | { 160 | return; 161 | } 162 | 163 | if (GUILayout.Button("Download", this.buttonStyle)) 164 | { 165 | Application.OpenURL(addon.RemoteInfo.Download); 166 | list.ShowList = false; 167 | } 168 | if (Event.current.type == EventType.repaint) 169 | { 170 | list.ToolTip.Text = GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) ? list.ToolTip.Text = addon.RemoteInfo.Download : String.Empty; 171 | } 172 | } 173 | 174 | private void DrawCompatibilityIssues() 175 | { 176 | GUILayout.BeginVertical(this.boxStyle); 177 | GUILayout.Label("COMPATIBILITY ISSUES", this.nameTitleStyle); 178 | foreach (var addon in AddonLibrary.Addons.Where(a => !a.IsCompatible)) 179 | { 180 | GUILayout.Label("The currently installed version of " + addon.Name + " was built to run on KSP " + addon.LocalInfo.KspVersion, this.messageStyle, GUILayout.MinWidth(575.0f)); 181 | } 182 | GUILayout.EndVertical(); 183 | } 184 | 185 | private void DrawUpdateHeadings() 186 | { 187 | GUILayout.BeginHorizontal(); 188 | GUILayout.Label("ADD-ON NAME", this.nameTitleStyle, GUILayout.Width(250.0f)); 189 | GUILayout.Label("CURRENT", this.titleStyle, GUILayout.Width(100.0f)); 190 | GUILayout.Label("AVAILABLE", this.titleStyle, GUILayout.Width(100.0f)); 191 | GUILayout.EndHorizontal(); 192 | } 193 | 194 | private void DrawUpdateInformation(Addon addon) 195 | { 196 | GUILayout.Label(addon.Name, this.nameLabelStyle, GUILayout.Width(250.0f)); 197 | GUILayout.Label(addon.LocalInfo.Version.ToString(), this.labelStyle, GUILayout.Width(100.0f)); 198 | GUILayout.Label(addon.RemoteInfo.Version.ToString(), this.labelStyle, GUILayout.Width(100.0f)); 199 | } 200 | 201 | private void DrawUpdateIssues() 202 | { 203 | GUILayout.BeginVertical(this.boxStyle); 204 | this.DrawUpdateHeadings(); 205 | 206 | foreach (var addon in AddonLibrary.Addons.Where(a => a.IsUpdateAvailable)) 207 | { 208 | GUILayout.BeginHorizontal(); 209 | this.DrawUpdateInformation(addon); 210 | GUILayout.FlexibleSpace(); 211 | this.DrawActionButton(addon); 212 | GUILayout.EndHorizontal(); 213 | } 214 | GUILayout.EndVertical(); 215 | } 216 | 217 | private void InitialiseStyles() 218 | { 219 | this.boxStyle = new GUIStyle(HighLogic.Skin.box) 220 | { 221 | padding = new RectOffset(10, 10, 5, 5) 222 | }; 223 | 224 | this.nameTitleStyle = new GUIStyle(HighLogic.Skin.label) 225 | { 226 | normal = 227 | { 228 | textColor = Color.white 229 | }, 230 | alignment = TextAnchor.MiddleLeft, 231 | fontStyle = FontStyle.Bold, 232 | stretchWidth = true 233 | }; 234 | 235 | this.titleStyle = new GUIStyle(HighLogic.Skin.label) 236 | { 237 | normal = 238 | { 239 | textColor = Color.white 240 | }, 241 | alignment = TextAnchor.MiddleCenter, 242 | fontStyle = FontStyle.Bold 243 | }; 244 | 245 | this.nameLabelStyle = new GUIStyle(HighLogic.Skin.label) 246 | { 247 | fixedHeight = 25.0f, 248 | alignment = TextAnchor.MiddleLeft, 249 | stretchWidth = true 250 | }; 251 | 252 | this.labelStyle = new GUIStyle(HighLogic.Skin.label) 253 | { 254 | fixedHeight = 25.0f, 255 | alignment = TextAnchor.MiddleCenter, 256 | }; 257 | 258 | this.messageStyle = new GUIStyle(HighLogic.Skin.label) 259 | { 260 | stretchWidth = true 261 | }; 262 | 263 | this.buttonStyle = new GUIStyle(HighLogic.Skin.button) 264 | { 265 | normal = 266 | { 267 | textColor = Color.white 268 | } 269 | }; 270 | } 271 | 272 | private void Window(int id) 273 | { 274 | try 275 | { 276 | if (AddonLibrary.Addons.Any(a => a.IsUpdateAvailable)) 277 | { 278 | this.DrawUpdateIssues(); 279 | } 280 | if (AddonLibrary.Addons.Any(a => !a.IsCompatible)) 281 | { 282 | this.DrawCompatibilityIssues(); 283 | } 284 | if (GUILayout.Button("CLOSE", this.buttonStyle)) 285 | { 286 | Destroy(this); 287 | } 288 | GUI.DragWindow(); 289 | } 290 | catch (Exception ex) 291 | { 292 | Logger.Exception(ex); 293 | } 294 | } 295 | 296 | #endregion 297 | } 298 | } -------------------------------------------------------------------------------- /KSP-AVC/KSP-AVC.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F745CC0C-B7A0-4EF2-BF5A-1D3F0C19202C} 8 | Library 9 | Properties 10 | KSP_AVC 11 | KSP-AVC 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | false 18 | none 19 | false 20 | ..\Output\KSP-AVC\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | false 25 | 26 | 27 | none 28 | true 29 | ..\Output\KSP-AVC\ 30 | TRACE 31 | prompt 32 | 4 33 | false 34 | false 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | ..\..\..\KSP-Environment\KSP_x64_Data\Managed\Assembly-CSharp.dll 58 | False 59 | 60 | 61 | ..\..\Game\KSP_x64_Data\Managed\System.dll 62 | False 63 | 64 | 65 | ..\..\Game\KSP_x64_Data\Managed\System.Xml.dll 66 | False 67 | 68 | 69 | ..\..\..\KSP-Environment\KSP_x64_Data\Managed\UnityEngine.dll 70 | False 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | $(PostBuildEventDependsOn); 85 | PostBuildMacros; 86 | 87 | xcopy "$(SolutionDir)Output\KSP-AVC\*" "$(SolutionDir)..\..\KSP-Environment\GameData\KSP-AVC\*" /E /Y 88 | del "$(SolutionDir)Release\KSP-AVC\*" /Q 89 | xcopy "$(SolutionDir)Documents\KSP-AVC\*" "$(SolutionDir)Release\KSP-AVC\Documents\*" /E /Y 90 | 7z.exe a -tzip -mx3 "$(SolutionDir)Release\KSP-AVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Output\KSP-AVC" 91 | 7z.exe a -tzip -mx3 "$(SolutionDir)Release\KSP-AVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Documents\KSP-AVC\*" 92 | 93 | 100 | -------------------------------------------------------------------------------- /KSP-AVC/Logger.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Collections; 22 | using System.Collections.Generic; 23 | using System.IO; 24 | using System.Reflection; 25 | 26 | using UnityEngine; 27 | 28 | #endregion 29 | 30 | namespace KSP_AVC 31 | { 32 | [KSPAddon(KSPAddon.Startup.Instantly, false)] 33 | public class Logger : MonoBehaviour 34 | { 35 | #region Fields 36 | 37 | private static readonly AssemblyName assemblyName; 38 | private static readonly string fileName; 39 | private static readonly List messages = new List(); 40 | 41 | #endregion 42 | 43 | #region Constructors 44 | 45 | static Logger() 46 | { 47 | assemblyName = Assembly.GetExecutingAssembly().GetName(); 48 | fileName = Path.ChangeExtension(Assembly.GetExecutingAssembly().Location, "log"); 49 | File.Delete(fileName); 50 | 51 | lock (messages) 52 | { 53 | messages.Add(new[] {"Executing: " + assemblyName.Name + " - " + assemblyName.Version}); 54 | messages.Add(new[] {"Assembly: " + Assembly.GetExecutingAssembly().Location}); 55 | } 56 | Blank(); 57 | } 58 | 59 | #endregion 60 | 61 | #region Destructors 62 | 63 | ~Logger() 64 | { 65 | Flush(); 66 | } 67 | 68 | #endregion 69 | 70 | #region Methods: public 71 | 72 | public static void Blank() 73 | { 74 | lock (messages) 75 | { 76 | messages.Add(new string[] {}); 77 | } 78 | } 79 | 80 | public static void Error(string message) 81 | { 82 | lock (messages) 83 | { 84 | messages.Add(new[] {"Error " + DateTime.Now.TimeOfDay, message}); 85 | } 86 | } 87 | 88 | public static void Exception(Exception ex) 89 | { 90 | lock (messages) 91 | { 92 | messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, ex.ToString()}); 93 | Blank(); 94 | } 95 | } 96 | 97 | public static void Exception(Exception ex, string location) 98 | { 99 | lock (messages) 100 | { 101 | messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, location + " // " + ex}); 102 | Blank(); 103 | } 104 | } 105 | 106 | public static void Flush() 107 | { 108 | lock (messages) 109 | { 110 | if (messages.Count == 0) 111 | { 112 | return; 113 | } 114 | 115 | using (var file = File.AppendText(fileName)) 116 | { 117 | foreach (var message in messages) 118 | { 119 | file.WriteLine(message.Length > 0 ? message.Length > 1 ? "[" + message[0] + "]: " + message[1] : message[0] : string.Empty); 120 | if (message.Length > 0) 121 | { 122 | print(message.Length > 1 ? assemblyName.Name + " -> " + message[1] : assemblyName.Name + " -> " + message[0]); 123 | } 124 | } 125 | } 126 | messages.Clear(); 127 | } 128 | } 129 | 130 | public static void Log(object obj) 131 | { 132 | lock (messages) 133 | { 134 | try 135 | { 136 | if (obj is IEnumerable) 137 | { 138 | messages.Add(new[] {"Text " + DateTime.Now.TimeOfDay, obj.ToString()}); 139 | foreach (var o in obj as IEnumerable) 140 | { 141 | messages.Add(new[] {"\t", o.ToString()}); 142 | } 143 | } 144 | else 145 | { 146 | messages.Add(new[] {"Text " + DateTime.Now.TimeOfDay, obj.ToString()}); 147 | } 148 | } 149 | catch (Exception ex) 150 | { 151 | Exception(ex); 152 | } 153 | } 154 | } 155 | 156 | public static void Log(string name, object obj) 157 | { 158 | lock (messages) 159 | { 160 | try 161 | { 162 | if (obj is IEnumerable) 163 | { 164 | messages.Add(new[] {"Text " + DateTime.Now.TimeOfDay, name}); 165 | foreach (var o in obj as IEnumerable) 166 | { 167 | messages.Add(new[] {"\t", o.ToString()}); 168 | } 169 | } 170 | else 171 | { 172 | messages.Add(new[] {"Text " + DateTime.Now.TimeOfDay, obj.ToString()}); 173 | } 174 | } 175 | catch (Exception ex) 176 | { 177 | Exception(ex); 178 | } 179 | } 180 | } 181 | 182 | public static void Log(string message) 183 | { 184 | lock (messages) 185 | { 186 | messages.Add(new[] {"Text " + DateTime.Now.TimeOfDay, message}); 187 | } 188 | } 189 | 190 | public static void Warning(string message) 191 | { 192 | lock (messages) 193 | { 194 | messages.Add(new[] {"Warning " + DateTime.Now.TimeOfDay, message}); 195 | } 196 | } 197 | 198 | #endregion 199 | 200 | #region Methods: protected 201 | 202 | protected void Awake() 203 | { 204 | DontDestroyOnLoad(this); 205 | } 206 | 207 | protected void LateUpdate() 208 | { 209 | Flush(); 210 | } 211 | 212 | protected void OnDestroy() 213 | { 214 | Flush(); 215 | } 216 | 217 | #endregion 218 | } 219 | } -------------------------------------------------------------------------------- /KSP-AVC/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System.Reflection; 21 | using System.Runtime.InteropServices; 22 | 23 | #endregion 24 | 25 | [assembly: AssemblyTitle("KSP-AVC")] 26 | [assembly: AssemblyProduct("KSP-AVC")] 27 | [assembly: AssemblyCopyright("Copyright © 2015 CYBUTEK")] 28 | [assembly: ComVisible(false)] 29 | [assembly: Guid("be1fd3ec-c1ba-47ec-9e16-f83da6fe87d5")] 30 | [assembly: AssemblyVersion("1.1.6.2")] -------------------------------------------------------------------------------- /KSP-AVC/Starter.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Linq; 22 | using System.Reflection; 23 | 24 | using UnityEngine; 25 | 26 | #endregion 27 | 28 | namespace KSP_AVC 29 | { 30 | [KSPAddon(KSPAddon.Startup.Instantly, false)] 31 | public class Starter : MonoBehaviour 32 | { 33 | #region Fields 34 | 35 | private static bool hasAlreadyChecked; 36 | private CheckerProgressGui checkerProgressGui; 37 | private FirstRunGui firstRunGui; 38 | 39 | #endregion 40 | 41 | #region Methods: protected 42 | 43 | protected void Awake() 44 | { 45 | try 46 | { 47 | if (this.HasAlreadyChecked()) 48 | { 49 | return; 50 | } 51 | DontDestroyOnLoad(this); 52 | } 53 | catch (Exception ex) 54 | { 55 | Logger.Exception(ex); 56 | } 57 | Logger.Log("Starter was created."); 58 | } 59 | 60 | protected void OnDestroy() 61 | { 62 | try 63 | { 64 | if (this.firstRunGui != null) 65 | { 66 | Destroy(this.firstRunGui); 67 | } 68 | if (this.checkerProgressGui != null) 69 | { 70 | Destroy(this.checkerProgressGui); 71 | } 72 | } 73 | catch (Exception ex) 74 | { 75 | Logger.Exception(ex); 76 | } 77 | Logger.Log("Starter was destroyed."); 78 | } 79 | 80 | protected void Start() 81 | { 82 | try 83 | { 84 | if (new System.Version(Configuration.GetVersion()) < Assembly.GetExecutingAssembly().GetName().Version) 85 | { 86 | this.ShowUpdatedWindow(); 87 | } 88 | else if (Configuration.GetFirstRun()) 89 | { 90 | this.ShowInstalledWindow(); 91 | } 92 | } 93 | catch (Exception ex) 94 | { 95 | Logger.Exception(ex); 96 | } 97 | } 98 | 99 | protected void Update() 100 | { 101 | if (HighLogic.LoadedScene == GameScenes.SPACECENTER) 102 | { 103 | Destroy(gameObject); 104 | } 105 | 106 | try 107 | { 108 | if (this.firstRunGui != null) 109 | { 110 | return; 111 | } 112 | if (this.ShowIssuesWindow()) 113 | { 114 | return; 115 | } 116 | if (this.checkerProgressGui == null) 117 | { 118 | this.checkerProgressGui = this.gameObject.AddComponent(); 119 | } 120 | } 121 | catch (Exception ex) 122 | { 123 | Logger.Exception(ex); 124 | } 125 | } 126 | 127 | #endregion 128 | 129 | #region Methods: private 130 | 131 | private bool HasAlreadyChecked() 132 | { 133 | if (hasAlreadyChecked) 134 | { 135 | Destroy(this); 136 | return true; 137 | } 138 | hasAlreadyChecked = true; 139 | return false; 140 | } 141 | 142 | private void ShowInstalledWindow() 143 | { 144 | Configuration.SetFirstRun(false); 145 | this.firstRunGui = this.gameObject.AddComponent(); 146 | } 147 | 148 | private bool ShowIssuesWindow() 149 | { 150 | if (!AddonLibrary.Populated || !AddonLibrary.ProcessingComplete) 151 | { 152 | return false; 153 | } 154 | if (AddonLibrary.Addons.Any(a => a.IsUpdateAvailable || !a.IsCompatible)) 155 | { 156 | this.gameObject.AddComponent(); 157 | } 158 | Destroy(this); 159 | return true; 160 | } 161 | 162 | private void ShowUpdatedWindow() 163 | { 164 | Configuration.SetVersion(Assembly.GetExecutingAssembly().GetName().Version.ToString()); 165 | this.firstRunGui = this.gameObject.AddComponent(); 166 | this.firstRunGui.HasBeenUpdated = true; 167 | } 168 | 169 | #endregion 170 | } 171 | } -------------------------------------------------------------------------------- /KSP-AVC/ToolTipGui.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | 22 | using UnityEngine; 23 | 24 | #endregion 25 | 26 | namespace KSP_AVC 27 | { 28 | public class ToolTipGui : MonoBehaviour 29 | { 30 | #region Fields 31 | 32 | private GUIContent content; 33 | private GUIStyle labelStyle; 34 | private Rect position; 35 | 36 | #endregion 37 | 38 | #region Properties 39 | 40 | public string Text 41 | { 42 | get { return (this.content ?? GUIContent.none).text; } 43 | set { this.content = new GUIContent(value); } 44 | } 45 | 46 | #endregion 47 | 48 | #region Methods: protected 49 | 50 | protected void Awake() 51 | { 52 | try 53 | { 54 | DontDestroyOnLoad(this); 55 | } 56 | catch (Exception ex) 57 | { 58 | Logger.Exception(ex); 59 | } 60 | Logger.Log("ToolTipGui was created."); 61 | } 62 | 63 | protected void OnDestroy() 64 | { 65 | Logger.Log("ToolTipGui was destroyed."); 66 | } 67 | 68 | protected void OnGUI() 69 | { 70 | try 71 | { 72 | if (this.content == null || String.IsNullOrEmpty(this.content.text)) 73 | { 74 | return; 75 | } 76 | 77 | GUILayout.Window(this.GetInstanceID(), this.position, this.Window, String.Empty, GUIStyle.none); 78 | } 79 | catch (Exception ex) 80 | { 81 | Logger.Exception(ex); 82 | } 83 | } 84 | 85 | protected void Start() 86 | { 87 | try 88 | { 89 | this.InitialiseStyles(); 90 | } 91 | catch (Exception ex) 92 | { 93 | Logger.Exception(ex); 94 | } 95 | } 96 | 97 | protected void Update() 98 | { 99 | this.position.size = this.labelStyle.CalcSize(this.content ?? GUIContent.none); 100 | this.position.x = Mathf.Clamp(Input.mousePosition.x + 20.0f, 0, Screen.width - this.position.width); 101 | this.position.y = Screen.height - Input.mousePosition.y + (this.position.x < Input.mousePosition.x + 20.0f ? 20.0f : 0); 102 | } 103 | 104 | #endregion 105 | 106 | #region Methods: private 107 | 108 | private static Texture2D GetBackgroundTexture() 109 | { 110 | var texture = new Texture2D(1, 1, TextureFormat.ARGB32, false); 111 | texture.SetPixel(1, 1, new Color(1.0f, 1.0f, 1.0f, 1.0f)); 112 | texture.Apply(); 113 | return texture; 114 | } 115 | 116 | private void InitialiseStyles() 117 | { 118 | this.labelStyle = new GUIStyle 119 | { 120 | padding = new RectOffset(4, 4, 2, 2), 121 | normal = 122 | { 123 | textColor = Color.black, 124 | background = GetBackgroundTexture() 125 | }, 126 | fontSize = 11 127 | }; 128 | } 129 | 130 | private void Window(int windowId) 131 | { 132 | try 133 | { 134 | GUI.BringWindowToFront(windowId); 135 | GUILayout.Label(this.content ?? GUIContent.none, this.labelStyle); 136 | } 137 | catch (Exception ex) 138 | { 139 | Logger.Exception(ex); 140 | } 141 | } 142 | 143 | #endregion 144 | } 145 | } -------------------------------------------------------------------------------- /KSP-AVC/Toolbar/ToolbarWindow.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Linq; 22 | 23 | using UnityEngine; 24 | 25 | #endregion 26 | 27 | namespace KSP_AVC.Toolbar 28 | { 29 | [KSPAddon(KSPAddon.Startup.Instantly, false)] 30 | public class ToolbarWindow : MonoBehaviour 31 | { 32 | #region Fields 33 | 34 | private string addonList; 35 | private GUIStyle labelGreen; 36 | private GUIStyle labelYellow; 37 | private Rect position = new Rect(0.0f, 0.0f, 400.0f, 0.0f); 38 | private Vector2 scrollPosition; 39 | private bool showAddons; 40 | private bool useScrollView; 41 | private GUIStyle windowStyle; 42 | 43 | #endregion 44 | 45 | #region Methods: protected 46 | 47 | protected void Awake() 48 | { 49 | try 50 | { 51 | DontDestroyOnLoad(this); 52 | } 53 | catch (Exception ex) 54 | { 55 | Logger.Exception(ex); 56 | } 57 | } 58 | 59 | protected void OnGUI() 60 | { 61 | try 62 | { 63 | this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, String.Empty, this.windowStyle); 64 | this.CheckScrollViewUsage(); 65 | } 66 | catch (Exception ex) 67 | { 68 | Logger.Exception(ex); 69 | } 70 | } 71 | 72 | protected void Start() 73 | { 74 | try 75 | { 76 | if (AssemblyLoader.loadedAssemblies.Any(a => a.name == "DevHelper")) 77 | { 78 | this.position.y = 60.0f; 79 | } 80 | this.InitialiseStyles(); 81 | } 82 | catch (Exception ex) 83 | { 84 | Logger.Exception(ex); 85 | } 86 | } 87 | 88 | protected void Update() 89 | { 90 | try 91 | { 92 | if (HighLogic.LoadedScene != GameScenes.LOADING && HighLogic.LoadedScene != GameScenes.MAINMENU) 93 | { 94 | Destroy(this); 95 | } 96 | } 97 | catch (Exception ex) 98 | { 99 | Logger.Exception(ex); 100 | } 101 | } 102 | 103 | #endregion 104 | 105 | #region Methods: private 106 | 107 | private void CheckScrollViewUsage() 108 | { 109 | if (this.position.height < Screen.height * 0.5f || this.useScrollView) 110 | { 111 | return; 112 | } 113 | 114 | this.useScrollView = true; 115 | this.position.height = Screen.height * 0.5f; 116 | } 117 | 118 | private void CopyToClipboard() 119 | { 120 | if (!GUILayout.Button("Copy to Clipboard")) 121 | { 122 | return; 123 | } 124 | 125 | var kspVersion = AddonInfo.ActualKspVersion.ToString(); 126 | if (Environment.OSVersion.Platform == PlatformID.Win32NT) 127 | { 128 | if (IntPtr.Size == 8) 129 | { 130 | kspVersion += " (Win64)"; 131 | } 132 | else 133 | { 134 | kspVersion += " (Win32)"; 135 | } 136 | } 137 | else 138 | { 139 | kspVersion += " (" + Environment.OSVersion.Platform + ")"; 140 | } 141 | 142 | var copyText = "KSP: " + kspVersion + 143 | " - Unity: " + Application.unityVersion + 144 | " - OS: " + SystemInfo.operatingSystem + 145 | this.addonList; 146 | 147 | var textEditor = new TextEditor 148 | { 149 | text = copyText 150 | }; 151 | textEditor.SelectAll(); 152 | textEditor.Copy(); 153 | } 154 | 155 | private void DrawAddonBoxEnd() 156 | { 157 | if (this.useScrollView) 158 | { 159 | GUILayout.EndScrollView(); 160 | } 161 | else 162 | { 163 | GUILayout.EndVertical(); 164 | } 165 | } 166 | 167 | private void DrawAddonBoxStart() 168 | { 169 | if (this.useScrollView) 170 | { 171 | this.scrollPosition = GUILayout.BeginScrollView(this.scrollPosition, GUILayout.Height(Screen.height * 0.5f)); 172 | } 173 | else 174 | { 175 | GUILayout.BeginVertical(GUI.skin.scrollView); 176 | } 177 | } 178 | 179 | private void DrawAddonList() 180 | { 181 | this.DrawAddonBoxStart(); 182 | this.DrawAddons(); 183 | this.DrawAddonBoxEnd(); 184 | 185 | GUILayout.Space(5.0f); 186 | this.CopyToClipboard(); 187 | GUILayout.Space(5.0f); 188 | } 189 | 190 | private void DrawAddons() 191 | { 192 | this.addonList = String.Empty; 193 | foreach (var addon in AddonLibrary.Addons) 194 | { 195 | var labelStyle = !addon.IsCompatible || addon.IsUpdateAvailable ? this.labelYellow : this.labelGreen; 196 | this.addonList += Environment.NewLine + addon.Name + " - " + addon.LocalInfo.Version; 197 | GUILayout.BeginHorizontal(); 198 | GUILayout.Label(addon.Name, labelStyle); 199 | GUILayout.FlexibleSpace(); 200 | GUILayout.Label(addon.LocalInfo != null ? addon.LocalInfo.Version.ToString() : String.Empty, labelStyle); 201 | GUILayout.EndHorizontal(); 202 | } 203 | } 204 | 205 | private void InitialiseStyles() 206 | { 207 | this.windowStyle = new GUIStyle 208 | { 209 | normal = 210 | { 211 | background = Utils.GetTexture("OverlayBackground.png", 400, 100) 212 | }, 213 | border = new RectOffset(3, 3, 20, 3), 214 | padding = new RectOffset(10, 10, 23, 5) 215 | }; 216 | 217 | this.labelGreen = new GUIStyle 218 | { 219 | normal = 220 | { 221 | textColor = Color.green 222 | } 223 | }; 224 | 225 | this.labelYellow = new GUIStyle 226 | { 227 | normal = 228 | { 229 | textColor = Color.yellow 230 | } 231 | }; 232 | } 233 | 234 | private void Window(int windowId) 235 | { 236 | try 237 | { 238 | GUILayout.BeginHorizontal(); 239 | GUILayout.Label("Installed Add-ons: " + AddonLibrary.TotalCount); 240 | GUILayout.FlexibleSpace(); 241 | if (GUILayout.Toggle(this.showAddons, "Show Add-ons") != this.showAddons) 242 | { 243 | this.showAddons = !this.showAddons; 244 | this.position.height = 0.0f; 245 | } 246 | GUILayout.EndHorizontal(); 247 | if (this.showAddons) 248 | { 249 | this.DrawAddonList(); 250 | } 251 | } 252 | catch (Exception ex) 253 | { 254 | Logger.Exception(ex); 255 | } 256 | } 257 | 258 | #endregion 259 | } 260 | } -------------------------------------------------------------------------------- /KSP-AVC/Utils.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.IO; 22 | using System.Reflection; 23 | 24 | using UnityEngine; 25 | 26 | #endregion 27 | 28 | namespace KSP_AVC 29 | { 30 | public static class Utils 31 | { 32 | #region Fields 33 | 34 | private static readonly string textureDirectory = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), "Textures"); 35 | 36 | #endregion 37 | 38 | #region Methods: public 39 | 40 | public static Texture2D GetTexture(string file, int width, int height) 41 | { 42 | try 43 | { 44 | var texture = new Texture2D(width, height, TextureFormat.ARGB32, false); 45 | texture.LoadImage(File.ReadAllBytes(Path.Combine(textureDirectory, file))); 46 | return texture; 47 | } 48 | catch (Exception ex) 49 | { 50 | Logger.Exception(ex); 51 | return null; 52 | } 53 | } 54 | 55 | #endregion 56 | } 57 | } -------------------------------------------------------------------------------- /KSP-AVC/VersionInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Text.RegularExpressions; 22 | 23 | #endregion 24 | 25 | namespace KSP_AVC 26 | { 27 | public class VersionInfo : IComparable 28 | { 29 | #region Constructors 30 | 31 | public VersionInfo(long major = 0, long minor = 0, long patch = 0, long build = 0) 32 | { 33 | this.SetVersion(major, minor, patch, build); 34 | } 35 | 36 | public VersionInfo(string version) 37 | { 38 | this.SetVersion(version); 39 | } 40 | 41 | public VersionInfo(Version version) 42 | { 43 | this.SetVersion(version.ToString()); 44 | } 45 | 46 | #endregion 47 | 48 | #region Properties 49 | 50 | public static VersionInfo AnyValue 51 | { 52 | get { return new VersionInfo(-1, -1, -1, -1); } 53 | } 54 | 55 | public static VersionInfo MaxValue 56 | { 57 | get { return new VersionInfo(Int64.MaxValue, Int64.MaxValue, Int64.MaxValue, Int64.MaxValue); } 58 | } 59 | 60 | public static VersionInfo MinValue 61 | { 62 | get { return new VersionInfo(); } 63 | } 64 | 65 | public bool Any 66 | { 67 | get { return this.Major == -1 && this.Minor == -1 && this.Patch == -1 && this.Build == -1; } 68 | } 69 | 70 | public long Build { get; set; } 71 | 72 | public long Major { get; set; } 73 | 74 | public long Minor { get; set; } 75 | 76 | public long Patch { get; set; } 77 | 78 | #endregion 79 | 80 | #region Operators 81 | 82 | public static bool operator ==(VersionInfo v1, VersionInfo v2) 83 | { 84 | return Equals(v1, v2); 85 | } 86 | 87 | public static bool operator >(VersionInfo v1, VersionInfo v2) 88 | { 89 | return v1.CompareTo(v2) > 0; 90 | } 91 | 92 | public static bool operator >=(VersionInfo v1, VersionInfo v2) 93 | { 94 | return v1.CompareTo(v2) >= 0; 95 | } 96 | 97 | public static implicit operator Version(VersionInfo version) 98 | { 99 | return new Version(Convert.ToInt32(version.Major), Convert.ToInt32(version.Minor), Convert.ToInt32(version.Patch), Convert.ToInt32(version.Build)); 100 | } 101 | 102 | public static implicit operator VersionInfo(Version version) 103 | { 104 | return new VersionInfo(version.Major, version.Minor, version.Build, version.Revision); 105 | } 106 | 107 | public static bool operator !=(VersionInfo v1, VersionInfo v2) 108 | { 109 | return !Equals(v1, v2); 110 | } 111 | 112 | public static bool operator <(VersionInfo v1, VersionInfo v2) 113 | { 114 | return v1.CompareTo(v2) < 0; 115 | } 116 | 117 | public static bool operator <=(VersionInfo v1, VersionInfo v2) 118 | { 119 | return v1.CompareTo(v2) <= 0; 120 | } 121 | 122 | #endregion 123 | 124 | #region Methods: public 125 | 126 | public int CompareTo(object obj) 127 | { 128 | if (obj == null) 129 | { 130 | return 1; 131 | } 132 | 133 | var other = obj as VersionInfo; 134 | if (other == null) 135 | { 136 | throw new ArgumentException("Not a VersionInfo object."); 137 | } 138 | 139 | if (this.Major != -1 && other.Major != -1) 140 | { 141 | var major = this.Major.CompareTo(other.Major); 142 | if (major != 0) 143 | { 144 | return major; 145 | } 146 | } 147 | 148 | if (this.Minor != -1 && other.Minor != -1) 149 | { 150 | var minor = this.Minor.CompareTo(other.Minor); 151 | if (minor != 0) 152 | { 153 | return minor; 154 | } 155 | } 156 | 157 | if (this.Patch != -1 && other.Patch != -1) 158 | { 159 | var patch = this.Patch.CompareTo(other.Patch); 160 | if (patch != 0) 161 | { 162 | return patch; 163 | } 164 | } 165 | 166 | if (this.Build != -1 && other.Build != -1) 167 | { 168 | var build = this.Build.CompareTo(other.Build); 169 | if (build != 0) 170 | { 171 | return build; 172 | } 173 | } 174 | 175 | return 0; 176 | } 177 | 178 | public override bool Equals(object obj) 179 | { 180 | if (ReferenceEquals(null, obj)) 181 | { 182 | return false; 183 | } 184 | if (ReferenceEquals(this, obj)) 185 | { 186 | return true; 187 | } 188 | return obj.GetType() == this.GetType() && this.Equals((VersionInfo)obj); 189 | } 190 | 191 | public override int GetHashCode() 192 | { 193 | unchecked 194 | { 195 | var hashCode = this.Major.GetHashCode(); 196 | hashCode = (hashCode * 397) ^ this.Minor.GetHashCode(); 197 | hashCode = (hashCode * 397) ^ this.Patch.GetHashCode(); 198 | hashCode = (hashCode * 397) ^ this.Build.GetHashCode(); 199 | return hashCode; 200 | } 201 | } 202 | 203 | public void SetVersion(long major = 0, long minor = 0, long patch = 0, long build = 0) 204 | { 205 | this.Major = major; 206 | this.Minor = minor; 207 | this.Patch = patch; 208 | this.Build = build; 209 | } 210 | 211 | public void SetVersion(string version) 212 | { 213 | var sections = Regex.Replace(version, @"[^\d\.]", String.Empty).Split('.'); 214 | 215 | switch (sections.Length) 216 | { 217 | case 1: 218 | this.SetVersion(Int64.Parse(sections[0])); 219 | return; 220 | 221 | case 2: 222 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1])); 223 | return; 224 | 225 | case 3: 226 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2])); 227 | return; 228 | 229 | case 4: 230 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2]), Int64.Parse(sections[3])); 231 | return; 232 | 233 | default: 234 | this.SetVersion(); 235 | return; 236 | } 237 | } 238 | 239 | public override string ToString() 240 | { 241 | if (this.Any) 242 | { 243 | return "Any"; 244 | } 245 | 246 | if (this.Build != 0) 247 | { 248 | return String.Format("{0}.{1}.{2}.{3}", this.Major, this.Minor, this.Patch, this.Build).Replace("-1", "*"); 249 | } 250 | return this.Patch != 0 ? String.Format("{0}.{1}.{2}", this.Major, this.Minor, this.Patch).Replace("-1", "*") : String.Format("{0}.{1}", this.Major, this.Minor).Replace("-1", "*"); 251 | } 252 | 253 | #endregion 254 | 255 | #region Methods: protected 256 | 257 | protected bool Equals(VersionInfo other) 258 | { 259 | return (this.Major == -1 || other.Major == -1 || this.Major.Equals(other.Major)) && 260 | (this.Minor == -1 || other.Minor == -1 || this.Minor.Equals(other.Minor)) && 261 | (this.Patch == -1 || other.Patch == -1 || this.Patch.Equals(other.Patch)) && 262 | (this.Build == -1 || other.Build == -1 || this.Build.Equals(other.Build)); 263 | } 264 | 265 | #endregion 266 | } 267 | } -------------------------------------------------------------------------------- /MiniAVC/Addon.cs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 CYBUTEK 2 | // 3 | // This program is free software: you can redistribute it and/or modify it under the terms of the GNU 4 | // General Public License as published by the Free Software Foundation, either version 3 of the 5 | // License, or (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 8 | // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | // General Public License for more details. 10 | // 11 | // You should have received a copy of the GNU General Public License along with this program. If not, 12 | // see . 13 | 14 | using System; 15 | using System.IO; 16 | using System.Threading; 17 | using UnityEngine; 18 | 19 | namespace MiniAVC 20 | { 21 | public class Addon 22 | { 23 | private readonly AddonSettings settings; 24 | 25 | public Addon(string path, AddonSettings settings) 26 | { 27 | this.settings = settings; 28 | RunProcessLocalInfo(path); 29 | } 30 | 31 | public string Base64String 32 | { 33 | get 34 | { 35 | return LocalInfo.Base64String + RemoteInfo.Base64String; 36 | } 37 | } 38 | 39 | public bool HasError { get; private set; } 40 | 41 | public bool IsCompatible 42 | { 43 | get { return IsLocalReady && LocalInfo.IsCompatible; } 44 | } 45 | 46 | public bool IsIgnored 47 | { 48 | get 49 | { 50 | return settings.IgnoredUpdates.Contains(Base64String); 51 | } 52 | } 53 | 54 | public bool IsLocalReady { get; private set; } 55 | 56 | public bool IsProcessingComplete { get; private set; } 57 | 58 | public bool IsRemoteReady { get; private set; } 59 | 60 | public bool IsUpdateAvailable 61 | { 62 | get { return IsProcessingComplete && LocalInfo.Version != null && RemoteInfo.Version != null && RemoteInfo.Version > LocalInfo.Version && RemoteInfo.IsCompatibleKspVersion && RemoteInfo.IsCompatibleGitHubVersion; } 63 | } 64 | 65 | public AddonInfo LocalInfo { get; private set; } 66 | 67 | public string Name 68 | { 69 | get { return LocalInfo.Name; } 70 | } 71 | 72 | public AddonInfo RemoteInfo { get; private set; } 73 | 74 | public AddonSettings Settings 75 | { 76 | get { return settings; } 77 | } 78 | 79 | public void RunProcessLocalInfo(string file) 80 | { 81 | ThreadPool.QueueUserWorkItem(ProcessLocalInfo, file); 82 | } 83 | 84 | public void RunProcessRemoteInfo() 85 | { 86 | ThreadPool.QueueUserWorkItem(ProcessRemoteInfo); 87 | } 88 | 89 | private void FetchLocalInfo(string path) 90 | { 91 | using (var stream = new StreamReader(File.OpenRead(path))) 92 | { 93 | LocalInfo = new AddonInfo(path, stream.ReadToEnd()); 94 | IsLocalReady = true; 95 | 96 | if (LocalInfo.ParseError) 97 | { 98 | SetHasError(); 99 | } 100 | } 101 | } 102 | 103 | private void FetchRemoteInfo() 104 | { 105 | using (var www = new WWW(Uri.EscapeUriString(LocalInfo.Url))) 106 | { 107 | while (!www.isDone) 108 | { 109 | Thread.Sleep(100); 110 | } 111 | if (www.error == null) 112 | { 113 | SetRemoteInfo(www); 114 | } 115 | else 116 | { 117 | SetLocalInfoOnly(); 118 | } 119 | } 120 | } 121 | 122 | private void ProcessLocalInfo(object state) 123 | { 124 | try 125 | { 126 | var path = (string)state; 127 | if (File.Exists(path)) 128 | { 129 | FetchLocalInfo(path); 130 | RunProcessRemoteInfo(); 131 | } 132 | else 133 | { 134 | Logger.Log("File Not Found: " + path); 135 | SetHasError(); 136 | } 137 | } 138 | catch (Exception ex) 139 | { 140 | Logger.Exception(ex); 141 | SetHasError(); 142 | } 143 | } 144 | 145 | private void ProcessRemoteInfo(object state) 146 | { 147 | try 148 | { 149 | if (settings.FirstRun) 150 | { 151 | return; 152 | } 153 | 154 | if (!settings.AllowCheck || string.IsNullOrEmpty(LocalInfo.Url)) 155 | { 156 | SetLocalInfoOnly(); 157 | return; 158 | } 159 | 160 | FetchRemoteInfo(); 161 | } 162 | catch (Exception ex) 163 | { 164 | Logger.Exception(ex); 165 | SetLocalInfoOnly(); 166 | } 167 | } 168 | 169 | private void SetHasError() 170 | { 171 | HasError = true; 172 | IsProcessingComplete = true; 173 | } 174 | 175 | private void SetLocalInfoOnly() 176 | { 177 | RemoteInfo = LocalInfo; 178 | IsRemoteReady = true; 179 | IsProcessingComplete = true; 180 | Logger.Log(LocalInfo); 181 | Logger.Blank(); 182 | } 183 | 184 | private void SetRemoteInfo(WWW www) 185 | { 186 | RemoteInfo = new AddonInfo(LocalInfo.Url, www.text); 187 | RemoteInfo.FetchRemoteData(); 188 | 189 | if (LocalInfo.Version == RemoteInfo.Version) 190 | { 191 | Logger.Log("Identical remote version found: Using remote version information only."); 192 | Logger.Log(RemoteInfo); 193 | Logger.Blank(); 194 | LocalInfo = RemoteInfo; 195 | } 196 | else 197 | { 198 | Logger.Log(LocalInfo); 199 | Logger.Log(RemoteInfo + "\n\tUpdateAvailable: " + IsUpdateAvailable); 200 | Logger.Blank(); 201 | } 202 | 203 | IsRemoteReady = true; 204 | IsProcessingComplete = true; 205 | } 206 | } 207 | } -------------------------------------------------------------------------------- /MiniAVC/AddonLibrary.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | using System.IO; 23 | using System.Linq; 24 | using System.Threading; 25 | 26 | #endregion 27 | 28 | namespace MiniAVC 29 | { 30 | public static class AddonLibrary 31 | { 32 | #region Fields 33 | 34 | private static List addons; 35 | 36 | #endregion 37 | 38 | #region Constructors 39 | 40 | static AddonLibrary() 41 | { 42 | ThreadPool.QueueUserWorkItem(ProcessAddonPopulation); 43 | } 44 | 45 | #endregion 46 | 47 | #region Properties 48 | 49 | public static List Addons 50 | { 51 | get { return (addons != null) ? addons.Where(a => !a.HasError).ToList() : null; } 52 | } 53 | 54 | public static List AddonsProcessed 55 | { 56 | get { return (addons != null) ? addons.Where(a => !a.HasError && a.IsProcessingComplete).ToList() : null; } 57 | } 58 | 59 | public static bool Populated { get; private set; } 60 | 61 | public static List Settings { get; private set; } 62 | 63 | public static int TotalCount 64 | { 65 | get { return (addons != null) ? addons.Count : 0; } 66 | } 67 | 68 | #endregion 69 | 70 | #region Methods: public 71 | 72 | public static void Remove(Addon addon) 73 | { 74 | if (addons == null) 75 | { 76 | return; 77 | } 78 | 79 | addons.Remove(addon); 80 | } 81 | 82 | #endregion 83 | 84 | #region Methods: private 85 | 86 | private static void ProcessAddonPopulation(object state) 87 | { 88 | try 89 | { 90 | var threadAddons = new List(); 91 | var threadSettings = new List(); 92 | foreach (var rootPath in AssemblyLoader.loadedAssemblies.Where(a => a.name == "MiniAVC").Select(a => Path.GetDirectoryName(a.path))) 93 | { 94 | var settings = AddonSettings.Load(rootPath); 95 | threadSettings.Add(settings); 96 | threadAddons.AddRange(Directory.GetFiles(rootPath, "*.version", SearchOption.AllDirectories).Select(p => new Addon(p, settings)).ToList()); 97 | } 98 | addons = threadAddons; 99 | Settings = threadSettings; 100 | Populated = true; 101 | } 102 | catch (Exception ex) 103 | { 104 | Logger.Exception(ex); 105 | } 106 | } 107 | 108 | #endregion 109 | } 110 | } -------------------------------------------------------------------------------- /MiniAVC/AddonSettings.cs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 CYBUTEK 2 | // 3 | // This program is free software: you can redistribute it and/or modify it under the terms of the GNU 4 | // General Public License as published by the Free Software Foundation, either version 3 of the 5 | // License, or (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 8 | // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | // General Public License for more details. 10 | // 11 | // You should have received a copy of the GNU General Public License along with this program. If not, 12 | // see . 13 | 14 | using System.Collections.Generic; 15 | using System.IO; 16 | using System.Xml.Serialization; 17 | using UnityEngine; 18 | 19 | namespace MiniAVC 20 | { 21 | public class AddonSettings 22 | { 23 | private bool firstRun = true; 24 | 25 | public AddonSettings() { } 26 | 27 | public AddonSettings(string fileName) 28 | { 29 | FileName = fileName; 30 | } 31 | 32 | public bool AllowCheck { get; set; } 33 | 34 | [XmlIgnore] 35 | public string FileName { get; set; } 36 | 37 | public bool FirstRun 38 | { 39 | get { return firstRun; } 40 | set { firstRun = value; } 41 | } 42 | 43 | public List IgnoredUpdates { get; set; } = new List(); 44 | 45 | public static AddonSettings Load(string rootPath) 46 | { 47 | var filePath = Path.Combine(rootPath, "MiniAVC.xml"); 48 | 49 | if (!File.Exists(filePath)) 50 | { 51 | return new AddonSettings(filePath); 52 | } 53 | 54 | AddonSettings settings; 55 | using (var stream = new FileStream(filePath, FileMode.Open)) 56 | { 57 | settings = new XmlSerializer(typeof(AddonSettings)).Deserialize(stream) as AddonSettings; 58 | settings.FileName = filePath; 59 | stream.Close(); 60 | } 61 | return settings; 62 | } 63 | 64 | public void Save() 65 | { 66 | using (var stream = new FileStream(FileName, FileMode.Create)) 67 | { 68 | new XmlSerializer(typeof(AddonSettings)).Serialize(stream, this); 69 | stream.Close(); 70 | } 71 | } 72 | } 73 | } -------------------------------------------------------------------------------- /MiniAVC/FirstRunGui.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Collections.Generic; 22 | 23 | using UnityEngine; 24 | 25 | #endregion 26 | 27 | namespace MiniAVC 28 | { 29 | public class FirstRunGui : MonoBehaviour 30 | { 31 | #region Fields 32 | 33 | private GUIStyle buttonStyle; 34 | private bool hasCentred; 35 | private GUIStyle labelStyle; 36 | private Rect position = new Rect(Screen.width, Screen.height, 0, 0); 37 | private GUIStyle titleStyle; 38 | 39 | #endregion 40 | 41 | #region Properties 42 | 43 | public List Addons { get; set; } 44 | 45 | public AddonSettings Settings { get; set; } 46 | 47 | #endregion 48 | 49 | #region Methods: protected 50 | 51 | protected void Awake() 52 | { 53 | try 54 | { 55 | DontDestroyOnLoad(this); 56 | } 57 | catch (Exception ex) 58 | { 59 | Logger.Exception(ex); 60 | } 61 | Logger.Log("FirstRunGui was created."); 62 | } 63 | 64 | protected void OnDestroy() 65 | { 66 | Logger.Log("FirstRunGui was destroyed."); 67 | } 68 | 69 | protected void OnGUI() 70 | { 71 | try 72 | { 73 | this.position = GUILayout.Window(this.GetInstanceID(), this.position, this.Window, "MiniAVC", HighLogic.Skin.window); 74 | this.CentreWindow(); 75 | } 76 | catch (Exception ex) 77 | { 78 | Logger.Exception(ex); 79 | } 80 | } 81 | 82 | protected void Start() 83 | { 84 | try 85 | { 86 | this.InitialiseStyles(); 87 | } 88 | catch (Exception ex) 89 | { 90 | Logger.Exception(ex); 91 | } 92 | } 93 | 94 | #endregion 95 | 96 | #region Methods: private 97 | 98 | private void CentreWindow() 99 | { 100 | if (this.hasCentred || !(this.position.width > 0) || !(this.position.height > 0)) 101 | { 102 | return; 103 | } 104 | this.position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); 105 | this.hasCentred = true; 106 | } 107 | 108 | private void DrawAddonList() 109 | { 110 | GUILayout.Label("Allow these add-ons to check for updates?", this.titleStyle, GUILayout.Width(300.0f)); 111 | foreach (var addon in this.Addons) 112 | { 113 | GUILayout.Label(addon.Name, this.labelStyle); 114 | } 115 | } 116 | 117 | private void DrawButtonNo() 118 | { 119 | if (!GUILayout.Button("NO", this.buttonStyle)) 120 | { 121 | return; 122 | } 123 | 124 | this.Settings.FirstRun = false; 125 | this.Settings.AllowCheck = false; 126 | this.Settings.Save(); 127 | foreach (var addon in this.Addons) 128 | { 129 | Logger.Log("Remote checking has been disabled for: " + addon.Name); 130 | addon.RunProcessRemoteInfo(); 131 | } 132 | Destroy(this); 133 | } 134 | 135 | private void DrawButtonYes() 136 | { 137 | if (!GUILayout.Button("YES", this.buttonStyle, GUILayout.Width(200.0f))) 138 | { 139 | return; 140 | } 141 | 142 | this.Settings.FirstRun = false; 143 | this.Settings.AllowCheck = true; 144 | this.Settings.Save(); 145 | foreach (var addon in this.Addons) 146 | { 147 | Logger.Log("Remote checking has been enabled for: " + addon.Name); 148 | addon.RunProcessRemoteInfo(); 149 | } 150 | Destroy(this); 151 | } 152 | 153 | private void InitialiseStyles() 154 | { 155 | this.titleStyle = new GUIStyle(HighLogic.Skin.label) 156 | { 157 | normal = 158 | { 159 | textColor = Color.white 160 | }, 161 | fontSize = 13, 162 | fontStyle = FontStyle.Bold, 163 | alignment = TextAnchor.MiddleCenter, 164 | stretchWidth = true 165 | }; 166 | this.labelStyle = new GUIStyle(HighLogic.Skin.label) 167 | { 168 | fontSize = 13, 169 | alignment = TextAnchor.MiddleCenter, 170 | stretchWidth = true 171 | }; 172 | 173 | this.buttonStyle = new GUIStyle(HighLogic.Skin.button) 174 | { 175 | normal = 176 | { 177 | textColor = Color.white 178 | } 179 | }; 180 | } 181 | 182 | private void Window(int id) 183 | { 184 | try 185 | { 186 | GUILayout.BeginVertical(HighLogic.Skin.box); 187 | this.DrawAddonList(); 188 | GUILayout.EndVertical(); 189 | GUILayout.BeginHorizontal(); 190 | this.DrawButtonYes(); 191 | this.DrawButtonNo(); 192 | GUILayout.EndHorizontal(); 193 | GUI.DragWindow(); 194 | } 195 | catch (Exception ex) 196 | { 197 | Logger.Exception(ex); 198 | } 199 | } 200 | 201 | #endregion 202 | } 203 | } -------------------------------------------------------------------------------- /MiniAVC/IssueGui.cs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 CYBUTEK 2 | // 3 | // This program is free software: you can redistribute it and/or modify it under the terms of the GNU 4 | // General Public License as published by the Free Software Foundation, either version 3 of the 5 | // License, or (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 8 | // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | // General Public License for more details. 10 | // 11 | // You should have received a copy of the GNU General Public License along with this program. If not, 12 | // see . 13 | 14 | using System; 15 | 16 | using UnityEngine; 17 | 18 | namespace MiniAVC 19 | { 20 | public class IssueGui : MonoBehaviour 21 | { 22 | private GUIStyle buttonStyle; 23 | private bool hasCentred; 24 | private GUIStyle labelStyle; 25 | private Rect position = new Rect(Screen.width, Screen.height, 0, 0); 26 | private GUIStyle titleStyle; 27 | private ToolTipGui toolTipGui; 28 | 29 | public Addon Addon { get; set; } 30 | 31 | protected void Awake() 32 | { 33 | try 34 | { 35 | DontDestroyOnLoad(this); 36 | } 37 | catch (Exception ex) 38 | { 39 | Logger.Exception(ex); 40 | } 41 | Logger.Log("IssueGui was created."); 42 | } 43 | 44 | protected void OnDestroy() 45 | { 46 | Logger.Log("IssueGui was destroyed."); 47 | } 48 | 49 | protected void OnGUI() 50 | { 51 | try 52 | { 53 | position = GUILayout.Window(GetInstanceID(), position, Window, Addon.Name, HighLogic.Skin.window); 54 | CentreWindow(); 55 | } 56 | catch (Exception ex) 57 | { 58 | Logger.Exception(ex); 59 | } 60 | } 61 | 62 | protected void Start() 63 | { 64 | try 65 | { 66 | InitialiseStyles(); 67 | } 68 | catch (Exception ex) 69 | { 70 | Logger.Exception(ex); 71 | } 72 | } 73 | 74 | private void CentreWindow() 75 | { 76 | if (hasCentred || !(position.width > 0) || !(position.height > 0)) 77 | { 78 | return; 79 | } 80 | position.center = new Vector2(Screen.width * 0.5f, Screen.height * 0.5f); 81 | hasCentred = true; 82 | } 83 | 84 | private void DrawDownloadButton() 85 | { 86 | if (String.IsNullOrEmpty(Addon.RemoteInfo.Download)) 87 | { 88 | return; 89 | } 90 | 91 | if (GUILayout.Button("UPDATE", buttonStyle)) 92 | { 93 | Application.OpenURL(Addon.RemoteInfo.Download); 94 | } 95 | 96 | if (toolTipGui == null) 97 | { 98 | toolTipGui = gameObject.AddComponent(); 99 | } 100 | toolTipGui.Text = GUILayoutUtility.GetLastRect().Contains(Event.current.mousePosition) ? Addon.RemoteInfo.Download : String.Empty; 101 | } 102 | 103 | private void DrawNotCompatible() 104 | { 105 | if (Addon.IsCompatible) 106 | { 107 | return; 108 | } 109 | 110 | GUILayout.BeginVertical(HighLogic.Skin.box); 111 | GUILayout.Label($"Unsupported by KSP v{VersioningBase.GetVersionString()}, please use v{Addon.LocalInfo.KspVersion}.", titleStyle, GUILayout.Width(400.0f)); 112 | GUILayout.EndVertical(); 113 | } 114 | 115 | private void DrawUpdateAvailable() 116 | { 117 | if (!Addon.IsUpdateAvailable) 118 | { 119 | return; 120 | } 121 | 122 | GUILayout.BeginVertical(HighLogic.Skin.box); 123 | GUILayout.Label("AN UPDATE IS AVAILABLE", titleStyle); 124 | GUILayout.BeginHorizontal(); 125 | GUILayout.FlexibleSpace(); 126 | GUILayout.Label("Installed: " + Addon.LocalInfo.Version, labelStyle, GUILayout.Width(150.0f)); 127 | GUILayout.Label("Available: " + Addon.RemoteInfo.Version, labelStyle, GUILayout.Width(150.0f)); 128 | GUILayout.FlexibleSpace(); 129 | GUILayout.EndHorizontal(); 130 | DrawDownloadButton(); 131 | GUILayout.EndVertical(); 132 | } 133 | 134 | private void InitialiseStyles() 135 | { 136 | titleStyle = new GUIStyle(HighLogic.Skin.label) 137 | { 138 | normal = 139 | { 140 | textColor = Color.white 141 | }, 142 | fontSize = 13, 143 | fontStyle = FontStyle.Bold, 144 | alignment = TextAnchor.MiddleCenter, 145 | stretchWidth = true 146 | }; 147 | 148 | labelStyle = new GUIStyle(HighLogic.Skin.label) 149 | { 150 | fontSize = 13, 151 | alignment = TextAnchor.MiddleCenter, 152 | stretchWidth = true 153 | }; 154 | 155 | buttonStyle = new GUIStyle(HighLogic.Skin.button) 156 | { 157 | normal = 158 | { 159 | textColor = Color.white 160 | } 161 | }; 162 | } 163 | 164 | private void Window(int id) 165 | { 166 | try 167 | { 168 | DrawUpdateAvailable(); 169 | DrawNotCompatible(); 170 | 171 | GUILayout.BeginHorizontal(); 172 | if (GUILayout.Button("REMIND ME LATER", buttonStyle)) 173 | { 174 | Destroy(this); 175 | } 176 | if (GUILayout.Button("IGNORE THIS UPDATE", buttonStyle, GUILayout.Width(175f))) 177 | { 178 | Addon.Settings.IgnoredUpdates.Add(Addon.Base64String); 179 | Addon.Settings.Save(); 180 | Destroy(this); 181 | } 182 | GUILayout.EndHorizontal(); 183 | 184 | GUI.DragWindow(); 185 | } 186 | catch (Exception ex) 187 | { 188 | Logger.Exception(ex); 189 | } 190 | } 191 | } 192 | } -------------------------------------------------------------------------------- /MiniAVC/Logger.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Collections; 22 | using System.Collections.Generic; 23 | using System.IO; 24 | using System.Reflection; 25 | 26 | using UnityEngine; 27 | 28 | #endregion 29 | 30 | namespace MiniAVC 31 | { 32 | [KSPAddon(KSPAddon.Startup.Instantly, false)] 33 | public class Logger : MonoBehaviour 34 | { 35 | #region Fields 36 | 37 | private static readonly AssemblyName assemblyName; 38 | private static readonly string fileName; 39 | 40 | private static readonly List messages = new List(); 41 | 42 | #endregion 43 | 44 | #region Constructors 45 | 46 | static Logger() 47 | { 48 | assemblyName = Assembly.GetExecutingAssembly().GetName(); 49 | fileName = assemblyName.Name + ".log"; 50 | File.Delete(fileName); 51 | 52 | messages.Add(new[] {"Executing: " + assemblyName.Name + " - " + assemblyName.Version}); 53 | messages.Add(new[] {"Assembly: " + Assembly.GetExecutingAssembly().Location}); 54 | Blank(); 55 | } 56 | 57 | #endregion 58 | 59 | #region Destructors 60 | 61 | ~Logger() 62 | { 63 | Flush(); 64 | } 65 | 66 | #endregion 67 | 68 | #region Methods: public 69 | 70 | public static void Blank() 71 | { 72 | lock (messages) 73 | { 74 | messages.Add(new string[] {}); 75 | } 76 | } 77 | 78 | public static void Error(string message) 79 | { 80 | lock (messages) 81 | { 82 | messages.Add(new[] {"Error " + DateTime.Now.TimeOfDay, message}); 83 | } 84 | } 85 | 86 | public static void Exception(Exception ex) 87 | { 88 | lock (messages) 89 | { 90 | messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, ex.ToString()}); 91 | Blank(); 92 | } 93 | } 94 | 95 | public static void Exception(Exception ex, string location) 96 | { 97 | lock (messages) 98 | { 99 | messages.Add(new[] {"Exception " + DateTime.Now.TimeOfDay, location + " // " + ex}); 100 | Blank(); 101 | } 102 | } 103 | 104 | public static void Flush() 105 | { 106 | lock (messages) 107 | { 108 | if (messages.Count == 0) 109 | { 110 | return; 111 | } 112 | 113 | using (var file = File.AppendText(fileName)) 114 | { 115 | foreach (var message in messages) 116 | { 117 | file.WriteLine(message.Length > 0 ? message.Length > 1 ? "[" + message[0] + "]: " + message[1] : message[0] : string.Empty); 118 | if (message.Length > 0) 119 | { 120 | print(message.Length > 1 ? assemblyName.Name + " -> " + message[1] : assemblyName.Name + " -> " + message[0]); 121 | } 122 | } 123 | } 124 | messages.Clear(); 125 | } 126 | } 127 | 128 | public static void Log(object obj) 129 | { 130 | lock (messages) 131 | { 132 | try 133 | { 134 | if (obj is IEnumerable) 135 | { 136 | messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, obj.ToString()}); 137 | foreach (var o in obj as IEnumerable) 138 | { 139 | messages.Add(new[] {"\t", o.ToString()}); 140 | } 141 | } 142 | else 143 | { 144 | messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, obj.ToString()}); 145 | } 146 | } 147 | catch (Exception ex) 148 | { 149 | Exception(ex); 150 | } 151 | } 152 | } 153 | 154 | public static void Log(string name, object obj) 155 | { 156 | lock (messages) 157 | { 158 | try 159 | { 160 | if (obj is IEnumerable) 161 | { 162 | messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, name}); 163 | foreach (var o in obj as IEnumerable) 164 | { 165 | messages.Add(new[] {"\t", o.ToString()}); 166 | } 167 | } 168 | else 169 | { 170 | messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, obj.ToString()}); 171 | } 172 | } 173 | catch (Exception ex) 174 | { 175 | Exception(ex); 176 | } 177 | } 178 | } 179 | 180 | public static void Log(string message) 181 | { 182 | lock (messages) 183 | { 184 | messages.Add(new[] {"Log " + DateTime.Now.TimeOfDay, message}); 185 | } 186 | } 187 | 188 | public static void Warning(string message) 189 | { 190 | lock (messages) 191 | { 192 | messages.Add(new[] {"Warning " + DateTime.Now.TimeOfDay, message}); 193 | } 194 | } 195 | 196 | #endregion 197 | 198 | #region Methods: protected 199 | 200 | protected void Awake() 201 | { 202 | DontDestroyOnLoad(this); 203 | } 204 | 205 | protected void LateUpdate() 206 | { 207 | Flush(); 208 | } 209 | 210 | protected void OnDestroy() 211 | { 212 | Flush(); 213 | } 214 | 215 | #endregion 216 | } 217 | } -------------------------------------------------------------------------------- /MiniAVC/MiniAVC.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | AnyCPU 7 | {F1351BAB-76F1-41DE-B01C-496163CB44D8} 8 | Library 9 | Properties 10 | MiniAVC 11 | MiniAVC 12 | v3.5 13 | 512 14 | 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | none 27 | true 28 | ..\Output\MiniAVC\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | ..\..\..\KSP-Environment\KSP_x64_Data\Managed\Assembly-CSharp.dll 50 | False 51 | 52 | 53 | ..\..\Game\KSP_x64_Data\Managed\System.dll 54 | False 55 | 56 | 57 | ..\..\Game\KSP_x64_Data\Managed\System.Xml.dll 58 | False 59 | 60 | 61 | ..\..\..\KSP-Environment\KSP_x64_Data\Managed\UnityEngine.dll 62 | False 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | $(PostBuildEventDependsOn); 77 | PostBuildMacros; 78 | 79 | xcopy "$(SolutionDir)Output\MiniAVC\*" "$(SolutionDir)..\Game\GameData\MiniAVC\*" /E /Y 80 | del "$(SolutionDir)Release\MiniAVC\*" /Q 81 | xcopy "$(SolutionDir)Documents\MiniAVC\*" "$(SolutionDir)Release\MiniAVC\Documents\*" /E /Y 82 | 7z.exe a -tzip -mx3 "$(SolutionDir)Release\MiniAVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Output\MiniAVC" 83 | 7z.exe a -tzip -mx3 "$(SolutionDir)Release\MiniAVC\$(ProjectName)-@(VersionNumber).zip" "$(SolutionDir)Documents\MiniAVC\*" 84 | 85 | 92 | -------------------------------------------------------------------------------- /MiniAVC/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System.Reflection; 21 | using System.Runtime.InteropServices; 22 | 23 | #endregion 24 | 25 | [assembly: AssemblyTitle("MiniAVC")] 26 | [assembly: AssemblyProduct("MiniAVC")] 27 | [assembly: AssemblyCopyright("Copyright © CYBUTEK 2014")] 28 | [assembly: ComVisible(false)] 29 | [assembly: Guid("d3138342-d8a8-4ab3-96e7-e7f086c13212")] 30 | [assembly: AssemblyVersion("1.0.3.3")] -------------------------------------------------------------------------------- /MiniAVC/Starter.cs: -------------------------------------------------------------------------------- 1 | // Copyright (C) 2014 CYBUTEK 2 | // 3 | // This program is free software: you can redistribute it and/or modify it under the terms of the GNU 4 | // General Public License as published by the Free Software Foundation, either version 3 of the 5 | // License, or (at your option) any later version. 6 | // 7 | // This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without 8 | // even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 9 | // General Public License for more details. 10 | // 11 | // You should have received a copy of the GNU General Public License along with this program. If not, 12 | // see . 13 | 14 | #region Using Directives 15 | 16 | using System; 17 | using System.Collections.Generic; 18 | using System.Linq; 19 | 20 | using UnityEngine; 21 | 22 | #endregion Using Directives 23 | 24 | namespace MiniAVC 25 | { 26 | [KSPAddon(KSPAddon.Startup.Instantly, false)] 27 | public class Starter : MonoBehaviour 28 | { 29 | #region Fields 30 | 31 | private static bool alreadyRunning; 32 | private FirstRunGui shownFirstRunGui; 33 | private IssueGui shownIssueGui; 34 | 35 | #endregion Fields 36 | 37 | #region Methods: protected 38 | 39 | protected void Awake() 40 | { 41 | try 42 | { 43 | // Only allow one instance to run. 44 | if (alreadyRunning) 45 | { 46 | Destroy(this); 47 | return; 48 | } 49 | alreadyRunning = true; 50 | 51 | // Unload if KSP-AVC is detected. 52 | if (AssemblyLoader.loadedAssemblies.Any(a => a.name == "KSP-AVC")) 53 | { 54 | Logger.Log("KSP-AVC was detected... Unloading MiniAVC!"); 55 | Destroy(this); 56 | return; 57 | } 58 | } 59 | catch (Exception ex) 60 | { 61 | Logger.Exception(ex); 62 | } 63 | Logger.Log("Starter was created."); 64 | } 65 | 66 | protected void OnDestroy() 67 | { 68 | Logger.Log("Starter was destroyed."); 69 | } 70 | 71 | protected void Update() 72 | { 73 | try 74 | { 75 | // Stop updating if there is already a gui being shown or the addon library has not 76 | // been populated. 77 | if (!AddonLibrary.Populated || this.shownFirstRunGui != null || this.shownIssueGui != null) 78 | { 79 | return; 80 | } 81 | 82 | // Do not show first start if no add-ons were found, or just destroy if all add-ons 83 | // have been processed. 84 | if (AddonLibrary.TotalCount == 0) 85 | { 86 | Destroy(this); 87 | return; 88 | } 89 | 90 | // Create and show first run gui if required. 91 | if (this.CreateFirstRunGui()) 92 | { 93 | return; 94 | } 95 | 96 | // Create and show issue gui if required. 97 | this.CreateIssueGui(); 98 | } 99 | catch (Exception ex) 100 | { 101 | Logger.Exception(ex); 102 | } 103 | } 104 | 105 | #endregion Methods: protected 106 | 107 | #region Methods: private 108 | 109 | private bool CreateFirstRunGui() 110 | { 111 | foreach (var settings in AddonLibrary.Settings.Where(s => s.FirstRun)) 112 | { 113 | this.shownFirstRunGui = this.gameObject.AddComponent(); 114 | this.shownFirstRunGui.Settings = settings; 115 | this.shownFirstRunGui.Addons = AddonLibrary.Addons.Where(a => a.Settings == settings).ToList(); 116 | return true; 117 | } 118 | return false; 119 | } 120 | 121 | private void CreateIssueGui() 122 | { 123 | foreach (var addon in AddonLibrary.AddonsProcessed) 124 | { 125 | if (!addon.HasError && (addon.IsUpdateAvailable || !addon.IsCompatible) && !addon.IsIgnored) 126 | { 127 | this.shownIssueGui = this.gameObject.AddComponent(); 128 | this.shownIssueGui.Addon = addon; 129 | this.shownIssueGui.enabled = true; 130 | AddonLibrary.Remove(addon); 131 | break; 132 | } 133 | AddonLibrary.Remove(addon); 134 | } 135 | } 136 | 137 | #endregion Methods: private 138 | } 139 | } -------------------------------------------------------------------------------- /MiniAVC/ToolTipGui.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | 22 | using UnityEngine; 23 | 24 | #endregion 25 | 26 | namespace MiniAVC 27 | { 28 | public class ToolTipGui : MonoBehaviour 29 | { 30 | #region Fields 31 | 32 | private GUIContent content; 33 | private GUIStyle labelStyle; 34 | private Rect position; 35 | 36 | #endregion 37 | 38 | #region Properties 39 | 40 | public string Text 41 | { 42 | get { return (this.content ?? GUIContent.none).text; } 43 | set { this.content = new GUIContent(value); } 44 | } 45 | 46 | #endregion 47 | 48 | #region Methods: protected 49 | 50 | protected void Awake() 51 | { 52 | try 53 | { 54 | DontDestroyOnLoad(this); 55 | } 56 | catch (Exception ex) 57 | { 58 | Logger.Exception(ex); 59 | } 60 | Logger.Log("ToolTipGui was created."); 61 | } 62 | 63 | protected void OnDestroy() 64 | { 65 | Logger.Log("ToolTipGui was destroyed."); 66 | } 67 | 68 | protected void OnGUI() 69 | { 70 | try 71 | { 72 | if (this.content == null || String.IsNullOrEmpty(this.content.text)) 73 | { 74 | return; 75 | } 76 | 77 | GUILayout.Window(this.GetInstanceID(), this.position, this.Window, String.Empty, GUIStyle.none); 78 | } 79 | catch (Exception ex) 80 | { 81 | Logger.Exception(ex); 82 | } 83 | } 84 | 85 | protected void Start() 86 | { 87 | try 88 | { 89 | this.InitialiseStyles(); 90 | } 91 | catch (Exception ex) 92 | { 93 | Logger.Exception(ex); 94 | } 95 | } 96 | 97 | protected void Update() 98 | { 99 | this.position.size = this.labelStyle.CalcSize(this.content); 100 | this.position.x = Mathf.Clamp(Input.mousePosition.x + 20.0f, 0, Screen.width - this.position.width); 101 | this.position.y = Screen.height - Input.mousePosition.y + (this.position.x < Input.mousePosition.x + 20.0f ? 20.0f : 0); 102 | } 103 | 104 | #endregion 105 | 106 | #region Methods: private 107 | 108 | private static Texture2D GetBackgroundTexture() 109 | { 110 | var background = new Texture2D(1, 1, TextureFormat.ARGB32, false); 111 | background.SetPixel(1, 1, new Color(1.0f, 1.0f, 1.0f, 1.0f)); 112 | background.Apply(); 113 | return background; 114 | } 115 | 116 | private void InitialiseStyles() 117 | { 118 | this.labelStyle = new GUIStyle 119 | { 120 | padding = new RectOffset(4, 4, 2, 2), 121 | normal = 122 | { 123 | textColor = Color.black, 124 | background = GetBackgroundTexture() 125 | }, 126 | fontSize = 11 127 | }; 128 | } 129 | 130 | private void Window(int windowId) 131 | { 132 | try 133 | { 134 | GUI.BringWindowToFront(windowId); 135 | GUILayout.Label(this.content ?? GUIContent.none, this.labelStyle); 136 | } 137 | catch (Exception ex) 138 | { 139 | Logger.Exception(ex); 140 | } 141 | } 142 | 143 | #endregion 144 | } 145 | } -------------------------------------------------------------------------------- /MiniAVC/VersionInfo.cs: -------------------------------------------------------------------------------- 1 | // 2 | // Copyright (C) 2014 CYBUTEK 3 | // 4 | // This program is free software: you can redistribute it and/or modify 5 | // it under the terms of the GNU General Public License as published by 6 | // the Free Software Foundation, either version 3 of the License, or 7 | // (at your option) any later version. 8 | // 9 | // This program is distributed in the hope that it will be useful, 10 | // but WITHOUT ANY WARRANTY; without even the implied warranty of 11 | // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 12 | // GNU General Public License for more details. 13 | // 14 | // You should have received a copy of the GNU General Public License 15 | // along with this program. If not, see . 16 | // 17 | 18 | #region Using Directives 19 | 20 | using System; 21 | using System.Text.RegularExpressions; 22 | 23 | #endregion 24 | 25 | namespace MiniAVC 26 | { 27 | public class VersionInfo : IComparable 28 | { 29 | #region Constructors 30 | 31 | public VersionInfo(long major = 0, long minor = 0, long patch = 0, long build = 0) 32 | { 33 | this.SetVersion(major, minor, patch, build); 34 | } 35 | 36 | public VersionInfo(string version) 37 | { 38 | var sections = Regex.Replace(version, @"[^\d\.]", String.Empty).Split('.'); 39 | 40 | switch (sections.Length) 41 | { 42 | case 1: 43 | this.SetVersion(Int64.Parse(sections[0])); 44 | return; 45 | 46 | case 2: 47 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1])); 48 | return; 49 | 50 | case 3: 51 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2])); 52 | return; 53 | 54 | case 4: 55 | this.SetVersion(Int64.Parse(sections[0]), Int64.Parse(sections[1]), Int64.Parse(sections[2]), Int64.Parse(sections[3])); 56 | return; 57 | 58 | default: 59 | this.SetVersion(); 60 | return; 61 | } 62 | } 63 | 64 | #endregion 65 | 66 | #region Properties 67 | 68 | public static VersionInfo AnyValue 69 | { 70 | get { return new VersionInfo(-1, -1, -1, -1); } 71 | } 72 | 73 | public static VersionInfo MaxValue 74 | { 75 | get { return new VersionInfo(Int64.MaxValue, Int64.MaxValue, Int64.MaxValue, Int64.MaxValue); } 76 | } 77 | 78 | public static VersionInfo MinValue 79 | { 80 | get { return new VersionInfo(); } 81 | } 82 | 83 | public bool Any 84 | { 85 | get { return this.Major == -1 && this.Minor == -1 && this.Patch == -1 && this.Build == -1; } 86 | } 87 | 88 | public long Build { get; set; } 89 | 90 | public long Major { get; set; } 91 | 92 | public long Minor { get; set; } 93 | 94 | public long Patch { get; set; } 95 | 96 | #endregion 97 | 98 | #region Operators 99 | 100 | public static bool operator ==(VersionInfo v1, VersionInfo v2) 101 | { 102 | return Equals(v1, v2); 103 | } 104 | 105 | public static bool operator >(VersionInfo v1, VersionInfo v2) 106 | { 107 | return v1.CompareTo(v2) > 0; 108 | } 109 | 110 | public static bool operator >=(VersionInfo v1, VersionInfo v2) 111 | { 112 | return v1.CompareTo(v2) >= 0; 113 | } 114 | 115 | public static implicit operator Version(VersionInfo version) 116 | { 117 | return new Version(Convert.ToInt32(version.Major), Convert.ToInt32(version.Minor), Convert.ToInt32(version.Patch), Convert.ToInt32(version.Build)); 118 | } 119 | 120 | public static implicit operator VersionInfo(Version version) 121 | { 122 | return new VersionInfo(version.Major, version.Minor, version.Build, version.Revision); 123 | } 124 | 125 | public static bool operator !=(VersionInfo v1, VersionInfo v2) 126 | { 127 | return !Equals(v1, v2); 128 | } 129 | 130 | public static bool operator <(VersionInfo v1, VersionInfo v2) 131 | { 132 | return v1.CompareTo(v2) < 0; 133 | } 134 | 135 | public static bool operator <=(VersionInfo v1, VersionInfo v2) 136 | { 137 | return v1.CompareTo(v2) <= 0; 138 | } 139 | 140 | #endregion 141 | 142 | #region Methods: public 143 | 144 | public int CompareTo(object obj) 145 | { 146 | if (obj == null) 147 | { 148 | return 1; 149 | } 150 | 151 | var other = obj as VersionInfo; 152 | if (other == null) 153 | { 154 | throw new ArgumentException("Not a VersionInfo object."); 155 | } 156 | 157 | if (this.Major != -1 && other.Major != -1) 158 | { 159 | var major = this.Major.CompareTo(other.Major); 160 | if (major != 0) 161 | { 162 | return major; 163 | } 164 | } 165 | 166 | if (this.Minor != -1 && other.Minor != -1) 167 | { 168 | var minor = this.Minor.CompareTo(other.Minor); 169 | if (minor != 0) 170 | { 171 | return minor; 172 | } 173 | } 174 | 175 | if (this.Patch != -1 && other.Patch != -1) 176 | { 177 | var patch = this.Patch.CompareTo(other.Patch); 178 | if (patch != 0) 179 | { 180 | return patch; 181 | } 182 | } 183 | 184 | if (this.Build != -1 && other.Build != -1) 185 | { 186 | var build = this.Build.CompareTo(other.Build); 187 | if (build != 0) 188 | { 189 | return build; 190 | } 191 | } 192 | 193 | return 0; 194 | } 195 | 196 | public override bool Equals(object obj) 197 | { 198 | if (ReferenceEquals(null, obj)) 199 | { 200 | return false; 201 | } 202 | if (ReferenceEquals(this, obj)) 203 | { 204 | return true; 205 | } 206 | return obj.GetType() == this.GetType() && this.Equals((VersionInfo)obj); 207 | } 208 | 209 | public override int GetHashCode() 210 | { 211 | unchecked 212 | { 213 | var hashCode = this.Major.GetHashCode(); 214 | hashCode = (hashCode * 397) ^ this.Minor.GetHashCode(); 215 | hashCode = (hashCode * 397) ^ this.Patch.GetHashCode(); 216 | hashCode = (hashCode * 397) ^ this.Build.GetHashCode(); 217 | return hashCode; 218 | } 219 | } 220 | 221 | public void SetVersion(long major = 0, long minor = 0, long patch = 0, long build = 0) 222 | { 223 | this.Major = major; 224 | this.Minor = minor; 225 | this.Patch = patch; 226 | this.Build = build; 227 | } 228 | 229 | public override string ToString() 230 | { 231 | if (this.Any) 232 | { 233 | return "Any"; 234 | } 235 | 236 | if (this.Build > 0) 237 | { 238 | return String.Format("{0}.{1}.{2}.{3}", this.Major, this.Minor, this.Patch, this.Build); 239 | } 240 | return this.Patch > 0 ? String.Format("{0}.{1}.{2}", this.Major, this.Minor, this.Patch) : String.Format("{0}.{1}", this.Major, this.Minor).Replace("-1", "*"); 241 | } 242 | 243 | #endregion 244 | 245 | #region Methods: protected 246 | 247 | protected bool Equals(VersionInfo other) 248 | { 249 | return (this.Major == -1 || other.Major == -1 || this.Major.Equals(other.Major)) && 250 | (this.Minor == -1 || other.Minor == -1 || this.Minor.Equals(other.Minor)) && 251 | (this.Patch == -1 || other.Patch == -1 || this.Patch.Equals(other.Patch)) && 252 | (this.Build == -1 || other.Build == -1 || this.Build.Equals(other.Build)); 253 | } 254 | 255 | #endregion 256 | } 257 | } -------------------------------------------------------------------------------- /Output/AVCToolkit/AVCToolkit.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/AVCToolkit/AVCToolkit.exe -------------------------------------------------------------------------------- /Output/KSP-AVC/KSP-AVC.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/KSP-AVC.dll -------------------------------------------------------------------------------- /Output/KSP-AVC/KSP-AVC.version: -------------------------------------------------------------------------------- 1 | { 2 | "NAME":"KSP-AVC Plugin", 3 | "URL":"http://ksp-avc.cybutek.net/version.php?id=2", 4 | "VERSION": 5 | { 6 | "MAJOR":1, 7 | "MINOR":1, 8 | "PATCH":6, 9 | "BUILD":2 10 | }, 11 | "KSP_VERSION": 12 | { 13 | "MAJOR":1, 14 | "MINOR":2, 15 | "PATCH":0 16 | } 17 | } -------------------------------------------------------------------------------- /Output/KSP-AVC/Textures/DropDownActive.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/Textures/DropDownActive.png -------------------------------------------------------------------------------- /Output/KSP-AVC/Textures/DropDownBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/Textures/DropDownBackground.png -------------------------------------------------------------------------------- /Output/KSP-AVC/Textures/DropDownHover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/Textures/DropDownHover.png -------------------------------------------------------------------------------- /Output/KSP-AVC/Textures/DropDownNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/Textures/DropDownNormal.png -------------------------------------------------------------------------------- /Output/KSP-AVC/Textures/DropDownOnHover.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/Textures/DropDownOnHover.png -------------------------------------------------------------------------------- /Output/KSP-AVC/Textures/DropDownOnNormal.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/Textures/DropDownOnNormal.png -------------------------------------------------------------------------------- /Output/KSP-AVC/Textures/OverlayBackground.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/KSP-AVC/Textures/OverlayBackground.png -------------------------------------------------------------------------------- /Output/MiniAVC/MiniAVC.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/CYBUTEK/KSPAddonVersionChecker/5f0c5e8a1f66cc3cde4d2c4b439f7364748a33da/Output/MiniAVC/MiniAVC.dll --------------------------------------------------------------------------------