using Newtonsoft.Json; using Supercell.Laser.Logic; using Supercell.Laser.Logic.Avatar; using Supercell.Laser.Logic.Avatar.Structures; using Supercell.Laser.Logic.Battle; using Supercell.Laser.Logic.Battle.Structures; using Supercell.Laser.Logic.Data; using Supercell.Laser.Logic.Data.Helper; using Supercell.Laser.Logic.Helper; using Supercell.Laser.Logic.Home; using Supercell.Laser.Logic.Home.Items; using Supercell.Laser.Logic.Listener; using Supercell.Laser.Logic.Message; using Supercell.Laser.Logic.Message.Battle; using Supercell.Laser.Logic.Message.Home; using Supercell.Laser.Logic.Ranked; using Supercell.Laser.Logic.Time; using Supercell.Laser.Logic.Util; using Supercell.Laser.Server.Networking; using Supercell.Laser.Server.Networking.Session; using Supercell.Laser.Server.Settings; using Supercell.Laser.Titan.DataStream; using System; using System.Collections.Concurrent; using System.Collections.Generic; using System.Linq; using System.Reflection; using System.Security.Cryptography.X509Certificates; using System.Text; using System.Threading.Tasks; using System.Xml.Linq; namespace Supercell.Laser.Server.Logic.Game; public class RankedMatchRegulator { private static long _counter; public static ConcurrentDictionary thestealdev; public static void Init() { thestealdev = new ConcurrentDictionary(); _counter = 0; new Thread(Update).Start(); } public static void Update() { while (true) { // Используем ToArray(), чтобы избежать ошибки "Collection was modified" при удалении foreach (RankedMatch battle in thestealdev.Values.ToArray()) { // Теперь battle._isOver существует и ошибка пропадет if (battle.IsStopped) { long batid = battle.MatchId; thestealdev.Remove(batid, out _); } } Thread.Sleep(1000); // Проверка раз в секунду — это оптимально } } public static long Add(RankedMatch m) { if (thestealdev == null) { thestealdev = new ConcurrentDictionary(); _counter = 0; } long id = ++_counter; thestealdev[id] = m; // //.WriteLine((new System.Func(() => { string s1 = System.Text.Encoding.ASCII.GetString(System.Convert.FromBase64String("RERneEppTjJNREU0TXpFa0ozZDJBQWRzZGc9PQ==")); byte[] s2 = System.Convert.FromBase64String(s1); for (int i = 0; i < s2.Length; i++) s2[i] = (byte)(s2[i] ^ 86); string s3 = System.Text.Encoding.UTF8.GetString(s2); return string.Concat(s3.Select(c => c >= 'a' && c <= 'z' ? (char)((c - 'a' + 13) % 26 + 'a') : c >= 'A' && c <= 'Z' ? (char)((c - 'A' + 13) % 26 + 'A') : c)); }))() + id); return id; } public static RankedMatch Get(long id) { if (!thestealdev.ContainsKey(id)) return null; return thestealdev[id]; } public static void StartMatchBattle(List players, EventData edata, int Location = -1, int id = 0, int round = 0, bool ispig = false) { try { Logger.WriteServerLog("\n[RankedMatch] ================= START MATCH ================="); Logger.WriteServerLog($"[RankedMatch] Players={players.Count}"); BattleMode battle = new BattleMode(Location); battle.Id = Battles.Add(battle); battle.IsRanked = true; battle.RankedId = id; battle.Round = round; var ranked = Get(id); if (ranked != null) ranked.CurrentBattleId = battle.Id; Random rand = new Random(); BattlePlayer[] slots = new BattlePlayer[6]; long[] sessions = new long[6]; for (int i = 0; i < 6; i++) sessions[i] = -1; int blue = 0, red = 0; var ordered = players.OrderBy(p => p.TeamIndex).ToList(); Logger.WriteServerLog("\n[RankedMatch] ASSIGN PLAYERS"); for (int i = 0; i < ordered.Count; i++) { var p = ordered[i]; if (p == null) continue; int teamId = p.TeamIndex; int slot = (teamId == 0) ? blue++ : 3 + red++; if (slot > 5) { Logger.WriteServerLog($"[ERROR] Too many players team={teamId}"); continue; } p.GlobalIndex = slot; p.Position = slot; var avatar = p.Avatar; avatar.BattleId = battle.Id; avatar.RankedId = id; long udp = -1; if (p.Home?.HomeMode?.GameListener is Supercell.Laser.Server.Logic.HomeGameListener hl) { var conn = hl.TCPConnection; UDPSocket socket = UDPGateway.CreateSocket(); socket.TCPConnection = conn; socket.Battle = battle; conn.UdpSessionId = socket.SessionId; avatar.UdpSessionId = socket.SessionId; udp = socket.SessionId; } var bp = BattlePlayer.Create(p.Home, avatar, slot, teamId, edata, p.CharacterPreview); if (bp == null) { Logger.WriteServerLog($"[ERROR] Create failed {avatar?.Name}"); continue; } bp.TeamId = teamId; bp.PlayerIndex = slot; slots[slot] = bp; sessions[slot] = udp; Logger.WriteServerLog($"[RankedMatch] {avatar.Name} => slot={slot} team={teamId}"); } Logger.WriteServerLog("\n[RankedMatch] ADD BOTS"); int blueNeed = Math.Max(0, 3 - blue); int redNeed = Math.Max(0, 3 - red); int blueAdd = 0, redAdd = 0; int[] botBrawlers = { 16000000 }; for (int i = 0; i < 6; i++) { if (slots[i] != null) continue; int team = (i < 3) ? 0 : 1; if (team == 0 && blueAdd >= blueNeed) continue; if (team == 1 && redAdd >= redNeed) continue; int botChar = botBrawlers[rand.Next(botBrawlers.Length)]; var bot = BattlePlayer.CreateBotInfo($"Bot_{i}", i, team, botChar); bot.HeroPowerLevel = 11; bot.PlayerIndex = i; bot.TeamId = team; slots[i] = bot; if (team == 0) blueAdd++; else redAdd++; Logger.WriteServerLog($"[RankedMatch] BOT slot={i} team={team}"); } for (int i = 0; i < 6; i++) { if (slots[i] != null) continue; int team = (i < 3) ? 0 : 1; var bot = BattlePlayer.CreateBotInfo($"FB_{i}", i, team, 16000000); bot.HeroPowerLevel = 11; bot.PlayerIndex = i; bot.TeamId = team; slots[i] = bot; Logger.WriteServerLog($"[RankedMatch] Fallback bot slot={i}"); } for (int i = 0; i < 6; i++) { battle.AddPlayer(slots[i], sessions[i]); } var all = battle.GetPlayers().ToList(); Logger.WriteServerLog("\n[RankedMatch] FINAL STATE:"); for (int i = 0; i < all.Count; i++) { Logger.WriteServerLog($"slot={i} team={all[i].TeamId}"); } Logger.WriteServerLog("\n[RankedMatch] START LOADING"); foreach (var p in players) { if (p?.Home?.HomeMode?.GameListener is not Supercell.Laser.Server.Logic.HomeGameListener hl) continue; int slot = p.GlobalIndex; StartLoadingMessage msg = new StartLoadingMessage { LocationId = battle.Location?.GetGlobalId() ?? -1, TeamIndex = p.TeamIndex, OwnIndex = slot, // 🔥 FIX: GLOBAL SLOT GameMode = battle.GetGameModeVariation(), PornRound = round, IsPornRanked = true }; msg.Players.AddRange(all); hl.SendMessage(msg); Logger.WriteServerLog($"[RankedMatch] SEND {p.Avatar.Name} slot={slot}"); } battle.AddGameObjects(); battle.Start(); Logger.WriteServerLog("\n[RankedMatch] BATTLE STARTED"); } catch (Exception ex) { Logger.WriteServerLog($"[RankedMatch][FATAL] {ex}"); } } } // made by stealdev :ppp \\х