/// <inheritdoc/>
        public async Task <bool> HandleMessage(IPlayerSession session, GodotMessage message)
        {
            if (session.PlayerAccount == null)
            {
                return(false);
            }

            List <PlayerCharacter>?characters = null;

            if (_muplonenDbContext.PlayerCharacters != null)
            {
                characters = await _muplonenDbContext.PlayerCharacters
                             .Where(character => character.PlayerAccountId == session.PlayerAccount.Id)
                             .ToListAsync();
            }

            await session.Connection.BuildAndSend(OutgoingMessages.CharacterList, reply =>
            {
                if (characters == null || characters.Count == 0)
                {
                    reply.WriteByte(0);
                    return;
                }

                reply.WriteByte((byte)characters.Count);
                foreach (var character in characters)
                {
                    reply.WriteString(character.Charactername);
                    reply.WriteString(character.CreatedAt.ToString(Thread.CurrentThread.CurrentUICulture.DateTimeFormat.ShortDatePattern));
                }
            });

            return(true);
        }
        /// <inheritdoc/>
        public async Task <bool> HandleMessage(IPlayerSession session, GodotMessage message)
        {
            if (session.PlayerAccount == null || session.PlayerCharacter == null)
            {
                return(false);
            }

            if (session.RoomInstance == null)
            {
                return(true);
            }

            var position = message.ReadVector3i();
            await session.Connection.Build(OutgoingMessages.OtherPlayerMove, async msg =>
            {
                msg.WriteString(session.PlayerCharacter.Charactername);
                msg.WriteVector3i(position);
                foreach (var recipient in session.RoomInstance.Sessions.AllSessions.Where(other => other != session))
                {
                    await recipient.Connection.Send(msg);
                }
            });

            return(true);
        }
        /// <inheritdoc/>
        public async Task <bool> HandleMessage(IPlayerSession session, GodotMessage message)
        {
            if (session.PlayerAccount == null || session.PlayerCharacter == null)
            {
                return(false);
            }

            // Cannot chat when not in a room, but no reason to disconnect...
            if (session.RoomInstance == null)
            {
                return(true);
            }

            var text = message.ReadString();

            _logger.LogInformation("\"{0}\" ({1}) said: \"{2}\"", session.PlayerCharacter.Charactername, session.SessionId, text);

            await session.Connection.Build(OutgoingMessages.Chat, async msg =>
            {
                msg.WriteString(session.PlayerCharacter.Charactername);
                msg.WriteString(text);
                foreach (var recipient in session.RoomInstance.Sessions.AllSessions)
                {
                    await recipient.Connection.Send(msg);
                }
            });

            return(true);
        }
        /// <inheritdoc/>
        public async Task <bool> HandleMessage(IPlayerSession session, GodotMessage message)
        {
            var accountname = message.ReadString().ToLower();
            var password    = message.ReadString();

            // Check, if name is taken
            var accountAlreadyExists = false;

            if (_muplonenDbContext.PlayerAccounts != null)
            {
                accountAlreadyExists = await _muplonenDbContext.PlayerAccounts.AnyAsync(account => account.Accountname == accountname);
            }

            if (accountAlreadyExists)
            {
                await session.Connection.BuildAndSend(OutgoingMessages.AccountRegistration, reply =>
                {
                    reply.WriteByte(0);
                    reply.WriteString("Account name already in use. Please choose a different name.");
                });

                return(false);
            }

            var hashedPassword = _passwordHasher.CreateHashedPassword(password);

            // Create and save account
            var account = new PlayerAccount()
            {
                Accountname = accountname, PasswordHash = hashedPassword
            };

            _muplonenDbContext.Add(account);
            await _muplonenDbContext.SaveChangesAsync();

            _logger.LogInformation("Account \"{0}\" ({1}) created by session {2}", accountname, account.Id, session.SessionId);

            // Tell the client that the account has been created and close the connection.
            await session.Connection.BuildAndSend(OutgoingMessages.AccountRegistration, reply =>
            {
                reply.WriteByte(1);
                reply.WriteString("Account created. You can now log in.");
            });

            await session.Connection.Close();

            return(true);
        }
        /// <inheritdoc/>
        public async Task <bool> HandleMessage(IPlayerSession session, GodotMessage message)
        {
            if (session.PlayerAccount == null || session.PlayerCharacter != null)
            {
                return(false);
            }

            var charactername = message.ReadString().ToLower();

            var characterAlreadyExists = false;

            if (_muplonenDbContext.PlayerCharacters != null)
            {
                characterAlreadyExists = await _muplonenDbContext.PlayerCharacters.AnyAsync(character => character.Charactername == charactername);
            }

            if (characterAlreadyExists)
            {
                await session.Connection.BuildAndSend(OutgoingMessages.CharacterCreation, reply =>
                {
                    reply.WriteByte(0);
                    reply.WriteString("Charactername already taken. Please try a different one.");
                });

                return(true);
            }

            var newCharacter = new PlayerCharacter()
            {
                Charactername   = charactername,
                PlayerAccountId = session.PlayerAccount.Id,
                PlayerAccount   = session.PlayerAccount
            };

            _muplonenDbContext.Add(newCharacter);
            await _muplonenDbContext.SaveChangesAsync();

            _logger.LogInformation("\"{0}\" ({1}) created character \"{2}\" ({3}).",
                                   session.PlayerAccount.Accountname, session.PlayerAccount.Id, newCharacter.Charactername, newCharacter.Id);

            await session.Connection.BuildAndSend(OutgoingMessages.CharacterCreation, reply =>
            {
                reply.WriteByte(1);
            });

            return(true);
        }
