Fix whitespace [skip actions]

This commit is contained in:
github-actions
2022-07-21 07:21:22 +00:00
committed by Melledy
parent 510d564bcb
commit ae2d1fe438
166 changed files with 12928 additions and 12928 deletions

View File

@@ -2,11 +2,11 @@ package emu.grasscutter.server.game;
public abstract class BaseGameSystem {
protected final GameServer server;
public BaseGameSystem(GameServer server) {
this.server = server;
}
public GameServer getServer() {
return this.server;
}

View File

@@ -51,97 +51,97 @@ import static emu.grasscutter.utils.Language.translate;
public final class GameServer extends KcpServer {
// Game server base
private final InetSocketAddress address;
private final GameServerPacketHandler packetHandler;
private final GameServerPacketHandler packetHandler;
private final Map<Integer, Player> players;
private final Set<World> worlds;
// Server systems
private final InventorySystem inventorySystem;
private final GachaSystem gachaSystem;
private final ShopSystem shopSystem;
private final MultiplayerSystem multiplayerSystem;
private final DungeonSystem dungeonSystem;
private final ExpeditionSystem expeditionSystem;
private final DropSystem dropSystem;
private final WorldDataSystem worldDataSystem;
private final BattlePassSystem battlePassSystem;
private final CombineManger combineSystem;
private final TowerSystem towerSystem;
private final AnnouncementSystem announcementSystem;
private final QuestSystem questSystem;
// Extra
private final ServerTaskScheduler scheduler;
private final InventorySystem inventorySystem;
private final GachaSystem gachaSystem;
private final ShopSystem shopSystem;
private final MultiplayerSystem multiplayerSystem;
private final DungeonSystem dungeonSystem;
private final ExpeditionSystem expeditionSystem;
private final DropSystem dropSystem;
private final WorldDataSystem worldDataSystem;
private final BattlePassSystem battlePassSystem;
private final CombineManger combineSystem;
private final TowerSystem towerSystem;
private final AnnouncementSystem announcementSystem;
private final QuestSystem questSystem;
// Extra
private final ServerTaskScheduler scheduler;
private final CommandMap commandMap;
private final TaskMap taskMap;
private ChatManagerHandler chatManager;
public GameServer() {
this(getAdapterInetSocketAddress());
}
private ChatManagerHandler chatManager;
public GameServer(InetSocketAddress address) {
ChannelConfig channelConfig = new ChannelConfig();
channelConfig.nodelay(true, 40, 2, true);
channelConfig.setMtu(1400);
channelConfig.setSndwnd(256);
channelConfig.setRcvwnd(256);
channelConfig.setTimeoutMillis(30 * 1000);//30s
channelConfig.setUseConvChannel(true);
channelConfig.setAckNoDelay(false);
public GameServer() {
this(getAdapterInetSocketAddress());
}
this.init(GameSessionManager.getListener(),channelConfig,address);
public GameServer(InetSocketAddress address) {
ChannelConfig channelConfig = new ChannelConfig();
channelConfig.nodelay(true, 40, 2, true);
channelConfig.setMtu(1400);
channelConfig.setSndwnd(256);
channelConfig.setRcvwnd(256);
channelConfig.setTimeoutMillis(30 * 1000);//30s
channelConfig.setUseConvChannel(true);
channelConfig.setAckNoDelay(false);
DungeonChallenge.initialize();
EnergyManager.initialize();
StaminaManager.initialize();
CookingManager.initialize();
CombineManger.initialize();
this.init(GameSessionManager.getListener(),channelConfig,address);
// Game Server base
this.address = address;
this.packetHandler = new GameServerPacketHandler(PacketHandler.class);
this.players = new ConcurrentHashMap<>();
this.worlds = Collections.synchronizedSet(new HashSet<>());
// Extra
this.scheduler = new ServerTaskScheduler();
this.commandMap = new CommandMap(true);
DungeonChallenge.initialize();
EnergyManager.initialize();
StaminaManager.initialize();
CookingManager.initialize();
CombineManger.initialize();
// Game Server base
this.address = address;
this.packetHandler = new GameServerPacketHandler(PacketHandler.class);
this.players = new ConcurrentHashMap<>();
this.worlds = Collections.synchronizedSet(new HashSet<>());
// Extra
this.scheduler = new ServerTaskScheduler();
this.commandMap = new CommandMap(true);
this.taskMap = new TaskMap(true);
// Create game systems
this.inventorySystem = new InventorySystem(this);
this.gachaSystem = new GachaSystem(this);
this.shopSystem = new ShopSystem(this);
this.multiplayerSystem = new MultiplayerSystem(this);
this.dungeonSystem = new DungeonSystem(this);
this.dropSystem = new DropSystem(this);
this.expeditionSystem = new ExpeditionSystem(this);
this.combineSystem = new CombineManger(this);
this.towerSystem = new TowerSystem(this);
this.worldDataSystem = new WorldDataSystem(this);
this.battlePassSystem = new BattlePassSystem(this);
this.announcementSystem = new AnnouncementSystem(this);
this.questSystem = new QuestSystem(this);
// Chata manager
this.chatManager = new ChatManager(this);
// Hook into shutdown event.
Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
}
// Create game systems
this.inventorySystem = new InventorySystem(this);
this.gachaSystem = new GachaSystem(this);
this.shopSystem = new ShopSystem(this);
this.multiplayerSystem = new MultiplayerSystem(this);
this.dungeonSystem = new DungeonSystem(this);
this.dropSystem = new DropSystem(this);
this.expeditionSystem = new ExpeditionSystem(this);
this.combineSystem = new CombineManger(this);
this.towerSystem = new TowerSystem(this);
this.worldDataSystem = new WorldDataSystem(this);
this.battlePassSystem = new BattlePassSystem(this);
this.announcementSystem = new AnnouncementSystem(this);
this.questSystem = new QuestSystem(this);
// Chata manager
this.chatManager = new ChatManager(this);
// Hook into shutdown event.
Runtime.getRuntime().addShutdownHook(new Thread(this::onServerShutdown));
}
@Deprecated
public ChatManagerHandler getChatManager() {
return chatManager;
}
@Deprecated
public void setChatManager(ChatManagerHandler chatManager) {
this.chatManager = chatManager;
}
public ChatManagerHandler getChatSystem() {
return chatManager;
}
@@ -150,71 +150,71 @@ public final class GameServer extends KcpServer {
this.chatManager = chatManager;
}
private static InetSocketAddress getAdapterInetSocketAddress(){
InetSocketAddress inetSocketAddress;
if(GAME_INFO.bindAddress.equals("")){
inetSocketAddress=new InetSocketAddress(GAME_INFO.bindPort);
}else{
inetSocketAddress=new InetSocketAddress(
GAME_INFO.bindAddress,
GAME_INFO.bindPort
);
}
return inetSocketAddress;
}
private static InetSocketAddress getAdapterInetSocketAddress() {
InetSocketAddress inetSocketAddress;
if (GAME_INFO.bindAddress.equals("")) {
inetSocketAddress=new InetSocketAddress(GAME_INFO.bindPort);
}else {
inetSocketAddress=new InetSocketAddress(
GAME_INFO.bindAddress,
GAME_INFO.bindPort
);
}
return inetSocketAddress;
}
public void registerPlayer(Player player) {
getPlayers().put(player.getUid(), player);
}
public void registerPlayer(Player player) {
getPlayers().put(player.getUid(), player);
}
public Player getPlayerByUid(int id) {
return this.getPlayerByUid(id, false);
}
public Player getPlayerByUid(int id) {
return this.getPlayerByUid(id, false);
}
public Player getPlayerByUid(int id, boolean allowOfflinePlayers) {
// Console check
if (id == GameConstants.SERVER_CONSOLE_UID) {
return null;
}
public Player getPlayerByUid(int id, boolean allowOfflinePlayers) {
// Console check
if (id == GameConstants.SERVER_CONSOLE_UID) {
return null;
}
// Get from online players
Player player = this.getPlayers().get(id);
// Get from online players
Player player = this.getPlayers().get(id);
if (!allowOfflinePlayers) {
return player;
}
if (!allowOfflinePlayers) {
return player;
}
// Check database if character isnt here
if (player == null) {
player = DatabaseHelper.getPlayerByUid(id);
}
// Check database if character isnt here
if (player == null) {
player = DatabaseHelper.getPlayerByUid(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 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) {
// Get from online players
Player player = this.getPlayerByUid(id, true);
public SocialDetail.Builder getSocialDetailByUid(int id) {
// Get from online players
Player player = this.getPlayerByUid(id, true);
if (player == null) {
return null;
}
if (player == null) {
return null;
}
return player.getSocialDetail();
}
return player.getSocialDetail();
}
public Account getAccountByName(String username) {
Optional<Player> playerOpt = getPlayers().values().stream().filter(player -> player.getAccount().getUsername().equals(username)).findFirst();
if (playerOpt.isPresent()) {
return playerOpt.get().getAccount();
}
return DatabaseHelper.getAccountByName(username);
}
public Account getAccountByName(String username) {
Optional<Player> playerOpt = getPlayers().values().stream().filter(player -> player.getAccount().getUsername().equals(username)).findFirst();
if (playerOpt.isPresent()) {
return playerOpt.get().getAccount();
}
return DatabaseHelper.getAccountByName(username);
}
public synchronized void onTick() {
var tickStart = Instant.now();
@@ -244,43 +244,43 @@ public final class GameServer extends KcpServer {
event.call();
}
public void registerWorld(World world) {
this.getWorlds().add(world);
}
public void registerWorld(World world) {
this.getWorlds().add(world);
}
public void deregisterWorld(World world) {
// TODO Auto-generated method stub
public void deregisterWorld(World world) {
// TODO Auto-generated method stub
}
}
public void start() {
// Schedule game loop.
Timer gameLoop = new Timer();
gameLoop.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
onTick();
} catch (Exception e) {
Grasscutter.getLogger().error(translate("messages.game.game_update_error"), e);
}
}
}, new Date(), 1000L);
Grasscutter.getLogger().info(translate("messages.status.free_software"));
Grasscutter.getLogger().info(translate("messages.game.port_bind", Integer.toString(address.getPort())));
ServerStartEvent event = new ServerStartEvent(ServerEvent.Type.GAME, OffsetDateTime.now());
event.call();
}
public void start() {
// Schedule game loop.
Timer gameLoop = new Timer();
gameLoop.scheduleAtFixedRate(new TimerTask() {
@Override
public void run() {
try {
onTick();
} catch (Exception e) {
Grasscutter.getLogger().error(translate("messages.game.game_update_error"), e);
}
}
}, new Date(), 1000L);
Grasscutter.getLogger().info(translate("messages.status.free_software"));
Grasscutter.getLogger().info(translate("messages.game.port_bind", Integer.toString(address.getPort())));
ServerStartEvent event = new ServerStartEvent(ServerEvent.Type.GAME, OffsetDateTime.now());
event.call();
}
public void onServerShutdown() {
ServerStopEvent event = new ServerStopEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call();
public void onServerShutdown() {
ServerStopEvent event = new ServerStopEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call();
// Kick and save all players
List<Player> list = new ArrayList<>(this.getPlayers().size());
list.addAll(this.getPlayers().values());
// Kick and save all players
List<Player> list = new ArrayList<>(this.getPlayers().size());
list.addAll(this.getPlayers().values());
for (Player player : list) {
player.getSession().close();
}
}
for (Player player : list) {
player.getSession().close();
}
}
}

View File

@@ -18,84 +18,84 @@ import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
@SuppressWarnings("unchecked")
public class GameServerPacketHandler {
private final Int2ObjectMap<PacketHandler> handlers;
private final Int2ObjectMap<PacketHandler> handlers;
public GameServerPacketHandler(Class<? extends PacketHandler> handlerClass) {
this.handlers = new Int2ObjectOpenHashMap<>();
public GameServerPacketHandler(Class<? extends PacketHandler> handlerClass) {
this.handlers = new Int2ObjectOpenHashMap<>();
this.registerHandlers(handlerClass);
}
this.registerHandlers(handlerClass);
}
public void registerPacketHandler(Class<? extends PacketHandler> handlerClass) {
try {
Opcodes opcode = handlerClass.getAnnotation(Opcodes.class);
public void registerPacketHandler(Class<? extends PacketHandler> handlerClass) {
try {
Opcodes opcode = handlerClass.getAnnotation(Opcodes.class);
if (opcode == null || opcode.disabled() || opcode.value() <= 0) {
return;
}
if (opcode == null || opcode.disabled() || opcode.value() <= 0) {
return;
}
PacketHandler packetHandler = handlerClass.getDeclaredConstructor().newInstance();
PacketHandler packetHandler = handlerClass.getDeclaredConstructor().newInstance();
this.handlers.put(opcode.value(), packetHandler);
} catch (Exception e) {
e.printStackTrace();
}
}
this.handlers.put(opcode.value(), packetHandler);
} catch (Exception e) {
e.printStackTrace();
}
}
public void registerHandlers(Class<? extends PacketHandler> handlerClass) {
Reflections reflections = new Reflections("emu.grasscutter.server.packet");
Set<?> handlerClasses = reflections.getSubTypesOf(handlerClass);
public void registerHandlers(Class<? extends PacketHandler> handlerClass) {
Reflections reflections = new Reflections("emu.grasscutter.server.packet");
Set<?> handlerClasses = reflections.getSubTypesOf(handlerClass);
for (Object obj : handlerClasses) {
this.registerPacketHandler((Class<? extends PacketHandler>) obj);
}
for (Object obj : handlerClasses) {
this.registerPacketHandler((Class<? extends PacketHandler>) obj);
}
// Debug
Grasscutter.getLogger().debug("Registered " + this.handlers.size() + " " + handlerClass.getSimpleName() + "s");
}
// Debug
Grasscutter.getLogger().debug("Registered " + this.handlers.size() + " " + handlerClass.getSimpleName() + "s");
}
public void handle(GameSession session, int opcode, byte[] header, byte[] payload) {
PacketHandler handler = this.handlers.get(opcode);
public void handle(GameSession session, int opcode, byte[] header, byte[] payload) {
PacketHandler handler = this.handlers.get(opcode);
if (handler != null) {
try {
// Make sure session is ready for packets
SessionState state = session.getState();
if (handler != null) {
try {
// Make sure session is ready for packets
SessionState state = session.getState();
if (opcode == PacketOpcodes.PingReq) {
// Always continue if packet is ping request
} else if (opcode == PacketOpcodes.GetPlayerTokenReq) {
if (state != SessionState.WAITING_FOR_TOKEN) {
return;
}
} else if (opcode == PacketOpcodes.PlayerLoginReq) {
if (state != SessionState.WAITING_FOR_LOGIN) {
return;
}
} else if (opcode == PacketOpcodes.SetPlayerBornDataReq) {
if (state != SessionState.PICKING_CHARACTER) {
return;
}
} else {
if (state != SessionState.ACTIVE) {
return;
}
}
if (opcode == PacketOpcodes.PingReq) {
// Always continue if packet is ping request
} else if (opcode == PacketOpcodes.GetPlayerTokenReq) {
if (state != SessionState.WAITING_FOR_TOKEN) {
return;
}
} else if (opcode == PacketOpcodes.PlayerLoginReq) {
if (state != SessionState.WAITING_FOR_LOGIN) {
return;
}
} else if (opcode == PacketOpcodes.SetPlayerBornDataReq) {
if (state != SessionState.PICKING_CHARACTER) {
return;
}
} else {
if (state != SessionState.ACTIVE) {
return;
}
}
// Invoke event.
ReceivePacketEvent event = new ReceivePacketEvent(session, opcode, payload); event.call();
if(!event.isCanceled()) // If event is not canceled, continue.
handler.handle(session, header, event.getPacketData());
} catch (Exception ex) {
// TODO Remove this when no more needed
ex.printStackTrace();
}
return; // Packet successfully handled
}
// Invoke event.
ReceivePacketEvent event = new ReceivePacketEvent(session, opcode, payload); event.call();
if (!event.isCanceled()) // If event is not canceled, continue.
handler.handle(session, header, event.getPacketData());
} catch (Exception ex) {
// TODO Remove this when no more needed
ex.printStackTrace();
}
return; // Packet successfully handled
}
// Log unhandled packets
if (GAME_INFO.logPackets == ServerDebugMode.MISSING) {
Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + emu.grasscutter.net.packet.PacketOpcodesUtils.getOpcodeName(opcode));
}
}
// Log unhandled packets
if (GAME_INFO.logPackets == ServerDebugMode.MISSING) {
Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + emu.grasscutter.net.packet.PacketOpcodesUtils.getOpcodeName(opcode));
}
}
}

