GameServerPacketHandler.java 3.19 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
3
4
package emu.grasscutter.server.game;

import java.util.Set;

5
import emu.grasscutter.server.event.game.ReceivePacketEvent;
Melledy's avatar
Melledy committed
6
7
8
import org.reflections.Reflections;

import emu.grasscutter.Grasscutter;
9
import emu.grasscutter.Grasscutter.ServerDebugMode;
Melledy's avatar
Melledy committed
10
11
12
13
14
15
16
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;

17
18
import static emu.grasscutter.Configuration.*;

KingRainbow44's avatar
KingRainbow44 committed
19
@SuppressWarnings("unchecked")
Melledy's avatar
Melledy committed
20
21
public class GameServerPacketHandler {
	private final Int2ObjectMap<PacketHandler> handlers;
KingRainbow44's avatar
KingRainbow44 committed
22

Melledy's avatar
Melledy committed
23
24
	public GameServerPacketHandler(Class<? extends PacketHandler> handlerClass) {
		this.handlers = new Int2ObjectOpenHashMap<>();
KingRainbow44's avatar
KingRainbow44 committed
25

Melledy's avatar
Melledy committed
26
27
		this.registerHandlers(handlerClass);
	}
28

coooookies's avatar
coooookies committed
29
30
31
32
33
34
35
36
	public void registerPacketHandler(Class<? extends PacketHandler> handlerClass) {
		try {
			Opcodes opcode = handlerClass.getAnnotation(Opcodes.class);

			if (opcode == null || opcode.disabled() || opcode.value() <= 0) {
				return;
			}

KingRainbow44's avatar
KingRainbow44 committed
37
			PacketHandler packetHandler = handlerClass.getDeclaredConstructor().newInstance();
coooookies's avatar
coooookies committed
38
39
40
41
42

			this.handlers.put(opcode.value(), packetHandler);
		} catch (Exception e) {
			e.printStackTrace();
		}
43
44
	}

Melledy's avatar
Melledy committed
45
46
47
	public void registerHandlers(Class<? extends PacketHandler> handlerClass) {
		Reflections reflections = new Reflections("emu.grasscutter.server.packet");
		Set<?> handlerClasses = reflections.getSubTypesOf(handlerClass);
KingRainbow44's avatar
KingRainbow44 committed
48

Melledy's avatar
Melledy committed
49
		for (Object obj : handlerClasses) {
coooookies's avatar
coooookies committed
50
			this.registerPacketHandler((Class<? extends PacketHandler>) obj);
Melledy's avatar
Melledy committed
51
		}
KingRainbow44's avatar
KingRainbow44 committed
52

Melledy's avatar
Melledy committed
53
		// Debug
54
		Grasscutter.getLogger().debug("Registered " + this.handlers.size() + " " + handlerClass.getSimpleName() + "s");
Melledy's avatar
Melledy committed
55
	}
KingRainbow44's avatar
KingRainbow44 committed
56

Melledy's avatar
Melledy committed
57
	public void handle(GameSession session, int opcode, byte[] header, byte[] payload) {
58
		PacketHandler handler = this.handlers.get(opcode);
KingRainbow44's avatar
KingRainbow44 committed
59

Melledy's avatar
Melledy committed
60
61
62
63
		if (handler != null) {
			try {
				// Make sure session is ready for packets
				SessionState state = session.getState();
KingRainbow44's avatar
KingRainbow44 committed
64

Melledy's avatar
Melledy committed
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
				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;
					}
				}
KingRainbow44's avatar
KingRainbow44 committed
84

85
86
87
				// Invoke event.
				ReceivePacketEvent event = new ReceivePacketEvent(session, opcode, payload); event.call();
				if(!event.isCanceled()) // If event is not canceled, continue.
KingRainbow44's avatar
KingRainbow44 committed
88
					handler.handle(session, header, event.getPacketData());
Melledy's avatar
Melledy committed
89
90
91
92
93
94
			} catch (Exception ex) {
				// TODO Remove this when no more needed
				ex.printStackTrace();
			}
			return; // Packet successfully handled
		}
KingRainbow44's avatar
KingRainbow44 committed
95

Melledy's avatar
Melledy committed
96
		// Log unhandled packets
97
		if (SERVER.debugLevel == ServerDebugMode.MISSING) {
98
			Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + emu.grasscutter.net.packet.PacketOpcodesUtil.getOpcodeName(opcode));
Melledy's avatar
Melledy committed
99
100
101
		}
	}
}