// You know the rules and so do I // A full commitment's what I'm thinking of // You wouldn't get this from any other guy // I just wanna tell you how I'm feeling // Gotta make you understand // Never gonna give you up // Never gonna let you down // Never gonna run around and desert you // Never gonna make you cry // Never gonna say goodbye // Never gonna tell a lie and hurt you void ReadRulesFromFile(string rulePath) { try { string[] content = File.ReadAllLines(rulePath).Where(s => s.Length > 0 && !s.StartsWith("##")).ToArray(); string fileName = Path.GetFileName(rulePath); int lines = File.ReadAllLines(rulePath).Where(s => s.StartsWith("##")).ToArray().Length; int currentLine = 0; foreach (string s in content) { lines++; currentLine++; string[] splitted = s.Split(':'); // Read flag and rules. string flag = splitted[0]; string[] objects = new string[0]; if (splitted.Length > 1) { // Support for object names that have space in it, using quotation mark, instead of using %20. if (splitted[1].Contains("\"")) { // Check if there is an odd number of quotation marks. if (splitted[1].Count(f => f == '\"') % 2 != 0) { ModConsole.LogError($"[MOP] Quote hasn't been closed properly: {s} in rule file {fileName}({lines})."); continue; } splitted[1] = Regex.Match(splitted[1], "\"[^\"]*\"").Value.Replace(" ", "%20").Replace("\"", ""); } // Split all objects with space char. objects = splitted[1].Trim().Split(' '); // Replace the %20 in object names to space. for (int i = 0; i < objects.Length; i++) { objects[i] = objects[i].Replace("%20", " "); } } if (objects.Length > 0 && objects.ContainsAny(illegalValues)) { ModConsole.LogError($"[MOP] Illegal object: {objects[0]} in rule file {fileName}."); continue; } // Apply these rules switch (flag) { default: ModConsole.LogError($"[MOP] Unrecognized flag '{flag}' in {fileName} ({lines})."); break; case "ignore": // Ignore at place bool fullIgnore = false; if (objects.Length > 1) { if (objects[1].ToLower() == "fullignore") { fullIgnore = true; } else { RulesManager.Instance.IgnoreRulesAtPlaces.Add(new IgnoreRuleAtPlace(objects[0], objects[1])); break; } } // Disabling some of the root object is pointless, so we inform abot that the user. RulesManager.Instance.IgnoreRules.Add(new IgnoreRule(objects[0], fullIgnore)); break; case "ignore_full": ObsoleteWarning(flag, fileName, lines, s, "ignore: <object_name> fullIgnore"); RulesManager.Instance.IgnoreRules.Add(new IgnoreRule(objects[0], true)); break; case "toggle": ToggleModes mode = ToggleModes.Simple; if (objects.Length > 1) { switch (objects[1]) { default: ModConsole.LogError($"[MOP] Unrecognized method '{objects[1]}' in {fileName} ({lines})."); break; case "renderer": mode = ToggleModes.Renderer; break; case "item": mode = ToggleModes.Item; break; case "vehicle": mode = ToggleModes.Vehicle; break; case "vehicle_physics": mode = ToggleModes.VehiclePhysics; break; } } RulesManager.Instance.ToggleRules.Add(new ToggleRule(objects[0], mode)); break; case "satsuma_ignore_renderer": RulesManager.Instance.SpecialRules.SatsumaIgnoreRenderers = true; break; case "dont_destroy_empty_beer_bottles": ObsoleteWarning(flag, fileName, lines, s, "dont_destroy_empty_bottles"); RulesManager.Instance.SpecialRules.DontDestroyEmptyBeerBottles = true; break; case "dont_destroy_empty_bottles": RulesManager.Instance.SpecialRules.DontDestroyEmptyBeerBottles = true; break; case "sector": Vector3 pos = ParseToVector3(objects[0]); Vector3 scale = ParseToVector3(objects[1]); Vector3 rot = ParseToVector3(objects[2]); string[] whitelist = GetWhitelist(objects); RulesManager.Instance.NewSectors.Add(new NewSector(pos, scale, rot, whitelist)); break; case "min_ver": if (fileName == CustomFile) { break; } if (currentLine != 1) { ModConsole.Log($"\n=================================" + $"\n\n<color=cyan>[MOP] Flag '{flag}' must be first in the order!\n\n" + $"File: {fileName}\n" + $"Line: {lines}\n" + $"You can ignore that message.</color>"); } int major, minor, revision = 0; string[] verSplitted = objects[0].Split('.'); major = int.Parse(verSplitted[0]); minor = int.Parse(verSplitted[1]); if (verSplitted.Length == 3) { revision = int.Parse(verSplitted[2]); } int modMajor, modMinor, modRevision = 0; string[] modVersionSpliited = MOP.ModVersionShort.Split('.'); modMajor = int.Parse(modVersionSpliited[0]); modMinor = int.Parse(modVersionSpliited[1]); if (modVersionSpliited.Length == 3) { modRevision = int.Parse(modVersionSpliited[2]); } bool isOutdated = false; if (major > modMajor) { isOutdated = true; } else { if (minor > modMinor && major == modMajor) { isOutdated = true; } else { if (revision > modRevision && minor == modMinor && major == modMajor) { isOutdated = true; } } } if (isOutdated) { ModConsole.LogError($"[MOP] Rule file {fileName} is for the newer version of MOP. Please update MOP right now!\n\n" + $"Your MOP version: {modMajor}.{modMinor}.{modRevision}\n" + $"Required version: {major}.{minor}.{revision}"); return; } break; // Custom.txt exclusives. case "ignore_mod_vehicles": if (fileName != CustomFile) { ModConsole.LogError($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } RulesManager.Instance.SpecialRules.IgnoreModVehicles = true; break; case "toggle_all_vehicles_physics_only": if (fileName != CustomFile) { ModConsole.LogError($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } RulesManager.Instance.SpecialRules.ToggleAllVehiclesPhysicsOnly = true; break; } } } catch (Exception ex) { ModConsole.LogError($"[MOP] Error loading rule {Path.GetFileName(rulePath)}: {ex}."); NewMessage($"<color=red>MOP: Error loading rule :("); } }
public ToggleRule(string ObjectName, ToggleModes ToggleMode) { this.ObjectName = ObjectName; this.ToggleMode = ToggleMode; }
// You know the rules and so do I // A full commitment's what I'm thinking of // You wouldn't get this from any other guy // I just wanna tell you how I'm feeling // Gotta make you understand // Never gonna give you up // Never gonna let you down // Never gonna run around and desert you // Never gonna make you cry // Never gonna say goodbye // Never gonna tell a lie and hurt you void ReadRulesFromFile(string rulePath) { try { string[] content = File.ReadAllLines(rulePath).Where(s => s.Length > 0 && !s.StartsWith("##")).ToArray(); string fileName = Path.GetFileName(rulePath); int lines = File.ReadAllLines(rulePath).Where(s => s.StartsWith("##")).ToArray().Length; int currentLine = 0; foreach (string s in content) { lines++; currentLine++; string[] splitted = s.Split(':'); // Read flag and rules. string flag = splitted[0]; string[] objects = new string[0]; if (splitted.Length > 1) { objects = splitted[1].Trim().Split(' '); for (int i = 0; i < objects.Length; i++) { objects[i] = objects[i].Replace("%20", " "); } } if (objects.Length > 0 && objects.ContainsAny(illegalValues)) { ModConsole.Error($"[MOP] Illegal object: {objects[0]} in rule file {fileName}."); continue; } // Apply these rules switch (flag) { default: ModConsole.Error($"[MOP] Unrecognized flag '{flag}' in {fileName} ({lines})."); break; case "ignore": // Ignore at place if (objects.Length > 1) { Rules.instance.IgnoreRulesAtPlaces.Add(new IgnoreRuleAtPlace(objects[0], objects[1])); break; } Rules.instance.IgnoreRules.Add(new IgnoreRule(objects[0], false)); break; case "ignore_full": Rules.instance.IgnoreRules.Add(new IgnoreRule(objects[0], true)); break; case "toggle": ToggleModes mode = ToggleModes.Normal; if (objects.Length > 1) { switch (objects[1]) { default: ModConsole.Error($"[MOP] Unrecognized method '{objects[1]}' in {fileName} ({lines})."); break; case "renderer": mode = ToggleModes.Renderer; break; case "item": mode = ToggleModes.Item; break; case "vehicle": mode = ToggleModes.Vehicle; break; case "vehicle_physics": mode = ToggleModes.VehiclePhysics; break; } } Rules.instance.ToggleRules.Add(new ToggleRule(objects[0], mode)); break; case "satsuma_ignore_renderer": Rules.instance.SpecialRules.SatsumaIgnoreRenderers = true; break; case "dont_destroy_empty_beer_bottles": Rules.instance.SpecialRules.DontDestroyEmptyBeerBottles = true; break; case "sector": Vector3 pos = ParseToVector3(objects[0]); Vector3 scale = ParseToVector3(objects[1]); Vector3 rot = ParseToVector3(objects[2]); string[] whitelist = GetWhitelist(objects); Rules.instance.NewSectors.Add(new NewSector(pos, scale, rot, whitelist)); break; case "min_ver": if (fileName == "Custom.txt") { break; } if (currentLine != 1) { ModConsole.Print($"\n=================================" + $"\n\n<color=cyan>[MOP] Flag '{flag}' must be first in the order!\n\n" + $"File: {fileName}\n" + $"Line: {lines}\n" + $"You can ignore that message.</color>"); } int major, minor, revision = 0; string[] verSplitted = objects[0].Split('.'); major = int.Parse(verSplitted[0]); minor = int.Parse(verSplitted[1]); if (verSplitted.Length == 3) { revision = int.Parse(verSplitted[2]); } int modMajor, modMinor, modRevision = 0; string[] modVersionSpliited = MOP.ModVersion.Split('.'); modMajor = int.Parse(modVersionSpliited[0]); modMinor = int.Parse(modVersionSpliited[1]); if (modVersionSpliited.Length == 3) { modRevision = int.Parse(modVersionSpliited[2]); } bool isOutdated = false; if (major > modMajor) { isOutdated = true; } else { if (minor > modMinor && major == modMajor) { isOutdated = true; } else { if (revision > modRevision && minor == modMinor && major == modMajor) { isOutdated = true; } } } if (isOutdated) { ModConsole.Error($"[MOP] Rule file {fileName} is for the newer version of MOP. Please update MOP right now!\n\n" + $"Your MOP version: {modMajor}.{modMinor}.{modRevision}\n" + $"Required version: {major}.{minor}.{revision}"); return; } break; // Custom.txt exclusives. case "ignore_mod_vehicles": if (fileName != "Custom.txt") { ModConsole.Error($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } Rules.instance.SpecialRules.IgnoreModVehicles = true; break; case "toggle_all_vehicles_physics_only": if (fileName != "Custom.txt") { ModConsole.Error($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } Rules.instance.SpecialRules.ToggleAllVehiclesPhysicsOnly = true; break; case "experimental_driveway_sector": if (fileName != "Custom.txt") { ModConsole.Error($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } Rules.instance.SpecialRules.DrivewaySector = true; break; case "experimental_satsuma_trunk": if (fileName != "Custom.txt") { ModConsole.Error($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } Rules.instance.SpecialRules.ExperimentalSatsumaTrunk = true; break; case "experimental_optimization": if (fileName != "Custom.txt") { ModConsole.Error($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } Rules.instance.SpecialRules.ExperimentalOptimization = true; break; case "experimental_save_optimization": if (fileName != "Custom.txt") { ModConsole.Error($"[MOP] Flag: {flag} is only allowed to be used in custom rule file."); continue; } Rules.instance.SpecialRules.ExperimentalSaveOptimization = true; break; } } } catch (Exception ex) { ModConsole.Error($"[MOP] Error loading rule {Path.GetFileName(rulePath)}: {ex}."); NewMessage($"<color=red>MOP: Error loading rule :("); } }