View File

@@ -21,108 +21,108 @@ import static emu.grasscutter.config.Configuration.*;
import static emu.grasscutter.utils.Language.translate;
public class GameSession implements GameSessionManager.KcpChannel {
private final GameServer server;
private GameSessionManager.KcpTunnel tunnel;
private final GameServer server;
private GameSessionManager.KcpTunnel tunnel;
private Account account;
private Player player;
private Account account;
private Player player;
private boolean useSecretKey;
private SessionState state;
private boolean useSecretKey;
private SessionState state;
private int clientTime;
private long lastPingTime;
private int lastClientSeq = 10;
private int clientTime;
private long lastPingTime;
private int lastClientSeq = 10;
public GameSession(GameServer server) {
this.server = server;
this.state = SessionState.WAITING_FOR_TOKEN;
this.lastPingTime = System.currentTimeMillis();
}
public GameSession(GameServer server) {
this.server = server;
this.state = SessionState.WAITING_FOR_TOKEN;
this.lastPingTime = System.currentTimeMillis();
}
public GameServer getServer() {
return server;
}
public GameServer getServer() {
return server;
}
public InetSocketAddress getAddress() {
try{
return tunnel.getAddress();
}catch (Throwable ignore){
return null;
}
}
public InetSocketAddress getAddress() {
try {
return tunnel.getAddress();
}catch (Throwable ignore) {
return null;
}
}
public boolean useSecretKey() {
return useSecretKey;
}
public boolean useSecretKey() {
return useSecretKey;
}
public Account getAccount() {
return account;
}
public Account getAccount() {
return account;
}
public void setAccount(Account account) {
this.account = account;
}
public void setAccount(Account account) {
this.account = account;
}
public String getAccountId() {
return this.getAccount().getId();
}
public String getAccountId() {
return this.getAccount().getId();
}
public Player getPlayer() {
return player;
}
public Player getPlayer() {
return player;
}
public synchronized void setPlayer(Player player) {
this.player = player;
this.player.setSession(this);
this.player.setAccount(this.getAccount());
}
public synchronized void setPlayer(Player player) {
this.player = player;
this.player.setSession(this);
this.player.setAccount(this.getAccount());
}
public SessionState getState() {
return state;
}
public SessionState getState() {
return state;
}
public void setState(SessionState state) {
this.state = state;
}
public void setState(SessionState state) {
this.state = state;
}
public boolean isLoggedIn() {
return this.getPlayer() != null;
}
public boolean isLoggedIn() {
return this.getPlayer() != null;
}
public void setUseSecretKey(boolean useSecretKey) {
this.useSecretKey = useSecretKey;
}
public void setUseSecretKey(boolean useSecretKey) {
this.useSecretKey = useSecretKey;
}
public int getClientTime() {
return this.clientTime;
}
public int getClientTime() {
return this.clientTime;
}
public long getLastPingTime() {
return lastPingTime;
}
public long getLastPingTime() {
return lastPingTime;
}
public void updateLastPingTime(int clientTime) {
this.clientTime = clientTime;
this.lastPingTime = System.currentTimeMillis();
}
public void updateLastPingTime(int clientTime) {
this.clientTime = clientTime;
this.lastPingTime = System.currentTimeMillis();
}
public int getNextClientSequence() {
return ++lastClientSeq;
}
public int getNextClientSequence() {
return ++lastClientSeq;
}
public void replayPacket(int opcode, String name) {
String filePath = PACKET(name);
File p = new File(filePath);
String filePath = PACKET(name);
File p = new File(filePath);
if (!p.exists()) return;
if (!p.exists()) return;
byte[] packet = FileUtils.read(p);
byte[] packet = FileUtils.read(p);
BasePacket basePacket = new BasePacket(opcode);
basePacket.setData(packet);
BasePacket basePacket = new BasePacket(opcode);
basePacket.setData(packet);
send(basePacket);
send(basePacket);
}
public void logPacket( String sendOrRecv, int opcode, byte[] payload) {
@@ -130,162 +130,162 @@ public class GameSession implements GameSessionManager.KcpChannel {
System.out.println(Utils.bytesToHex(payload));
}
public void send(BasePacket packet) {
// Test
if (packet.getOpcode() <= 0) {
Grasscutter.getLogger().warn("Tried to send packet with missing cmd id!");
return;
}
// Test
if (packet.getOpcode() <= 0) {
Grasscutter.getLogger().warn("Tried to send packet with missing cmd id!");
return;
}
// DO NOT REMOVE (unless we find a way to validate code before sending to client which I don't think we can)
// Stop WindSeedClientNotify from being sent for security purposes.
if(PacketOpcodesUtils.BANNED_PACKETS.contains(packet.getOpcode())) {
return;
}
// DO NOT REMOVE (unless we find a way to validate code before sending to client which I don't think we can)
// Stop WindSeedClientNotify from being sent for security purposes.
if (PacketOpcodesUtils.BANNED_PACKETS.contains(packet.getOpcode())) {
return;
}
// Header
if (packet.shouldBuildHeader()) {
packet.buildHeader(this.getNextClientSequence());
}
// Header
if (packet.shouldBuildHeader()) {
packet.buildHeader(this.getNextClientSequence());
}
// Log
switch (GAME_INFO.logPackets) {
case ALL -> {
if (!PacketOpcodesUtils.LOOP_PACKETS.contains(packet.getOpcode())) {
// Log
switch (GAME_INFO.logPackets) {
case ALL -> {
if (!PacketOpcodesUtils.LOOP_PACKETS.contains(packet.getOpcode())) {
logPacket("SEND", packet.getOpcode(), packet.getData());
}
}
case WHITELIST-> {
if (SERVER.debugWhitelist.contains(packet.getOpcode())) {
logPacket("SEND", packet.getOpcode(), packet.getData());
}
}
case BLACKLIST-> {
}
case WHITELIST-> {
if (SERVER.debugWhitelist.contains(packet.getOpcode())) {
logPacket("SEND", packet.getOpcode(), packet.getData());
}
}
case BLACKLIST-> {
if (!SERVER.debugBlacklist.contains(packet.getOpcode())) {
logPacket("SEND", packet.getOpcode(), packet.getData());
}
}
default -> {}
}
default -> {}
}
// Invoke event.
SendPacketEvent event = new SendPacketEvent(this, packet); event.call();
if(!event.isCanceled()) { // If event is not cancelled, continue.
tunnel.writeData(event.getPacket().build());
}
// Invoke event.
SendPacketEvent event = new SendPacketEvent(this, packet); event.call();
if (!event.isCanceled()) { // If event is not cancelled, continue.
tunnel.writeData(event.getPacket().build());
}
}
@Override
public void onConnected(GameSessionManager.KcpTunnel tunnel) {
this.tunnel = tunnel;
Grasscutter.getLogger().info(translate("messages.game.connect", this.getAddress().toString()));
}
@Override
public void onConnected(GameSessionManager.KcpTunnel tunnel) {
this.tunnel = tunnel;
Grasscutter.getLogger().info(translate("messages.game.connect", this.getAddress().toString()));
}
@Override
public void handleReceive(byte[] bytes) {
// Decrypt and turn back into a packet
Crypto.xor(bytes, useSecretKey() ? Crypto.ENCRYPT_KEY : Crypto.DISPATCH_KEY);
ByteBuf packet = Unpooled.wrappedBuffer(bytes);
@Override
public void handleReceive(byte[] bytes) {
// Decrypt and turn back into a packet
Crypto.xor(bytes, useSecretKey() ? Crypto.ENCRYPT_KEY : Crypto.DISPATCH_KEY);
ByteBuf packet = Unpooled.wrappedBuffer(bytes);
// Log
//logPacket(packet);
// Handle
try {
boolean allDebug = GAME_INFO.logPackets == ServerDebugMode.ALL;
while (packet.readableBytes() > 0) {
// Length
if (packet.readableBytes() < 12) {
return;
}
// Packet sanity check
int const1 = packet.readShort();
if (const1 != 17767) {
if(allDebug){
Grasscutter.getLogger().error("Bad Data Package Received: got {} ,expect 17767",const1);
}
return; // Bad packet
}
// Data
int opcode = packet.readShort();
int headerLength = packet.readShort();
int payloadLength = packet.readInt();
byte[] header = new byte[headerLength];
byte[] payload = new byte[payloadLength];
// Log
//logPacket(packet);
// Handle
try {
boolean allDebug = GAME_INFO.logPackets == ServerDebugMode.ALL;
while (packet.readableBytes() > 0) {
// Length
if (packet.readableBytes() < 12) {
return;
}
// Packet sanity check
int const1 = packet.readShort();
if (const1 != 17767) {
if (allDebug) {
Grasscutter.getLogger().error("Bad Data Package Received: got {} ,expect 17767",const1);
}
return; // Bad packet
}
// Data
int opcode = packet.readShort();
int headerLength = packet.readShort();
int payloadLength = packet.readInt();
byte[] header = new byte[headerLength];
byte[] payload = new byte[payloadLength];
packet.readBytes(header);
packet.readBytes(payload);
// Sanity check #2
int const2 = packet.readShort();
if (const2 != -30293) {
if(allDebug){
Grasscutter.getLogger().error("Bad Data Package Received: got {} ,expect -30293",const2);
}
return; // Bad packet
}
// Log packet
switch (GAME_INFO.logPackets) {
case ALL -> {
if (!PacketOpcodesUtils.LOOP_PACKETS.contains(opcode)) {
packet.readBytes(header);
packet.readBytes(payload);
// Sanity check #2
int const2 = packet.readShort();
if (const2 != -30293) {
if (allDebug) {
Grasscutter.getLogger().error("Bad Data Package Received: got {} ,expect -30293",const2);
}
return; // Bad packet
}
// Log packet
switch (GAME_INFO.logPackets) {
case ALL -> {
if (!PacketOpcodesUtils.LOOP_PACKETS.contains(opcode)) {
logPacket("RECV",opcode, payload);
}
}
case WHITELIST-> {
if (SERVER.debugWhitelist.contains(opcode)) {
logPacket("RECV",opcode, payload);
}
}
case BLACKLIST-> {
if (!(SERVER.debugBlacklist.contains(opcode))) {
logPacket("RECV",opcode, payload);
}
}
default -> {}
}
}
case WHITELIST-> {
if (SERVER.debugWhitelist.contains(opcode)) {
logPacket("RECV",opcode, payload);
}
}
case BLACKLIST-> {
if (!(SERVER.debugBlacklist.contains(opcode))) {
logPacket("RECV",opcode, payload);
}
}
default -> {}
}
// Handle
getServer().getPacketHandler().handle(this, opcode, header, payload);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//byteBuf.release(); //Needn't
packet.release();
}
}
// Handle
getServer().getPacketHandler().handle(this, opcode, header, payload);
}
} catch (Exception e) {
e.printStackTrace();
} finally {
//byteBuf.release(); //Needn't
packet.release();
}
}
@Override
public void handleClose() {
setState(SessionState.INACTIVE);
//send disconnection pack in case of reconnection
Grasscutter.getLogger().info(translate("messages.game.disconnect", this.getAddress().toString()));
// Save after disconnecting
if (this.isLoggedIn()) {
Player player = getPlayer();
// Call logout event.
player.onLogout();
}
try {
send(new BasePacket(PacketOpcodes.ServerDisconnectClientNotify));
}catch (Throwable ignore){
Grasscutter.getLogger().warn("closing {} error",getAddress().getAddress().getHostAddress());
}
tunnel = null;
}
@Override
public void handleClose() {
setState(SessionState.INACTIVE);
//send disconnection pack in case of reconnection
Grasscutter.getLogger().info(translate("messages.game.disconnect", this.getAddress().toString()));
// Save after disconnecting
if (this.isLoggedIn()) {
Player player = getPlayer();
// Call logout event.
player.onLogout();
}
try {
send(new BasePacket(PacketOpcodes.ServerDisconnectClientNotify));
}catch (Throwable ignore) {
Grasscutter.getLogger().warn("closing {} error",getAddress().getAddress().getHostAddress());
}
tunnel = null;
}
public void close() {
tunnel.close();
}
public void close() {
tunnel.close();
}
public boolean isActive() {
return getState() == SessionState.ACTIVE;
}
public boolean isActive() {
return getState() == SessionState.ACTIVE;
}
public enum SessionState {
INACTIVE,
WAITING_FOR_TOKEN,
WAITING_FOR_LOGIN,
PICKING_CHARACTER,
ACTIVE
}
public enum SessionState {
INACTIVE,
WAITING_FOR_TOKEN,
WAITING_FOR_LOGIN,
PICKING_CHARACTER,
ACTIVE
}
}