/// <summary> /// 服务器广播准备 /// </summary> /// <param name="obj"></param> private void OnServerBroadcastShiSanZhangReady(byte[] obj) { SSS_READY proto = SSS_READY.decode(obj); IGameCommand command = new ReadyCommand(proto.pos); CommandQueue.Enqueue(command); }
public void sendReady() { ReadyCommand cmd = new ReadyCommand(); cmd.type = (int)CommandType.READY; cmd.playerName = curPlayer.playerName; cmd.partyName = curParty.partyName; cmd.isReady = !curPlayer.isReady; string jsonCmd = JsonUtility.ToJson(cmd); currentSocket.Send(jsonCmd); curPlayer.isReady = !curPlayer.isReady; }
public IActionResult UnBanAction(string UserIp, string SteamId, string Reason, string Comment) { UnBanModel.UserIp = UserIp; UnBanModel.Reason = Reason; UnBanModel.SteamId = SteamId; UnBanModel.Comment = Comment; if (UnBanModel.SteamId == "0") { UnBanModel.Message = "Вы не можете разбанить этого игрока"; Global.Debug("User " + Program._client.GetUser(Global.Sessions[UnBanModel.UserIp].User.DiscordId).Mention + " try to unban Server player"); } else { ReadyCommand c = new ReadyCommand() { SenderDiscordId = Global.Sessions[UserIp].User.DiscordId, IsSuccess = true, FailedDebugMessage = "Администратор " + Program._client.GetUser(Global.Sessions[UnBanModel.UserIp].User.DiscordId).Mention + " попытался разбанить игрока со SteamId64: " + UnBanModel.SteamId + " по причине '" + UnBanModel.Reason + "'. Комментарий администратора: '" + UnBanModel.Comment + "'", SuccessDebugMessage = "Игрок (Nickname) (SteamId64: " + UnBanModel.SteamId + "), забаненный по причине '(Reason)', был разбанен администратором " + Program._client.GetUser(Global.Sessions[UnBanModel.UserIp].User.DiscordId).Mention + " по причине '" + UnBanModel.Reason + "'. Комментарий администратора: '" + UnBanModel.Comment + "'", CommandName = "unban", Args = new List <string>() { UnBanModel.SteamId } }; if (!Global.SaveUsers()) { Global.DebugSystemError("Failed to save USER: \nName: " + Global.users.Where(x => x.DiscordId == Global.Sessions[UserIp].User.DiscordId).First().Name + " \nDiscordId: " + Global.users.Where(x => x.DiscordId == Global.Sessions[UserIp].User.DiscordId).First().DiscordId); } UnBanModel.Message = Global.SendCommandToReady(c, Global.servers.FirstOrDefault().ServerName); } return(RedirectToAction("Refresh", new { UserIp, SteamId, Reason, Comment, UnBanModel.Message })); }
public static string SendCommandToReady(ReadyCommand command, string server) { if (server == WrongServerName) { return("Сервер обновляет данные. Команда не отправлена"); } List <ReadyCommand> commands = new List <ReadyCommand>(); if (File.Exists(Path.Combine(ServerInfoFiles[server], OFivePlugin.Global.ReadyCommandsFileName))) { try { using (StreamReader sr = new StreamReader(Path.Combine(ServerInfoFiles[server], OFivePlugin.Global.ReadyCommandsFileName))) { commands = (List <ReadyCommand>)Formatter_Commands.Deserialize(sr); } } catch (InvalidOperationException) { return("Произошла техническая ошибка. Пожалуйста, сообщите об этом руководству."); } } commands.Add(command); try { using (StreamWriter sw = new StreamWriter(Path.Combine(ServerInfoFiles[server], OFivePlugin.Global.ReadyCommandsFileName))) { Formatter_Commands.Serialize(sw, commands); } return("Команда успешно послана на сервер"); } catch (InvalidOperationException) { return("Произошла техническая ошибка (2). Пожалуйста, сообщите об этом руководству."); } }
void Update() { if (messageQueue.Count > 0) { string message = messageQueue.Dequeue(); Command curCommand = JsonUtility.FromJson <Command>(message); if (curCommand.type == (int)CommandType.ERROR) { ErrorMessage eMessage = JsonUtility.FromJson <ErrorMessage>(message); SceneControl.Instance.error(eMessage.errorMessage, eMessage.prevScreen); } else if (curCommand.type == (int)CommandType.APPROVE_CREATE) { ApproveCreate appr = JsonUtility.FromJson <ApproveCreate>(message); curParty = appr.party; PartyControl.Instance.curParty = appr.party; curPlayer.isHost = true; SceneControl.Instance.goToSceneID(21); } else if (curCommand.type == (int)CommandType.APPROVE_JOIN) { ApproveJoin appr = JsonUtility.FromJson <ApproveJoin>(message); curParty = appr.party; PartyControl.Instance.curParty = appr.party; SceneControl.Instance.goToSceneID(21); } else if (curCommand.type == (int)CommandType.APPROVE_LEAVE) { curParty = null; PartyControl.Instance.curParty = null; curPlayer.isHost = false; curPlayer.isReady = false; } else if (curCommand.type == (int)CommandType.READY) { ReadyCommand cmd = JsonUtility.FromJson <ReadyCommand>(message); foreach (PlayerInfo player in PartyControl.Instance.curParty.userList) { if (player.playerName.Equals(cmd.playerName)) { player.isReady = cmd.isReady; } } PartyScreenViewModel.Instance.reloadView(); } else if (curCommand.type == (int)CommandType.PARTY_LIST) { PartyList pList = JsonUtility.FromJson <PartyList>(message); JoinPartyViewModel.Instance.displayParties(pList.partyList); } else if (curCommand.type == (int)CommandType.RELOAD_VIEW) { ReloadView reloadView = JsonUtility.FromJson <ReloadView>(message); curParty = reloadView.party; PartyControl.Instance.curParty = reloadView.party; PartyScreenViewModel.Instance.reloadView(); } else if (curCommand.type == (int)CommandType.CREATE_PLAYER) { CreatePlayer crtPlay = JsonUtility.FromJson <CreatePlayer>(message); curPlayer.id = crtPlay.playerID; } else if (curCommand.type == (int)CommandType.LOAD_CONFIRM) { load = true; } } }
public IActionResult Ban(string UserIp, string Server, string Player, string Reason, int Time, string Comment, string CustomReason) { AdminModel.UserIp = UserIp; AdminModel.Server = Global.servers.Where(x => x.ServerName == Server).First(); if (AdminModel.Server.players.Where(x => x.Nickname == Player).FirstOrDefault() == default) { Global.DebugSystemError("Catch wrong player nickname: '" + Player + "'"); return(RedirectToAction("Refresh", new { UserIp, Server, AdminModel.Server.players.First().Nickname, Reason, Time, Comment, CustomReason, AdminModel.Message })); } else { AdminModel.Player = AdminModel.Server.players.Where(x => x.Nickname == Player).FirstOrDefault(); } AdminModel.Reason = Global.reasons.Where(x => x.Id == Reason).First(); if (Global.Sessions.ContainsKey(UserIp)) { if (Global.Sessions[UserIp].Reason.Id != AdminModel.Reason.Id) { Time = AdminModel.Reason.Time; } } else { Time = AdminModel.Reason.Time; } AdminModel.Time = Time; Global.Sessions[UserIp].Reason = AdminModel.Reason; AdminModel.CustomReason = CustomReason; AdminModel.Comment = Comment; if (AdminModel.Player.Playerid == 0) { AdminModel.Message = "Вы не можете забанить этого игрока"; Global.Debug("User " + Program._client.GetUser(Global.Sessions[AdminModel.UserIp].User.DiscordId).Mention + " try to ban Server player on Server " + AdminModel.Server.ServerName); } else { string reasontranscript = AdminModel.Reason.Transcript; if (AdminModel.Reason.Id == "3" || AdminModel.Reason.Id == "4") { reasontranscript = CustomReason; } string reasonid = AdminModel.Reason.Id; if (AdminModel.Reason.Id == "4") { reasonid = "Своя причина"; } ReadyCommand c = new ReadyCommand(); if (reasonid != "0") { int bancount = (Global.InfoSite.BanCount = Global.InfoSite.BanCount + 1); if (!Global.SaveSiteInfo()) { Global.DebugSystemError("Failed to save site info"); } c = new ReadyCommand() { SenderDiscordId = Global.Sessions[UserIp].User.DiscordId, IsSuccess = true, FailedDebugMessage = "Бан не прошел. Бан номер " + bancount + ". Администратор " + Program._client.GetUser(Global.Sessions[AdminModel.UserIp].User.DiscordId).Mention + " попытался забанить игрока " + AdminModel.Player.Nickname + " (steamid: " + AdminModel.Player.SteamId + ") на сервере '" + AdminModel.Server.ServerName + "' по причине " + reasonid + "(" + reasontranscript + ") на " + AdminModel.Time + " минут. Комментарий администратора: '" + AdminModel.Comment + "'", SuccessDebugMessage = "Бан номер " + bancount + ". Администратор " + Program._client.GetUser(Global.Sessions[AdminModel.UserIp].User.DiscordId).Mention + " забанил игрока " + AdminModel.Player.Nickname + " (steamid: " + AdminModel.Player.SteamId + ") на сервере '" + AdminModel.Server.ServerName + "' по причине " + reasonid + "(" + reasontranscript + ") на " + AdminModel.Time + " минут. Комментарий администратора: '" + AdminModel.Comment + "'", CommandName = "ban", Args = new List <string>() { AdminModel.Player.Playerid.ToString(), AdminModel.Time.ToString(), reasonid + "(" + reasontranscript + ") на " + AdminModel.Time + " минут администратором " + Program._client.GetUser(Global.Sessions[AdminModel.UserIp].User.DiscordId).Username + ". Комментарий: " + AdminModel.Comment } }; } else { c = new ReadyCommand() { SenderDiscordId = Global.Sessions[UserIp].User.DiscordId, IsSuccess = true, FailedDebugMessage = string.Empty, SuccessDebugMessage = string.Empty, CommandName = "ban", Args = new List <string>() { AdminModel.Player.Playerid.ToString(), AdminModel.Time.ToString(), reasonid + "(" + reasontranscript + ") на " + AdminModel.Time + " минут администратором " + Program._client.GetUser(Global.Sessions[AdminModel.UserIp].User.DiscordId).Username + ". Комментарий: " + AdminModel.Comment } }; } if (!Global.SaveUsers()) { Global.DebugSystemError("Failed to save USER: \nName: " + Global.users.Where(x => x.DiscordId == Global.Sessions[UserIp].User.DiscordId).First().Name + " \nDiscordId: " + Global.users.Where(x => x.DiscordId == Global.Sessions[UserIp].User.DiscordId).First().DiscordId); } AdminModel.Message = Global.SendCommandToReady(c, AdminModel.Server.ServerName); } return(RedirectToAction("Refresh", new { UserIp, Server, AdminModel.Server.players.First().Nickname, Reason, Time, Comment, CustomReason, AdminModel.Message })); }
public IActionResult BcAction(string UserIp, string Server, string BroadcastName, string Player, int Team, int Time, string Text2, string colors) { #region main BbcModel.UserIp = UserIp; string Text = Text2; BbcModel.Broadcast = Global.broadcasts.Where(x => x.Name == BroadcastName).First(); if (Global.servers.Where(x => x.ServerName == Server).FirstOrDefault() == default) { Global.DebugSystemError("Catch wrong server name: '" + Server + "'"); return(RedirectToAction("Refresh", new { UserIp, Server, BroadcastName, Player, Team, Time, Text, colors, BbcModel.Message })); } else { BbcModel.Server = Global.servers.Where(x => x.ServerName == Server).First(); } if (BbcModel.Server.players.Where(x => x.Nickname == Player).FirstOrDefault() == default) { Global.DebugSystemError("Catch wrong player nickname: '" + Player + "'"); BbcModel.Player = BbcModel.Server.players.First(); } else { BbcModel.Player = BbcModel.Server.players.Where(x => x.Nickname == Player).FirstOrDefault(); } BbcModel.Team = Global.teams.Where(x => x.Id == Team).First(); BbcModel.Time = Time; BbcModel.colors = colors; if (BbcModel.Time < 1) { BbcModel.Time = 1; } else if (BbcModel.Time > 999) { BbcModel.Time = 999; } BbcModel.Text = Text2; BbcModel.colors = colors; #endregion string sendtext = GetBody(Text); Global.DebugSystem("text1: " + sendtext); while (sendtext.Contains(font1)) { Global.DebugSystem("index: " + sendtext.IndexOf(font1)); if (!sendtext.Contains(font2)) { Global.DebugShutdownError(sendtext); } int numberoffontbetween = sendtext.Substring(sendtext.IndexOf(font1), sendtext.IndexOf(font2) - sendtext.IndexOf(font1)).Count(x => x.ToString() == font1); int indexFontStart = sendtext.IndexOf(font1); string font; int indexof = sendtext.IndexOf("\">"); string sendtext2 = sendtext; int tempadder = 0; int count = 0; while (indexof < sendtext.IndexOf(font1)) { Global.Debug(count + "text: '" + sendtext2 + "'"); int lenght = sendtext2.IndexOf("\">") + "\">".Length; sendtext2 = sendtext2.Remove(0, lenght); tempadder += lenght; indexof = sendtext2.IndexOf("\">") + tempadder; Global.DebugSystem("new sendtext2: '" + sendtext2 + "'"); Global.DebugSystem("new indexof: " + indexof); count++; } font = sendtext.Substring(sendtext.IndexOf(font1), indexof - sendtext.IndexOf(font1) + "\">".Length); Global.DebugSystem("mfont: '" + font + "'"); Global.DebugSystem("text0: '" + sendtext + "'" + sendtext.Substring(sendtext.IndexOf(font1)).IndexOf("\">") + " " + sendtext.IndexOf(font1) + " " + "\">".Length + "'"); Global.DebugSystem("Success"); sendtext = sendtext.Remove(indexFontStart, font.Length).Insert(indexFontStart, CreateNewFontStart(font, GetFontType(font))); int indexFontClose = sendtext.IndexOf(font2, numberoffontbetween + 1); sendtext = sendtext.Remove(indexFontClose, "</font>".Length).Insert(indexFontClose, CreateNewFontClose(GetFontType(font))); } ReadyCommand c = new ReadyCommand(); switch (BbcModel.Broadcast.BroadcastType) { case BroadcastType.Bc: c = new ReadyCommand() { SenderDiscordId = Global.Sessions[UserIp].User.DiscordId, IsSuccess = true, FailedDebugMessage = "", SuccessDebugMessage = "Администратор " + Program._client.GetUser(Global.Sessions[BbcModel.UserIp].User.DiscordId).Mention + " run bc command with args: server: " + BbcModel.Server.ServerName + " time: " + BbcModel.Time + " text: '" + Text + "'", CommandName = Global.BroadcastCommands[BbcModel.Broadcast.BroadcastType], Args = new List <string>() { BbcModel.Time.ToString(), sendtext } }; BbcModel.Message = Global.SendCommandToReady(c, BbcModel.Server.ServerName); break; case BroadcastType.Pbc: c = new ReadyCommand() { SenderDiscordId = Global.Sessions[UserIp].User.DiscordId, IsSuccess = true, FailedDebugMessage = "", SuccessDebugMessage = "Администратор " + Program._client.GetUser(Global.Sessions[BbcModel.UserIp].User.DiscordId).Mention + " run pbc command with args: server: " + BbcModel.Server.ServerName + " target: " + BbcModel.Player.Nickname + " time: " + BbcModel.Time + " text: '" + Text + "'", CommandName = Global.BroadcastCommands[BbcModel.Broadcast.BroadcastType], Args = new List <string>() { BbcModel.Player.Playerid.ToString(), BbcModel.Time.ToString(), sendtext } }; BbcModel.Message = Global.SendCommandToReady(c, BbcModel.Server.ServerName); break; case BroadcastType.Tbc: c = new ReadyCommand() { SenderDiscordId = Global.Sessions[UserIp].User.DiscordId, IsSuccess = true, FailedDebugMessage = "", SuccessDebugMessage = "Администратор " + Program._client.GetUser(Global.Sessions[BbcModel.UserIp].User.DiscordId).Mention + " run tbc command with args: server: " + BbcModel.Server.ServerName + " team: " + BbcModel.Team.Name + " time: " + BbcModel.Time + " text: '" + Text + "'", CommandName = Global.BroadcastCommands[BbcModel.Broadcast.BroadcastType], Args = new List <string>() { BbcModel.Team.SmodTeam.ToString(), BbcModel.Time.ToString(), sendtext } }; BbcModel.Message = Global.SendCommandToReady(c, BbcModel.Server.ServerName); break; } return(RedirectToAction("Refresh", new { UserIp, Server, BroadcastName, Player, Team, Time, Text, colors, BbcModel.Message })); }
public IActionResult Ban(string UserIp, string Nickname, string SteamId, string Reason, int Time, string Comment, string CustomReason) { OfflineModel.UserIp = UserIp; OfflineModel.SteamId = SteamId; OfflineModel.Reason = Global.reasons.Where(x => x.Id == Reason).First(); if (Global.Sessions.ContainsKey(UserIp)) { if (Global.Sessions[UserIp].Reason.Id != OfflineModel.Reason.Id) { Time = OfflineModel.Reason.Time; } } else { Time = OfflineModel.Reason.Time; } OfflineModel.Time = Time; Global.Sessions[UserIp].Reason = OfflineModel.Reason; OfflineModel.CustomReason = CustomReason; OfflineModel.Comment = Comment; if (OfflineModel.SteamId == "0") { OfflineModel.Message = "Вы не можете забанить этого игрока"; Global.Debug("User " + Program._client.GetUser(Global.Sessions[OfflineModel.UserIp].User.DiscordId).Mention + " try to ban Server player (offline mode)"); } else { string reasontranscript = OfflineModel.Reason.Transcript; if (OfflineModel.Reason.Id == "3" || OfflineModel.Reason.Id == "4") { reasontranscript = CustomReason; } string reasonid = OfflineModel.Reason.Id; if (OfflineModel.Reason.Id == "4") { reasonid = "Своя причина"; } int bancount = (Global.InfoSite.BanCount = Global.InfoSite.BanCount + 1); if (!Global.SaveSiteInfo()) { Global.DebugSystemError("Failed to save site info"); } ReadyCommand c = new ReadyCommand() { SenderDiscordId = Global.Sessions[UserIp].User.DiscordId, IsSuccess = true, FailedDebugMessage = "Бан номер " + bancount + " (Оффлайн-мод). Администратор " + Program._client.GetUser(Global.Sessions[OfflineModel.UserIp].User.DiscordId).Mention + " забанил игрока со SteamId64: " + OfflineModel.SteamId + " по причине " + reasonid + "(" + reasontranscript + ") на " + OfflineModel.Time + " минут. Комментарий администратора: '" + OfflineModel.Comment + "'", SuccessDebugMessage = "Бан номер " + bancount + ". Администратор " + Program._client.GetUser(Global.Sessions[OfflineModel.UserIp].User.DiscordId).Mention + " забанил игрока со SteamId64: " + OfflineModel.SteamId + " по причине " + reasonid + "(" + reasontranscript + ") на " + OfflineModel.Time + " минут. Комментарий администратора: '" + OfflineModel.Comment + "'", CommandName = "oban", Args = new List <string>() { "", OfflineModel.SteamId, OfflineModel.Time.ToString(), reasonid + "(" + reasontranscript + ") на " + OfflineModel.Time + " минут администратором " + Program._client.GetUser(Global.Sessions[OfflineModel.UserIp].User.DiscordId).Username + ". Комментарий: " + OfflineModel.Comment } }; if (!Global.SaveUsers()) { Global.DebugSystemError("Failed to save USER: \nName: " + Global.users.Where(x => x.DiscordId == Global.Sessions[UserIp].User.DiscordId).First().Name + " \nDiscordId: " + Global.users.Where(x => x.DiscordId == Global.Sessions[UserIp].User.DiscordId).First().DiscordId); } OfflineModel.Message = Global.SendCommandToReady(c, Global.servers.First().ServerName); } return(RedirectToAction("Refresh", new { UserIp, Nickname, SteamId, Reason, Time, Comment, CustomReason, OfflineModel.Message })); }
// Update is called once per frame void Update() { List <NetworkCommand> cmds = Network.getPendingCommands(); if (cmds != null) { foreach (NetworkCommand cmd in cmds) { /*** IN-GAME ACTIONS ***/ if (cmd is MoveCommand) { MoveCommand move = (MoveCommand)cmd; Pos start = Network.getPlayer(move.clientID).grid_pos; Pos end = move.end; Debug.Log("Move received! From " + start + " to " + end); mapManager.move(start, end); } if (cmd is AttackCommand) { AttackCommand attack = (AttackCommand)cmd; Pos start = Network.getPlayer(attack.clientID).grid_pos; Pos end = attack.end; Debug.Log("Attack received! From " + start + " to " + end + " action No: " + attack.actionNo); mapManager.attack(start, end, attack.actionNo); } if (cmd is WaitCommand) { WaitCommand wait = (WaitCommand)cmd; Debug.Log("Wait received! From client#" + wait.clientID); Client waitingClient = Network.getPeer(wait.clientID); waitingClient.playerObject.wait(); } if (cmd is InteractCommand) { InteractCommand interact = (InteractCommand)cmd; Pos start = Network.getPlayer(interact.clientID).grid_pos; Pos end = interact.end; Debug.Log("Interact received! From " + start + " to " + end); mapManager.interact(start, end); } if (cmd is UseItemCommand) { UseItemCommand item = (UseItemCommand)cmd; Player player = Network.getPlayer(item.clientID); Item itemToUse = player.inventory.GetItemFromSlot(item.slotIndex); player.inventory.DecrementItemAtSlot(item.slotIndex); InventoryManager.UseItem(itemToUse, player); Debug.Log("Use Item received! From client#" + item.clientID + " for item in slot #" + item.slotIndex); } /*** LOBBY ACTIONS ***/ if (cmd is ReadyCommand) { ReadyCommand ready = (ReadyCommand)cmd; Debug.Log("Received READY"); Client client = Network.getPeer(ready.clientID); if (client == null) { Network.setPeer(ready.clientID); client = Network.getPeer(ready.clientID); } client.ready = !client.ready; } if (cmd is NicknameCommand) { NicknameCommand nickname = (NicknameCommand)cmd; Debug.Log("Received nickname: " + nickname.nickname); Client client = Network.getPeer(nickname.clientID); if (client == null) { Network.setPeer(nickname.clientID); client = Network.getPeer(nickname.clientID); } client.nickname = nickname.nickname; } if (cmd is ClassnameCommand) { ClassnameCommand classname = (ClassnameCommand)cmd; Debug.Log("Received classname: " + classname.classname); Client client = Network.getPeer(classname.clientID); if (client == null) { Network.setPeer(classname.clientID); client = Network.getPeer(classname.clientID); } client.classname = classname.classname; } if (cmd is UpdateClientInfoCommand) // called when a new player joins and needs to be synchronized { UpdateClientInfoCommand update = (UpdateClientInfoCommand)cmd; Debug.Log("Received update from client#" + update.clientID); Client client = Network.getPeer(update.clientID); if (client == null) { Network.setPeer(update.clientID); client = Network.getPeer(update.clientID); } client.nickname = update.nickname; client.classname = update.classname; client.ready = update.ready; } if (cmd is SetSeedCommand) { SetSeedCommand seed = (SetSeedCommand)cmd; Debug.Log("Received seed!"); Settings.MasterSeed = seed.seed; } /*** NETWORK ACTIONS ***/ if (cmd is JoinCommand) { JoinCommand _join = (JoinCommand)cmd; // to avoid conflict with 'join' keyword if (clientID == 0) { clientID = _join.clientID; Debug.Log("Joined game! Client ID #" + clientID + " assigned!"); } else { Debug.Log("New player with client ID #" + _join.clientID + " joined!"); Network.submitCommand(new UpdateClientInfoCommand(Network.getPeer(clientID))); if (clientID == 1) { Network.submitCommand(new SetSeedCommand(Settings.MasterSeed)); } } Network.setPeer(_join.clientID); } if (cmd is StartCommand) { StartCommand start = (StartCommand)cmd; Debug.Log("Received START"); if (SceneManager.GetActiveScene().name == "NewMenu") // only loads new scene if we're in the lobby { SceneManager.LoadScene("Procedural"); foreach (Client client in Network.getPeers()) { client.ready = false; } } else { GameManager.NextLevel(); } } if (cmd is EndCommand) { EndCommand end = (EndCommand)cmd; Debug.Log("Received END"); } if (cmd is DisconnectCommand) { DisconnectCommand disconnect = (DisconnectCommand)cmd; Debug.Log("Received DISCONNECT from client #" + disconnect.clientID); Network.removePeer(disconnect.clientID); if (clientID >= disconnect.clientID) { clientID--; Debug.Log("Changed client ID to " + clientID); } } } } if (!Network.connected()) { clientID = 0; } }