Esempio n. 6
0
        /// <inheritdoc/>
        public async Task <bool> HandleMessage(IPlayerSession session, GodotMessage message)
        {
            if (session.PlayerAccount == null || session.PlayerCharacter != null)
            {
                return(false);
            }

            var charactername = message.ReadString().ToLower();

            PlayerCharacter?playerCharacter = null;

            if (_muplonenDbContext.PlayerCharacters != null)
            {
                playerCharacter = await _muplonenDbContext.PlayerCharacters.FirstOrDefaultAsync(character => character.Charactername == charactername);
            }

            if (playerCharacter == null)
            {
                _logger.LogInformation("\"{0}\" ({1}) tried to select character \"{2}\", but the character does not exist.",
                                       session.PlayerAccount.Accountname, session.PlayerAccount.Id, charactername);
                return(false);
            }

            if (playerCharacter.PlayerAccountId != session.PlayerAccount.Id)
            {
                _logger.LogInformation("\"{0}\" ({1}) tried to select character \"{2}\" ({3}), but the character belongs to account ({4}).",
                                       session.PlayerAccount.Accountname, session.PlayerAccount.Id, playerCharacter.Charactername, playerCharacter.PlayerAccountId);
                return(false);
            }

            session.PlayerCharacter = playerCharacter;
            await session.Connection.BuildAndSend(OutgoingMessages.CharacterSelection, reply =>
            {
                reply.WriteByte(1);
            });

            // Join room
            await _roomManager.AddPlayerToRoomInstance(session, Guid.Empty);

            return(true);
        }
        /// <inheritdoc/>
        public async Task <bool> HandleMessage(IPlayerSession session, GodotMessage message)
        {
            var accountname = message.ReadString().ToLower();
            var password    = message.ReadString();

            // Fetch account
            PlayerAccount?account = null;

            if (_muplonenDbContext.PlayerAccounts != null)
            {
                account = await _muplonenDbContext.PlayerAccounts.FirstAsync(account => account.Accountname == accountname);
            }

            if (account == null)
            {
                await session.Connection.BuildAndSend(OutgoingMessages.AccountLogin, reply =>
                {
                    reply.WriteByte(0);
                    reply.WriteString("Account does not exist.");
                });

                return(false);
            }

            // Check password
            if (!_passwordHasher.IsSamePassword(password, account.PasswordHash))
            {
                await session.Connection.BuildAndSend(OutgoingMessages.AccountLogin, reply =>
                {
                    reply.WriteByte(0);
                    reply.WriteString("Wrong password.");
                });

                return(false);
            }

            // Put account into session
            if (_playerSessionManager.Sessions.TryGetByAccountId(account.Id, out IPlayerSession? existingSession) && existingSession != null)
            {
                _logger.LogInformation("Tried to log into account \"{0}\" ({1}) from session {2}, but account is already logged in from session {3}",
                                       account.Accountname, account.Id, session.SessionId, existingSession.SessionId);

                await session.Connection.BuildAndSend(OutgoingMessages.AccountLogin, reply =>
                {
                    reply.WriteByte(0);
                    reply.WriteString("Account already in use by another session.");
                });

                return(false);
            }

            session.PlayerAccount = account;
            _logger.LogInformation("Account \"{0}\" ({1}) logged in with session {2}", account.Accountname, account.Id, session.SessionId);

            // Tell the client that the login was successfull
            await session.Connection.BuildAndSend(OutgoingMessages.AccountLogin, reply =>
            {
                reply.WriteByte(1);
            });

            return(true);
        }