/// <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); } // 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) { 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); }
/// <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); }