2022-04-17 05:43:07 -07:00
|
|
|
package emu.grasscutter.server.game;
|
|
|
|
|
|
|
|
import java.util.Set;
|
|
|
|
|
2022-04-23 02:08:31 -04:00
|
|
|
import emu.grasscutter.server.event.game.ReceivePacketEvent;
|
2022-04-17 05:43:07 -07:00
|
|
|
import org.reflections.Reflections;
|
|
|
|
|
|
|
|
import emu.grasscutter.Grasscutter;
|
2022-04-30 22:52:09 -07:00
|
|
|
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
2022-04-17 05:43:07 -07:00
|
|
|
import emu.grasscutter.net.packet.Opcodes;
|
|
|
|
import emu.grasscutter.net.packet.PacketHandler;
|
|
|
|
import emu.grasscutter.net.packet.PacketOpcodes;
|
|
|
|
import emu.grasscutter.server.game.GameSession.SessionState;
|
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
|
|
|
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
|
|
|
|
2022-05-06 21:04:39 -04:00
|
|
|
@SuppressWarnings("unchecked")
|
2022-04-17 05:43:07 -07:00
|
|
|
public class GameServerPacketHandler {
|
|
|
|
private final Int2ObjectMap<PacketHandler> handlers;
|
|
|
|
|
|
|
|
public GameServerPacketHandler(Class<? extends PacketHandler> handlerClass) {
|
|
|
|
this.handlers = new Int2ObjectOpenHashMap<>();
|
|
|
|
|
|
|
|
this.registerHandlers(handlerClass);
|
|
|
|
}
|
2022-05-01 18:41:51 +08:00
|
|
|
|
2022-05-01 20:47:54 +08:00
|
|
|
public void registerPacketHandler(Class<? extends PacketHandler> handlerClass) {
|
|
|
|
try {
|
|
|
|
Opcodes opcode = handlerClass.getAnnotation(Opcodes.class);
|
|
|
|
|
|
|
|
if (opcode == null || opcode.disabled() || opcode.value() <= 0) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
PacketHandler packetHandler = (PacketHandler) handlerClass.newInstance();
|
|
|
|
|
|
|
|
this.handlers.put(opcode.value(), packetHandler);
|
|
|
|
} catch (Exception e) {
|
|
|
|
e.printStackTrace();
|
|
|
|
}
|
2022-05-01 18:41:51 +08:00
|
|
|
}
|
|
|
|
|
2022-04-17 05:43:07 -07:00
|
|
|
public void registerHandlers(Class<? extends PacketHandler> handlerClass) {
|
|
|
|
Reflections reflections = new Reflections("emu.grasscutter.server.packet");
|
|
|
|
Set<?> handlerClasses = reflections.getSubTypesOf(handlerClass);
|
|
|
|
|
|
|
|
for (Object obj : handlerClasses) {
|
2022-05-01 20:47:54 +08:00
|
|
|
this.registerPacketHandler((Class<? extends PacketHandler>) obj);
|
2022-04-17 05:43:07 -07:00
|
|
|
}
|
|
|
|
|
|
|
|
// Debug
|
|
|
|
Grasscutter.getLogger().info("Registered " + this.handlers.size() + " " + handlerClass.getSimpleName() + "s");
|
|
|
|
}
|
|
|
|
|
|
|
|
public void handle(GameSession session, int opcode, byte[] header, byte[] payload) {
|
2022-04-23 02:08:31 -04:00
|
|
|
PacketHandler handler = this.handlers.get(opcode);
|
2022-04-17 05:43:07 -07:00
|
|
|
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-04-23 02:08:31 -04:00
|
|
|
// 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());
|
2022-04-17 05:43:07 -07:00
|
|
|
} catch (Exception ex) {
|
|
|
|
// TODO Remove this when no more needed
|
|
|
|
ex.printStackTrace();
|
|
|
|
}
|
|
|
|
return; // Packet successfully handled
|
|
|
|
}
|
|
|
|
|
|
|
|
// Log unhandled packets
|
2022-04-30 22:52:09 -07:00
|
|
|
if (Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING) {
|
2022-04-27 05:44:30 +08:00
|
|
|
Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + emu.grasscutter.net.packet.PacketOpcodesUtil.getOpcodeName(opcode));
|
2022-04-17 05:43:07 -07:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|