private void HandleUpdateActivePlayers(NetworkMessage netMsg) { var playersUpdate = netMsg.ReadMessage <PlayersUpdateMessage>(); Debug.Log("UPDATE ACTIVE PLAYERS:"); foreach (var playerData in playersUpdate.Players) { var existingPlayer = activePlayers.Find(p => p.ID == playerData.ID); if (existingPlayer == null) { existingPlayer = new NetworkPlayer() { ID = playerData.ID, Name = playerData.Name, CharacterType = playerData.CharacterType, IsSelf = playerData.ID == client.connection.connectionId }; existingPlayer.Connection = (existingPlayer.IsSelf) ? client.connection : null; activePlayers.Add(existingPlayer); OnPlayerConnect?.Invoke(existingPlayer); } // todo, this is dumb existingPlayer.Name = playerData.Name; existingPlayer.Player.CritterController.transform.SetPositionAndRotation(playerData.Position, playerData.Rotation); Debug.Log("PLAYER #" + playerData.ID + " name" + playerData.Name); } OnActivePlayersUpdated?.Invoke(); }
public override IEnumerator Initialize() { networkServerSimple = new WrappedNetworkServerSimple(); networkServerSimple.RegisterHandler(GameMsgType.UpdateCritterInput, HandeUpdateCritterInput); networkServerSimple.OnClientConnected += OnClientConnected; networkServerSimple.OnClientDisconnected += OnClientDisconnected; networkServerSimple.RegisterHandler(GameMsgType.Effects, HandleEffectReceived); networkServerSimple.Initialize(); networkServerSimple.Listen(CONNECTION_PORT); _isConnected = true; Debug.Log("Server Initialized"); CurrentPlayer.isServer = true; CurrentPlayer.ID = 0; CurrentPlayer.IsSelf = true; CurrentPlayer.ServerConnection = this; CurrentPlayer.PostCritterStatePacket += (p) => { PostCritterStatePacket(p, CurrentPlayer); }; activePlayers.Add(CurrentPlayer); OnPlayerConnect?.Invoke(CurrentPlayer); UpdateActivePlayers(); yield break; }
/// <summary> /// Listen for new clients /// </summary> private void Listen() { while (true) { if (tcpClients.Count <= 256) { TcpClient client = listener.AcceptTcpClient(); tcpClients.Add(client); if (OnPlayerConnect != null) { OnPlayerConnect.Invoke(client); } Thread clientThread = new Thread(new ParameterizedThreadStart(HandleClient)); clientThread.Start(client); } } }
/* * private void LoadGUIBase(object obj) * { * var pointer = (uint)obj; * * if (pointer == 0 && this.GUI != null) * { * this.GUI?.Dispose(); * this.GUI = null; * } * * if (pointer > 0 && this.GUI?.BasePointer != pointer) * { * this.GUI?.Dispose(); * this.GUI = new GUIBase(this.Client, pointer); * } * } */ private void LoadPlayerObj(object obj) { var pointer = (uint)obj; if (pointer == 0 && this.PJInfo != null) { this.PJInfo?.Dispose(); this.PJInfo = null; OnPlayerConnect?.Invoke(this, false); } if (pointer > 0 && this.PJInfo?.BasePointer != pointer) { this.PJInfo?.Dispose(); this.PJInfo = new PlayerObj(this.Client, pointer); OnPlayerConnect?.Invoke(this, true); } }
private void StartPlayer(int id, string name) { if (m_players.ContainsKey(id)) { return; } if (string.IsNullOrEmpty(name)) { name = "Player" + (++m_totalPlayerCount); } NetPlayer player = new NetPlayer(this, id); m_players[id] = player; m_eventProcessor.QueueEvent(delegate() { // UGH! This is not thread safe because someone might add handler to OnPlayerConnect // Odds or low though. OnPlayerConnect.Emit(this, new PlayerConnectMessageArgs(player)); }); }
private void OnClientConnected(NetworkConnection obj) { Debug.Log("Server OnClientConnected" + obj.address + "connectionID " + obj.connectionId); var player = new NetworkPlayer(); player.Connection = obj; player.ID = obj.connectionId; player.PostCritterStatePacket += (p) => { PostCritterStatePacket(p, player); }; player.ServerConnection = this; activePlayers.Add(player); OnPlayerConnect?.Invoke(player); UpdateActivePlayers(); }
private static void OnConnect(PlayerConnectArgs e) { OnPlayerConnect?.Invoke(e); }
private void ForwardOnPlayerConnect(NetworkPlayer obj) { OnPlayerConnect?.Invoke(obj); }
public async Task <bool> RefreshListing() { //Make sure listing is enabled if (Server.Rcon == null) { return(false); } Logger.Log("Performing Listing Refresh"); if (_connections.Count == 0) { Logger.Log("Skipping refresh because we have no connections."); return(false); } //Create a mapping of users and prepare some temporary array for additions and removals. var listedUsers = await Server.Rcon.ListAsync(); List <int> removals = new List <int>(); Logger.Log("Fetched " + listedUsers.Length); //Go through each listing adding elements and updating existing elements foreach (var lu in listedUsers) { Player player; if (_connections.TryGetValue(lu.Connection, out player)) { if (player.UUID != lu.UUID) { Player newp = new Player(player) { UUID = lu.UUID }; if (_connections.TryUpdate(lu.Connection, newp, player)) { try { //Send the update event Logger.Log("Player Updated from RCON LIST: " + newp); OnPlayerUpdate?.Invoke(newp); } catch (Exception e) { Logger.LogError(e, "OnPlayerUpdate for RCON Exception: {0}"); } } else { Logger.LogError("Failed to update connection: " + newp); } } } else { //Its a new connection. player = new Player(Server, lu.Connection) { UUID = lu.UUID, Username = lu.Name }; //Skip the player if they are pending if (_pending.ToArray().Any(pp => pp.character == lu.Name)) { Logger.Log("Skipping user " + player + " because they are pending."); continue; } //Add it if (_connections.TryAdd(player.Connection, player)) { try { Logger.Log("User " + player + " joined without us noticing."); //Make sure they have a valid username await EnforceCharacterName(player); OnPlayerConnect?.Invoke(player); //we should tell starwatch to restart because this only ever happens when the logs stop working await Server.Terminate("User joined without notice, dead logs."); } catch (Exception e) { Logger.LogError(e, "OnPlayerConnect for Sneaky Exception: {0}"); } } } //Update the sessions await UpdateSessionAsync(player); } return(true); }
public override async Task <bool> HandleMessage(Message msg) { //Only nicks are within chat messages so we should abort if it is. if (msg.Level == Message.LogLevel.Chat) { //Nickname has changed? if (msg.Content.StartsWith("/nick")) { string content = msg.Content.Trim(); string nickname = content.Length <= 6 ? " " : msg.Content.Substring(6); Player player = _connections.Values.Where(p => p.Username.Equals(msg.Author)).First(); if (player != null) { Logger.Log("Nickname set for " + player + " to " + nickname); _connections[player.Connection].Nickname = nickname; //Validate the nickname if (!await EnforceCharacterName(player)) { try { //Invoke the change OnPlayerUpdate?.Invoke(_connections[player.Connection]); } catch (Exception e) { Logger.LogError(e, "OnPlayerUpdate Exception - Nickname: {0}"); } } } else { Logger.LogError("Failed to set the nickname '{0}' on player '{1}' because they are not on the connection list!", nickname, msg.Author); } } //Abort now since nicknames are the only chat evernts we care about return(false); } //Only info logs contain useful information if (msg.Level != Message.LogLevel.Info) { return(false); } //check if its a warp message if (msg.Content.StartsWith("UniverseServer: Warp") && !msg.Content.Contains("failed")) { int toIndex = msg.Content.IndexOf('t'); string sub = msg.Content.Substring(31, toIndex - 1 - 31); int connection = int.Parse(sub); string location = msg.Content.Substring(toIndex + 3); if (_connections.ContainsKey(connection)) { Logger.Log("Player updated their location!"); _connections[connection].Whereami = location; //Attempt to update the cache //TODO: Make a WorldManager if (_connections[connection].Location is CelestialWorld celesial && celesial.Details == null) { try { await celesial.GetDetailsAsync(Server); } catch (Exception) { } } try { //Tell the world the event occured OnPlayerUpdate?.Invoke(_connections[connection]); } catch (Exception e) { Logger.LogError(e, "OnPlayerUpdate Exception: {0}"); } } else { Logger.LogError("Attempted to warp a player that isn't in the connection list!"); } //Abort now since only warp starts with UniverseServer: Warp return(false); } //check if its a logged in message if (msg.Content.StartsWith("UniverseServer: Logged")) { //Match the regex var match = regexLoggedMsg.Match(msg.Content); if (match.Success) { //Get the groups string account = match.Groups[1].Value; string character = match.Groups[2].Value; string address = match.Groups[3].Value; //Do some trimming of the accounts if (account.Equals("<anonymous>")) { account = null; } else { account = account.Substring(1, account.Length - 2); } //Add to the pending connections _pending.Add(new PendingPlayer() { address = address, account = account, character = character }); } else { Logger.LogWarning("Unable to match logged message: {0}", msg.Content); } //Abort now since only logged starts with UniverseServer: Logged return(false); } //check if the message is a connected message if (msg.Content.StartsWith("UniverseServer: Client")) { //Match the regex var match = regexClientMsg.Match(msg.Content); if (match.Success) { //Get the data string character = match.Groups[1].Value; int connection = int.Parse(match.Groups[2].Value); string address = match.Groups[3].Value; bool wasConnection = match.Groups[4].Value == "connected"; string reason = match.Groups[6].Success ? match.Groups[6].Value : null; if (wasConnection) { //If we are connecting, look for the matching pending connection var pending = _pending.Where(pp => pp.address.Equals(address) && pp.character.Equals(character)).FirstOrDefault(); if (pending.character.Equals(character)) { //Remove the account from the pending and create a new session _pending.Remove(pending); //Try to check if the address is a VPN bool isVPN = false; try { if (Validator != null) { Logger.Log("Checking IP for VPN: {0}", pending.address); isVPN = Validator.Check(pending.address); } } catch (Exception e) { Logger.LogError(e, "Failed to check address: {0}"); } //Create the player object var player = new Player(Server, connection) { AccountName = pending.account, Username = pending.character, IP = pending.address, IsVPN = isVPN }; //Add to the connections _connections.TryAdd(connection, player); await CreateSessionAsync(player); //Save the last seen date of the account. if (!player.IsAnonymous) { var account = await player.GetAccountAsync(); if (account != null) { player.IsAdmin = account.IsAdmin; account.UpdateLastSeen(); await account.SaveAsync(Server.DbContext); } } //Send the event off try { //Invoke the events. This shouldn't have to many listeners to this. Logger.Log("Player Connected: {0}", player); OnPlayerConnect?.Invoke(_connections[connection]); //Make sure they have a valid username await EnforceCharacterName(_connections[connection]); } catch (Exception e) { Logger.LogError(e, "OnPlayerConnect Exception: {0}", e); } } else { Logger.LogError("Failed to find the pending request! " + address); } } else { //It was a disconnection, so find them in the list of players Player player; if (_connections.TryGetValue(connection, out player)) { try { //Invoke the events. This shouldn't have to many listeners to this. OnPlayerDisconnect?.Invoke(player, reason ?? "Disconnected for unkown reasons"); } catch (Exception e) { Logger.LogError(e, "OnPlayerDisconnect Exception: {0}", e); } } //Remove the connection _connections.TryRemove(connection, out _); await RemoveSessionAsync(connection); } } else { Logger.LogWarning("Unable to match client message: {0}", msg.Content); } //Abort now since only client starts with UniverseServer: Client return(false); } return(false); }
/// <summary> /// Main callback handler. /// </summary> /// <param name="call"></param> /// <returns></returns> private async Task GbxRemoteClient_OnCallback(MethodCall call) { switch (call.Method) { case "ManiaPlanet.PlayerConnect": case "TrackMania.PlayerConnect": OnPlayerConnect?.Invoke( (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[0]), (bool)XmlRpcTypes.ToNativeValue <bool>(call.Arguments[1]) ); break; case "ManiaPlanet.PlayerDisconnect": case "TrackMania.PlayerDisconnect": OnPlayerDisconnect?.Invoke( (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[0]), (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[1]) ); break; case "ManiaPlanet.PlayerChat": case "TrackMania.PlayerChat": OnPlayerChat?.Invoke( (int)XmlRpcTypes.ToNativeValue <int>(call.Arguments[0]), (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[1]), (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[2]), (bool)XmlRpcTypes.ToNativeValue <bool>(call.Arguments[3]) ); break; case "ManiaPlanet.Echo": case "TrackMania.Echo": OnEcho?.Invoke( (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[0]), (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[1]) ); break; case "ManiaPlanet.BeginMatch": case "TrackMania.BeginMatch": OnBeginMatch?.Invoke(); break; case "ManiaPlanet.EndMatch": case "TrackMania.EndMatch": OnEndMatch?.Invoke( (SPlayerRanking[])XmlRpcTypes.ToNativeValue <SPlayerRanking>(call.Arguments[0]), (int)XmlRpcTypes.ToNativeValue <int>(call.Arguments[1]) ); break; case "ManiaPlanet.BeginMap": case "TrackMania.BeginMap": OnBeginMap?.Invoke( (SMapInfo)XmlRpcTypes.ToNativeValue <SMapInfo>(call.Arguments[0]) ); break; case "ManiaPlanet.EndMap": case "TrackMania.EndMap": OnEndMap?.Invoke( (SMapInfo)XmlRpcTypes.ToNativeValue <SMapInfo>(call.Arguments[0]) ); break; case "ManiaPlanet.StatusChanged": case "TrackMania.StatusChanged": OnStatusChanged?.Invoke( (int)XmlRpcTypes.ToNativeValue <int>(call.Arguments[0]), (string)XmlRpcTypes.ToNativeValue <string>(call.Arguments[1]) ); break; case "ManiaPlanet.PlayerInfoChanged": case "TrackMania.PlayerInfoChanged": OnPlayerInfoChanged?.Invoke( (SPlayerInfo)XmlRpcTypes.ToNativeValue <SPlayerInfo>(call.Arguments[0]) ); break; case "ManiaPlanet.ModeScriptCallback": case "TrackMania.ModeScriptCallback": await HandleModeScriptCallback(call); break; case "ManiaPlanet.ModeScriptCallbackArray": case "TrackMania.ModeScriptCallbackArray": await HandleModeScriptCallback(call); break; } // always invoke the OnAnyCallback event OnAnyCallback?.Invoke(call, (object[])XmlRpcTypes.ToNativeValue <object>( new XmlRpcArray(call.Arguments) )); }
internal static void HandlePlayerConnected(string nickName, string Ip, string username, string serial, int versionNumber, string versionString) { OnPlayerConnect?.Invoke(nickName, Ip, username, serial, versionNumber, versionString); }