diff --git a/SysBot.Pokemon/Helpers/NotRaidBot.cs b/SysBot.Pokemon/Helpers/NotRaidBot.cs index 235e597..204d61b 100644 --- a/SysBot.Pokemon/Helpers/NotRaidBot.cs +++ b/SysBot.Pokemon/Helpers/NotRaidBot.cs @@ -2,7 +2,7 @@ { public static class NotRaidBot { - public const string Version = "v8.1.6"; + public const string Version = "v8.1.7"; public const string Repo = "https://github.com/bdawg1989/NotRaidBot"; public const string ConfigPath = "config.json"; } diff --git a/SysBot.Pokemon/SV/BotRaid/RotatingRaidBotSV.cs b/SysBot.Pokemon/SV/BotRaid/RotatingRaidBotSV.cs index 49e3aaa..b2ec72c 100644 --- a/SysBot.Pokemon/SV/BotRaid/RotatingRaidBotSV.cs +++ b/SysBot.Pokemon/SV/BotRaid/RotatingRaidBotSV.cs @@ -1137,8 +1137,23 @@ private async Task OverrideSeedIndex(int index, CancellationToken token) } } + private async Task CreateMysteryRaidAsync() + { + await Task.Yield(); + + try + { + CreateMysteryRaid(); + } + catch (Exception ex) + { + Log($"Error in CreateMysteryRaid: {ex.Message}"); + } + } + private void CreateMysteryRaid() { + uint randomSeed = GenerateRandomShinySeed(); Random random = new(); var mysteryRaidsSettings = Settings.RaidSettings.MysteryRaidsSettings; @@ -1161,33 +1176,60 @@ private void CreateMysteryRaid() // Randomly pick a StoryProgressLevel from the enabled levels GameProgress gameProgress = enabledLevels[random.Next(enabledLevels.Count)]; - // Get allowed star counts for the selected progress - List allowedStars = GetAllowedStarCounts(mysteryRaidsSettings, gameProgress); + // Initialize a list to store possible difficulties + List possibleDifficulties = []; - if (allowedStars.Count == 0) + // Determine possible difficulties based on the selected GameProgress + switch (gameProgress) { - Log($"No allowed star count found for {gameProgress}. Skipping this Mystery Raid."); - return; + case GameProgress.Unlocked3Stars: + if (mysteryRaidsSettings.Unlocked3StarSettings.Allow1StarRaids) possibleDifficulties.Add(1); + if (mysteryRaidsSettings.Unlocked3StarSettings.Allow2StarRaids) possibleDifficulties.Add(2); + if (mysteryRaidsSettings.Unlocked3StarSettings.Allow3StarRaids) possibleDifficulties.Add(3); + break; + + case GameProgress.Unlocked4Stars: + if (mysteryRaidsSettings.Unlocked4StarSettings.Allow1StarRaids) possibleDifficulties.Add(1); + if (mysteryRaidsSettings.Unlocked4StarSettings.Allow2StarRaids) possibleDifficulties.Add(2); + if (mysteryRaidsSettings.Unlocked4StarSettings.Allow3StarRaids) possibleDifficulties.Add(3); + if (mysteryRaidsSettings.Unlocked4StarSettings.Allow4StarRaids) possibleDifficulties.Add(4); + break; + + case GameProgress.Unlocked5Stars: + if (mysteryRaidsSettings.Unlocked5StarSettings.Allow3StarRaids) possibleDifficulties.Add(3); + if (mysteryRaidsSettings.Unlocked5StarSettings.Allow4StarRaids) possibleDifficulties.Add(4); + if (mysteryRaidsSettings.Unlocked5StarSettings.Allow5StarRaids) possibleDifficulties.Add(5); + break; + + case GameProgress.Unlocked6Stars: + if (mysteryRaidsSettings.Unlocked6StarSettings.Allow3StarRaids) possibleDifficulties.Add(3); + if (mysteryRaidsSettings.Unlocked6StarSettings.Allow4StarRaids) possibleDifficulties.Add(4); + if (mysteryRaidsSettings.Unlocked6StarSettings.Allow5StarRaids) possibleDifficulties.Add(5); + if (mysteryRaidsSettings.Unlocked6StarSettings.Allow6StarRaids) possibleDifficulties.Add(6); + break; } - // Generate a shiny seed that produces an allowed star count - uint randomSeed; - int starCount; - do + // Check if there are any enabled difficulty levels + if (possibleDifficulties.Count == 0) { - randomSeed = GenerateRandomShinySeed(); - var clone = new Xoroshiro128Plus(randomSeed); - uint difficulty = (uint)clone.NextInt(100); - int progressValue = (int)gameProgress; - bool isBlack = gameProgress == GameProgress.Unlocked6Stars && difficulty > 70 && mysteryRaidsSettings.Unlocked6StarSettings.Allow6StarRaids; - starCount = RaidExtensions.GetStarCount(null, difficulty, progressValue, isBlack); - } while (!allowedStars.Contains(starCount)); + Log("No difficulty levels enabled for the selected Story Progress. Mystery Raids will be turned off."); + Settings.RaidSettings.MysteryRaids = false; // Disable Mystery Raids + return; // Exit the method + } - // Now we have a valid shiny seed that produces an allowed star count - var finalClone = new Xoroshiro128Plus(randomSeed); + // Randomly pick a difficulty level from the possible difficulties + int randomDifficultyLevel = possibleDifficulties[random.Next(possibleDifficulties.Count)]; + + // Determine the crystal type based on difficulty level + var crystalType = randomDifficultyLevel switch + { + >= 1 and <= 5 => TeraCrystalType.Base, + 6 => TeraCrystalType.Black, + _ => throw new ArgumentException("Invalid difficulty level.") + }; string seedValue = randomSeed.ToString("X8"); - int contentType = starCount == 6 ? 1 : 0; + int contentType = randomDifficultyLevel == 6 ? 1 : 0; TeraRaidMapParent map; if (!IsBlueberry && !IsKitakami) { @@ -1217,14 +1259,14 @@ private void CreateMysteryRaid() RotatingRaidParameters newRandomShinyRaid = new() { Seed = seedValue, - Species = (Species)pk.Species, + Species = Species.None, SpeciesForm = pk.Form, Title = $"Mystery Shiny Raid", AddedByRACommand = true, - DifficultyLevel = starCount, + DifficultyLevel = randomDifficultyLevel, StoryProgress = (GameProgressEnum)gameProgress, - CrystalType = starCount == 6 ? TeraCrystalType.Black : TeraCrystalType.Base, - IsShiny = true, + CrystalType = crystalType, + IsShiny = pk.IsShiny, PartyPK = battlers.Length > 0 ? battlers : [""] }; @@ -1235,44 +1277,36 @@ private void CreateMysteryRaid() // Insert the new raid at the determined position Settings.ActiveRaids.Insert(insertPosition, newRandomShinyRaid); - // Log the addition for debugging purposes - Log($"Added Mystery Shiny Raid - Species: {(Species)pk.Species}, Seed: {seedValue}, Stars: {starCount}."); + Log($"Added Mystery Raid - Species: {(Species)pk.Species}, Seed: {seedValue}."); } - private static List GetAllowedStarCounts(MysteryRaidsSettings settings, GameProgress progress) + private static uint GenerateRandomShinySeed() { - List allowedStars = []; + Random random = new(); + uint seed; - switch (progress) + do { - case GameProgress.Unlocked3Stars: - if (settings.Unlocked3StarSettings.Allow1StarRaids) allowedStars.Add(1); - if (settings.Unlocked3StarSettings.Allow2StarRaids) allowedStars.Add(2); - if (settings.Unlocked3StarSettings.Allow3StarRaids) allowedStars.Add(3); - break; - case GameProgress.Unlocked4Stars: - if (settings.Unlocked4StarSettings.Allow1StarRaids) allowedStars.Add(1); - if (settings.Unlocked4StarSettings.Allow2StarRaids) allowedStars.Add(2); - if (settings.Unlocked4StarSettings.Allow3StarRaids) allowedStars.Add(3); - if (settings.Unlocked4StarSettings.Allow4StarRaids) allowedStars.Add(4); - break; - case GameProgress.Unlocked5Stars: - if (settings.Unlocked5StarSettings.Allow3StarRaids) allowedStars.Add(3); - if (settings.Unlocked5StarSettings.Allow4StarRaids) allowedStars.Add(4); - if (settings.Unlocked5StarSettings.Allow5StarRaids) allowedStars.Add(5); - break; - case GameProgress.Unlocked6Stars: - if (settings.Unlocked6StarSettings.Allow3StarRaids) allowedStars.Add(3); - if (settings.Unlocked6StarSettings.Allow4StarRaids) allowedStars.Add(4); - if (settings.Unlocked6StarSettings.Allow5StarRaids) allowedStars.Add(5); - if (settings.Unlocked6StarSettings.Allow6StarRaids) allowedStars.Add(6); - break; + // Generate a random uint + byte[] buffer = new byte[4]; + random.NextBytes(buffer); + seed = BitConverter.ToUInt32(buffer, 0); } + while (Raidshiny(seed) == 0); + + return seed; + } - return allowedStars; + private static int Raidshiny(uint Seed) + { + Xoroshiro128Plus xoroshiro128Plus = new(Seed); + _ = (uint)xoroshiro128Plus.NextInt(4294967295uL); + uint num2 = (uint)xoroshiro128Plus.NextInt(4294967295uL); + uint num3 = (uint)xoroshiro128Plus.NextInt(4294967295uL); + return (((num3 >> 16) ^ (num3 & 0xFFFF)) >> 4 == ((num2 >> 16) ^ (num2 & 0xFFFF)) >> 4) ? 1 : 0; } - private string ExtractTeraTypeFromEmbed(Embed embed) + private static string ExtractTeraTypeFromEmbed(Embed embed) { var statsField = embed.Fields.FirstOrDefault(f => f.Name == "**__Stats__**"); if (statsField != null) @@ -1312,36 +1346,10 @@ private string[] GetBattlerForTeraType(string teraType) "Rock" => battlers.RockBattler, "Steel" => battlers.SteelBattler, "Water" => battlers.WaterBattler, - _ => [] + _ => [] }; } - private static uint GenerateRandomShinySeed() - { - Random random = new(); - uint seed; - - do - { - // Generate a random uint - byte[] buffer = new byte[4]; - random.NextBytes(buffer); - seed = BitConverter.ToUInt32(buffer, 0); - } - while (Raidshiny(seed) == 0); - - return seed; - } - - private static int Raidshiny(uint Seed) - { - Xoroshiro128Plus xoroshiro128Plus = new(Seed); - _ = (uint)xoroshiro128Plus.NextInt(4294967295uL); - uint num2 = (uint)xoroshiro128Plus.NextInt(4294967295uL); - uint num3 = (uint)xoroshiro128Plus.NextInt(4294967295uL); - return (((num3 >> 16) ^ (num3 & 0xFFFF)) >> 4 == ((num2 >> 16) ^ (num2 & 0xFFFF)) >> 4) ? 1 : 0; - } - private async Task ReadValue(string fieldName, int size, List pointer, CancellationToken token) { byte[] valueBytes = await SwitchConnection.PointerPeek(size, pointer, token).ConfigureAwait(false); @@ -1916,10 +1924,25 @@ private async Task CheckIfTrainerBanned(RaidMyStatus trainer, ulong nid, i { if (!await IsConnectedToLobby(token)) return (false, new List<(ulong, RaidMyStatus)>()); - await EnqueueEmbed(null, "", false, false, false, false, token).ConfigureAwait(false); + + Task? delayTask = null; + TimeSpan wait; + + if (Settings.ActiveRaids[RotationCount].AddedByRACommand && + Settings.ActiveRaids[RotationCount].Title != "Mystery Shiny Raid") + { + delayTask = Task.Delay(Settings.EmbedToggles.RequestEmbedTime * 1000, token) + .ContinueWith(async _ => await EnqueueEmbed(null, "", false, false, false, false, token), token); + wait = TimeSpan.FromSeconds(160); + } + else + { + await EnqueueEmbed(null, "", false, false, false, false, token).ConfigureAwait(false); + wait = TimeSpan.FromSeconds(160); + } List<(ulong, RaidMyStatus)> lobbyTrainers = []; - var wait = TimeSpan.FromSeconds(160); + var endTime = DateTime.Now + wait; bool full = false; @@ -1991,7 +2014,11 @@ private async Task CheckIfTrainerBanned(RaidMyStatus trainer, ulong nid, i } } - await Task.Delay(5_000, token).ConfigureAwait(false); + + if (delayTask != null) + { + await delayTask; + } if (lobbyTrainers.Count == 0) { @@ -2296,14 +2323,6 @@ private async Task EnqueueEmbed(List? names, string message, bool hatTri code = "Free For All"; } - // Apply delay only if the raid was added by RA command, not a Mystery Shiny Raid, and has a code - if (Settings.ActiveRaids[RotationCount].AddedByRACommand && - Settings.ActiveRaids[RotationCount].Title != "Mystery Shiny Raid" && - code != "Free For All") - { - await Task.Delay(Settings.EmbedToggles.RequestEmbedTime * 1000, token).ConfigureAwait(false); - } - // Description can only be up to 4096 characters. //var description = Settings.ActiveRaids[RotationCount].Description.Length > 0 ? string.Join("\n", Settings.ActiveRaids[RotationCount].Description) : ""; var description = Settings.EmbedToggles.RaidEmbedDescription.Length > 0 ? string.Join("\n", Settings.EmbedToggles.RaidEmbedDescription) : ""; @@ -2445,16 +2464,9 @@ private async Task EnqueueEmbed(List? names, string message, bool hatTri ImageUrl = imageBytes != null ? $"attachment://{fileName}" : null, // Set ImageUrl based on imageBytes }; - if (!raidstart && !upnext) - { - if (Settings.ActiveRaids[RotationCount].AddedByRACommand && - Settings.ActiveRaids[RotationCount].Title != "Mystery Shiny Raid" && - code != "Free For All") - { - await Task.Delay(Settings.EmbedToggles.RequestEmbedTime * 1000, token).ConfigureAwait(false); - } + if (!raidstart && !upnext && code != "Free For All") await CurrentRaidInfo(null, code, false, false, false, false, turl, false, token).ConfigureAwait(false); - } + // Only include footer if not posting 'upnext' embed with the 'Preparing Raid' title if (!(upnext && Settings.RaidSettings.TotalRaidsToHost == 0)) { @@ -2586,11 +2598,10 @@ private async Task EnqueueEmbed(List? names, string message, bool hatTri embed.ThumbnailUrl = turl; embed.WithImageUrl($"attachment://{fileName}"); } - EchoUtil.RaidEmbed(imageBytes, fileName, embed); } - private string CleanEmojiStrings(string input) + private static string CleanEmojiStrings(string input) { if (string.IsNullOrEmpty(input)) return input; @@ -2880,18 +2891,15 @@ public async Task StartGameRaid(PokeRaidHubConfig config, CancellationToken toke await Task.Delay(5_000 + timing.ExtraTimeLoadOverworld, token).ConfigureAwait(false); Log("Back in the overworld!"); - LostRaid = 0; - if (Settings.RaidSettings.MysteryRaids) { // Count the number of existing Mystery Shiny Raids int mysteryRaidCount = Settings.ActiveRaids.Count(raid => raid.Title.Contains("Mystery Shiny Raid")); - // Only create and add a new Mystery Shiny Raid if there are two or fewer in the list if (mysteryRaidCount <= 1) { - CreateMysteryRaid(); + await CreateMysteryRaidAsync(); } } }