ModWorker.cs 11 KB

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