private void PlayerUpdate(NetworkClient player)
        {
            OnPlayerUpdate?.Invoke(player);

            if (_network.Clients.Count(x => x.Status == ClientStatus.Waiting) <= 0)
            {
                Continue();
            }
        }
Esempio n. 2
0
        public async Task <World> RefreshLocation(int connection)
        {
            //Make sure listing is enabled and make sure the player exists
            if (Server.Rcon == null)
            {
                return(null);
            }
            if (!_connections.ContainsKey(connection))
            {
                Logger.LogError("Attempted to refresh the location of a null connection: {0}", connection);
                return(null);
            }

            //Perform a whereis
            var response = await Server.Rcon.WhereisAsync(connection);

            if (response.Success)
            {
                //Update the location and execute the event
                Logger.Log("Player updated their location via whereis!");
                _connections[connection].Whereami = response.Message;
                try
                {
                    OnPlayerUpdate?.Invoke(_connections[connection]);
                }
                catch (Exception e)
                {
                    Logger.LogError(e, "OnPlayerUpdate Exception: {0}");
                }

                //Return the new world
                return(_connections[connection].Location);
            }
            else
            {
                Logger.LogWarning("Failed to refresh a players location: " + response.Message);
                return(null);
            }
        }
Esempio n. 3
0
        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);
        }
Esempio n. 4
0
        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);
        }
Esempio n. 5
0
 internal void PlayerUpdate(Player player)
 {
     OnPlayerUpdate?.Invoke(this, new PlayerUpdateEventArgs(player));
 }
Esempio n. 6
0
 public static void PlayerUpdate()
 {
     //DebugManager.LogToFile("[OnPlayerUpdate] Player is updating!");
     OnPlayerUpdate?.Invoke();
 }