mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-06-26 18:14:50 +08:00
Compare commits
No commits in common. "141b1913cbfe1c9b7d2f8ac224e53f877790c7a2" and "e152728ddcda3d8309fdb73b7d837deb9d0216cd" have entirely different histories.
141b1913cb
...
e152728ddc
@ -52,7 +52,7 @@ public final class AccountCommand implements CommandHandler {
|
|||||||
account.addPermission("*");
|
account.addPermission("*");
|
||||||
account.save(); // Save account to database.
|
account.save(); // Save account to database.
|
||||||
|
|
||||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.create", Integer.toString(account.getReservedPlayerUid())));
|
CommandHandler.sendMessage(null, translate(sender, "commands.account.create", Integer.toString(account.getPlayerUid())));
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
case "delete":
|
case "delete":
|
||||||
@ -66,7 +66,7 @@ public final class AccountCommand implements CommandHandler {
|
|||||||
|
|
||||||
// Get the player for the account.
|
// Get the player for the account.
|
||||||
// If that player is currently online, we kick them before proceeding with the deletion.
|
// If that player is currently online, we kick them before proceeding with the deletion.
|
||||||
Player player = Grasscutter.getGameServer().getPlayerByAccountId(toDelete.getId());
|
Player player = Grasscutter.getGameServer().getPlayerByUid(toDelete.getPlayerUid());
|
||||||
if (player != null) {
|
if (player != null) {
|
||||||
player.getSession().close();
|
player.getSession().close();
|
||||||
}
|
}
|
||||||
|
@ -57,8 +57,7 @@ public final class GiveAllCommand implements CommandHandler {
|
|||||||
}
|
}
|
||||||
// This will handle stats and talents
|
// This will handle stats and talents
|
||||||
avatar.recalcStats();
|
avatar.recalcStats();
|
||||||
// Don't try to add each avatar to the current team
|
player.addAvatar(avatar);
|
||||||
player.addAvatar(avatar, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//some test items
|
//some test items
|
||||||
|
@ -15,7 +15,7 @@ public final class KickCommand implements CommandHandler {
|
|||||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||||
if (sender != null) {
|
if (sender != null) {
|
||||||
CommandHandler.sendMessage(sender, translate(sender, "commands.kick.player_kick_player",
|
CommandHandler.sendMessage(sender, translate(sender, "commands.kick.player_kick_player",
|
||||||
Integer.toString(sender.getUid()), sender.getAccount().getUsername(),
|
Integer.toString(sender.getAccount().getPlayerUid()), sender.getAccount().getUsername(),
|
||||||
Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
||||||
} else {
|
} else {
|
||||||
CommandHandler.sendMessage(null, translate(sender, "commands.kick.server_kick_player", Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
CommandHandler.sendMessage(null, translate(sender, "commands.kick.server_kick_player", Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
||||||
|
@ -44,7 +44,7 @@ public final class SendMailCommand implements CommandHandler {
|
|||||||
}
|
}
|
||||||
case "all" -> mailBuilder = new MailBuilder(true, new Mail());
|
case "all" -> mailBuilder = new MailBuilder(true, new Mail());
|
||||||
default -> {
|
default -> {
|
||||||
if (DatabaseHelper.getPlayerByUid(Integer.parseInt(args.get(0))) != null) {
|
if (DatabaseHelper.getPlayerById(Integer.parseInt(args.get(0))) != null) {
|
||||||
mailBuilder = new MailBuilder(Integer.parseInt(args.get(0)), new Mail());
|
mailBuilder = new MailBuilder(Integer.parseInt(args.get(0)), new Mail());
|
||||||
} else {
|
} else {
|
||||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.user_not_exist", args.get(0)));
|
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.user_not_exist", args.get(0)));
|
||||||
|
@ -8,7 +8,6 @@ import dev.morphia.query.FindOptions;
|
|||||||
import dev.morphia.query.Sort;
|
import dev.morphia.query.Sort;
|
||||||
import dev.morphia.query.experimental.filters.Filters;
|
import dev.morphia.query.experimental.filters.Filters;
|
||||||
import emu.grasscutter.GameConstants;
|
import emu.grasscutter.GameConstants;
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
import emu.grasscutter.game.friends.Friendship;
|
import emu.grasscutter.game.friends.Friendship;
|
||||||
@ -50,7 +49,7 @@ public final class DatabaseHelper {
|
|||||||
account.setId(Integer.toString(DatabaseManager.getNextId(account)));
|
account.setId(Integer.toString(DatabaseManager.getNextId(account)));
|
||||||
|
|
||||||
if (reservedId > 0) {
|
if (reservedId > 0) {
|
||||||
account.setReservedPlayerUid(reservedId);
|
account.setPlayerId(reservedId);
|
||||||
}
|
}
|
||||||
|
|
||||||
DatabaseHelper.saveAccount(account);
|
DatabaseHelper.saveAccount(account);
|
||||||
@ -105,28 +104,25 @@ public final class DatabaseHelper {
|
|||||||
// This should optimally be wrapped inside a transaction, to make sure an error thrown mid-way does not leave the
|
// This should optimally be wrapped inside a transaction, to make sure an error thrown mid-way does not leave the
|
||||||
// database in an inconsistent state, but unfortunately Mongo only supports that when we have a replica set ...
|
// database in an inconsistent state, but unfortunately Mongo only supports that when we have a replica set ...
|
||||||
|
|
||||||
Player player = Grasscutter.getGameServer().getPlayerByAccountId(target.getId());
|
// Delete Mail.class data
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("mail").deleteMany(eq("ownerUid", target.getPlayerUid()));
|
||||||
|
// Delete Avatar.class data
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("avatars").deleteMany(eq("ownerId", target.getPlayerUid()));
|
||||||
|
// Delete GachaRecord.class data
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("gachas").deleteMany(eq("ownerId", target.getPlayerUid()));
|
||||||
|
// Delete GameItem.class data
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("items").deleteMany(eq("ownerId", target.getPlayerUid()));
|
||||||
|
// Delete GameMainQuest.class data
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("quests").deleteMany(eq("ownerUid", target.getPlayerUid()));
|
||||||
|
|
||||||
if (player != null) {
|
// Delete friendships.
|
||||||
// Close session first
|
// Here, we need to make sure to not only delete the deleted account's friendships,
|
||||||
player.getSession().close();
|
// but also all friendship entries for that account's friends.
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("ownerId", target.getPlayerUid()));
|
||||||
|
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("friendId", target.getPlayerUid()));
|
||||||
|
|
||||||
// Delete data from collections
|
// Delete the player.
|
||||||
DatabaseManager.getGameDatabase().getCollection("mail").deleteMany(eq("ownerUid", player.getUid()));
|
DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("id", target.getPlayerUid())).delete();
|
||||||
DatabaseManager.getGameDatabase().getCollection("avatars").deleteMany(eq("ownerId", player.getUid()));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("gachas").deleteMany(eq("ownerId", player.getUid()));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("items").deleteMany(eq("ownerId", player.getUid()));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("quests").deleteMany(eq("ownerUid", player.getUid()));
|
|
||||||
|
|
||||||
// Delete friendships.
|
|
||||||
// Here, we need to make sure to not only delete the deleted account's friendships,
|
|
||||||
// but also all friendship entries for that account's friends.
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("ownerId", player.getUid()));
|
|
||||||
DatabaseManager.getGameDatabase().getCollection("friendships").deleteMany(eq("friendId", player.getUid()));
|
|
||||||
|
|
||||||
// Delete the player last.
|
|
||||||
DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("id", player.getUid())).delete();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Finally, delete the account itself.
|
// Finally, delete the account itself.
|
||||||
DatabaseManager.getGameDatastore().find(Account.class).filter(Filters.eq("id", target.getId())).delete();
|
DatabaseManager.getGameDatastore().find(Account.class).filter(Filters.eq("id", target.getId())).delete();
|
||||||
@ -136,19 +132,15 @@ public final class DatabaseHelper {
|
|||||||
return DatabaseManager.getGameDatastore().find(Player.class).stream().toList();
|
return DatabaseManager.getGameDatastore().find(Player.class).stream().toList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Player getPlayerByUid(int id) {
|
public static Player getPlayerById(int id) {
|
||||||
return DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("_id", id)).first();
|
return DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("_id", id)).first();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Player getPlayerByAccount(Account account) {
|
public static boolean checkPlayerExists(int id) {
|
||||||
return DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("accountId", account.getId())).first();
|
return DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("_id", id)).first() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static boolean checkPlayerExists(int uid) {
|
public static synchronized Player createPlayer(Player character, int reservedId) {
|
||||||
return DatabaseManager.getGameDatastore().find(Player.class).filter(Filters.eq("_id", uid)).count() > 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
public static synchronized Player generatePlayerUid(Player character, int reservedId) {
|
|
||||||
// Check if reserved id
|
// Check if reserved id
|
||||||
int id;
|
int id;
|
||||||
if (reservedId > 0 && !checkPlayerExists(reservedId)) {
|
if (reservedId > 0 && !checkPlayerExists(reservedId)) {
|
||||||
|
@ -21,7 +21,7 @@ public class Account {
|
|||||||
private String username;
|
private String username;
|
||||||
private String password; // Unused for now
|
private String password; // Unused for now
|
||||||
|
|
||||||
private int reservedPlayerId;
|
@AlsoLoad("playerUid") private int playerId;
|
||||||
private String email;
|
private String email;
|
||||||
|
|
||||||
private String token;
|
private String token;
|
||||||
@ -67,12 +67,12 @@ public class Account {
|
|||||||
this.token = token;
|
this.token = token;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getReservedPlayerUid() {
|
public int getPlayerUid() {
|
||||||
return this.reservedPlayerId;
|
return this.playerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setReservedPlayerUid(int playerId) {
|
public void setPlayerId(int playerId) {
|
||||||
this.reservedPlayerId = playerId;
|
this.playerId = playerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String getEmail() {
|
public String getEmail() {
|
||||||
|
@ -50,7 +50,6 @@ import emu.grasscutter.server.event.player.PlayerJoinEvent;
|
|||||||
import emu.grasscutter.server.event.player.PlayerQuitEvent;
|
import emu.grasscutter.server.event.player.PlayerQuitEvent;
|
||||||
import emu.grasscutter.server.game.GameServer;
|
import emu.grasscutter.server.game.GameServer;
|
||||||
import emu.grasscutter.server.game.GameSession;
|
import emu.grasscutter.server.game.GameSession;
|
||||||
import emu.grasscutter.server.game.GameSession.SessionState;
|
|
||||||
import emu.grasscutter.server.packet.send.*;
|
import emu.grasscutter.server.packet.send.*;
|
||||||
import emu.grasscutter.utils.DateHelper;
|
import emu.grasscutter.utils.DateHelper;
|
||||||
import emu.grasscutter.utils.Position;
|
import emu.grasscutter.utils.Position;
|
||||||
@ -248,6 +247,7 @@ public class Player {
|
|||||||
|
|
||||||
public void setAccount(Account account) {
|
public void setAccount(Account account) {
|
||||||
this.account = account;
|
this.account = account;
|
||||||
|
this.account.setPlayerId(getUid());
|
||||||
}
|
}
|
||||||
|
|
||||||
public GameSession getSession() {
|
public GameSession getSession() {
|
||||||
@ -809,7 +809,7 @@ public class Player {
|
|||||||
this.hasSentAvatarDataNotify = hasSentAvatarDataNotify;
|
this.hasSentAvatarDataNotify = hasSentAvatarDataNotify;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAvatar(Avatar avatar, boolean addToCurrentTeam) {
|
public void addAvatar(Avatar avatar) {
|
||||||
boolean result = getAvatars().addAvatar(avatar);
|
boolean result = getAvatars().addAvatar(avatar);
|
||||||
|
|
||||||
if (result) {
|
if (result) {
|
||||||
@ -820,22 +820,14 @@ public class Player {
|
|||||||
if (hasSentAvatarDataNotify()) {
|
if (hasSentAvatarDataNotify()) {
|
||||||
// Recalc stats
|
// Recalc stats
|
||||||
avatar.recalcStats();
|
avatar.recalcStats();
|
||||||
// Packet, show notice on left if the avatar will be added to the team
|
// Packet
|
||||||
sendPacket(new PacketAvatarAddNotify(avatar, addToCurrentTeam && this.getTeamManager().canAddAvatarToCurrentTeam()));
|
sendPacket(new PacketAvatarAddNotify(avatar, false));
|
||||||
if (addToCurrentTeam) {
|
|
||||||
// If space in team, add
|
|
||||||
this.getTeamManager().addAvatarToCurrentTeam(avatar);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
// Failed adding avatar
|
// Failed adding avatar
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void addAvatar(Avatar avatar) {
|
|
||||||
addAvatar(avatar, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
public void addFlycloak(int flycloakId) {
|
public void addFlycloak(int flycloakId) {
|
||||||
this.getFlyCloakList().add(flycloakId);
|
this.getFlyCloakList().add(flycloakId);
|
||||||
this.sendPacket(new PacketAvatarGainFlycloakNotify(flycloakId));
|
this.sendPacket(new PacketAvatarGainFlycloakNotify(flycloakId));
|
||||||
@ -1017,8 +1009,8 @@ public class Player {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
List<Integer> showAvatarList = DatabaseHelper.getPlayerByUid(id).getShowAvatarList();
|
List<Integer> showAvatarList = DatabaseHelper.getPlayerById(id).getShowAvatarList();
|
||||||
AvatarStorage avatars = DatabaseHelper.getPlayerByUid(id).getAvatars();
|
AvatarStorage avatars = DatabaseHelper.getPlayerById(id).getAvatars();
|
||||||
avatars.loadFromDatabase();
|
avatars.loadFromDatabase();
|
||||||
if (showAvatarList != null) {
|
if (showAvatarList != null) {
|
||||||
for (int avatarId : showAvatarList) {
|
for (int avatarId : showAvatarList) {
|
||||||
@ -1058,7 +1050,7 @@ public class Player {
|
|||||||
player = this;
|
player = this;
|
||||||
shouldRecalc = false;
|
shouldRecalc = false;
|
||||||
} else {
|
} else {
|
||||||
player = DatabaseHelper.getPlayerByUid(id);
|
player = DatabaseHelper.getPlayerById(id);
|
||||||
player.getAvatars().loadFromDatabase();
|
player.getAvatars().loadFromDatabase();
|
||||||
player.getInventory().loadFromDatabase();
|
player.getInventory().loadFromDatabase();
|
||||||
shouldRecalc = true;
|
shouldRecalc = true;
|
||||||
@ -1177,8 +1169,7 @@ public class Player {
|
|||||||
DatabaseHelper.savePlayer(this);
|
DatabaseHelper.savePlayer(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Called from tokenrsp
|
public void onLogin() {
|
||||||
public void loadFromDatabase() {
|
|
||||||
// Make sure these exist
|
// Make sure these exist
|
||||||
if (this.getTeamManager() == null) {
|
if (this.getTeamManager() == null) {
|
||||||
this.teamManager = new TeamManager(this);
|
this.teamManager = new TeamManager(this);
|
||||||
@ -1206,14 +1197,6 @@ public class Player {
|
|||||||
this.getMailHandler().loadFromDatabase();
|
this.getMailHandler().loadFromDatabase();
|
||||||
this.getQuestManager().loadFromDatabase();
|
this.getQuestManager().loadFromDatabase();
|
||||||
|
|
||||||
// Add to gameserver (Always handle last)
|
|
||||||
if (getSession().isActive()) {
|
|
||||||
getServer().registerPlayer(this);
|
|
||||||
getProfile().setPlayer(this); // Set online
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void onLogin() {
|
|
||||||
// Quest - Commented out because a problem is caused if you log out while this quest is active
|
// Quest - Commented out because a problem is caused if you log out while this quest is active
|
||||||
/*
|
/*
|
||||||
if (getQuestManager().getMainQuestById(351) == null) {
|
if (getQuestManager().getMainQuestById(351) == null) {
|
||||||
@ -1233,6 +1216,12 @@ public class Player {
|
|||||||
World world = new World(this);
|
World world = new World(this);
|
||||||
world.addPlayer(this);
|
world.addPlayer(this);
|
||||||
|
|
||||||
|
// Add to gameserver
|
||||||
|
if (getSession().isActive()) {
|
||||||
|
getServer().registerPlayer(this);
|
||||||
|
getProfile().setPlayer(this); // Set online
|
||||||
|
}
|
||||||
|
|
||||||
// Multiplayer setting
|
// Multiplayer setting
|
||||||
this.setProperty(PlayerProperty.PROP_PLAYER_MP_SETTING_TYPE, this.getMpSetting().getNumber());
|
this.setProperty(PlayerProperty.PROP_PLAYER_MP_SETTING_TYPE, this.getMpSetting().getNumber());
|
||||||
this.setProperty(PlayerProperty.PROP_IS_MP_MODE_AVAILABLE, 1);
|
this.setProperty(PlayerProperty.PROP_IS_MP_MODE_AVAILABLE, 1);
|
||||||
@ -1259,9 +1248,6 @@ public class Player {
|
|||||||
// First notify packets sent
|
// First notify packets sent
|
||||||
this.setHasSentAvatarDataNotify(true);
|
this.setHasSentAvatarDataNotify(true);
|
||||||
|
|
||||||
// Set session state
|
|
||||||
session.setState(SessionState.ACTIVE);
|
|
||||||
|
|
||||||
// Call join event.
|
// Call join event.
|
||||||
PlayerJoinEvent event = new PlayerJoinEvent(this); event.call();
|
PlayerJoinEvent event = new PlayerJoinEvent(this); event.call();
|
||||||
if(event.isCanceled()) // If event is not cancelled, continue.
|
if(event.isCanceled()) // If event is not cancelled, continue.
|
||||||
|
@ -44,7 +44,7 @@ public class TeamInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean addAvatar(Avatar avatar) {
|
public boolean addAvatar(Avatar avatar) {
|
||||||
if (contains(avatar)) {
|
if (size() >= GAME_OPTIONS.avatarLimits.singlePlayerTeam || contains(avatar)) {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -104,20 +104,6 @@ public class TeamManager {
|
|||||||
this.mpTeam = mpTeam;
|
this.mpTeam = mpTeam;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Search through all teams and if the team matches, return that index.
|
|
||||||
* Otherwise, return -1.
|
|
||||||
* No match could mean that the team does not currently belong to the player.
|
|
||||||
*/
|
|
||||||
public int getTeamId(TeamInfo team) {
|
|
||||||
for (int i = 1; i <= this.teams.size(); i++) {
|
|
||||||
if (this.teams.get(i).equals(team)) {
|
|
||||||
return i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
public int getCurrentTeamId() {
|
public int getCurrentTeamId() {
|
||||||
// Starts from 1
|
// Starts from 1
|
||||||
return currentTeamIndex;
|
return currentTeamIndex;
|
||||||
@ -200,107 +186,6 @@ public class TeamManager {
|
|||||||
|
|
||||||
// Methods
|
// Methods
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there is space to add the number of avatars to the team.
|
|
||||||
*/
|
|
||||||
public boolean canAddAvatarsToTeam(TeamInfo team, int avatars) {
|
|
||||||
return team.size() + avatars <= getMaxTeamSize();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there is space to add to the team.
|
|
||||||
*/
|
|
||||||
public boolean canAddAvatarToTeam(TeamInfo team) {
|
|
||||||
return canAddAvatarsToTeam(team, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there is space to add the number of avatars to the current team.
|
|
||||||
* If the current team is temporary, returns false.
|
|
||||||
*/
|
|
||||||
public boolean canAddAvatarsToCurrentTeam(int avatars) {
|
|
||||||
if (this.useTemporarilyTeamIndex != -1){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return canAddAvatarsToTeam(this.getCurrentTeamInfo(), avatars);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Returns true if there is space to add to the current team.
|
|
||||||
* If the current team is temporary, returns false.
|
|
||||||
*/
|
|
||||||
public boolean canAddAvatarToCurrentTeam() {
|
|
||||||
return canAddAvatarsToCurrentTeam(1);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to add the collection of avatars to the team.
|
|
||||||
* Returns true if all were successfully added.
|
|
||||||
* If some can not be added, returns false and does not add any.
|
|
||||||
*/
|
|
||||||
public boolean addAvatarsToTeam(TeamInfo team, Collection<Avatar> avatars) {
|
|
||||||
if (!canAddAvatarsToTeam(team, avatars.size())) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Convert avatars into a collection of avatar IDs, then add
|
|
||||||
team.getAvatars().addAll(avatars.stream().map(a -> a.getAvatarId()).toList());
|
|
||||||
|
|
||||||
// Update team
|
|
||||||
if (this.getPlayer().isInMultiplayer()) {
|
|
||||||
if (team.equals(this.getMpTeam())) {
|
|
||||||
// MP team Packet
|
|
||||||
this.updateTeamEntities(new PacketChangeMpTeamAvatarRsp(getPlayer(), team));
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
// SP team update packet
|
|
||||||
getPlayer().sendPacket(new PacketAvatarTeamUpdateNotify(getPlayer()));
|
|
||||||
|
|
||||||
int teamId = this.getTeamId(team);
|
|
||||||
if (teamId != -1) {
|
|
||||||
// This is one of the player's teams
|
|
||||||
// Update entites
|
|
||||||
if (teamId == this.getCurrentTeamId()) {
|
|
||||||
this.updateTeamEntities(new PacketSetUpAvatarTeamRsp(getPlayer(), teamId, team));
|
|
||||||
} else {
|
|
||||||
getPlayer().sendPacket(new PacketSetUpAvatarTeamRsp(getPlayer(), teamId, team));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to add an avatar to a team.
|
|
||||||
* Returns true if successful.
|
|
||||||
*/
|
|
||||||
public boolean addAvatarToTeam(TeamInfo team, Avatar avatar){
|
|
||||||
return addAvatarsToTeam(team, Collections.singleton(avatar));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to add the collection of avatars to the current team.
|
|
||||||
* Will not modify a temporary team.
|
|
||||||
* Returns true if all were successfully added.
|
|
||||||
* If some can not be added, returns false and does not add any.
|
|
||||||
*/
|
|
||||||
public boolean addAvatarsToCurrentTeam(Collection<Avatar> avatars) {
|
|
||||||
if (this.useTemporarilyTeamIndex != -1){
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
return addAvatarsToTeam(this.getCurrentTeamInfo(), avatars);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Try to add an avatar to the current team.
|
|
||||||
* Will not modify a temporary team.
|
|
||||||
* Returns true if successful.
|
|
||||||
*/
|
|
||||||
public boolean addAvatarToCurrentTeam(Avatar avatar) {
|
|
||||||
return addAvatarsToCurrentTeam(Collections.singleton(avatar));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateTeamResonances() {
|
private void updateTeamResonances() {
|
||||||
Int2IntOpenHashMap map = new Int2IntOpenHashMap();
|
Int2IntOpenHashMap map = new Int2IntOpenHashMap();
|
||||||
|
|
||||||
@ -430,7 +315,19 @@ public class TeamManager {
|
|||||||
|
|
||||||
// Clear current team info and add avatars from our new team
|
// Clear current team info and add avatars from our new team
|
||||||
teamInfo.getAvatars().clear();
|
teamInfo.getAvatars().clear();
|
||||||
this.addAvatarsToTeam(teamInfo, newTeam);
|
for (Avatar avatar : newTeam) {
|
||||||
|
teamInfo.addAvatar(avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Update packet
|
||||||
|
getPlayer().sendPacket(new PacketAvatarTeamUpdateNotify(getPlayer()));
|
||||||
|
|
||||||
|
// Update entites
|
||||||
|
if (teamId == this.getCurrentTeamId()) {
|
||||||
|
this.updateTeamEntities(new PacketSetUpAvatarTeamRsp(getPlayer(), teamId, teamInfo));
|
||||||
|
} else {
|
||||||
|
getPlayer().sendPacket(new PacketSetUpAvatarTeamRsp(getPlayer(), teamId, teamInfo));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupMpTeam(List<Long> list) {
|
public void setupMpTeam(List<Long> list) {
|
||||||
@ -454,7 +351,12 @@ public class TeamManager {
|
|||||||
|
|
||||||
// Clear current team info and add avatars from our new team
|
// Clear current team info and add avatars from our new team
|
||||||
teamInfo.getAvatars().clear();
|
teamInfo.getAvatars().clear();
|
||||||
this.addAvatarsToTeam(teamInfo, newTeam);
|
for (Avatar avatar : newTeam) {
|
||||||
|
teamInfo.addAvatar(avatar);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Packet
|
||||||
|
this.updateTeamEntities(new PacketChangeMpTeamAvatarRsp(getPlayer(), teamInfo));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setupTemporaryTeam(List<List<Long>> guidList) {
|
public void setupTemporaryTeam(List<List<Long>> guidList) {
|
||||||
|
@ -118,7 +118,6 @@ public final class GameServer extends KcpServer {
|
|||||||
public ChatManagerHandler getChatManager() {
|
public ChatManagerHandler getChatManager() {
|
||||||
return chatManager;
|
return chatManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setChatManager(ChatManagerHandler chatManager) {
|
public void setChatManager(ChatManagerHandler chatManager) {
|
||||||
this.chatManager = chatManager;
|
this.chatManager = chatManager;
|
||||||
}
|
}
|
||||||
@ -190,17 +189,12 @@ public final class GameServer extends KcpServer {
|
|||||||
|
|
||||||
// Check database if character isnt here
|
// Check database if character isnt here
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
player = DatabaseHelper.getPlayerByUid(id);
|
player = DatabaseHelper.getPlayerById(id);
|
||||||
}
|
}
|
||||||
|
|
||||||
return player;
|
return player;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Player getPlayerByAccountId(String accountId) {
|
|
||||||
Optional<Player> playerOpt = getPlayers().values().stream().filter(player -> player.getAccount().getId().equals(accountId)).findFirst();
|
|
||||||
return playerOpt.orElse(null);
|
|
||||||
}
|
|
||||||
|
|
||||||
public SocialDetail.Builder getSocialDetailByUid(int id) {
|
public SocialDetail.Builder getSocialDetailByUid(int id) {
|
||||||
// Get from online players
|
// Get from online players
|
||||||
Player player = this.getPlayerByUid(id, true);
|
Player player = this.getPlayerByUid(id, true);
|
||||||
|
@ -52,7 +52,7 @@ public final class GachaHandler implements Router {
|
|||||||
response.status(403).send("Requested account was not found");
|
response.status(403).send("Requested account was not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Player player = Grasscutter.getGameServer().getPlayerByAccountId(account.getId());
|
Player player = Grasscutter.getGameServer().getPlayerByUid(account.getPlayerUid());
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
response.status(403).send("No player associated with requested account");
|
response.status(403).send("No player associated with requested account");
|
||||||
return;
|
return;
|
||||||
@ -88,7 +88,7 @@ public final class GachaHandler implements Router {
|
|||||||
response.status(403).send("Requested account was not found");
|
response.status(403).send("Requested account was not found");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
Player player = Grasscutter.getGameServer().getPlayerByAccountId(account.getId());
|
Player player = Grasscutter.getGameServer().getPlayerByUid(account.getPlayerUid());
|
||||||
if (player == null) {
|
if (player == null) {
|
||||||
response.status(403).send("No player associated with requested account");
|
response.status(403).send("No player associated with requested account");
|
||||||
return;
|
return;
|
||||||
|
@ -1,16 +1,11 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
import static emu.grasscutter.Configuration.ACCOUNT;
|
|
||||||
|
|
||||||
import emu.grasscutter.Grasscutter;
|
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.Account;
|
import emu.grasscutter.game.Account;
|
||||||
import emu.grasscutter.game.player.Player;
|
|
||||||
import emu.grasscutter.net.packet.Opcodes;
|
import emu.grasscutter.net.packet.Opcodes;
|
||||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||||
import emu.grasscutter.net.proto.GetPlayerTokenReqOuterClass.GetPlayerTokenReq;
|
import emu.grasscutter.net.proto.GetPlayerTokenReqOuterClass.GetPlayerTokenReq;
|
||||||
import emu.grasscutter.net.packet.PacketHandler;
|
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;
|
||||||
import emu.grasscutter.server.game.GameSession.SessionState;
|
import emu.grasscutter.server.game.GameSession.SessionState;
|
||||||
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
|
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
|
||||||
@ -20,12 +15,6 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
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);
|
GetPlayerTokenReq req = GetPlayerTokenReq.parseFrom(payload);
|
||||||
|
|
||||||
// Authenticate
|
// Authenticate
|
||||||
@ -41,35 +30,27 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
|
|||||||
|
|
||||||
// Set account
|
// Set account
|
||||||
session.setAccount(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.setUseSecretKey(true);
|
||||||
session.setState(SessionState.WAITING_FOR_LOGIN);
|
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
|
// Send packet
|
||||||
session.send(new PacketGetPlayerTokenRsp(session));
|
session.send(new PacketGetPlayerTokenRsp(session, doesPlayerExist));
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,11 @@ public class HandlerPlayerLoginReq extends PacketHandler {
|
|||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
// Check
|
// Check
|
||||||
if (session.getAccount() == null) {
|
if (session.getAccount() == null) {
|
||||||
session.close();
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Max players limit
|
||||||
|
if (ACCOUNT.maxPlayer > -1 && Grasscutter.getGameServer().getPlayers().size() >= ACCOUNT.maxPlayer) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,21 +35,23 @@ public class HandlerPlayerLoginReq extends PacketHandler {
|
|||||||
|
|
||||||
// Authenticate session
|
// Authenticate session
|
||||||
if (!req.getToken().equals(session.getAccount().getToken())) {
|
if (!req.getToken().equals(session.getAccount().getToken())) {
|
||||||
session.close();
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Load character from db
|
// Load character from db
|
||||||
Player player = session.getPlayer();
|
Player player = DatabaseHelper.getPlayerById(session.getAccount().getPlayerUid());
|
||||||
|
|
||||||
// Show opening cutscene if player has no avatars
|
if (player == null) {
|
||||||
if (player.getAvatars().getAvatarCount() == 0) {
|
// Send packets
|
||||||
// Pick character
|
|
||||||
session.setState(SessionState.PICKING_CHARACTER);
|
session.setState(SessionState.PICKING_CHARACTER);
|
||||||
session.send(new BasePacket(PacketOpcodes.DoSetPlayerBornDataNotify));
|
session.send(new BasePacket(PacketOpcodes.DoSetPlayerBornDataNotify));
|
||||||
} else {
|
} else {
|
||||||
|
// Set character
|
||||||
|
session.setPlayer(player);
|
||||||
|
|
||||||
// Login done
|
// Login done
|
||||||
session.getPlayer().onLogin();
|
session.getPlayer().onLogin();
|
||||||
|
session.setState(SessionState.ACTIVE);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Final packet to tell client logging in is done
|
// Final packet to tell client logging in is done
|
||||||
|
@ -46,38 +46,59 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Get player object
|
String nickname = req.getNickName();
|
||||||
Player player = session.getPlayer();
|
if (nickname == null) {
|
||||||
|
nickname = "Traveler";
|
||||||
// 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
|
// Call creation event.
|
||||||
session.getPlayer().onLogin();
|
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);
|
||||||
|
|
||||||
// Born resp packet
|
try {
|
||||||
session.send(new BasePacket(PacketOpcodes.SetPlayerBornDataRsp));
|
// Save to db
|
||||||
|
DatabaseHelper.createPlayer(player, session.getAccount().getPlayerUid());
|
||||||
|
|
||||||
// Default mail
|
// Create avatar
|
||||||
var welcomeMail = GAME_INFO.joinOptions.welcomeMail;
|
if (player.getAvatars().getAvatarCount() == 0) {
|
||||||
MailBuilder mailBuilder = new MailBuilder(player.getUid(), new Mail());
|
Avatar mainCharacter = new Avatar(avatarId);
|
||||||
mailBuilder.mail.mailContent.title = welcomeMail.title;
|
mainCharacter.setSkillDepotData(GameData.getAvatarSkillDepotDataMap().get(startingSkillDepot));
|
||||||
mailBuilder.mail.mailContent.sender = welcomeMail.sender;
|
player.addAvatar(mainCharacter);
|
||||||
// Please credit Grasscutter if changing something here. We don't condone commercial use of the project.
|
player.setMainCharacterId(avatarId);
|
||||||
mailBuilder.mail.mailContent.content = welcomeMail.content + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>";
|
player.setHeadImage(avatarId);
|
||||||
mailBuilder.mail.itemList.addAll(Arrays.asList(welcomeMail.items));
|
player.getTeamManager().getCurrentSinglePlayerTeamInfo().getAvatars().add(mainCharacter.getAvatarId());
|
||||||
mailBuilder.mail.importance = 1;
|
player.save(); // TODO save player team in different object
|
||||||
player.sendMail(mailBuilder.mail);
|
}
|
||||||
|
|
||||||
|
// 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));
|
||||||
|
|
||||||
|
// 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();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,16 +10,16 @@ import emu.grasscutter.utils.Crypto;
|
|||||||
|
|
||||||
public class PacketGetPlayerTokenRsp extends BasePacket {
|
public class PacketGetPlayerTokenRsp extends BasePacket {
|
||||||
|
|
||||||
public PacketGetPlayerTokenRsp(GameSession session) {
|
public PacketGetPlayerTokenRsp(GameSession session, boolean doesPlayerExist) {
|
||||||
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
super(PacketOpcodes.GetPlayerTokenRsp, true);
|
||||||
|
|
||||||
this.setUseDispatchKey(true);
|
this.setUseDispatchKey(true);
|
||||||
|
|
||||||
GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder()
|
GetPlayerTokenRsp p = GetPlayerTokenRsp.newBuilder()
|
||||||
.setUid(session.getPlayer().getUid())
|
.setUid(session.getAccount().getPlayerUid())
|
||||||
.setToken(session.getAccount().getToken())
|
.setToken(session.getAccount().getToken())
|
||||||
.setAccountType(1)
|
.setAccountType(1)
|
||||||
.setIsProficientPlayer(session.getPlayer().getAvatars().getAvatarCount() > 0) // Not sure where this goes
|
.setIsProficientPlayer(doesPlayerExist) // Not sure where this goes
|
||||||
.setSecretKeySeed(Crypto.ENCRYPT_SEED)
|
.setSecretKeySeed(Crypto.ENCRYPT_SEED)
|
||||||
.setSecurityCmdBuffer(ByteString.copyFrom(Crypto.ENCRYPT_SEED_BUFFER))
|
.setSecurityCmdBuffer(ByteString.copyFrom(Crypto.ENCRYPT_SEED_BUFFER))
|
||||||
.setPlatformType(3)
|
.setPlatformType(3)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user