namespace Supercell.Laser.Server.Message { using Supercell.Laser.Logic.Avatar; using Supercell.Laser.Logic.Avatar.Structures; using Supercell.Laser.Logic.Data.Helper; using Supercell.Laser.Logic.Club; using Supercell.Laser.Logic.Command.Home; using Supercell.Laser.Logic.Command.Avatar; using Supercell.Laser.Logic.Data; using Supercell.Laser.Logic.Friends; using Supercell.Laser.Logic.Home; using Supercell.Laser.Logic.Home.Gatcha; using Supercell.Laser.Logic.Home.Structures; using Supercell.Laser.Logic.Listener; using Supercell.Laser.Logic.Message.Account; using Supercell.Laser.Logic.Message.Club; using Supercell.Laser.Logic.Message.Friends; using Supercell.Laser.Logic.Message.Home; using Supercell.Laser.Logic.Message.Ranking; using Supercell.Laser.Logic.Message.Security; using Supercell.Laser.Logic.Message.Team; using Supercell.Laser.Logic.Message.Udp; using Supercell.Laser.Logic.Stream.Entry; using Supercell.Laser.Logic.Team; using Supercell.Laser.Server.Database; using Supercell.Laser.Server.Database.Models; using Supercell.Laser.Server.Logic.Game; using Supercell.Laser.Server.Networking; using Supercell.Laser.Server.Networking.Session; using Supercell.Laser.Server.Settings; using Supercell.Laser.Server.Logic; using System.Diagnostics; using System.Text.RegularExpressions; using Supercell.Laser.Server.Database.Cache; using Supercell.Laser.Logic.Util; using Supercell.Laser.Logic.Battle; using Supercell.Laser.Logic.Message.Battle; using Supercell.Laser.Server.Networking.UDP.Game; using Supercell.Laser.Server.Networking.Security; using Supercell.Laser.Logic.Home.Items; using Supercell.Laser.Logic.Team.Stream; using Supercell.Laser.Logic.Message.Team.Stream; using Supercell.Laser.Logic.Message; using Supercell.Laser.Logic.Message.Account.Auth; using Newtonsoft.Json.Linq; using MySql.Data.MySqlClient.Memcached; using Org.BouncyCastle.Asn1.X509; public class MessageManager { public Connection Connection { get; } public HomeMode HomeMode; private DateTime LastKeepAlive; public List Heroes; public MessageManager(Connection connection) { Connection = connection; LastKeepAlive = DateTime.UtcNow; } public bool IsAlive() { return (int)(DateTime.UtcNow - LastKeepAlive).TotalSeconds < 30; } private int ResolveCurrentSkinId() { if (HomeMode?.Home == null || HomeMode.Avatar == null) { return 0; } int characterId = HomeMode.Home.CharacterId; int characterInstanceId = GlobalId.GetInstanceId(characterId); int selectedSkinInstanceId = 0; if (characterInstanceId >= 0 && characterInstanceId < HomeMode.Home.SelectedSkins.Length) { selectedSkinInstanceId = HomeMode.Home.SelectedSkins[characterInstanceId]; } Hero hero = HomeMode.Avatar.GetHero(characterId); if (hero != null && hero.SelectedSkinId > 0) { selectedSkinInstanceId = hero.SelectedSkinId; } if (HomeMode.Home.SkinId > 0) { SkinData skinData = DataTables.Get(DataType.Skin).GetDataByGlobalId(HomeMode.Home.SkinId); if (skinData != null) { return HomeMode.Home.SkinId; } } return selectedSkinInstanceId > 0 ? GlobalId.CreateGlobalId((int)DataType.Skin, selectedSkinInstanceId) : 0; } public void ReceiveMessage(GameMessage message) { Heroes = new List(); switch (message.GetMessageType()) { case 10100: ClientHelloReceived((ClientHelloMessage)message); break; case 10101: LoginReceived((AuthenticationMessage)message); break; case 10107: ClientCapabilitesReceived((ClientCapabilitiesMessage)message); break; case 10108: LastKeepAlive = DateTime.UtcNow; LobbyInfoMessage LobbyInfo = new LobbyInfoMessage(); LobbyInfo.PlayersOnline = Sessions.Count; LobbyInfo.Version = "v27.269.1"; Connection.Send(new KeepAliveServerMessage()); //Connection.Send(LobbyInfo); break; case 10110: AnalyticEventReceived((AnalyticEventMessage)message); break; case 10212: ChangeName((ChangeAvatarNameMessage)message); break; case 10177: ClientInfoReceived((ClientInfoMessage)message); break; case 10501: AcceptFriendReceived((AcceptFriendMessage)message); break; case 10502: AddFriendReceived((AddFriendMessage)message); break; case 10504: AskForFriendListReceived((AskForFriendListMessage)message); break; case 10506: RemoveFriendReceived((RemoveFriendMessage)message); break; case 10555: break; case 14101: GoHomeReceived((GoHomeMessage)message); break; case 14102: EndClientTurnReceived((EndClientTurnMessage)message); break; case 14103: MatchmakeRequestReceived((MatchmakeRequestMessage)message); break; case 14104: StartSpectateReceived((StartSpectateMessage)message); break; case 14106: CancelMatchMaking((CancelMatchmakingMessage)message); break; case 14107: StopSpectateReceived((StopSpectateMessage)message); break; case 14109: GoHomeFromOfflinePractiseReceived((GoHomeFromOfflinePractiseMessage)message); break; case 14110: AskForBattleEndReceived((AskForBattleEndMessage)message); break; case 14113: GetPlayerProfile((GetPlayerProfileMessage)message); break; case 14166: break; case 14301: CreateAllianceReceived((CreateAllianceMessage)message); break; case 14302: AskForAllianceDataReceived((AskForAllianceDataMessage)message); break; case 14303: AskForJoinableAllianceListReceived((AskForJoinableAllianceListMessage)message); break; case 14305: JoinAllianceReceived((JoinAllianceMessage)message); break; case 14307: KickAllianceMemberReceived((KickAllianceMemberMessage)message); break; case 14308: LeaveAllianceReceived((LeaveAllianceMessage)message); break; case 14315: ChatToAllianceStreamReceived((ChatToAllianceStreamMessage)message); break; case 14316: ChangeAllianceSettingsReceived((ChangeAllianceSettingsMessage)message); break; case 14330: SendAllianceMailMessage((SendAllianceMailMessage)message); break; case 14777: DoNotDisturbReceived((DoNotDisturbMessage)message); break; case 14350: TeamCreateReceived((TeamCreateMessage)message); break; case 14353: TeamLeaveReceived((TeamLeaveMessage)message); break; case 14354: TeamChangeMemberSettingsReceived((TeamChangeMemberSettingsMessage)message); break; case 14355: TeamSetMemberReadyReceived((TeamSetMemberReadyMessage)message); break; case 14359: TeamChatReceived((TeamChatMessage)message); break; case 14361: TeamMemberStatusReceived((TeamMemberStatusMessage)message); break; case 14362: TeamSetEventReceived((TeamSetEventMessage)message); break; case 14363: TeamSetLocationReceived((TeamSetLocationMessage)message); break; case 14365: TeamInviteReceived((TeamInviteMessage)message); break; case 14366: PlayerStatusReceived((PlayerStatusMessage)message); break; case 14369: TeamPremadeChatReceived((TeamPremadeChatMessage)message); break; case 14778: SetTeamChatMutedReceived((SetTeamChatMutedMessage)message); break; case 14403: GetLeaderboardReceived((GetLeaderboardMessage)message); break; case 14479: TeamInvitationResponseReceived((TeamInvitationResponseMessage)message); break; case 14600: AvatarNameCheckRequestReceived((AvatarNameCheckRequestMessage)message); break; case 18686: SetSupportedCreator((SetSupportedCreatorMessage)message); break; case 14277: GetMapsChampionshipMessageReceived((GetSeasonRewardsMessage)message); break; case 14114: GetBattleLogReceived((GetBatteLogMessage)message); break; default: Logger.Warning($"MessageManager::ReceiveMessage - no case for {message.GetType().Name} ({message.GetMessageType()})"); break; } try { if (message.GetMessageType() == 10107) { Account accSave = Accounts.Load(HomeMode.Avatar.AccountId); Accounts.Save(accSave); // Console.WriteLine("SENT ----------------------- " + message.GetMessageType()); } // Console.WriteLine("EEE " + message.GetMessageType()); } catch { ; } } private void GetMapsChampionshipMessageReceived(GetSeasonRewardsMessage message) { SeasonRewardsMessage mc = new SeasonRewardsMessage(); mc.Type = message.Type; Console.WriteLine(message.Type); Connection.Send(mc); } private void GetBattleLogReceived(GetBatteLogMessage message) { Connection.Send( new BatteLogMessage()); } private void SetSupportedCreator(SetSupportedCreatorMessage message) { string inputCode = message.Creator?.Trim(); string filePath = LogicHelperConfig.creatorPath; if (string.IsNullOrWhiteSpace(inputCode)) { // Клиент шлёт пустую строку при открытии экрана — просто возвращаем текущий код. // Реальное удаление только если пришёл явный null (не пустая строка). if (message.Creator == null) { HomeMode.Avatar.SupportedCreator = null; SaveCurrentAccount(); Logger.Info($"Player {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId} removed their creator code"); } string currentCode = HomeMode.Avatar.SupportedCreator ?? string.Empty; Connection.Send(new SetSupportedCreatorResponse { Name = currentCode }); return; } bool isCodeValid = false; string tagInJson = string.Empty; int gemsInJson = 0; if (File.Exists(filePath)) { try { string json = File.ReadAllText(filePath); JArray creatorsArray = JArray.Parse(json); foreach (JToken creatorToken in creatorsArray) { string codeInJson = creatorToken["Code"]?.ToString(); if (string.Equals(codeInJson, inputCode, StringComparison.OrdinalIgnoreCase)) { isCodeValid = true; tagInJson = creatorToken["Tag"]?.ToString() ?? string.Empty; int.TryParse(creatorToken["Gems"]?.ToString(), out gemsInJson); break; } } } catch (Exception ex) { Logger.Error($"Error reading file {filePath}: {ex.Message}"); } } else { Logger.Warning($"File not found: {filePath}"); } if (!isCodeValid) { // Код не найден в файле — если у игрока уже был установлен другой код, оставляем его. // Отвечаем текущим значением чтобы клиент не показывал "ссылка недействительна". string currentCode = HomeMode.Avatar.SupportedCreator ?? string.Empty; Connection.Send(new SetSupportedCreatorResponse { Name = currentCode }); return; } HomeMode.Avatar.SupportedCreator = inputCode; Connection.Send(new SetSupportedCreatorResponse { Name = inputCode }); SaveCurrentAccount(); Logger.Info($"Player {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId} activated creator code '{inputCode}'"); if (HomeMode.Home.CreatorCodeActivated) return; long creatorId = LogicLongCodeGenerator.ToId(tagInJson); if (HomeMode.Avatar.AccountId == creatorId) return; Account account = Accounts.Load(creatorId); if (account == null) { Logger.Warning($"SetSupportedCreator: creator account not found for tag '{tagInJson}' (id={creatorId})"); return; } HomeMode.Home.CreatorCodeActivated = true; LogicGiveDeliveryItemsCommand command = new LogicGiveDeliveryItemsCommand(); DeliveryUnit unit = new DeliveryUnit(100); GatchaDrop reward = new GatchaDrop(8) { Count = gemsInJson }; unit.AddDrop(reward); command.DeliveryUnits.Add(unit); command.Execute(HomeMode); AvailableServerCommandMessage commandMsg = new AvailableServerCommandMessage { Command = command }; HomeMode.GameListener.SendMessage(commandMsg); Notification notification = new Notification { Id = 89, MessageEntry = $"Ваш Creator-код был использован игроком {HomeMode.Avatar.Name}. Вам зачислено {gemsInJson} гемов.", DonationCount = gemsInJson }; account.Home.NotificationFactory.Add(notification); LogicAddNotificationCommand notificationCommand = new LogicAddNotificationCommand { Notification = notification }; AvailableServerCommandMessage notificationMsg = new AvailableServerCommandMessage { Command = notificationCommand }; if (Sessions.IsSessionActive(creatorId)) { var session = Sessions.GetSession(creatorId); session.GameListener.SendTCPMessage(notificationMsg); } Accounts.Save(account); } private void SendEmptyCreatorResponse() { LogicSetSupportedCreatorCommand response = new() { Name = string.Empty }; AvailableServerCommandMessage msg = new AvailableServerCommandMessage { Command = response }; Connection.Send(msg); } private void TeamPremadeChatReceived(TeamPremadeChatMessage message) { if (HomeMode.Avatar.TeamId <= 0) return; TeamEntry team = GetTeam(); if (team == null) return; QuickChatStreamEntry entry = new QuickChatStreamEntry(); entry.AccountId = HomeMode.Avatar.AccountId; entry.TargetId = message.TargetId; entry.Name = HomeMode.Avatar.Name; if (message.TargetId > 0) { TeamMember member = team.GetMember(message.TargetId); if (member != null) { entry.TargetPlayerName = member.DisplayData.Name; } } entry.MessageDataId = message.MessageDataId; entry.Unknown1 = message.Unknown1; entry.Unknown2 = message.Unknown2; team.AddStreamEntry(entry); } private void DoNotDisturbReceived(DoNotDisturbMessage message) { HomeMode.Avatar.DoNotDisturb = message.State; SaveCurrentAccount(); AvailableServerCommandMessage serverCommandMessage = new AvailableServerCommandMessage(); serverCommandMessage.Command = new LogicInviteBlockingChangedCommand { State = message.State }; Connection.Send(serverCommandMessage); if (HomeMode.Avatar.AllianceId <= 0) { return; } Alliance alliance = Alliances.Load(HomeMode.Avatar.AllianceId); if (alliance == null) { return; } AllianceMember member = alliance.GetMemberById(HomeMode.Avatar.AccountId); if (member == null) { return; } member.DoNotDisturb = message.State; Alliances.Save(alliance); AllianceDataMessage dataMessage = new AllianceDataMessage { Alliance = alliance, IsMyAlliance = true }; foreach (AllianceMember allianceMember in alliance.Members.ToArray()) { if (!LogicServerListener.Instance.IsPlayerOnline(allianceMember.AccountId)) { continue; } LogicServerListener.Instance.GetGameListener(allianceMember.AccountId).SendTCPMessage(dataMessage); } } private void SetTeamChatMutedReceived(SetTeamChatMutedMessage message) { HomeMode.Avatar.DisabledTeamChat = message.State; SaveCurrentAccount(); AvailableServerCommandMessage serverCommandMessage = new AvailableServerCommandMessage(); serverCommandMessage.Command = new LogicTeamChatMuteStateChangedCommand { State = message.State }; Connection.Send(serverCommandMessage); } private void TeamChatReceived(TeamChatMessage message) { if (HomeMode.Avatar.TeamId <= 0) return; TeamEntry team = GetTeam(); if (team == null) return; ChatStreamEntry entry = new ChatStreamEntry(); entry.AccountId = HomeMode.Avatar.AccountId; entry.Name = HomeMode.Avatar.Name; entry.Message = message.Message; Logger.Command($"Team chat from {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}: {message.Message}"); team.AddStreamEntry(entry); } private void AvatarNameCheckRequestReceived(AvatarNameCheckRequestMessage message) { if (AdRegex.IsMatch(message.Name)) { Connection.Send(new AuthenticationFailedMessage { ErrorCode = 11, Message = "Вы не можете поменять свой ник на этот." }); return; } LogicChangeAvatarNameCommand command = new LogicChangeAvatarNameCommand(); command.Name = message.Name; command.ChangeNameCost = 0; command.Execute(HomeMode); AvailableServerCommandMessage serverCommandMessage = new AvailableServerCommandMessage(); serverCommandMessage.Command = command; Connection.Send(serverCommandMessage); } private void TeamSetEventReceived(TeamSetEventMessage message) { if (HomeMode.Avatar.TeamId <= 0) return; TeamEntry team = GetTeam(); if (team == null) return; if (message.EventSlot == 2) return; EventData data = Events.GetEvent(message.EventSlot); if (data == null) return; team.EventSlot = message.EventSlot; team.LocationId = data.LocationId; team.TeamUpdated(); } private BattleMode SpectatedBattle; private void StopSpectateReceived(StopSpectateMessage message) { if (SpectatedBattle != null) { SpectatedBattle.RemoveSpectator(Connection.UdpSessionId); SpectatedBattle = null; } SendHomeData(); } private void StartSpectateReceived(StartSpectateMessage message) { Account data = Accounts.Load(message.AccountId); if (data == null) return; ClientAvatar avatar = data.Avatar; long battleId = avatar.BattleId; BattleMode battle = Battles.Get(battleId); if (battle == null) return; SpectatedBattle = battle; UDPSocket socket = UDPGateway.CreateSocket(); socket.Battle = battle; socket.IsSpectator = true; socket.TCPConnection = Connection; Connection.UdpSessionId = socket.SessionId; battle.AddSpectator(socket.SessionId, new UDPGameListener(socket, Connection)); StartLoadingMessage startLoading = new StartLoadingMessage(); startLoading.LocationId = battle.Location.GetGlobalId(); startLoading.TeamIndex = 0; startLoading.OwnIndex = 0; startLoading.GameMode = (battle.GetGameModeVariation() == 6 || battle.GetGameModeVariation() == 9) ? 6 : 1; Connection.Send(startLoading); UdpConnectionInfoMessage info = new UdpConnectionInfoMessage(); info.SessionId = Connection.UdpSessionId; info.ServerAddress = Configuration.Instance.UdpHost; info.ServerPort = Configuration.Instance.UdpPort; Connection.Send(info); } private void GoHomeFromOfflinePractiseReceived(GoHomeFromOfflinePractiseMessage message) { if (Connection.Home != null && Connection.Avatar != null) { if (Connection.Avatar.IsTutorialState()) { Connection.Avatar.SkipTutorial(); } SendHomeData(); } } private void AskForBattleEndReceived(AskForBattleEndMessage message) { // Heroes = new List(); // BattleEnd3vs3Message battleEnd3vs3 = new BattleEnd3vs3Message(); // BattleEndSoloMessage battleEndSolo = new BattleEndSoloMessage(); // OwnHomeDataMessage ohd = new OwnHomeDataMessage(); // Hero hero = HomeMode.Avatar.GetHero(HomeMode.Home.CharacterId); // if (hero.CharacterId == 16000000 + message.BrawlerID) // { // battleEnd3vs3.BrawlerTrophies = hero.Trophies; // battleEnd3vs3.BrawlerHighestTrophies = hero.HighestTrophies; // battleEndSolo.BrawlerTrophies = hero.Trophies; // battleEndSolo.BrawlerHighestTrophies = hero.HighestTrophies; // } // ohd.Home = Connection.Home; // ohd.Avatar = Connection.Avatar; // //message.ProgressiveQuests = homeMode.Home.Quests.UpdateQuestsProgress(m_gameModeVariation, player.CharacterId, player.Kills, player.Damage, player.Heals, homeMode.Home); // if (message.players == 6) // { // battleEnd3vs3.battleResult = message.battleResult; // battleEnd3vs3.mathResult = message.mathResult; // battleEnd3vs3.BrawlerID = message.BrawlerID; // battleEnd3vs3.SkinID = message.SkinID; // battleEnd3vs3.Name = ohd.Avatar.Name; // battleEnd3vs3.Exp = ohd.Home.Exp; // } // if (message.players == 10) // { // battleEndSolo.battleResult = message.battleResult; // battleEndSolo.mathResult = message.mathResult; // battleEndSolo.BrawlerID = message.BrawlerID; // battleEndSolo.SkinID = message.SkinID; // battleEndSolo.Name = ohd.Avatar.Name; // battleEndSolo.Exp = ohd.Home.Exp; // } // if (message.players == 6) // { // if (battleEnd3vs3.BrawlerTrophies >= 0 && battleEnd3vs3.BrawlerTrophies <= 49) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Home.Exp += 8; // ohd.Avatar.TrioWins += 1; // } // else // { // battleEnd3vs3.TrophiesReward = 0; // ohd.Home.Exp += 4; // } // } // if (battleEnd3vs3.BrawlerTrophies >= 50 && battleEnd3vs3.BrawlerTrophies <= 99) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Home.Exp += 8; // ohd.Avatar.TrioWins += 1; // } // else // { // battleEnd3vs3.TrophiesReward = -1; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 100 && battleEnd3vs3.BrawlerTrophies <= 199) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -2; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 200 && battleEnd3vs3.BrawlerTrophies <= 299) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -3; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 300 && battleEnd3vs3.BrawlerTrophies <= 399) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -4; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 400 && battleEnd3vs3.BrawlerTrophies <= 499) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -5; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 500 && battleEnd3vs3.BrawlerTrophies <= 599) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -6; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 600 && battleEnd3vs3.BrawlerTrophies <= 699) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -7; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 700 && battleEnd3vs3.BrawlerTrophies <= 799) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 8; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -8; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 800 && battleEnd3vs3.BrawlerTrophies <= 899) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 7; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -9; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 900 && battleEnd3vs3.BrawlerTrophies <= 999) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 6; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -10; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 1000 && battleEnd3vs3.BrawlerTrophies <= 1099) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 5; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -11; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // if (battleEnd3vs3.BrawlerTrophies >= 1100 && battleEnd3vs3.BrawlerTrophies <= 1200) // { // if (message.battleResult == 0) // { // battleEnd3vs3.TrophiesReward = 3; // battleEnd3vs3.TokensReward = 35; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // ohd.Avatar.TrioWins += 1; // ohd.Home.Exp += 8; // } // else // { // battleEnd3vs3.TrophiesReward = -12; // ohd.Home.Exp += 4; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // } // } // } // if (message.players == 10) // { // if (battleEndSolo.BrawlerTrophies >= 0 && battleEndSolo.BrawlerTrophies <= 49) // { // if (message.battleResult == 1) // { // battleEndSolo.TrophiesReward = 10; // battleEndSolo.TokensReward = 34; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Avatar.SoloWins += 1; // ohd.Home.Exp += 15; // } // if (message.battleResult == 2) // { // battleEndSolo.TrophiesReward = 8; // battleEndSolo.TokensReward = 28; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 12; // } // if (message.battleResult == 3) // { // battleEndSolo.TrophiesReward = 7; // battleEndSolo.TokensReward = 22; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 9; // } // if (message.battleResult == 4) // { // battleEndSolo.TrophiesReward = 6; // battleEndSolo.TokensReward = 16; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 6; // } // if (message.battleResult == 5) // { // battleEndSolo.TrophiesReward = 4; // battleEndSolo.TokensReward = 12; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 5; // } // if (message.battleResult == 6) // { // battleEndSolo.TrophiesReward = 2; // battleEndSolo.TokensReward = 8; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 4; // } // if (message.battleResult == 7) // { // battleEndSolo.TrophiesReward = 2; // battleEndSolo.TokensReward = 6; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 3; // } // if (message.battleResult == 8) // { // battleEndSolo.TrophiesReward = 1; // battleEndSolo.TokensReward = 4; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 2; // } // if (message.battleResult == 9) // { // battleEndSolo.TrophiesReward = 0; // battleEndSolo.TokensReward = 2; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 1; // } // if (message.battleResult == 10) // { // battleEndSolo.TrophiesReward = 0; // battleEndSolo.TokensReward = 0; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // } // } // if (battleEndSolo.BrawlerTrophies >= 50 && battleEndSolo.BrawlerTrophies <= 99) // { // if (message.battleResult == 1) // { // battleEndSolo.TrophiesReward = 10; // battleEndSolo.TokensReward = 34; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Avatar.SoloWins += 1; // ohd.Home.Exp += 15; // } // if (message.battleResult == 2) // { // battleEndSolo.TrophiesReward = 8; // battleEndSolo.TokensReward = 28; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 12; // } // if (message.battleResult == 3) // { // battleEndSolo.TrophiesReward = 7; // battleEndSolo.TokensReward = 22; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 9; // } // if (message.battleResult == 4) // { // battleEndSolo.TrophiesReward = 6; // battleEndSolo.TokensReward = 16; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 6; // } // if (message.battleResult == 5) // { // battleEndSolo.TrophiesReward = 3; // battleEndSolo.TokensReward = 12; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 5; // } // if (message.battleResult == 6) // { // battleEndSolo.TrophiesReward = 2; // battleEndSolo.TokensReward = 8; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 4; // } // if (message.battleResult == 7) // { // battleEndSolo.TrophiesReward = 2; // battleEndSolo.TokensReward = 6; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 3; // } // if (message.battleResult == 8) // { // battleEndSolo.TrophiesReward = 0; // battleEndSolo.TokensReward = 4; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 2; // } // if (message.battleResult == 9) // { // battleEndSolo.TrophiesReward = -1; // battleEndSolo.TokensReward = 2; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 1; // } // if (message.battleResult == 10) // { // battleEndSolo.TrophiesReward = -2; // hero.AddTrophies(battleEndSolo.TrophiesReward); // } // } // if (battleEndSolo.BrawlerTrophies >= 100 && battleEndSolo.BrawlerTrophies <= 199) // { // if (message.battleResult == 1) // { // battleEndSolo.TrophiesReward = 10; // battleEndSolo.TokensReward = 34; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Avatar.SoloWins += 1; // ohd.Home.Exp += 15; // } // if (message.battleResult == 2) // { // battleEndSolo.TrophiesReward = 8; // battleEndSolo.TokensReward = 28; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 12; // } // if (message.battleResult == 3) // { // battleEndSolo.TrophiesReward = 7; // battleEndSolo.TokensReward = 22; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 9; // } // if (message.battleResult == 4) // { // battleEndSolo.TrophiesReward = 6; // battleEndSolo.TokensReward = 16; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 6; // } // if (message.battleResult == 5) // { // battleEndSolo.TrophiesReward = 3; // battleEndSolo.TokensReward = 12; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 5; // } // if (message.battleResult == 6) // { // battleEndSolo.TrophiesReward = 1; // battleEndSolo.TokensReward = 8; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 4; // } // if (message.battleResult == 7) // { // battleEndSolo.TrophiesReward = 0; // battleEndSolo.TokensReward = 6; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 3; // } // if (message.battleResult == 8) // { // battleEndSolo.TrophiesReward = -1; // battleEndSolo.TokensReward = 4; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 2; // } // if (message.battleResult == 9) // { // battleEndSolo.TrophiesReward = -2; // battleEndSolo.TokensReward = 2; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // ohd.Home.Exp += 1; // } // if (message.battleResult == 10) // { // battleEndSolo.TrophiesReward = -2; // hero.AddTrophies(battleEndSolo.TrophiesReward); // } // } // } // if (ohd.Avatar.IsPremium == true && message.players == 6) // { // battleEnd3vs3.TrophiesReward += 4; // battleEnd3vs3.TokensReward += 17; // hero.AddTrophies(battleEnd3vs3.TrophiesReward); // ohd.Avatar.AddTokens(battleEnd3vs3.TokensReward); // } // if (ohd.Avatar.IsPremium == true && message.players == 10) // { // battleEndSolo.TrophiesReward += 6; // battleEndSolo.TokensReward += 20; // hero.AddTrophies(battleEndSolo.TrophiesReward); // ohd.Avatar.AddTokens(battleEndSolo.TokensReward); // } // if (message.players == 10) // { // Connection.Send(battleEndSolo); // } // if (message.players == 6) // { // Connection.Send(battleEnd3vs3); // } ; } private void TeamSetLocationReceived(TeamSetLocationMessage message) { if (HomeMode.Avatar.TeamId <= 0) return; TeamEntry team = GetTeam(); if (team == null) return; team.LocationId = message.RequestedMap; //team.CustomModifiers = message.CustomModifiers.ToList(); team.Type = 1; team.TeamUpdated(); FriendOnlineStatusEntryMessage entryMessage = new FriendOnlineStatusEntryMessage(); entryMessage.AvatarId = HomeMode.Avatar.AccountId; entryMessage.PlayerStatus = HomeMode.Avatar.PlayerStatus; foreach (Friend friend in HomeMode.Avatar.Friends.ToArray()) { if (LogicServerListener.Instance.IsPlayerOnline(friend.AccountId)) { LogicServerListener.Instance.GetGameListener(friend.AccountId).SendTCPMessage(entryMessage); } } //HomeMode.Home.EventId = message.locid; } private void ChangeAllianceSettingsReceived(ChangeAllianceSettingsMessage message) { if (HomeMode.Avatar.AllianceId <= 0) return; if (HomeMode.Avatar.AllianceRole != AllianceRole.Leader) return; Alliance alliance = Alliances.Load(HomeMode.Avatar.AllianceId); if (alliance == null) return; if (message.BadgeId >= 8000000 && message.BadgeId < 8000000 + DataTables.Get(DataType.AllianceBadge).Count) { alliance.AllianceBadgeId = message.BadgeId; } else { alliance.AllianceBadgeId = 8000000; } alliance.Description = AdRegex.IsMatch(message.Description ?? "") ? "" : message.Description; alliance.RequiredTrophies = message.RequiredTrophies; Alliances.Save(alliance); Connection.Send(new AllianceResponseMessage() { ResponseType = 10 }); MyAllianceMessage myAlliance = new MyAllianceMessage(); myAlliance.Role = HomeMode.Avatar.AllianceRole; myAlliance.OnlineMembers = alliance.OnlinePlayers; myAlliance.AllianceHeader = alliance.Header; Connection.Send(myAlliance); } private void SendAllianceMailMessage(SendAllianceMailMessage message) { SendAllianceMailMessage sendAllianceMailMessage = message; if (HomeMode.Avatar.AllianceRole != AllianceRole.Leader && HomeMode.Avatar.AllianceRole != AllianceRole.CoLeader) return; if (!string.IsNullOrWhiteSpace(message.Text)) { if (HomeMode.Avatar.AllianceRole != AllianceRole.Leader && HomeMode.Avatar.AllianceRole != AllianceRole.CoLeader) return; if (message.Text.Length > 450) return; addNotifToAllAccounts(message.Text, HomeMode.Avatar.AllianceId); AllianceResponseMessage responseMessages = new AllianceResponseMessage(); responseMessages.ResponseType = 113; Connection.Send(responseMessages); } AllianceResponseMessage responseMessage = new AllianceResponseMessage(); responseMessage.ResponseType = 114; Connection.Send(responseMessage); Connection.Send(sendAllianceMailMessage); } private void addNotifToAllAccounts(string message, long club) { var allAccounts = Accounts.GetRankingList(); foreach (var account in allAccounts) { string accountId = LogicLongCodeGenerator.ToCode(account.AccountId); addNotif(accountId, message, club); } } private void addNotif(string accountId, string message, long club) { long id = LogicLongCodeGenerator.ToId(accountId); Account account = Accounts.Load(id); if (account == null) return; if (account.Avatar.AllianceId != club) return; Notification notification = new Notification { Id = 82, IsViewed = false, MessageEntry = message, Sender = HomeMode.Avatar.Name, ThumbnailSender = HomeMode.Home.ThumbnailId, NameColorSender = HomeMode.Home.Namecolor, skin = 0 }; long timestamp = DateTime.Now.Ticks / TimeSpan.TicksPerSecond; notification.TimePassed = Convert.ToInt32(timestamp % int.MaxValue); if (account.Home?.NotificationFactory == null) return; account.Home.NotificationFactory.Add(notification); Accounts.Save(account); if (LogicServerListener.Instance.IsPlayerOnline(account.AccountId)) { AvailableServerCommandMessage serverCommandMessage = new AvailableServerCommandMessage(); serverCommandMessage.Command = new LogicAddNotificationCommand { Notification = notification }; LogicServerListener.Instance.GetGameListener(account.AccountId).SendTCPMessage(serverCommandMessage); } } private void KickAllianceMemberReceived(KickAllianceMemberMessage message) { if (HomeMode.Avatar.AllianceId <= 0) return; Alliance alliance = Alliances.Load(HomeMode.Avatar.AllianceId); if (alliance == null) return; AllianceMember member = alliance.GetMemberById(message.AccountId); if (member == null) return; ClientAvatar avatar = Accounts.Load(message.AccountId).Avatar; if (HomeMode.Avatar.AllianceRole <= avatar.AllianceRole) return; alliance.Members.Remove(member); avatar.AllianceId = -1; AllianceStreamEntry entry = new AllianceStreamEntry(); entry.AuthorId = HomeMode.Avatar.AccountId; entry.AuthorName = HomeMode.Avatar.Name; entry.Id = ++alliance.Stream.EntryIdCounter; entry.PlayerId = avatar.AccountId; entry.PlayerName = avatar.Name; entry.Type = 4; entry.Event = 1; // kicked entry.AuthorRole = HomeMode.Avatar.AllianceRole; alliance.AddStreamEntry(entry); AllianceResponseMessage response = new AllianceResponseMessage(); response.ResponseType = 70; Connection.Send(response); if (alliance.Members.Count == 0) Alliances.Delete(alliance.Id); else Alliances.Save(alliance); if (LogicServerListener.Instance.IsPlayerOnline(avatar.AccountId)) { LogicServerListener.Instance.GetGameListener(avatar.AccountId).SendTCPMessage(new AllianceResponseMessage() { ResponseType = 100 }); LogicServerListener.Instance.GetGameListener(avatar.AccountId).SendTCPMessage(new MyAllianceMessage()); } } private void TeamSetMemberReadyReceived(TeamSetMemberReadyMessage message) { TeamEntry team = Teams.Get(HomeMode.Avatar.TeamId); if (team == null) return; TeamMember member = team.GetMember(HomeMode.Avatar.AccountId); if (member == null) return; member.IsReady = message.IsReady; team.TeamUpdated(); if (team.IsEveryoneReady()) { Teams.StartGame(team); } } private void TeamChangeMemberSettingsReceived(TeamChangeMemberSettingsMessage message) { ; } private void TeamMemberStatusReceived(TeamMemberStatusMessage message) { if (HomeMode == null) return; if (message.Status < 0) return; TeamEntry team = Teams.Get(HomeMode.Avatar.TeamId); if (team == null) return; TeamMember member = team.GetMember(HomeMode.Avatar.AccountId); if (member == null) return; member.State = message.Status; // Sync current character, skin, namecolor member.CharacterId = HomeMode.Home.CharacterId; member.SkinId = ResolveCurrentSkinId(); member.Namecolor = HomeMode.Home.Namecolor; member.DisplayData.ThumbnailId = HomeMode.Home.ThumbnailId; member.DisplayData.Name = HomeMode.Avatar.Name; Hero hero = HomeMode.Avatar.GetHero(HomeMode.Home.CharacterId); if (hero != null) { member.HeroTrophies = hero.Trophies; member.HeroHighestTrophies = hero.HighestTrophies; member.HeroLevel = hero.PowerLevel; } team.TeamUpdated(); } private void TeamInvitationResponseReceived(TeamInvitationResponseMessage message) { bool isAccept = message.Response == 1; TeamEntry team = Teams.Get(message.TeamId); if (team == null) return; TeamInviteEntry invite = team.GetInviteById(HomeMode.Avatar.AccountId); if (invite == null) return; team.Invites.Remove(invite); if (isAccept) { if (team.Members.Count >= team.MaxPlayers) return; TeamMember member = new TeamMember(); member.AccountId = HomeMode.Avatar.AccountId; member.CharacterId = HomeMode.Home.CharacterId; Hero hero = HomeMode.Avatar.GetHero(HomeMode.Home.CharacterId); member.SkinId = ResolveCurrentSkinId(); member.DisplayData = new PlayerDisplayData(HomeMode.Home.ThumbnailId, HomeMode.Avatar.Name) { Namecolor = HomeMode.Home.Namecolor }; if (hero != null) { member.HeroTrophies = hero.Trophies; member.HeroHighestTrophies = hero.HighestTrophies; member.HeroLevel = hero.PowerLevel; } member.IsOwner = false; member.State = 0; team.Members.Add(member); HomeMode.Avatar.TeamId = team.Id; } team.TeamUpdated(); } private TeamEntry GetTeam() { return Teams.Get(HomeMode.Avatar.TeamId); } private void TeamInviteReceived(TeamInviteMessage message) { TeamEntry team = GetTeam(); if (team == null) return; Account data = Accounts.Load(message.AvatarId); if (data == null) return; if (team.Members.Count >= team.MaxPlayers) return; TeamInviteEntry entry = new TeamInviteEntry(); entry.Slot = message.Team; entry.Name = data.Avatar.Name; entry.Id = message.AvatarId; entry.InviterId = HomeMode.Avatar.AccountId; team.Invites.Add(entry); team.TeamUpdated(); LogicGameListener gameListener = LogicServerListener.Instance.GetGameListener(message.AvatarId); if (gameListener != null) { TeamInvitationMessage teamInvitationMessage = new TeamInvitationMessage(); teamInvitationMessage.TeamId = team.Id; Friend friendEntry = new Friend(); friendEntry.AccountId = HomeMode.Avatar.AccountId; friendEntry.DisplayData = new PlayerDisplayData(HomeMode.Home.ThumbnailId, HomeMode.Avatar.Name) { Namecolor = HomeMode.Home.Namecolor }; friendEntry.Trophies = HomeMode.Avatar.Trophies; teamInvitationMessage.Unknown = 1; teamInvitationMessage.FriendEntry = friendEntry; gameListener.SendTCPMessage(teamInvitationMessage); } } private void TeamClearInviteMessageReceived(TeamClearInviteMessage message) { TeamEntry team = GetTeam(); if (team == null) return; TeamInviteEntry inviteToRemove = team.Invites.FirstOrDefault(invite => invite.Slot == message.Slot); if (inviteToRemove != null) { team.Invites.Remove(inviteToRemove); team.TeamUpdated(); } } private void TeamLeaveReceived(TeamLeaveMessage message) { if (HomeMode.Avatar.TeamId <= 0) return; TeamEntry team = Teams.Get(HomeMode.Avatar.TeamId); if (team == null) { Logger.Print("TeamLeave - Team is NULL!"); HomeMode.Avatar.TeamId = -1; Connection.Send(new TeamLeftMessage()); return; } TeamMember entry = team.GetMember(HomeMode.Avatar.AccountId); if (entry == null) return; HomeMode.Avatar.TeamId = -1; team.Members.Remove(entry); Connection.Send(new TeamLeftMessage()); team.TeamUpdated(); if (team.Members.Count == 0) { Teams.Remove(team.Id); } } private void TeamCreateReceived(TeamCreateMessage message) { TeamEntry team = Teams.Create(); team.Type = message.TeamType; team.MaxPlayers = team.Type == 1 ? 10 : 3; team.LocationId = Events.GetEvents()[0].LocationId; //Console.WriteLine($"[TeamCreateMessage] TeamType: {message.TeamType}."); TeamMember member = new TeamMember(); member.AccountId = HomeMode.Avatar.AccountId; member.CharacterId = HomeMode.Home.CharacterId; Hero hero = HomeMode.Avatar.GetHero(HomeMode.Home.CharacterId); member.SkinId = ResolveCurrentSkinId(); member.DisplayData = new PlayerDisplayData(HomeMode.Home.ThumbnailId, HomeMode.Avatar.Name) { Namecolor = HomeMode.Home.Namecolor }; if (hero != null) { member.HeroLevel = hero.PowerLevel; if (hero.HasStarpower) { CardData card = null; CharacterData cd = DataTables.Get(DataType.Character).GetDataByGlobalId(hero.CharacterId); card = DataTables.Get(DataType.Card).GetData(cd.Name + "_unique"); CardData card2 = DataTables.Get(DataType.Card).GetData(cd.Name + "_unique_2"); if (HomeMode.Avatar.SelectedStarpowers.Contains(card.GetGlobalId())) { member.HeroLevel = 9; member.Starpower = card.GetGlobalId(); } else if (HomeMode.Avatar.SelectedStarpowers.Contains(card2.GetGlobalId())) { member.HeroLevel = 9; member.Starpower = card2.GetGlobalId(); } else if (HomeMode.Avatar.Starpowers.Contains(card.GetGlobalId())) { member.HeroLevel = 9; member.Starpower = card.GetGlobalId(); } else if (HomeMode.Avatar.Starpowers.Contains(card2.GetGlobalId())) { member.HeroLevel = 9; member.Starpower = card2.GetGlobalId(); } } else { member.Starpower = 0; } if (hero.PowerLevel > 5) { string[] cards = { "GrowBush", "Shield", "Heal", "Jump", "ShootAround", "DestroyPet", "PetSlam", "Slow", "Push", "Dash", "SpeedBoost", "BurstHeal", "Spin", "Teleport", "Immunity", "Trail", "Totem", "Grab", "Swing", "Vision", "Regen", "HandGun", "Promote", "Sleep", "Slow", "Reload", "Reload", "Fake", "Trampoline", "Explode" }; CharacterData cd = DataTables.Get(DataType.Character).GetDataByGlobalId(hero.CharacterId); CardData WildCard = null; foreach (string cardname in cards) { string n = char.ToUpper(cd.Name[0]) + cd.Name.Substring(1); WildCard = DataTables.Get(DataType.Card).GetData(n + "_" + cardname); if (WildCard != null) { break; } } if (HomeMode.Avatar.Starpowers.Contains(WildCard.GetGlobalId())) { member.Gadget = WildCard.GetGlobalId(); } } else { member.Gadget = 0; } member.HeroTrophies = hero.Trophies; member.HeroHighestTrophies = hero.HighestTrophies; member.HeroLevel = hero.PowerLevel; } // end if (hero != null) member.IsOwner = true; member.State = 0; team.Members.Add(member); TeamMessage teamMessage = new TeamMessage(); teamMessage.Team = team; HomeMode.Avatar.TeamId = team.Id; Connection.Send(teamMessage); } private void AcceptFriendReceived(AcceptFriendMessage message) { Account data = Accounts.Load(message.AvatarId); if (data == null) return; { Friend entry = HomeMode.Avatar.GetRequestFriendById(message.AvatarId); if (entry == null) return; Friend oldFriend = HomeMode.Avatar.GetAcceptedFriendById(message.AvatarId); if (oldFriend != null) { HomeMode.Avatar.Friends.Remove(entry); Connection.Send(new OutOfSyncMessage()); return; } entry.FriendReason = 0; entry.FriendState = 4; FriendListUpdateMessage update = new FriendListUpdateMessage(); update.Entry = entry; Connection.Send(update); } { ClientAvatar avatar = data.Avatar; Friend entry = avatar.GetFriendById(HomeMode.Avatar.AccountId); if (entry == null) return; entry.FriendState = 4; entry.FriendReason = 0; if (LogicServerListener.Instance.IsPlayerOnline(avatar.AccountId)) { FriendListUpdateMessage update = new FriendListUpdateMessage(); update.Entry = entry; LogicServerListener.Instance.GetGameListener(avatar.AccountId).SendTCPMessage(update); } } } private void RemoveFriendReceived(RemoveFriendMessage message) { Account data = Accounts.Load(message.AvatarId); if (data == null) return; ClientAvatar avatar = data.Avatar; Friend MyEntry = HomeMode.Avatar.GetFriendById(message.AvatarId); if (MyEntry == null) return; MyEntry.FriendState = 0; HomeMode.Avatar.Friends.Remove(MyEntry); FriendListUpdateMessage update = new FriendListUpdateMessage(); update.Entry = MyEntry; Connection.Send(update); Friend OtherEntry = avatar.GetFriendById(HomeMode.Avatar.AccountId); if (OtherEntry == null) return; OtherEntry.FriendState = 0; avatar.Friends.Remove(OtherEntry); if (LogicServerListener.Instance.IsPlayerOnline(avatar.AccountId)) { FriendListUpdateMessage update2 = new FriendListUpdateMessage(); update2.Entry = OtherEntry; LogicServerListener.Instance.GetGameListener(avatar.AccountId).SendTCPMessage(update2); } } private void AddFriendReceived(AddFriendMessage message) { Account data = Accounts.Load(message.AvatarId); if (data == null) { Connection.Send(new AddFriendFailedMessage { Reason = 5 }); return; } if (data.Avatar.AccountId == HomeMode.Avatar.AccountId) { // 2 - too many invites // 4 - invite urself // 5 doesnt exist // 7 - u have too many friends, rm // 8 - u have too many friends Connection.Send(new AddFriendFailedMessage { Reason = 4 }); return; } if (data.Home.BlockFriendRequests) { Connection.Send(new AddFriendFailedMessage { Reason = 0 }); return; } ClientAvatar avatar = data.Avatar; Friend requestEntry = HomeMode.Avatar.GetFriendById(message.AvatarId); if (requestEntry != null) { AcceptFriendReceived(new AcceptFriendMessage() { AvatarId = message.AvatarId }); return; } else { Friend friendEntry = new Friend(); friendEntry.AccountId = HomeMode.Avatar.AccountId; friendEntry.DisplayData = new PlayerDisplayData(HomeMode.Home.ThumbnailId, HomeMode.Avatar.Name) { Namecolor = HomeMode.Home.Namecolor }; friendEntry.FriendReason = message.Reason; friendEntry.FriendState = 3; avatar.Friends.Add(friendEntry); Friend request = new Friend(); request.AccountId = avatar.AccountId; request.DisplayData = new PlayerDisplayData(data.Home.ThumbnailId, data.Avatar.Name) { Namecolor = data.Home.Namecolor }; request.FriendReason = 0; request.FriendState = 2; HomeMode.Avatar.Friends.Add(request); if (LogicServerListener.Instance.IsPlayerOnline(message.AvatarId)) { var gameListener = LogicServerListener.Instance.GetGameListener(message.AvatarId); FriendListUpdateMessage update = new FriendListUpdateMessage(); update.Entry = friendEntry; gameListener.SendTCPMessage(update); } FriendListUpdateMessage update2 = new FriendListUpdateMessage(); update2.Entry = request; Connection.Send(update2); } } private void AskForFriendListReceived(AskForFriendListMessage message) { FriendListMessage friendList = new FriendListMessage(); friendList.Friends = HomeMode.Avatar.Friends.ToArray(); Connection.Send(friendList); } private void PlayerStatusReceived(PlayerStatusMessage message) { if (HomeMode == null) return; HomeMode.Avatar.PlayerStatus = message.Status; Sessions.RefreshFriendEntries(HomeMode.Avatar); Sessions.RefreshAllianceEntries(HomeMode.Avatar); } private void SendMyAllianceData(Alliance alliance) { MyAllianceMessage myAlliance = new MyAllianceMessage(); myAlliance.Role = HomeMode.Avatar.AllianceRole; myAlliance.OnlineMembers = alliance.OnlinePlayers; myAlliance.AllianceHeader = alliance.Header; Connection.Send(myAlliance); AllianceStreamMessage stream = new AllianceStreamMessage(); stream.Entries = alliance.Stream.GetEntries(); Connection.Send(stream); } private int BotIdCounter; private void ChatToAllianceStreamReceived(ChatToAllianceStreamMessage message) { Alliance alliance = Alliances.Load(HomeMode.Avatar.AllianceId); if (alliance == null) return; if (message.Message.StartsWith("/")) { string[] cmd = message.Message.Substring(1).Split(' '); if (cmd.Length == 0) return; Logger.Command($"Alliance command from {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}: {message.Message}"); AllianceStreamEntryMessage response = new AllianceStreamEntryMessage(); response.Entry = new AllianceStreamEntry(); response.Entry.AuthorName = "Debugger"; response.Entry.AuthorId = 1; response.Entry.Id = alliance.Stream.EntryIdCounter + 667 + BotIdCounter++; response.Entry.AuthorRole = AllianceRole.Member; response.Entry.Type = 2; long accountId = HomeMode.Avatar.AccountId; switch (cmd[0]) { case "status": long megabytesUsed = Process.GetCurrentProcess().PrivateMemorySize64 / (1024 * 1024); response.Entry.Message = $"Server status\n" + $"Version: v{Program.SERVER_VERSION} ({Program.BUILD_TYPE})\n" + $"Online: {Sessions.Count}\n" + $"Cached accounts: {AccountCache.Count}\n" + $"Cached clubs: {AllianceCache.Count}\n" + $"Cached teams: {Teams.Count}\n" + $"Your tag: {LogicLongCodeGenerator.ToCode(accountId)}\n" + $"Memory: {megabytesUsed} MB"; Connection.Send(response); break; case "help": response.Entry.Message = "Club commands\n" + "/help - show this list\n" + "/status - show server status"; Connection.Send(response); break; default: response.Entry.Message = $"Unknown command \"{cmd[0]}\".\nUse /help to see available club commands."; Connection.Send(response); break; } return; } Logger.Command($"Alliance chat from {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}: {message.Message}"); alliance.SendChatMessage(HomeMode.Avatar.AccountId, message.Message); } private void JoinAllianceReceived(JoinAllianceMessage message) { Alliance alliance = Alliances.Load(message.AllianceId); if (HomeMode.Avatar.AllianceId > 0) return; if (alliance == null) return; if (alliance.Members.Count >= 100) return; AllianceStreamEntry entry = new AllianceStreamEntry(); entry.AuthorId = HomeMode.Avatar.AccountId; entry.AuthorName = HomeMode.Avatar.Name; entry.Id = ++alliance.Stream.EntryIdCounter; entry.PlayerId = HomeMode.Avatar.AccountId; entry.PlayerName = HomeMode.Avatar.Name; entry.Type = 4; entry.Event = 3; entry.AuthorRole = HomeMode.Avatar.AllianceRole; alliance.AddStreamEntry(entry); HomeMode.Avatar.AllianceRole = AllianceRole.Member; HomeMode.Avatar.AllianceId = alliance.Id; alliance.Members.Add(new AllianceMember(HomeMode.Avatar)); AllianceResponseMessage response = new AllianceResponseMessage(); response.ResponseType = 40; Connection.Send(response); SendMyAllianceData(alliance); } private void LeaveAllianceReceived(LeaveAllianceMessage message) { if (HomeMode.Avatar.AllianceId < 0 || HomeMode.Avatar.AllianceRole == AllianceRole.None) return; Alliance alliance = Alliances.Load(HomeMode.Avatar.AllianceId); if (alliance == null) return; alliance.RemoveMemberById(HomeMode.Avatar.AccountId); HomeMode.Avatar.AllianceId = -1; HomeMode.Avatar.AllianceRole = AllianceRole.None; AllianceStreamEntry entry = new AllianceStreamEntry(); entry.AuthorId = HomeMode.Avatar.AccountId; entry.AuthorName = HomeMode.Avatar.Name; entry.Id = ++alliance.Stream.EntryIdCounter; entry.PlayerId = HomeMode.Avatar.AccountId; entry.PlayerName = HomeMode.Avatar.Name; entry.Type = 4; entry.Event = 4; entry.AuthorRole = HomeMode.Avatar.AllianceRole; alliance.AddStreamEntry(entry); AllianceResponseMessage response = new AllianceResponseMessage(); response.ResponseType = 80; Connection.Send(response); if (alliance.Members.Count == 0) Alliances.Delete(alliance.Id); else Alliances.Save(alliance); MyAllianceMessage myAlliance = new MyAllianceMessage(); Connection.Send(myAlliance); } private void CreateAllianceReceived(CreateAllianceMessage message) { if (HomeMode.Avatar.AllianceId >= 0) return; Alliance alliance = new Alliance(); alliance.Name = AdRegex.IsMatch(message.Name ?? "") ? "Club" : message.Name; alliance.Description = AdRegex.IsMatch(message.Description ?? "") ? "" : message.Description; alliance.RequiredTrophies = message.RequiredTrophies; if (message.BadgeId >= 8000000 && message.BadgeId < 8000000 + DataTables.Get(DataType.AllianceBadge).Count) { alliance.AllianceBadgeId = message.BadgeId; } else { alliance.AllianceBadgeId = 8000000; } HomeMode.Avatar.AllianceRole = AllianceRole.Leader; alliance.Members.Add(new AllianceMember(HomeMode.Avatar)); Alliances.Create(alliance); HomeMode.Avatar.AllianceId = alliance.Id; AllianceResponseMessage response = new AllianceResponseMessage(); response.ResponseType = 20; Connection.Send(response); SendMyAllianceData(alliance); } private void AskForAllianceDataReceived(AskForAllianceDataMessage message) { Alliance alliance = Alliances.Load(message.AllianceId); if (alliance == null) return; AllianceDataMessage data = new AllianceDataMessage(); data.Alliance = alliance; data.IsMyAlliance = message.AllianceId == HomeMode.Avatar.AllianceId; Connection.Send(data); } private void AskForJoinableAllianceListReceived(AskForJoinableAllianceListMessage message) { JoinableAllianceListMessage list = new JoinableAllianceListMessage(); List alliances = Alliances.GetRandomAlliances(10); foreach (Alliance alliance in alliances) { list.JoinableAlliances.Add(alliance.Header); } Connection.Send(list); } private void ClientCapabilitesReceived(ClientCapabilitiesMessage message) { Connection.PingUpdated(message.Ping); Logger.Network($"Ping from {(Connection == null ? "conn#?" : Connection.Describe())}: {message.Ping}ms"); LobbyInfoMessage lobbyInfo = new LobbyInfoMessage(); lobbyInfo.Ping = message.Ping; lobbyInfo.PlayersOnline = Sessions.Count; Connection.Send(lobbyInfo); } private void GetLeaderboardReceived(GetLeaderboardMessage message) { if (message.LeaderboardType == 1) { Account[] rankingList = Leaderboards.GetAvatarRankingList(); LeaderboardMessage leaderboard = new LeaderboardMessage(); leaderboard.LeaderboardType = 1; leaderboard.Region = message.IsRegional ? "RU" : null; foreach (Account data in rankingList) { leaderboard.Avatars.Add(new KeyValuePair(data.Home, data.Avatar)); } leaderboard.OwnAvatarId = Connection.Avatar.AccountId; Connection.Send(leaderboard); } else if (message.LeaderboardType == 2) { Alliance[] rankingList = Leaderboards.GetAllianceRankingList(); LeaderboardMessage leaderboard = new LeaderboardMessage(); leaderboard.LeaderboardType = 2; leaderboard.Region = message.IsRegional ? "RU" : null; leaderboard.AllianceList.AddRange(rankingList); Connection.Send(leaderboard); } if (message.LeaderboardType == 0) { Account[] rankingList = Leaderboards.GetAvatarRankingList(); Hero hero = HomeMode.Avatar.GetHero(message.BrawlerID); LeaderboardMessage leaderboard = new LeaderboardMessage(); leaderboard.LeaderboardType = 0; leaderboard.Region = message.IsRegional ? "RU" : null; leaderboard.BrawlerTrophies = hero.Trophies; leaderboard.BrawlerID = message.BrawlerID; foreach (Account data in rankingList) { leaderboard.Avatars.Add(new KeyValuePair(data.Home, data.Avatar)); } leaderboard.OwnAvatarId = Connection.Avatar.AccountId; Connection.Send(leaderboard); } } private void GoHomeReceived(GoHomeMessage message) { if (Connection.Home != null && Connection.Avatar != null) { SendHomeData(); } } private void ClientInfoReceived(ClientInfoMessage message) { UdpConnectionInfoMessage info = new UdpConnectionInfoMessage(); info.SessionId = Connection.UdpSessionId; info.ServerAddress = Configuration.Instance.UdpHost; info.ServerPort = Configuration.Instance.UdpPort; Connection.Send(info); } private void CancelMatchMaking(CancelMatchmakingMessage message) { Matchmaking.CancelMatchmake(Connection); Connection.Send(new MatchMakingCancelledMessage()); } private void MatchmakeRequestReceived(MatchmakeRequestMessage message) { int slot = message.EventSlot; ClientHelloMessage hello = new ClientHelloMessage(); // кто тут уберет // тот долбоёб // if (HomeMode.Home.Character.Disabled || hello.KeyVersion == 14 && hello.MajorVersion == 27) // { // Connection.Send(new OutOfSyncMessage()); // return; // } if (!Events.HasSlot(slot)) { slot = 1; } Matchmaking.RequestMatchmake(Connection, slot); var (found, max, seconds) = Matchmaking.GetQueueStatus(slot); MatchMakingStatusMessage status = new MatchMakingStatusMessage(); status.Seconds = MatchmakingSlot.SEARCH_TIMEOUT; status.Found = found + 1; status.Max = max; status.ShowTips = true; Connection.Send(status); } private void EndClientTurnReceived(EndClientTurnMessage message) { HomeMode.ClientTurnReceived(message.Tick, message.Checksum, message.Commands); SaveCurrentAccount(); } private void GetPlayerProfile(GetPlayerProfileMessage message) { Account data = Accounts.Load(message.AccountId); if (data == null) return; Profile profile = Profile.Create(data.Home, data.Avatar); PlayerProfileMessage profileMessage = new PlayerProfileMessage(); profileMessage.Profile = profile; if (data.Avatar.AllianceId >= 0) { Alliance alliance = Alliances.Load(data.Avatar.AllianceId); if (alliance != null) { profileMessage.AllianceHeader = alliance.Header; profileMessage.AllianceRole = data.Avatar.AllianceRole; } } Connection.Send(profileMessage); } private static readonly Regex AdRegex = new Regex( @"tg|тг|@|t\.me|telega|telegram|телеграм|телега|тгк|ддос|ddos|t g|т г||http|www\.|\.com|\.ru|vk\.com|discord|youtube|youtu\.be|instagram|tiktok|twitch|twitter|x\.com|cheat|cheats|hack|hacks|хак|хакер|читер|читы|чит|mod\s*menu|modmenu|aimbot|wallhack|esp\b|speedhack|inject|injector", RegexOptions.IgnoreCase | RegexOptions.Compiled); private void ChangeName(ChangeAvatarNameMessage message) { if (message.Name.Length < 2 || message.Name.Length > 16) return; if (AdRegex.IsMatch(message.Name)) { AuditLogger.NameBlocked(Connection.Avatar.AccountId, Connection.Avatar.Name, message.Name); Connection.Send(new AuthenticationFailedMessage { ErrorCode = 11, Message = "Вы не можете поменять свой ник на этот." }); return; } if (HomeMode.Avatar.AllianceId > 0) { Alliance a = Alliances.Load(HomeMode.Avatar.AllianceId); if (a != null) { AllianceMember m = a.GetMemberById(HomeMode.Avatar.AccountId); if (m != null) m.DisplayData.Name = message.Name; } } LogicChangeAvatarNameCommand command = new() { Name = message.Name, ChangeNameCost = 0 }; AuditLogger.NameChanged(Connection.Avatar.AccountId, Connection.Avatar.Name, message.Name); command.Execute(HomeMode); AvailableServerCommandMessage serverCommandMessage = new() { Command = command }; Connection.Send(serverCommandMessage); } private void OnChangeCharacter(int characterId) { TeamEntry team = Teams.Get(HomeMode.Avatar.TeamId); if (team == null) return; TeamMember member = team.GetMember(HomeMode.Avatar.AccountId); if (member == null) return; Hero hero = HomeMode.Avatar.GetHero(characterId); if (hero == null) return; member.CharacterId = characterId; member.HeroTrophies = hero.Trophies; member.HeroHighestTrophies = hero.HighestTrophies; member.HeroLevel = hero.PowerLevel; member.Namecolor = HomeMode.Home.Namecolor; team.TeamUpdated(); } private static string ExtractCountryCode(AuthenticationMessage message) { if (string.IsNullOrWhiteSpace(message?.PreferredDeviceLanguage)) { return null; } string[] parts = message.PreferredDeviceLanguage.Split(new[] { '-', '_' }, StringSplitOptions.RemoveEmptyEntries); if (parts.Length == 0) { return null; } string candidate = parts.Length > 1 ? parts[^1] : parts[0]; if (candidate.Length != 2) { return null; } return BanRegistry.NormalizeCountryCode(candidate); } private static string BuildTimedBanMessage(string scope, DateTime? expiresAtUtc) { if (!expiresAtUtc.HasValue) { return $"Your {scope} is banned."; } return $"Your {scope} is temporarily banned until {expiresAtUtc.Value:yyyy-MM-dd HH:mm:ss} UTC."; } private static string BuildAccountBanMessage(ClientAvatar avatar) { if (avatar.Banned) { return "Your account is banned."; } return BuildTimedBanMessage("account", avatar.BanEndTime); } private void LoginReceived(AuthenticationMessage message) { string remoteIpAddress = Connection.RemoteIpAddress; string countryCode = ExtractCountryCode(message); Logger.Network( $"Login attempt from {(Connection == null ? "conn#?" : Connection.Describe())} — account #{message.AccountId}, " + $"v{message.Major}.{message.Minor}.{message.Build}, {(message.IsAndroid ? "Android" : "iOS")}, {countryCode ?? "unknown"}" ); if (BanRegistry.TryGetIpBan(remoteIpAddress, out BanEntry ipBanEntry)) { Logger.Warning($"Blocked IP-banned login for {(Connection == null ? "conn#?" : Connection.Describe())} | ip={remoteIpAddress}"); AuditLogger.LoginFailed("ip_ban", remoteIpAddress, message.Device ?? "?"); AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 11; loginFailed.Message = BuildTimedBanMessage("IP", ipBanEntry.ExpiresAtUtc); Connection.Send(loginFailed); return; } if (countryCode != null && BanRegistry.TryGetCountryBan(countryCode, out BanEntry countryBanEntry)) { Logger.Warning($"Blocked country-banned login for {(Connection == null ? "conn#?" : Connection.Describe())} | country={countryCode}"); AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 11; loginFailed.Message = BuildTimedBanMessage("country", countryBanEntry.ExpiresAtUtc); Connection.Send(loginFailed); return; } Account bannedDeviceAccount = Accounts.GetBannedAccountByAndroidId(message.AndroidId); if (bannedDeviceAccount != null) { Logger.Warning( $"Blocked device-banned login for {(Connection == null ? "conn#?" : Connection.Describe())} | " + $"androidId={message.AndroidId} | bannedBy={bannedDeviceAccount.Avatar.Name}#{bannedDeviceAccount.AccountId}" ); AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 11; loginFailed.Message = "Твоё устройство было заблокировано."; Connection.Send(loginFailed); return; } Account account = null; if (message.AccountId == 0) { account = Accounts.Create(); } else { account = Accounts.Load(message.AccountId); if (account.PassToken != message.PassToken) { account = null; } } if (account == null) { Logger.Warning($"Auth failed for {(Connection == null ? "conn#?" : Connection.Describe())} | account not found or invalid token"); AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 1; loginFailed.Message = "Your account not found.\nTry to clear app data."; Connection.Send(loginFailed); return; } // Kick duplicate sessions if (account.Avatar.AccountIdRedirect != 0 && Sessions.IsSessionActive(account.Avatar.AccountIdRedirect)) { Sessions.GetSession(account.Avatar.AccountIdRedirect).GameListener.SendTCPMessage(new AuthenticationFailedMessage { Message = "Другое устройство подключилось к этой игре!" }); Sessions.Remove(account.Avatar.AccountIdRedirect); } if (Sessions.IsSessionActive(message.AccountId)) { Sessions.GetSession(message.AccountId).GameListener.SendTCPMessage(new AuthenticationFailedMessage { Message = "Другое устройство подключилось к этой игре!" }); Sessions.Remove(message.AccountId); } // AccountIdRedirect if (account.Avatar.AccountIdRedirect != 0) { account = Accounts.Load(account.Avatar.AccountIdRedirect); if (account == null) { AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 22; loginFailed.Message = "Account not loaded."; Connection.Send(loginFailed); return; } } if (countryCode == null) { countryCode = BanRegistry.NormalizeCountryCode(account.Home?.CountryCode); if (countryCode != null && BanRegistry.TryGetCountryBan(countryCode, out BanEntry storedCountryBanEntry)) { Logger.Warning($"Blocked stored-country-banned login for {account.Avatar.Name}#{account.AccountId} | country={countryCode}"); AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 11; loginFailed.Message = BuildTimedBanMessage("country", storedCountryBanEntry.ExpiresAtUtc); Connection.Send(loginFailed); return; } } if (account.Avatar.TryExpireBan()) { Accounts.Save(account); } if (account.Avatar.HasActiveBan()) { Logger.Warning($"Blocked banned account login for {account.Avatar.Name}#{account.AccountId}"); AuditLogger.LoginFailed($"account_ban:{account.Avatar.BannedReason}", remoteIpAddress, message.Device ?? "?"); var session = Sessions.GetSession(message.AccountId); Sessions.Remove(message.AccountId); AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 11; loginFailed.Message = BuildAccountBanMessage(account.Avatar); Connection.Send(loginFailed); return; } if (message.Android == null) { Logger.Warning($"Rejected null OS version for {(Connection == null ? "conn#?" : Connection.Describe())}"); AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 11; account.Avatar.ApplyPermanentBan("missing_os_version"); account.Avatar.ResetTrophies(); account.Avatar.Name = "Brawler"; Accounts.UpdateLoginMetadata(account, message.Device, message.AndroidId, remoteIpAddress, countryCode); Accounts.Save(account); Connection.Send(loginFailed); return; } if (account.Avatar.Name == "Bot" && account.Avatar.Name == "Точно не бот") { AuthenticationFailedMessage loginFailed = new AuthenticationFailedMessage(); loginFailed.ErrorCode = 11; Connection.Send(loginFailed); return; } AuthenticationOkMessage loginOk = new AuthenticationOkMessage(); loginOk.AccountId = account.AccountId; loginOk.PassToken = account.PassToken; loginOk.ServerEnvironment = "prod"; Accounts.UpdateLoginMetadata(account, message.Device, message.AndroidId, remoteIpAddress, countryCode); Connection.Send(loginOk); HomeMode = HomeMode.LoadHomeState(new HomeGameListener(Connection), account.Home, account.Avatar, Events.GetEvents()); HomeMode.CharacterChanged += OnChangeCharacter; BattleMode battle = null; if (HomeMode.Avatar.BattleId > 0) { battle = Battles.Get(HomeMode.Avatar.BattleId); } if (battle == null) { SendHomeData(sendStoredNotifications: true); } else { StartLoadingMessage startLoading = new StartLoadingMessage(); startLoading.LocationId = battle.Location.GetGlobalId(); startLoading.TeamIndex = HomeMode.Avatar.TeamIndex; startLoading.OwnIndex = HomeMode.Avatar.OwnIndex; startLoading.GameMode = (battle.GetGameModeVariation() == 6 || battle.GetGameModeVariation() == 9) ? 6 : 1; startLoading.Players.AddRange(battle.GetPlayers()); UDPSocket socket = UDPGateway.CreateSocket(); socket.TCPConnection = Connection; socket.Battle = battle; Connection.UdpSessionId = socket.SessionId; battle.ChangePlayerSessionId(HomeMode.Avatar.UdpSessionId, socket.SessionId); HomeMode.Avatar.UdpSessionId = socket.SessionId; Connection.Send(startLoading); } Connection.Avatar.LastOnline = DateTime.UtcNow; Sessions.Create(HomeMode, Connection); Logger.Success( $"{HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId} logged in — " + $"v{message.Major}.{message.Minor}.{message.Build}, {(message.IsAndroid ? "Android" : "iOS")} {message.Android}, " + $"{message.Device}, {message.PreferredDeviceLanguage}, {countryCode ?? "unknown"}, online={Sessions.Count}" ); FriendListMessage friendList = new FriendListMessage(); friendList.Friends = HomeMode.Avatar.Friends.ToArray(); Connection.Send(friendList); if (HomeMode.Avatar.AllianceRole != AllianceRole.None && HomeMode.Avatar.AllianceId > 0) { Alliance alliance = Alliances.Load(HomeMode.Avatar.AllianceId); if (alliance != null) { SendMyAllianceData(alliance); AllianceDataMessage data = new AllianceDataMessage(); data.Alliance = alliance; data.IsMyAlliance = true; Connection.Send(data); } } foreach (Friend entry in HomeMode.Avatar.Friends.ToArray()) { if (LogicServerListener.Instance.IsPlayerOnline(entry.AccountId)) { FriendOnlineStatusEntryMessage statusEntryMessage = new FriendOnlineStatusEntryMessage(); statusEntryMessage.AvatarId = entry.AccountId; statusEntryMessage.PlayerStatus = entry.Avatar.PlayerStatus; Connection.Send(statusEntryMessage); } } if (HomeMode.Avatar.TeamId > 0) { TeamMessage teamMessage = new TeamMessage(); teamMessage.Team = Teams.Get(HomeMode.Avatar.TeamId); if (teamMessage.Team != null) { Connection.Send(teamMessage); TeamMember member = teamMessage.Team.GetMember(HomeMode.Avatar.AccountId); member.State = 0; member.Namecolor = HomeMode.Home.Namecolor; teamMessage.Team.TeamUpdated(); } } } private void AnalyticEventReceived(AnalyticEventMessage message) { if (HomeMode == null) { return; } Logger.Info($"Analytic event from {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}: {message.Type}"); if (message.Event == "{\"step\":\"click_to_end\",\"step_id\":\"18\"}" && HomeMode.Avatar.TutorialsCompletedCount < 2) { HomeMode.Avatar.TutorialsCompletedCount++; SaveCurrentAccount(); Logger.Info($"Tutorial progress updated for {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}: {HomeMode.Avatar.TutorialsCompletedCount}"); } if (string.IsNullOrWhiteSpace(message.Event)) { return; } try { string voucherCode = ExtractVoucherCode(message); if (string.IsNullOrWhiteSpace(voucherCode)) { return; } // Если этот код создан ботом для привязки — обработаем через TelegramBot try { if (Supercell.Laser.Server.Message.TelegramBot.TryHandleBindingVoucher(HomeMode, voucherCode)) { return; } } catch (Exception ex) { Logger.Exception("TelegramBot.TryHandleBindingVoucher failed", ex); } if (VoucherManager.TryRedeemVoucher(HomeMode, voucherCode, out var command, out var reason)) { AvailableServerCommandMessage serverCommandMessage = new AvailableServerCommandMessage(); serverCommandMessage.Command = command; Connection.Send(serverCommandMessage); SaveCurrentAccount(); Logger.Success($"Voucher redeemed for {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}: {voucherCode}"); } else { Logger.Warning($"Voucher redeem rejected for {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}: {voucherCode} ({reason})"); } } catch (Exception exception) { Logger.Exception($"Failed to process analytic event for {HomeMode.Avatar.Name}#{HomeMode.Avatar.AccountId}", exception); } } private void ClientHelloReceived(ClientHelloMessage message) { if (Sessions.Maintenance) { Connection.Send(new AuthenticationFailedMessage() { ErrorCode = 10 }); return; } Connection.Messaging.Seed = message.ClientSeed; Logger.Network($"New connection from {(Connection == null ? "conn#?" : Connection.Describe())} — protocol {message.Protocol}, key {message.KeyVersion}, v{message.MajorVersion}"); ServerHelloMessage hello = new ServerHelloMessage(); hello.SetServerHelloToken(Connection.Messaging.SessionToken); Connection.Send(hello); } private void SaveCurrentAccount() { if (HomeMode?.Avatar == null) { return; } Account account = Accounts.Load(HomeMode.Avatar.AccountId); if (account == null) { return; } account.Home = HomeMode.Home; account.Avatar = HomeMode.Avatar; AccountCache.Cache(account); Accounts.Save(account); } private void SendStoredNotifications() { if (HomeMode?.Home?.NotificationFactory?.NotificationList == null) { return; } foreach (var notification in HomeMode.Home.NotificationFactory.NotificationList) { AvailableServerCommandMessage serverCommandMessage = new AvailableServerCommandMessage(); serverCommandMessage.Command = new LogicAddNotificationCommand { Notification = notification }; Connection.Send(serverCommandMessage); } } private void SendHomeData(bool sendStoredNotifications = false) { if (Connection.Home == null || Connection.Avatar == null) { return; } OwnHomeDataMessage ownHomeData = new OwnHomeDataMessage { Home = Connection.Home, Avatar = Connection.Avatar }; Connection.Send(ownHomeData); if (sendStoredNotifications) { SendStoredNotifications(); } } private static string ExtractVoucherCode(AnalyticEventMessage message) { string code = ExtractVoucherCodeFromString(message.Event); if (!string.IsNullOrWhiteSpace(code)) { return code; } return ExtractVoucherCodeFromString(message.Type); } private static string ExtractVoucherCodeFromString(string value) { if (string.IsNullOrWhiteSpace(value)) { return null; } string trimmed = value.Trim(); if (trimmed.StartsWith("{") && trimmed.EndsWith("}")) { try { JObject payload = JObject.Parse(trimmed); string code = payload.Value("code"); if (!string.IsNullOrWhiteSpace(code)) { return code.Trim(); } string action = payload.Value("action"); if (string.Equals(action, "voucher", StringComparison.OrdinalIgnoreCase)) { code = payload.Value("voucher"); if (!string.IsNullOrWhiteSpace(code)) { return code.Trim(); } } string link = payload.Value("link") ?? payload.Value("url") ?? payload.Value("deep_link"); if (!string.IsNullOrWhiteSpace(link)) { return ExtractVoucherCodeFromString(link); } } catch { // Ignore JSON parsing errors } } if (trimmed.Contains("action=voucher", StringComparison.OrdinalIgnoreCase) || trimmed.Contains("code=", StringComparison.OrdinalIgnoreCase)) { int queryIndex = trimmed.IndexOf('?'); string query = queryIndex >= 0 ? trimmed.Substring(queryIndex + 1) : trimmed; string action = null; string code = null; foreach (string pair in query.Split('&', StringSplitOptions.RemoveEmptyEntries)) { string[] parts = pair.Split('=', 2); string key = Uri.UnescapeDataString(parts[0]).Trim(); string pairValue = parts.Length > 1 ? Uri.UnescapeDataString(parts[1]).Trim() : string.Empty; if (key.Equals("action", StringComparison.OrdinalIgnoreCase)) { action = pairValue; } else if (key.Equals("code", StringComparison.OrdinalIgnoreCase)) { code = pairValue; } } if (string.Equals(action, "voucher", StringComparison.OrdinalIgnoreCase) && !string.IsNullOrWhiteSpace(code)) { return code; } } string[] endpoints = new[] { "voucher/", "register/", "login/" }; foreach (string ep in endpoints) { int idx = trimmed.IndexOf(ep, StringComparison.OrdinalIgnoreCase); if (idx >= 0) { string code = trimmed.Substring(idx + ep.Length).Trim('/', ' ', '"'); int separator = code.IndexOfAny(new[] { '?', '&', '#' }); if (separator >= 0) { code = code.Substring(0, separator); } if (!string.IsNullOrWhiteSpace(code)) { return code; } } } return null; } } }