Commit a8293102 authored by Melledy's avatar Melledy Committed by GitHub
Browse files

Merge branch 'development' into stable

parents 304b9cb8 ecf7a81a
......@@ -16,6 +16,6 @@ public class HandlerGetAllMailReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
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;
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.GameServer;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.game.GameSession.SessionState;
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
......@@ -15,42 +21,73 @@ public class HandlerGetPlayerTokenReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
GetPlayerTokenReq req = GetPlayerTokenReq.parseFrom(payload);
// Authenticate
Account account = DatabaseHelper.getAccountById(req.getAccountUid());
if (account == null) {
return;
}
// Check token
if (!account.getToken().equals(req.getAccountToken())) {
if (account == null || !account.getToken().equals(req.getAccountToken())) {
return;
}
// Set account
session.setAccount(account);
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());
// Check if player object exists in server
// NOTE: CHECKING MUST SITUATED HERE (BEFORE getPlayerByUid)! because to save firstly ,to load secondly !!!
// TODO - optimize
boolean kicked = false;
Player exists = Grasscutter.getGameServer().getPlayerByAccountId(account.getId());
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
if (!doesPlayerExist) {
int id = DatabaseHelper.getNextPlayerId(session.getAccount().getPlayerUid());
if (id != session.getAccount().getPlayerUid()) {
session.getAccount().setPlayerId(id);
session.getAccount().save();
//NOTE: If there are 5 online players, max count of player is 5,
// a new client want to login by kicking one of them ,
// I think it should be allowed
if(!kicked) {
// Max players limit
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
session.send(new PacketGetPlayerTokenRsp(session, doesPlayerExist));
session.send(new PacketGetPlayerTokenRsp(session));
}
}
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketGetShopRsp;
import emu.grasscutter.server.packet.send.PacketGetWidgetSlotRsp;
@Opcodes(PacketOpcodes.GetWidgetSlotReq)
public class HandlerGetWidgetSlotReq extends PacketHandler {
@Override
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;
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.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.*;
import emu.grasscutter.net.proto.MarkMapReqOuterClass.MarkMapReq;
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)
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
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
MarkMapReq req = MarkMapReq.parseFrom(payload);
MarkMapReq.Operation op = req.getOp();
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));
}
session.getPlayer().getMapMarksManager().handleMapMarkReq(req);
}
}
......@@ -15,13 +15,13 @@ public class HandlerMcoinExchangeHcoinReq extends PacketHandler {
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
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));
return;
}
session.getPlayer().setCrystals(session.getPlayer().getCrystals() - exchangeReq.getMCoinNum());
session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() + exchangeReq.getHCoinNum());
session.getPlayer().setCrystals(session.getPlayer().getCrystals() - exchangeReq.getMcoinCost());
session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() + exchangeReq.getHcoin());
session.getPlayer().save();
session.send(new PacketMcoinExchangeHcoinRsp(RetcodeOuterClass.Retcode.RET_SUCC_VALUE));
}
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.quest.enums.QuestTrigger;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.NpcTalkReqOuterClass.NpcTalkReq;
......@@ -14,6 +15,10 @@ public class HandlerNpcTalkReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
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()));
}
......
package emu.grasscutter.server.packet.recv;
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.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
......
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.net.packet.BasePacket;
......@@ -12,6 +13,8 @@ import emu.grasscutter.server.game.GameSession.SessionState;
import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp;
import emu.grasscutter.server.packet.send.PacketTakeAchievementRewardReq;
import static emu.grasscutter.Configuration.ACCOUNT;
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
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 {
// Check
if (session.getAccount() == null) {
session.close();
return;
}
// Parse request
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
// 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
......
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;
import emu.grasscutter.server.packet.send.PacketHostPlayerNotify;
import emu.grasscutter.server.packet.send.PacketPlayerEnterSceneInfoNotify;
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.PacketSceneInitFinishRsp;
import emu.grasscutter.server.packet.send.PacketScenePlayerInfoNotify;
import emu.grasscutter.server.packet.send.PacketSceneTeamUpdateNotify;
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.PacketSyncScenePlayTeamEntityNotify;
import emu.grasscutter.server.packet.send.PacketSyncTeamEntityNotify;
......@@ -30,7 +30,7 @@ public class HandlerSceneInitFinishReq extends PacketHandler {
session.send(new PacketServerTimeNotify());
session.send(new PacketWorldPlayerInfoNotify(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 PacketHostPlayerNotify(session.getPlayer().getWorld()));
......
package emu.grasscutter.server.packet.recv;
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.PacketOpcodes;
import emu.grasscutter.net.proto.SceneTransToPointReqOuterClass.SceneTransToPointReq;
......
......@@ -23,7 +23,7 @@ public class HandlerSetEntityClientDataNotify extends PacketHandler {
BasePacket packet = new BasePacket(PacketOpcodes.SetEntityClientDataNotify, true);
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;
import java.util.Arrays;
import static emu.grasscutter.Configuration.*;
@Opcodes(PacketOpcodes.SetPlayerBornDataReq)
public class HandlerSetPlayerBornDataReq extends PacketHandler {
......@@ -44,58 +46,39 @@ public class HandlerSetPlayerBornDataReq extends PacketHandler {
return;
}
String nickname = req.getNickName();
if (nickname == null) {
nickname = "Traveler";
// Get player object
Player player = session.getPlayer();
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.
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);
// Login done
session.getPlayer().onLogin();
try {
// Save to db
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));
// Born resp packet
session.send(new BasePacket(PacketOpcodes.SetPlayerBornDataRsp));
// Default mail
MailBuilder mailBuilder = new MailBuilder(player.getUid(), new Mail());
mailBuilder.mail.mailContent.title = Grasscutter.getConfig().GameServer.WelcomeMailTitle;
mailBuilder.mail.mailContent.sender = Grasscutter.getConfig().GameServer.WelcomeMailSender;
// Please credit Grasscutter if changing something here. We don't condone commercial use of the project.
mailBuilder.mail.mailContent.content = Grasscutter.getConfig().GameServer.WelcomeMailContent + "\n<type=\"browser\" text=\"GitHub\" href=\"https://github.com/Melledy/Grasscutter\"/>";
mailBuilder.mail.itemList.addAll(Arrays.asList(Grasscutter.getConfig().GameServer.WelcomeMailItems));
mailBuilder.mail.importance = 1;
player.sendMail(mailBuilder.mail);
} catch (Exception e) {
Grasscutter.getLogger().error("Error creating player object: ", e);
session.close();
}
// 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);
}
}
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;
import java.util.LinkedList;
import java.util.List;
import java.util.Set;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.common.RewardItemData;
import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.data.common.ItemParamData;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.net.packet.Opcodes;
import emu.grasscutter.net.packet.PacketHandler;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.net.proto.TakePlayerLevelRewardReqOuterClass.TakePlayerLevelRewardReq;
import emu.grasscutter.server.game.GameSession;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import emu.grasscutter.server.packet.send.PacketTakePlayerLevelRewardRsp;
@Opcodes(PacketOpcodes.TakePlayerLevelRewardReq)
public class HandlerTakePlayerLevelRewardReq extends PacketHandler {
@Override
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
TakePlayerLevelRewardReq req = TakePlayerLevelRewardReq.parseFrom(payload);
int level = req.getLevel();
int rewardId = GameData.getPlayerLevelDataMap().get(level).getRewardId();
if (rewardId != 0) {
List<RewardItemData> rewardItems = GameData.getRewardDataMap().get(rewardId).getRewardItemList();
List<GameItem> items = new LinkedList<>();
for (RewardItemData rewardItem : rewardItems) {
if (rewardItem != null) {
if (rewardItem.getItemId() != 0) {
items.add(new GameItem(rewardItem.getItemId(), rewardItem.getItemCount()));
}
Player pl = session.getPlayer();
synchronized (pl) {
TakePlayerLevelRewardReq req = TakePlayerLevelRewardReq.parseFrom(payload);
int level = req.getLevel();
Set<Integer> rewardedLevels = session.getPlayer().getRewardedLevels();
if (!rewardedLevels.contains(level)) {// No duplicated reward
int rewardId = GameData.getPlayerLevelDataMap().get(level).getRewardId();
if (rewardId != 0) {
List<ItemParamData> rewardItems = GameData.getRewardDataMap().get(rewardId).getRewardItemList();
pl.getInventory().addItemParamDatas(rewardItems, ActionReason.PlayerUpgradeReward);
rewardedLevels.add(level);
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 {
@Override
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()));
}
}
Markdown is supported
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