Refactor accounts to not use a player uid

This commit is contained in:
Melledy
2022-05-27 00:22:55 -07:00
parent fc687a3bde
commit 141b1913cb
12 changed files with 144 additions and 133 deletions

View File

@@ -1,11 +1,16 @@
package emu.grasscutter.server.packet.recv;
import static emu.grasscutter.Configuration.ACCOUNT;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.GetPlayerTokenReqOuterClass.GetPlayerTokenReq;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.event.game.PlayerCreationEvent;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.game.GameSession.SessionState;
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
@@ -15,6 +20,12 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
// Max players limit
if (ACCOUNT.maxPlayer > -1 && Grasscutter.getGameServer().getPlayers().size() >= ACCOUNT.maxPlayer) {
session.close();
return;
}
GetPlayerTokenReq req = GetPlayerTokenReq.parseFrom(payload);
// Authenticate
@@ -30,27 +41,35 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
// Set account
session.setAccount(account);
// Get player
Player player = DatabaseHelper.getPlayerByAccount(account);
if (player == null) {
int nextPlayerUid = DatabaseHelper.getNextPlayerId(session.getAccount().getReservedPlayerUid());
// Call creation event.
PlayerCreationEvent event = new PlayerCreationEvent(session, Player.class); event.call();
// Create player instance from event.
player = event.getPlayerClass().getDeclaredConstructor(GameSession.class).newInstance(session);
// Save to db
DatabaseHelper.generatePlayerUid(player, nextPlayerUid);
}
// Set player object for session
session.setPlayer(player);
// Load player from database
player.loadFromDatabase();
// Set session state
session.setUseSecretKey(true);
session.setState(SessionState.WAITING_FOR_LOGIN);
// Has character
boolean doesPlayerExist = false;
if (account.getPlayerUid() > 0) {
// Set flag for player existing
doesPlayerExist = DatabaseHelper.checkPlayerExists(account.getPlayerUid());
}
// Set reserve player id if account doesnt exist
if (!doesPlayerExist) {
int id = DatabaseHelper.getNextPlayerId(session.getAccount().getPlayerUid());
if (id != session.getAccount().getPlayerUid()) {
session.getAccount().setPlayerId(id);
session.getAccount().save();
}
}
// Send packet
session.send(new PacketGetPlayerTokenRsp(session, doesPlayerExist));
session.send(new PacketGetPlayerTokenRsp(session));
}
}

View File

@@ -22,11 +22,7 @@ public class HandlerPlayerLoginReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
// Check
if (session.getAccount() == null) {
return;
}
// Max players limit
if (ACCOUNT.maxPlayer > -1 && Grasscutter.getGameServer().getPlayers().size() >= ACCOUNT.maxPlayer) {
session.close();
return;
}
@@ -35,23 +31,21 @@ public class HandlerPlayerLoginReq extends PacketHandler {
// Authenticate session
if (!req.getToken().equals(session.getAccount().getToken())) {
session.close();
return;
}
// Load character from db
Player player = DatabaseHelper.getPlayerById(session.getAccount().getPlayerUid());
Player player = session.getPlayer();
if (player == null) {
// Send packets
// Show opening cutscene if player has no avatars
if (player.getAvatars().getAvatarCount() == 0) {
// Pick character
session.setState(SessionState.PICKING_CHARACTER);
session.send(new BasePacket(PacketOpcodes.DoSetPlayerBornDataNotify));
} else {
// Set character
session.setPlayer(player);
// Login done
session.getPlayer().onLogin();
session.setState(SessionState.ACTIVE);
}
// Final packet to tell client logging in is done

View File

@@ -46,60 +46,38 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
return;
}
String nickname = req.getNickName();
if (nickname == null) {
nickname = "Traveler";
}
// Call creation event.
PlayerCreationEvent event = new PlayerCreationEvent(session, Player.class); event.call();
// Create player instance from event.
Player player = event.getPlayerClass().getDeclaredConstructor(GameSession.class).newInstance(session);
player.setNickname(nickname);
try {
// Save to db
DatabaseHelper.createPlayer(player, session.getAccount().getPlayerUid());
// Create avatar
if (player.getAvatars().getAvatarCount() == 0) {
Avatar mainCharacter = new Avatar(avatarId);
mainCharacter.setSkillDepotData(GameData.getAvatarSkillDepotDataMap().get(startingSkillDepot));
// Manually handle adding to team
player.addAvatar(mainCharacter, false);
player.setMainCharacterId(avatarId);
player.setHeadImage(avatarId);
player.getTeamManager().getCurrentSinglePlayerTeamInfo().getAvatars().add(mainCharacter.getAvatarId());
player.save(); // TODO save player team in different object
}
// Save account
session.getAccount().setPlayerId(player.getUid());
session.getAccount().save();
// Set character
session.setPlayer(player);
// Login done
session.getPlayer().onLogin();
session.setState(SessionState.ACTIVE);
// Born resp packet
session.send(new BasePacket(PacketOpcodes.SetPlayerBornDataRsp));
// Get player object
Player player = session.getPlayer();
// Default mail
var welcomeMail = GAME_INFO.joinOptions.welcomeMail;
MailBuilder mailBuilder = new MailBuilder(player.getUid(), new Mail());
mailBuilder.mail.mailContent.title = welcomeMail.title;
mailBuilder.mail.mailContent.sender = welcomeMail.sender;
// Please credit Grasscutter if changing something here. We don't condone commercial use of the project.
mailBuilder.mail.mailContent.content = welcomeMail.content + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>";
mailBuilder.mail.itemList.addAll(Arrays.asList(welcomeMail.items));
mailBuilder.mail.importance = 1;
player.sendMail(mailBuilder.mail);
} catch (Exception e) {
Grasscutter.getLogger().error("Error creating player object: ", e);
session.close();
// Create avatar
if (player.getAvatars().getAvatarCount() == 0) {
Avatar mainCharacter = new Avatar(avatarId);
mainCharacter.setSkillDepotData(GameData.getAvatarSkillDepotDataMap().get(startingSkillDepot));
// Manually handle adding to team
player.addAvatar(mainCharacter, false);
player.setMainCharacterId(avatarId);
player.setHeadImage(avatarId);
player.getTeamManager().getCurrentSinglePlayerTeamInfo().getAvatars().add(mainCharacter.getAvatarId());
player.save(); // TODO save player team in different object
} else {
return;
}
// Login done
session.getPlayer().onLogin();
// Born resp packet
session.send(new BasePacket(PacketOpcodes.SetPlayerBornDataRsp));
// Default mail
var welcomeMail = GAME_INFO.joinOptions.welcomeMail;
MailBuilder mailBuilder = new MailBuilder(player.getUid(), new Mail());
mailBuilder.mail.mailContent.title = welcomeMail.title;
mailBuilder.mail.mailContent.sender = welcomeMail.sender;
// Please credit Grasscutter if changing something here. We don't condone commercial use of the project.
mailBuilder.mail.mailContent.content = welcomeMail.content + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>";
mailBuilder.mail.itemList.addAll(Arrays.asList(welcomeMail.items));
mailBuilder.mail.importance = 1;
player.sendMail(mailBuilder.mail);
}
}

View File

@@ -10,16 +10,16 @@ import emu.grasscutter.utils.Crypto;
public class PacketGetPlayerTokenRsp extends BasePacket {
public PacketGetPlayerTokenRsp(GameSession session, boolean doesPlayerExist) {
public PacketGetPlayerTokenRsp(GameSession session) {
super(PacketOpcodes.GetPlayerTokenRsp, true);
this.setUseDispatchKey(true);
GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder()
.setUid(session.getAccount().getPlayerUid())
.setUid(session.getPlayer().getUid())
.setToken(session.getAccount().getToken())
.setAccountType(1)
.setIsProficientPlayer(doesPlayerExist) // Not sure where this goes
.setIsProficientPlayer(session.getPlayer().getAvatars().getAvatarCount() > 0) // Not sure where this goes
.setSecretKeySeed(Crypto.ENCRYPT_SEED)
.setSecurityCmdBuffer(ByteString.copyFrom(Crypto.ENCRYPT_SEED_BUFFER))
.setPlatformType(3)