using System; using System.Globalization; using System.IO; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Text; namespace IdleMafiaBot { enum JobMode { BestXp = 0, Mastery = 1, OneJob = 2 } enum Focus { Balanced = 0, XP = 1, Money = 2, Family = 3 } enum TrainOrder { Best = 0, Evenly = 1 } enum OtherDeviceWait { Off = 0, M15 = 15, M30 = 30, H1 = 60, H2 = 120 } sealed class Settings { public bool Jobs = true; public JobMode JobMode = JobMode.BestXp; public string OneJob = ""; public bool Heists = true; public bool HeistsFamilyOnly = false; public bool StartHeists = false; public string StartHeist = "Grand Vault of Caldera"; public string HeistsToday = ""; public bool WouldHelp(bool yourFamily, int xpPerHelp, double jobXpForHelp) { if (yourFamily) return true; return !HeistsFamilyOnly && xpPerHelp > 0 && xpPerHelp > jobXpForHelp; } public bool Fights = Program.Whale; public bool WarTargetsOnly = true; public bool ScoutFights = !Program.Whale; public int FightWinChance = 90; public static readonly int[] WinChances = { 95, 90, 75 }; public static readonly string[] WinChanceNames = { "Sure wins", "Likely wins", "Close fights" }; public static int WinChanceStep(int chance) { return WinChances.OrderBy(c => Math.Abs(c - chance)).ThenByDescending(c => c).First(); } public static string WinChanceName(int chance) { return WinChanceNames[Array.IndexOf(WinChances, WinChanceStep(chance))]; } public bool OnlyFightsSpendAll = false; public bool WhaleHunt = Program.Whale; public bool RememberPlayers = true; public long WhaleCash = Program.Whale ? 5000000000 : 100000000; public static readonly long[] WhaleAmounts = { 100000, 1000000, 10000000, 100000000, 1000000000, 5000000000, 10000000000, 100000000000 }; public int WhaleHits = 5; public const int WhaleHitsMax = 20; public int WhaleHitsNow { get { return Math.Max(1, Math.Min(WhaleHitsMax, WhaleHits)); } } public long BigPayerCash = 100000000; public int FightStaminaReserve = 15; public string NeverAttack = ""; public string AttackFirst = ""; public bool Bosses = true; public bool BossWeakestFirst = true; public static readonly string[] Retired = { "FightLowHealth", "FamilyDistrictsAt", "RobloxUsers", "Theme", "BossHitsPerRound", "FightsPerRound", "SpecificJob", "MasteryTarget", "CrewTarget", "CrewKeepGoing", "OpenNewCities", "HeistMinXp", "HeistsFamilyFirst", "FightMinHealth", "FightTarget", "BankMinutes", "BankWithFee", "WithdrawForPurchases", "OpsCollect", "OpsStart", "OpsName", "ShopMaxPrice", "ShopGold", "Collection", "CrewSort", "StaminaKeepPct", "IdleSeconds", "ShopForbidden", "ShopBankForbidden", "ShopCommon", "ShopUncommon", "ShopRare", "ShopEpic", "ShopLegendary", "ShopMythic", "ShopSecret", "ShopBankMythic", "ShopBankSecret", "ShopPingMythic", "ShopPingSecret", "ShopPingForbidden", "ShopMaxCommon", "ShopMaxUncommon", "ShopMaxRare", "ShopMaxEpic", "ShopMaxLegendary", "ShopMaxMythic", "ShopMaxSecret", "ShopGoldEpic", "ShopGoldLegendary", "ShopGoldMythic", "ShopGoldSecret", "ShopGoldForbidden", "ShopGoldMaxEpic", "ShopGoldMaxLegendary", "ShopGoldMaxMythic", "ShopGoldMaxSecret", "ShopGoldMaxForbidden", "ShopReserve", "ShopBudget", "ShopSpent", "ShopSpentDay" }; public bool Bank = true; public long BankAt = 0; public static readonly long[] BankAts = { 0, 1000000000, 5000000000, 10000000000, 50000000000, 100000000000, 500000000000 }; public bool Operations = true; public string OperationOnly = ""; public bool Playtime = true; public bool Contracts = true; public bool Crates = true; public bool Briefcases = true; public bool TrickOrTreat = false; public bool Events = true; public bool GlobalBoss = true; public bool GlobalBossConsumables = false; public string CratesOpenedAt = ""; public bool ShopBuy = true; public bool ShopWithdraw = true; public int ShopBankFrom = (int)Rarity.Mythic; public long ShopCashMax = 50000000000; public static readonly long[] ShopCashMaxes = { 0, 1000000, 100000000, 1000000000, 50000000000, 500000000000, 1000000000000, 5000000000000, 20000000000000, 50000000000000 }; public static readonly long[] ShopGoldMaxes = { 0, 10, 20, 40, 500, 1000, 5000 }; public int ShopGoldMax = 0; public bool ShopCashFor(double price) { return ShopCashMax <= 0 || price <= ShopCashMax; } public bool ShopBankFor(int rarity) { return ShopWithdraw && rarity >= ShopBankFrom; } public bool EquipBest = true; public bool MarketRelist = false; public static readonly bool MarketRelistShown = true; public int MarketMinutes = 30; public const int MarketMinutesLeast = 30; public string MarketPending = ""; public string MarketCheckUndone = ""; public bool Properties = true; public int GoldLots = 0; public string PropertyOnly = ""; public string PropertySeen = ""; public bool SafehouseUpgrade = true; public bool Animals = true; public bool AnimalFeed = true; public bool AnimalPremium = false; public bool AnimalTrain = true; public bool AnimalBuyFood = true; public bool AnimalBuyCrates = false; public long AnimalMaxPrice = 100000000; public static readonly long[] AnimalMaxPrices = { 100000000, 1000000000, 10000000000, 100000000000, 500000000000, 1000000000000, 2000000000000, 5000000000000, 10000000000000 }; public bool CrewSlots = true; public bool CrewFill = true; public CrewRoll CrewRollType = CrewRoll.Street; public LuckRoll CrewLuckRoll = LuckRoll.Same; public bool CrewReroll = false; public int CrewRerollStats = 0; public bool RerollsFirst = false; public bool CrewAutoRoll = false; public long AutoRollLimit = 1000000000; public static readonly long[] AutoRollLimits = { 100000000, 500000000, 1000000000, 5000000000, 10000000000, 100000000000, 500000000000, 1000000000000, 10000000000000, 50000000000000, 100000000000000 }; public bool TrainCrew = true; public int TrainAtOnce = 1; public TrainOrder TrainOrder = TrainOrder.Best; public bool DefendTerritory = false; public bool DefendHeal = false; public string NeverDefend = ""; public const int MaxTraining = 2; public const int Perfect = 45; public const int PerfectForbidden = 70; public static readonly int[] StatsGoals = { 0, Perfect }; public static readonly string[] StatsGoalNames = { "Off: stop at the best rarity", "On: until every one is perfect" }; public static int PerfectFor(int rarity) { return rarity >= (int)Rarity.Forbidden ? PerfectForbidden : Perfect; } public bool FamilyWatch = true; public bool GameStats = false; public bool Takedown = true; public bool GiveStamina = true; public string StaminaPerk = ""; public bool SpendPoints = true; public int PointsStat = 0; public int PointsStopEnergy = 0, PointsStopStamina = 0, PointsStopHealth = 0, PointsStopAttack = 0, PointsStopDefense = 0, PointsStopCapacity = 0; public int PointsStop(int stat) { var all = new[] { PointsStopEnergy, PointsStopStamina, PointsStopHealth, PointsStopAttack, PointsStopDefense, PointsStopCapacity }; return stat >= 0 && stat < all.Length ? Math.Max(0, all[stat]) : 0; } public bool WaitWhileBusy = true; public int IdleSeconds { get { return 15; } } public bool GiveFocusBack = true; public bool Rejoin = true; public bool KeepAlive = true; public OtherDeviceWait OtherDeviceRejoin = OtherDeviceWait.Off; public string DiscordLink = ""; public bool DiscordProblems = true; public bool DiscordRarity = true; public bool DiscordProperty = true; public bool DiscordSummary = true; public bool DiscordLevel = false; public bool DiscordBoss = false; public bool DiscordGlobalBoss = true; public string DiscordUserId = ""; public bool ShopPing = true; public int ShopPingFrom = (int)Rarity.Mythic; public bool ShopPingFor(int rarity) { return ShopPing && rarity >= ShopPingFrom; } public string StatsLink = ""; public string StatsMessage = ""; public bool RemoteControl = false; public string RemoteMessage = ""; public Focus Focus = Focus.Balanced; public string Account = ""; public int LastLevel = -1; public int LastPrestige = -1; public string Totals = ""; public string TrainedLevels = ""; public string BossesDoneUntil = ""; public int BossesOpenLevel; public bool RespectCycle = Program.Whale; public int RespectHigh = 13000, RespectLow = 7000; public int RespectHighNow { get { return Math.Max(RespectLow + 100, RespectHigh); } } public string GarrisonPicks = ""; public string RespectState = ""; public bool FightItems = false; public string Defence = ""; public string ExpDay = ""; public string ExpCardAt = ""; public bool ExpUsed = false; public bool ExpMostWantedDone = false; public string ExpUntil = ""; public int HealthPerHour = 0; public int BossHitHealth = 0; public string StageHits = ""; public string CratesLeft = ""; public int LastAttackPower = -1; public int LastDefensePower = -1; public string BarMax = ""; public bool WelcomeSeen = false; public string CheckOffered = ""; public int CheckHintLevel = 0; public string PresetInUse = ""; public string GroupsOff = ""; public static List GroupOff(string groupsOff, string key) { foreach (var part in (groupsOff ?? "").Split(';')) { int colon = part.IndexOf(':'); if (colon > 0 && part.Substring(0, colon) == key) return part.Substring(colon + 1).Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries).ToList(); } return new List(); } public static string GroupsOffWith(string groupsOff, string key, IEnumerable fields) { var parts = (groupsOff ?? "").Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).Where(p => !p.StartsWith(key + ":")).ToList(); parts.Add(key + ":" + string.Join(",", fields)); return string.Join(";", parts); } public string JobsReadAt = ""; public bool CrewGearOff = false; public int CrewOpenBefore = -1; public string AutoRollMine = ""; public bool ScreenFirst = false; public bool TasksSimple = true; public static readonly string[] PcFields = { "WelcomeSeen", "WaitWhileBusy", "GiveFocusBack", "Rejoin", "OtherDeviceRejoin", "KeepAlive", "DiscordLink", "DiscordProblems", "DiscordRarity", "DiscordProperty", "DiscordSummary", "DiscordLevel", "DiscordBoss", "DiscordGlobalBoss", "DiscordUserId", "ShopPing", "ShopPingFrom", "NeverAttack", "AttackFirst", "NeverDefend", "StatsLink", "RemoteControl", "RemoteMessage", "ScreenFirst", "TasksSimple" }; public static readonly string[] LinkFields = { "DiscordLink", "StatsLink" }; public void TakeAccountFields(Settings o) { foreach (var f in typeof(Settings).GetFields(BindingFlags.Public | BindingFlags.Instance)) if (Array.IndexOf(PcFields, f.Name) < 0) f.SetValue(this, f.GetValue(o)); } public void TakePcFields(Settings o) { foreach (var f in typeof(Settings).GetFields(BindingFlags.Public | BindingFlags.Instance)) if (Array.IndexOf(PcFields, f.Name) >= 0) f.SetValue(this, f.GetValue(o)); } public string Unreadable { get; set; } public void WhaleOnly() { Jobs = Heists = StartHeists = Bosses = GlobalBoss = Operations = Playtime = Contracts = Crates = Briefcases = TrickOrTreat = Events = ShopBuy = EquipBest = false; Properties = SafehouseUpgrade = CrewSlots = CrewFill = CrewReroll = TrainCrew = DefendTerritory = FamilyWatch = GameStats = Takedown = GiveStamina = SpendPoints = false; FightStaminaReserve = 0; WarTargetsOnly = false; } public long RerollerLimit = 10000000000000; public bool RerollerJobs = false; public bool RerollerGifts = false; public static readonly long[] RerollerAmounts = { 100000000000, 500000000000, 1000000000000, 5000000000000, 10000000000000, 25000000000000, 50000000000000, 100000000000000, 250000000000000, 500000000000000 }; public void RerollerOnly() { WhaleOnly(); Jobs = RerollerJobs; GiveStamina = RerollerGifts; Fights = WhaleHunt = RespectCycle = Animals = FightItems = AnimalPremium = false; CrewReroll = CrewFill = Bank = true; CrewRollType = CrewRoll.Elite; CrewLuckRoll = LuckRoll.Same; CrewRerollStats = 0; CrewAutoRoll = RerollsFirst = false; } public static readonly string[] WhaleFields = { "RespectCycle", "RespectHigh", "RespectLow", "GarrisonPicks", "FightItems", "AnimalPremium" }; public void MacroOnly() { RespectCycle = FightItems = AnimalPremium = false; } public static Settings Load(string file) { var s = new Settings(); string[] lines; for (int tries = 1; ; tries++) { try { if (!File.Exists(file)) return s; lines = File.ReadAllLines(file); break; } catch (Exception e) { if (tries < 8) { System.Threading.Thread.Sleep(250); continue; } string why = (e.Message ?? "").Replace(file, Path.GetFileName(file)).Trim().TrimEnd('.'); s.Unreadable = why.Length > 0 ? why : "it can't be opened"; return s; } } if (Array.IndexOf(lines, "OpsCollect=False") >= 0 && Array.IndexOf(lines, "OpsStart=False") >= 0 && !Array.Exists(lines, l => l.StartsWith("Operations="))) s.Operations = false; foreach (var line in lines) { int eq = line.IndexOf('='); if (eq <= 0) continue; var field = typeof(Settings).GetField(line.Substring(0, eq).Trim()); if (field == null) continue; SetText(s, field, line.Substring(eq + 1).Trim()); } if (!lines.Any(l => l.StartsWith("ShopCashMax="))) { Func off = r => Array.IndexOf(lines, "Shop" + r + "=False") >= 0; s.ShopCashMax = !off("Secret") ? 0 : !off("Mythic") ? 50000000000 : !off("Legendary") || !off("Epic") ? 1000000000 : !off("Rare") ? 100000000 : 1000000; if (off("Secret") && off("Mythic") && off("Legendary") && off("Epic") && off("Rare") && off("Uncommon") && off("Common")) s.ShopBuy = false; } if (!lines.Any(l => l.StartsWith("ShopBankFrom=")) && Array.IndexOf(lines, "ShopBankMythic=False") >= 0) { if (Array.IndexOf(lines, "ShopBankSecret=False") >= 0) s.ShopWithdraw = false; else s.ShopBankFrom = (int)Rarity.Secret; } if (!lines.Any(l => l.StartsWith("ShopPingFrom=")) && Array.IndexOf(lines, "ShopPingMythic=False") >= 0) { if (Array.IndexOf(lines, "ShopPingSecret=False") >= 0 && Array.IndexOf(lines, "ShopPingForbidden=False") >= 0) s.ShopPing = false; else s.ShopPingFrom = (int)Rarity.Secret; } if (s.PointsStat < 0 || s.PointsStat >= Game.StatNames.Length) s.PointsStat = 0; if (!Program.Whale) s.MacroOnly(); return s; } internal static bool SetText(Settings s, FieldInfo field, string v) { try { int n; long l; if (field.FieldType == typeof(bool)) field.SetValue(s, v == "1" || v.Equals("true", StringComparison.OrdinalIgnoreCase)); else if (field.FieldType == typeof(int)) { if (!int.TryParse(v, NumberStyles.Integer, CultureInfo.InvariantCulture, out n)) return false; field.SetValue(s, n); } else if (field.FieldType == typeof(long)) { if (!long.TryParse(v, NumberStyles.Integer, CultureInfo.InvariantCulture, out l) || l < 0 || (l == 0 && field.Name != "BankAt" && !field.Name.StartsWith("Shop"))) return false; field.SetValue(s, l); } else if (field.FieldType == typeof(string)) { if (v.IndexOf('\r') >= 0 || v.IndexOf('\n') >= 0) return false; field.SetValue(s, v); } else if (field.FieldType.IsEnum) { object e = Enum.Parse(field.FieldType, v); if (!Enum.IsDefined(field.FieldType, e)) return false; field.SetValue(s, e); } else return false; return true; } catch (Exception) { return false; } } static readonly object SaveLock = new object(); public void Save(string file, bool accountCopy = false) { if (Unreadable != null) return; var sb = new StringBuilder(); foreach (var f in typeof(Settings).GetFields(BindingFlags.Public | BindingFlags.Instance)) sb.AppendLine(f.Name + "=" + (accountCopy && Array.IndexOf(LinkFields, f.Name) >= 0 ? "" : Convert.ToString(f.GetValue(this), CultureInfo.InvariantCulture).Replace("\r", "").Replace("\n", ""))); lock (SaveLock) { string tmp = file + ".tmp"; using (var fs = new FileStream(tmp, FileMode.Create, FileAccess.Write)) using (var w = new StreamWriter(fs)) { w.Write(sb.ToString()); w.Flush(); fs.Flush(true); } if (File.Exists(file)) File.Replace(tmp, file, null); else File.Move(tmp, file); } } } }