ModWorker.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Drawing;
  4. using System.IO;
  5. using System.IO.Compression;
  6. using System.Linq;
  7. using System.Security.Cryptography;
  8. using System.Text;
  9. using System.Threading.Tasks;
  10. using Newtonsoft.Json.Linq;
  11. namespace FactorioModManager
  12. {
  13. public class ModWorker
  14. {
  15. public class Mod
  16. {
  17. public enum Availability
  18. {
  19. Required,
  20. Banned,
  21. Optional
  22. }
  23. public bool Enabled { get; set; } = true;
  24. public string Name { get;}
  25. public string Title { get; private set; }
  26. public Version Version { get; }
  27. public string Author { get; }
  28. public string Contact { get; }
  29. public string WebSite { get; }
  30. public string Description { get; private set; }
  31. public Version FactorioVersion { get; }
  32. public Image Thumbnail { get; set; }
  33. public bool Deletable { get; private set; } = true;
  34. public List<string> DependenciesModNames { get
  35. {
  36. List<string> val = new List<string>();
  37. for(int i = 0; i < Dependencies.Count; i++)
  38. {
  39. string dep = Dependencies.Keys.ElementAt(i);
  40. string mod = "";
  41. for(int j = 0; j < dep.Length; j++)
  42. {
  43. if(Char.IsLetterOrDigit(dep[j]) || dep[j] == '_' || dep[j] == '-')
  44. {
  45. mod += dep[j];
  46. }
  47. if (dep[j] == '>' || dep[j] == '<') break;
  48. }
  49. val.Add(mod);
  50. }
  51. return val;
  52. } }
  53. public Dictionary<string, Availability> Dependencies { get; } = new Dictionary<string, Availability>();
  54. public static Mod CreateSimple(string name, string title,bool enabled)
  55. {
  56. JObject json = new JObject()
  57. {
  58. {"name", name},
  59. {"title", title},
  60. {"version", "0.0.1" },
  61. {"factorio_version", "2.0" }
  62. };
  63. Mod mod = new Mod(json);
  64. mod.Enabled = enabled;
  65. mod.Deletable = false;
  66. return mod;
  67. }
  68. public Mod(JObject json)
  69. {
  70. if (json == null) return;
  71. if (json.ContainsKey("name")) Name = (string)json["name"];
  72. if (json.ContainsKey("version")) Version = new Version((string)json["version"]);
  73. if (json.ContainsKey("factorio_version")) FactorioVersion = new Version((string)json["factorio_version"]);
  74. if (json.ContainsKey("title")) Title = (string)json["title"];
  75. if (json.ContainsKey("author")) Author = (string)json["author"];
  76. if (json.ContainsKey("contact")) Contact = (string)json["contact"];
  77. if (json.ContainsKey("homepage")) WebSite = (string)json["homepage"];
  78. if (json.ContainsKey("description")) Description = (string)json["description"];
  79. if (json.ContainsKey("dependencies")) {
  80. JArray deps = (JArray)json["dependencies"];
  81. for(int i = 0; i < deps.Count; i++)
  82. {
  83. string data = deps[i].ToString();
  84. if (!data.Contains("base"))
  85. {
  86. Availability availability = Availability.Required;
  87. if (data.Contains("?"))
  88. {
  89. availability = Availability.Optional;
  90. }
  91. else if(data.Contains("!"))
  92. {
  93. availability = Availability.Banned;
  94. }
  95. Dependencies.Add(data, availability);
  96. }
  97. }
  98. }
  99. }
  100. public void SetLocalizedTitle(string Title)
  101. {
  102. this.Title = Title;
  103. }
  104. public void SetLocalizedDescription(string Description)
  105. {
  106. this.Description = Description;
  107. }
  108. }
  109. public delegate void OnModsLoaded();
  110. public OnModsLoaded ModsLoaded;
  111. public string WorkDir { get; set; } = @"data\mods";
  112. public F_API API { get; set; } = null;
  113. public List<Mod> InstalledMods { get; } = new List<Mod>();
  114. public List<Mod> UpdatebleMods { get; } = new List<Mod>();
  115. public static readonly string[] DLC_MODS =
  116. {
  117. "space-age",
  118. "elevated-rails",
  119. "quality"
  120. };
  121. public ModWorker()
  122. {
  123. CheckDirSize();
  124. }
  125. public void LoadModList()
  126. {
  127. InstalledMods.Clear();
  128. if (!String.IsNullOrEmpty(Settings.GamePath))
  129. {
  130. string[] files = Directory.GetFiles(Settings.GamePath);
  131. foreach(string mod in files)
  132. {
  133. if (mod.EndsWith(".zip"))
  134. {
  135. Mod jMod = null;
  136. StreamReader sr = new StreamReader(mod);
  137. using (ZipArchive archive = new ZipArchive(sr.BaseStream))
  138. {
  139. string modname = archive.Entries[0].FullName.Substring(0, archive.Entries[0].FullName.IndexOf('/') + 1);
  140. for (int i = 0; i < archive.Entries.Count; i++)
  141. {
  142. string path = archive.Entries[i].FullName;
  143. if (archive.Entries[i].FullName == modname + "info.json")
  144. {
  145. StreamReader ssr = new StreamReader(archive.Entries[i].Open());
  146. jMod = new Mod(JObject.Parse(ssr.ReadToEnd()));
  147. ssr.Close();
  148. break;
  149. }
  150. }
  151. for (int i = 0; i < archive.Entries.Count; i++)
  152. {
  153. if (archive.Entries[i].FullName.StartsWith(modname + "locale/" + Settings.LastLanguage + "/") && archive.Entries[i].FullName.EndsWith(".cfg"))
  154. {
  155. StreamReader ssr = new StreamReader(archive.Entries[i].Open());
  156. string content = ssr.ReadToEnd();
  157. ssr.Close();
  158. string[] lines = content.Split('\n');
  159. for (int j = 0; j < lines.Length; j++)
  160. {
  161. lines[j] = lines[j].Trim();
  162. if (lines[j].Equals("[mod-name]"))
  163. {
  164. jMod.SetLocalizedTitle(lines[j + 1].Split('=')[1].Replace("\\n","\n").Replace("\\t", "\t"));
  165. }
  166. if (lines[j].Equals("[mod-description]"))
  167. {
  168. jMod.SetLocalizedDescription(lines[j + 1].Split('=')[1].Replace("\\n", "\n").Replace("\\t", "\t"));
  169. }
  170. }
  171. }
  172. if(archive.Entries[i].FullName.StartsWith(modname+ "thumbnail."))
  173. {
  174. jMod.Thumbnail = Image.FromStream(archive.Entries[i].Open());
  175. }
  176. }
  177. }
  178. sr.Close();
  179. InstalledMods.Add(jMod);
  180. }
  181. }
  182. string[] folders = Directory.GetDirectories(Settings.GamePath);
  183. foreach (string folder in folders)
  184. {
  185. Version v;
  186. if(folder.Contains("_") && Version.TryParse(folder.Substring(folder.LastIndexOf("_") + 1),out v))
  187. {
  188. }
  189. }
  190. StreamReader srr = new StreamReader(Path.Combine(Settings.GamePath, "mod-list.json"));
  191. JObject jlist = JObject.Parse(srr.ReadToEnd());
  192. srr.Close();
  193. JArray list = (JArray)jlist["mods"];
  194. for(int i = 0; i < list.Count; i++)
  195. {
  196. string name = (string)((JObject)list[i])["name"];
  197. bool enabled = (bool)((JObject)list[i])["enabled"];
  198. if (DLC_MODS.Contains(name))
  199. {
  200. InstalledMods.Insert(0, Mod.CreateSimple(name,name,enabled));
  201. }
  202. int id = InstalledMods.FindIndex(x => x.Name == name);
  203. if (id != -1) InstalledMods[id].Enabled = enabled;
  204. }
  205. }
  206. //InstalledMods.Sort((x, y) => x.Title.CompareTo(y.Title));
  207. ModsLoaded?.Invoke();
  208. }
  209. public void CheckDirSize()
  210. {
  211. string dir = Path.Combine(Directory.GetCurrentDirectory(), WorkDir);
  212. Directory.CreateDirectory(dir);
  213. long size = new DirectoryInfo(dir).EnumerateFiles().Sum(file => file.Length);
  214. double sizeInMb = size / 1024 / 1024;
  215. if (sizeInMb > 500)
  216. {
  217. List<FileInfo> files = new DirectoryInfo(dir).EnumerateFiles().ToList();
  218. foreach(FileInfo file in files){
  219. File.Delete(file.FullName);
  220. }
  221. }
  222. }
  223. public string GetModList(bool enabledOnly = false)
  224. {
  225. JObject json = new JObject();
  226. JArray list = new JArray();
  227. List<Mod> mods = (enabledOnly) ? InstalledMods.Where(x=>x.Enabled).ToList() : InstalledMods;
  228. foreach (Mod mod in mods)
  229. {
  230. list.Add(new JObject()
  231. {
  232. {"name", mod.Name},
  233. {"enabled", mod.Enabled}
  234. });
  235. }
  236. json.Add("mods", list);
  237. return json.ToString();
  238. }
  239. }
  240. }