Skip to content
Snippets Groups Projects
Commit a8293102 authored by Melledy's avatar Melledy Committed by GitHub
Browse files

Merge branch 'development' into stable

parents 304b9cb8 ecf7a81a
Branches
Tags
No related merge requests found
Showing
with 342 additions and 183 deletions
...@@ -16,6 +16,6 @@ public class HandlerGetAllMailReq extends PacketHandler { ...@@ -16,6 +16,6 @@ public class HandlerGetAllMailReq 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 {
GetAllMailReqOuterClass.GetAllMailReq req = GetAllMailReqOuterClass.GetAllMailReq.parseFrom(payload); GetAllMailReqOuterClass.GetAllMailReq req = GetAllMailReqOuterClass.GetAllMailReq.parseFrom(payload);
session.send(new PacketGetAllMailRsp(session.getPlayer(), req.getIsGiftMail())); session.send(new PacketGetAllMailRsp(session.getPlayer(), req.getANKKGPJCINB()));
} }
} }
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.GameServer;
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;
...@@ -15,42 +21,73 @@ public class HandlerGetPlayerTokenReq extends PacketHandler { ...@@ -15,42 +21,73 @@ 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 {
GetPlayerTokenReq req = GetPlayerTokenReq.parseFrom(payload); GetPlayerTokenReq req = GetPlayerTokenReq.parseFrom(payload);
// Authenticate // Authenticate
Account account = DatabaseHelper.getAccountById(req.getAccountUid()); Account account = DatabaseHelper.getAccountById(req.getAccountUid());
if (account == null) { if (account == null || !account.getToken().equals(req.getAccountToken())) {
return;
}
// Check token
if (!account.getToken().equals(req.getAccountToken())) {
return; return;
} }
// Set account // Set account
session.setAccount(account); session.setAccount(account);
session.setUseSecretKey(true);
session.setState(SessionState.WAITING_FOR_LOGIN);
// Check if player object exists in server
// Has character // NOTE: CHECKING MUST SITUATED HERE (BEFORE getPlayerByUid)! because to save firstly ,to load secondly !!!
boolean doesPlayerExist = false; // TODO - optimize
if (account.getPlayerUid() > 0) { boolean kicked = false;
// Set flag for player existing Player exists = Grasscutter.getGameServer().getPlayerByAccountId(account.getId());
doesPlayerExist = DatabaseHelper.checkPlayerExists(account.getPlayerUid()); if (exists != null) {
GameSession existsSession = exists.getSession();
if (existsSession != session) {// No self-kicking
exists.onLogout();//must save immediately , or the below will load old data
existsSession.close();
Grasscutter.getLogger().warn("Player {} was kicked due to duplicated login", account.getUsername());
kicked = true;
}
} }
// Set reserve player id if account doesnt exist //NOTE: If there are 5 online players, max count of player is 5,
if (!doesPlayerExist) { // a new client want to login by kicking one of them ,
int id = DatabaseHelper.getNextPlayerId(session.getAccount().getPlayerUid()); // I think it should be allowed
if (id != session.getAccount().getPlayerUid()) { if(!kicked) {
session.getAccount().setPlayerId(id); // Max players limit
session.getAccount().save(); if (ACCOUNT.maxPlayer > -1 && Grasscutter.getGameServer().getPlayers().size() >= ACCOUNT.maxPlayer) {
session.close();
return;
} }
} }
// 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);
// Send packet // Send packet
session.send(new PacketGetPlayerTokenRsp(session, doesPlayerExist)); session.send(new PacketGetPlayerTokenRsp(session));
} }
} }
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
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.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketGetShopRsp;
import emu.grasscutter.server.packet.send.PacketGetWidgetSlotRsp;
@Opcodes(PacketOpcodes.GetWidgetSlotReq) @Opcodes(PacketOpcodes.GetWidgetSlotReq)
public class HandlerGetWidgetSlotReq extends PacketHandler { public class HandlerGetWidgetSlotReq 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 {
// Unhandled Player player = session.getPlayer();
session.send(new PacketGetWidgetSlotRsp(player));
} }
} }
package emu.grasscutter.server.packet.recv;
import java.math.BigInteger;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HitTreeNotifyOuterClass.HitTreeNotify;
import emu.grasscutter.server.game.GameSession;
/**
* Implement Deforestation Function
*/
@Opcodes(PacketOpcodes.HitTreeNotify)
public class HandlerHitTreeNotify extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
HitTreeNotify hit = HitTreeNotify.parseFrom(payload);
session.getPlayer().getDeforestationManager().onDeforestationInvoke(hit);
}
}
\ No newline at end of file
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.HomeChooseModuleReqOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketHomeChooseModuleRsp;
import emu.grasscutter.server.packet.send.PacketHomeComfortInfoNotify;
import emu.grasscutter.server.packet.send.PacketPlayerHomeCompInfoNotify;
@Opcodes(PacketOpcodes.HomeChooseModuleReq)
public class HandlerHomeChooseModuleReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
HomeChooseModuleReqOuterClass.HomeChooseModuleReq req =
HomeChooseModuleReqOuterClass.HomeChooseModuleReq.parseFrom(payload);
session.getPlayer().addRealmList(req.getModuleId());
session.getPlayer().setCurrentRealmId(req.getModuleId());
session.send(new PacketHomeChooseModuleRsp(req.getModuleId()));
session.send(new PacketPlayerHomeCompInfoNotify(session.getPlayer()));
session.send(new PacketHomeComfortInfoNotify(session.getPlayer()));
}
}
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.managers.MapMarkManager.MapMark;
import emu.grasscutter.game.managers.MapMarkManager.MapMarksManager;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq; import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketMarkMapRsp;
import emu.grasscutter.server.packet.send.PacketMarkNewNotify;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
import emu.grasscutter.utils.Position;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
@Opcodes(PacketOpcodes.MarkMapReq) @Opcodes(PacketOpcodes.MarkMapReq)
public class HandlerMarkMapReq extends PacketHandler { public class HandlerMarkMapReq extends PacketHandler {
private static boolean isInt(String str) {
try {
@SuppressWarnings("unused")
int x = Integer.parseInt(str);
return true; // String is an Integer
} catch (NumberFormatException e) {
return false; // String is not an Integer
}
}
@Override @Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
MarkMapReq req = MarkMapReq.parseFrom(payload); MarkMapReq req = MarkMapReq.parseFrom(payload);
MarkMapReq.Operation op = req.getOp(); session.getPlayer().getMapMarksManager().handleMapMarkReq(req);
Player player = session.getPlayer();
MapMarksManager mapMarksManager = player.getMapMarksManager();
if (op == MarkMapReq.Operation.ADD) {
MapMark newMapMark = new MapMark(req.getMark());
// keep teleporting functionality on fishhook mark.
if (newMapMark.getMapMarkPointType() == MapMarkPointTypeOuterClass.MapMarkPointType.MAP_MARK_POINT_TYPE_FISH_POOL) {
teleport(player, newMapMark);
return;
}
if (mapMarksManager.addMapMark(newMapMark)) {
player.save();
}
} else if (op == MarkMapReq.Operation.MOD) {
MapMark newMapMark = new MapMark(req.getMark());
if (mapMarksManager.removeMapMark(newMapMark.getPosition())) {
if (mapMarksManager.addMapMark(newMapMark)) {
player.save();
}
}
} else if (op == MarkMapReq.Operation.DEL) {
MapMark newMapMark = new MapMark(req.getMark());
if (mapMarksManager.removeMapMark(newMapMark.getPosition())) {
player.save();
}
} else if (op == MarkMapReq.Operation.GET) {
// no-op
}
// send all marks to refresh client map view.
HashMap<String, MapMark> mapMarks = mapMarksManager.getAllMapMarks();
session.send(new PacketMarkMapRsp(player, mapMarks));
}
private void teleport(Player player, MapMark mapMark) {
float y = isInt(mapMark.getName()) ? Integer.parseInt(mapMark.getName()) : 300;
float x = mapMark.getPosition().getX();
float z = mapMark.getPosition().getZ();
player.getPos().set(x, y, z);
if (mapMark.getSceneId() != player.getSceneId()) {
player.getWorld().transferPlayerToScene(player, mapMark.getSceneId(),
player.getPos());
} else {
player.getScene().broadcastPacket(new PacketSceneEntityAppearNotify(player));
}
} }
} }
...@@ -15,13 +15,13 @@ public class HandlerMcoinExchangeHcoinReq extends PacketHandler { ...@@ -15,13 +15,13 @@ public class HandlerMcoinExchangeHcoinReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception { public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq exchangeReq = McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq.parseFrom(payload); McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq exchangeReq = McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq.parseFrom(payload);
if (session.getPlayer().getCrystals() < exchangeReq.getMCoinNum() && exchangeReq.getMCoinNum() == exchangeReq.getHCoinNum()) { if (session.getPlayer().getCrystals() < exchangeReq.getMcoinCost() && exchangeReq.getMcoinCost() == exchangeReq.getHcoin()) {
session.send(new PacketMcoinExchangeHcoinRsp(RetcodeOuterClass.Retcode.RET_UNKNOWN_ERROR_VALUE)); session.send(new PacketMcoinExchangeHcoinRsp(RetcodeOuterClass.Retcode.RET_UNKNOWN_ERROR_VALUE));
return; return;
} }
session.getPlayer().setCrystals(session.getPlayer().getCrystals() - exchangeReq.getMCoinNum()); session.getPlayer().setCrystals(session.getPlayer().getCrystals() - exchangeReq.getMcoinCost());
session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() + exchangeReq.getHCoinNum()); session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() + exchangeReq.getHcoin());
session.getPlayer().save(); session.getPlayer().save();
session.send(new PacketMcoinExchangeHcoinRsp(RetcodeOuterClass.Retcode.RET_SUCC_VALUE)); session.send(new PacketMcoinExchangeHcoinRsp(RetcodeOuterClass.Retcode.RET_SUCC_VALUE));
} }
......
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.quest.enums.QuestTrigger;
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.NpcTalkReqOuterClass.NpcTalkReq; import emu.grasscutter.net.proto.NpcTalkReqOuterClass.NpcTalkReq;
...@@ -14,6 +15,10 @@ public class HandlerNpcTalkReq extends PacketHandler { ...@@ -14,6 +15,10 @@ public class HandlerNpcTalkReq 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 {
NpcTalkReq req = NpcTalkReq.parseFrom(payload); NpcTalkReq req = NpcTalkReq.parseFrom(payload);
// Why are there 2 quest triggers that do the same thing...
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_COMPLETE_TALK, req.getTalkId());
session.getPlayer().getQuestManager().triggerEvent(QuestTrigger.QUEST_CONTENT_FINISH_PLOT, req.getTalkId());
session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId())); session.send(new PacketNpcTalkRsp(req.getNpcEntityId(), req.getTalkId(), req.getEntityId()));
} }
......
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.custom.ScenePointEntry; import emu.grasscutter.data.binout.ScenePointEntry;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
......
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket; import emu.grasscutter.net.packet.BasePacket;
...@@ -12,6 +13,8 @@ import emu.grasscutter.server.game.GameSession.SessionState; ...@@ -12,6 +13,8 @@ import emu.grasscutter.server.game.GameSession.SessionState;
import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp; import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp;
import emu.grasscutter.server.packet.send.PacketTakeAchievementRewardReq; import emu.grasscutter.server.packet.send.PacketTakeAchievementRewardReq;
import static emu.grasscutter.Configuration.ACCOUNT;
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets @Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
public class HandlerPlayerLoginReq extends PacketHandler { public class HandlerPlayerLoginReq extends PacketHandler {
...@@ -19,31 +22,30 @@ public class HandlerPlayerLoginReq extends PacketHandler { ...@@ -19,31 +22,30 @@ 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; return;
} }
// Parse request // Parse request
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload); PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
// 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 = DatabaseHelper.getPlayerById(session.getAccount().getPlayerUid()); Player player = session.getPlayer();
if (player == null) { // Show opening cutscene if player has no avatars
// Send packets if (player.getAvatars().getAvatarCount() == 0) {
// 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
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.proto.QueryCodexMonsterBeKilledNumReqOuterClass;
import emu.grasscutter.net.proto.QueryCodexMonsterBeKilledNumReqOuterClass.QueryCodexMonsterBeKilledNumReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketQueryCodexMonsterBeKilledNumRsp;
@Opcodes(PacketOpcodes.QueryCodexMonsterBeKilledNumReq)
public class HandlerQueryCodexMonsterBeKilledNumReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
QueryCodexMonsterBeKilledNumReq req = QueryCodexMonsterBeKilledNumReq.parseFrom(payload);
session.send(new PacketQueryCodexMonsterBeKilledNumRsp(session.getPlayer(), req.getCodexIdListList()));
}
}
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.Inventory;
import emu.grasscutter.game.inventory.InventoryTab;
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.QuickUseWidgetRspOuterClass.QuickUseWidgetRsp;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketPullRecentChatRsp;
@Opcodes(PacketOpcodes.QuickUseWidgetReq)
public class HandlerQuickUseWidgetReq extends PacketHandler {
/*
* WARNING: with the consuming of material widget ( Example: bomb ),
* this is just a implement designed to the decreasing of count
*
* ### Known Bug: No effects after using item but decrease. ###
*
* If you know which Packet could make the effects, feel free to contribute!
* */
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
QuickUseWidgetRsp.Builder proto = QuickUseWidgetRsp.newBuilder();
Player pl = session.getPlayer();
synchronized (pl) {
int materialId = pl.getWidgetId();
Inventory inventory = session.getPlayer().getInventory();
InventoryTab inventoryTab = inventory.getInventoryTab(ItemType.ITEM_MATERIAL);
GameItem item = inventoryTab.getItemById(materialId);
int remain = item.getCount();
if (remain > 0) {
remain--;
if (remain <= 0) {
proto.setRetcode(1);
} else {
proto.setRetcode(0);
}
proto.setMaterialId(materialId);
inventory.removeItem(item,1);// decrease count
BasePacket rsp = new BasePacket(PacketOpcodes.QuickUseWidgetRsp);
rsp.setData(proto);
session.send(rsp);
Grasscutter.getLogger().warn("class has no effects in the game, feel free to implement it");
// but no effects in the game, feel free to implement it!
}
}
}
}
...@@ -9,12 +9,12 @@ import emu.grasscutter.server.game.GameSession; ...@@ -9,12 +9,12 @@ import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketHostPlayerNotify; import emu.grasscutter.server.packet.send.PacketHostPlayerNotify;
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneInfoNotify; import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneInfoNotify;
import emu.grasscutter.server.packet.send.PacketPlayerGameTimeNotify; import emu.grasscutter.server.packet.send.PacketPlayerGameTimeNotify;
import emu.grasscutter.server.packet.send.PacketPlayerWorldSceneInfoListNotify;
import emu.grasscutter.server.packet.send.PacketSceneAreaWeatherNotify; import emu.grasscutter.server.packet.send.PacketSceneAreaWeatherNotify;
import emu.grasscutter.server.packet.send.PacketSceneInitFinishRsp; import emu.grasscutter.server.packet.send.PacketSceneInitFinishRsp;
import emu.grasscutter.server.packet.send.PacketScenePlayerInfoNotify; import emu.grasscutter.server.packet.send.PacketScenePlayerInfoNotify;
import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify; import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify;
import emu.grasscutter.server.packet.send.PacketSceneTimeNotify; import emu.grasscutter.server.packet.send.PacketSceneTimeNotify;
import emu.grasscutter.server.packet.send.PacketSceneUnlockInfoNotify;
import emu.grasscutter.server.packet.send.PacketServerTimeNotify; import emu.grasscutter.server.packet.send.PacketServerTimeNotify;
import emu.grasscutter.server.packet.send.PacketSyncScenePlayTeamEntityNotify; import emu.grasscutter.server.packet.send.PacketSyncScenePlayTeamEntityNotify;
import emu.grasscutter.server.packet.send.PacketSyncTeamEntityNotify; import emu.grasscutter.server.packet.send.PacketSyncTeamEntityNotify;
...@@ -30,7 +30,7 @@ public class HandlerSceneInitFinishReq extends PacketHandler { ...@@ -30,7 +30,7 @@ public class HandlerSceneInitFinishReq extends PacketHandler {
session.send(new PacketServerTimeNotify()); session.send(new PacketServerTimeNotify());
session.send(new PacketWorldPlayerInfoNotify(session.getPlayer().getWorld())); session.send(new PacketWorldPlayerInfoNotify(session.getPlayer().getWorld()));
session.send(new PacketWorldDataNotify(session.getPlayer().getWorld())); session.send(new PacketWorldDataNotify(session.getPlayer().getWorld()));
session.send(new PacketSceneUnlockInfoNotify()); session.send(new PacketPlayerWorldSceneInfoListNotify());
session.send(new BasePacket(PacketOpcodes.SceneForceUnlockNotify)); session.send(new BasePacket(PacketOpcodes.SceneForceUnlockNotify));
session.send(new PacketHostPlayerNotify(session.getPlayer().getWorld())); session.send(new PacketHostPlayerNotify(session.getPlayer().getWorld()));
......
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.custom.ScenePointEntry; import emu.grasscutter.data.binout.ScenePointEntry;
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.SceneTransToPointReqOuterClass.SceneTransToPointReq; import emu.grasscutter.net.proto.SceneTransToPointReqOuterClass.SceneTransToPointReq;
......
...@@ -23,7 +23,7 @@ public class HandlerSetEntityClientDataNotify extends PacketHandler { ...@@ -23,7 +23,7 @@ public class HandlerSetEntityClientDataNotify extends PacketHandler {
BasePacket packet = new BasePacket(PacketOpcodes.SetEntityClientDataNotify, true); BasePacket packet = new BasePacket(PacketOpcodes.SetEntityClientDataNotify, true);
packet.setData(notif); packet.setData(notif);
session.getPlayer().getScene().broadcastPacketToOthers(session.getPlayer(), packet); session.getPlayer().getScene().broadcastPacket(packet);
} }
} }
...@@ -19,6 +19,8 @@ import emu.grasscutter.server.game.GameSession.SessionState; ...@@ -19,6 +19,8 @@ import emu.grasscutter.server.game.GameSession.SessionState;
import java.util.Arrays; import java.util.Arrays;
import static emu.grasscutter.Configuration.*;
@Opcodes(PacketOpcodes.SetPlayerBornDataReq) @Opcodes(PacketOpcodes.SetPlayerBornDataReq)
public class HandlerSetPlayerBornDataReq extends PacketHandler { public class HandlerSetPlayerBornDataReq extends PacketHandler {
...@@ -44,58 +46,39 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler { ...@@ -44,58 +46,39 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
return; return;
} }
String nickname = req.getNickName(); // Get player object
if (nickname == null) { Player player = session.getPlayer();
nickname = "Traveler"; player.setNickname(req.getNickName());
// 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;
} }
// Call creation event. // Login done
PlayerCreationEvent event = new PlayerCreationEvent(session, Player.class); event.call(); session.getPlayer().onLogin();
// Create player instance from event.
Player player = event.getPlayerClass().getDeclaredConstructor(GameSession.class).newInstance(session);
player.setNickname(nickname);
try { // Born resp packet
// Save to db session.send(new BasePacket(PacketOpcodes.SetPlayerBornDataRsp));
DatabaseHelper.createPlayer(player, session.getAccount().getPlayerUid());
// Create avatar
if (player.getAvatars().getAvatarCount() == 0) {
Avatar mainCharacter = new Avatar(avatarId);
mainCharacter.setSkillDepot(GameData.getAvatarSkillDepotDataMap().get(startingSkillDepot));
player.addAvatar(mainCharacter);
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));
// Default mail // Default mail
MailBuilder mailBuilder = new MailBuilder(player.getUid(), new Mail()); var welcomeMail = GAME_INFO.joinOptions.welcomeMail;
mailBuilder.mail.mailContent.title = Grasscutter.getConfig().GameServer.WelcomeMailTitle; MailBuilder mailBuilder = new MailBuilder(player.getUid(), new Mail());
mailBuilder.mail.mailContent.sender = Grasscutter.getConfig().GameServer.WelcomeMailSender; mailBuilder.mail.mailContent.title = welcomeMail.title;
// Please credit Grasscutter if changing something here. We don't condone commercial use of the project. mailBuilder.mail.mailContent.sender = welcomeMail.sender;
mailBuilder.mail.mailContent.content = Grasscutter.getConfig().GameServer.WelcomeMailContent + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>"; // Please credit Grasscutter if changing something here. We don't condone commercial use of the project.
mailBuilder.mail.itemList.addAll(Arrays.asList(Grasscutter.getConfig().GameServer.WelcomeMailItems)); mailBuilder.mail.mailContent.content = welcomeMail.content + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>";
mailBuilder.mail.importance = 1; mailBuilder.mail.itemList.addAll(Arrays.asList(welcomeMail.items));
player.sendMail(mailBuilder.mail); mailBuilder.mail.importance = 1;
} catch (Exception e) { player.sendMail(mailBuilder.mail);
Grasscutter.getLogger().error("Error creating player object: ", e);
session.close();
}
} }
} }
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.SetWidgetSlotReqOuterClass;
import emu.grasscutter.net.proto.WidgetSlotOpOuterClass;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketSetWidgetSlotRsp;
import emu.grasscutter.server.packet.send.PacketWidgetSlotChangeNotify;
@Opcodes(PacketOpcodes.SetWidgetSlotReq)
public class HandlerSetWidgetSlotReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
SetWidgetSlotReqOuterClass.SetWidgetSlotReq req = SetWidgetSlotReqOuterClass.SetWidgetSlotReq.parseFrom(payload);
Player player = session.getPlayer();
player.setWidgetId(req.getMaterialId());
// WidgetSlotChangeNotify op & slot key
session.send(new PacketWidgetSlotChangeNotify(WidgetSlotOpOuterClass.WidgetSlotOp.WIDGET_SLOT_OP_DETACH));
//only attaching the widget can set it
if(req.getOp() == WidgetSlotOpOuterClass.WidgetSlotOp.WIDGET_SLOT_OP_ATTACH){
// WidgetSlotChangeNotify slot
session.send(new PacketWidgetSlotChangeNotify(req.getMaterialId()));
}
// SetWidgetSlotRsp
session.send(new PacketSetWidgetSlotRsp(req.getMaterialId()));
}
}
package emu.grasscutter.server.packet.recv; package emu.grasscutter.server.packet.recv;
import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.RewardItemData; import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.packet.Opcodes; import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler; import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes; import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq; import emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq;
import emu.grasscutter.server.game.GameSession; import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.server.packet.send.PacketTakePlayerLevelRewardRsp; import emu.grasscutter.server.packet.send.PacketTakePlayerLevelRewardRsp;
@Opcodes(PacketOpcodes.TakePlayerLevelRewardReq) @Opcodes(PacketOpcodes.TakePlayerLevelRewardReq)
public class HandlerTakePlayerLevelRewardReq extends PacketHandler { public class HandlerTakePlayerLevelRewardReq 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 {
TakePlayerLevelRewardReq req = TakePlayerLevelRewardReq.parseFrom(payload); Player pl = session.getPlayer();
synchronized (pl) {
int level = req.getLevel(); TakePlayerLevelRewardReq req = TakePlayerLevelRewardReq.parseFrom(payload);
int rewardId = GameData.getPlayerLevelDataMap().get(level).getRewardId(); int level = req.getLevel();
Set<Integer> rewardedLevels = session.getPlayer().getRewardedLevels();
if (rewardId != 0) { if (!rewardedLevels.contains(level)) {// No duplicated reward
List<RewardItemData> rewardItems = GameData.getRewardDataMap().get(rewardId).getRewardItemList(); int rewardId = GameData.getPlayerLevelDataMap().get(level).getRewardId();
List<GameItem> items = new LinkedList<>(); if (rewardId != 0) {
for (RewardItemData rewardItem : rewardItems) { List<ItemParamData> rewardItems = GameData.getRewardDataMap().get(rewardId).getRewardItemList();
if (rewardItem != null) { pl.getInventory().addItemParamDatas(rewardItems, ActionReason.PlayerUpgradeReward);
if (rewardItem.getItemId() != 0) { rewardedLevels.add(level);
items.add(new GameItem(rewardItem.getItemId(), rewardItem.getItemCount())); pl.setRewardedLevels(rewardedLevels);
} pl.save();
session.send(new PacketTakePlayerLevelRewardRsp(level, rewardId));
} }
} }
session.getPlayer().getInventory().addItems(items);
session.getPlayer().sendPacket(new PacketItemAddHintNotify(items, ActionReason.PlayerUpgradeReward));
Set<Integer> rewardedLevels = session.getPlayer().getRewardedLevels();
rewardedLevels.add(level);
session.getPlayer().setRewardedLevels(rewardedLevels);
} }
session.send(new PacketTakePlayerLevelRewardRsp(level, rewardId));
} }
} }
...@@ -11,7 +11,10 @@ public class HandlerTowerAllDataReq extends PacketHandler { ...@@ -11,7 +11,10 @@ public class HandlerTowerAllDataReq 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 {
session.send(new PacketTowerAllDataRsp()); session.send(new PacketTowerAllDataRsp(
session.getServer().getTowerScheduleManager(),
session.getPlayer().getTowerManager()
));
} }
} }
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.data.GameData;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TryEnterHomeReqOuterClass;
import emu.grasscutter.scripts.data.SceneConfig;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketTryEnterHomeRsp;
import emu.grasscutter.utils.Position;
@Opcodes(PacketOpcodes.TryEnterHomeReq)
public class HandlerTryEnterHomeReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
TryEnterHomeReqOuterClass.TryEnterHomeReq req =
TryEnterHomeReqOuterClass.TryEnterHomeReq.parseFrom(payload);
if (req.getTargetUid() != session.getPlayer().getUid()) {
// I hope that tomorrow there will be a hero who can support multiplayer mode and write code like a poem
session.send(new PacketTryEnterHomeRsp());
return;
}
int realmId = 2000 + session.getPlayer().getCurrentRealmId();
Scene scene = session.getPlayer().getWorld().getSceneById(realmId);
Position pos = scene.getScriptManager().getConfig().born_pos;
session.getPlayer().getWorld().transferPlayerToScene(
session.getPlayer(),
realmId,
pos
);
session.send(new PacketTryEnterHomeRsp(req.getTargetUid()));
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment