Cache GetArchiveDataScRsp and GetActivityScheduleConfigScRsp packets

This commit is contained in:
Melledy
2023-12-03 02:23:16 -08:00
parent 08d48df258
commit d07b98f5e3
9 changed files with 50 additions and 21 deletions

View File

@@ -1,6 +1,10 @@
package emu.lunarcore.server.game; package emu.lunarcore.server.game;
import org.reflections.Reflections;
import emu.lunarcore.LunarCore;
import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CacheablePacket;
import io.netty.buffer.ByteBuf; import io.netty.buffer.ByteBuf;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
@@ -11,6 +15,19 @@ public class GameServerPacketCache {
public GameServerPacketCache() { public GameServerPacketCache() {
this.packets = new Int2ObjectOpenHashMap<>(); this.packets = new Int2ObjectOpenHashMap<>();
// Pre cache packets
var list = new Reflections(LunarCore.class.getPackageName()).getTypesAnnotatedWith(CacheablePacket.class);
for (Class<?> packetClass : list) {
try {
if (BasePacket.class.isAssignableFrom(packetClass)) {
var packet = (BasePacket) packetClass.getDeclaredConstructor().newInstance();
this.packets.put(packet.getCmdId(), Unpooled.wrappedBuffer(packet.build()));
}
} catch (Exception e) {
// Ignored
}
}
} }
public ByteBuf getCachedPacket(int cmdId) { public ByteBuf getCachedPacket(int cmdId) {

View File

@@ -2,7 +2,6 @@ package emu.lunarcore.server.game;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import ch.qos.logback.classic.Logger;
import emu.lunarcore.LunarCore; import emu.lunarcore.LunarCore;
import emu.lunarcore.game.account.Account; import emu.lunarcore.game.account.Account;
import emu.lunarcore.game.player.Player; import emu.lunarcore.game.player.Player;
@@ -160,9 +159,9 @@ public class GameSession {
} }
} }
} }
/** /**
* Sends a empty packet with the specified cmd id. * Sends a cached packet with the specified cmd id. If the packet isnt cacheable, then an empty packet is sent.
* @param cmdId * @param cmdId
*/ */
public void send(int cmdId) { public void send(int cmdId) {
@@ -173,8 +172,8 @@ public class GameSession {
// Log // Log
if (LunarCore.getConfig().getLogOptions().packets) { if (LunarCore.getConfig().getLogOptions().packets) {
if (!(LunarCore.getConfig().getLogOptions().filterLoopingPackets && CmdIdUtils.LOOP_PACKETS.contains(cmdId))) { if (!(LunarCore.getConfig().getLogOptions().filterLoopingPackets && CmdIdUtils.LOOP_PACKETS.contains(cmdId))) {
logPacket("RECV", cmdId, null); logPacket("RECV", cmdId, null);
} }
} }
} }
} }
@@ -188,7 +187,7 @@ public class GameSession {
} }
public void logPacket(String sendOrRecv, int opcode, byte[] payload) { public void logPacket(String sendOrRecv, int opcode, byte[] payload) {
LunarCore.getLogger().info(sendOrRecv + ": " + CmdIdUtils.getOpcodeName(opcode) + " (" + opcode + ")" + System.lineSeparator() + Utils.bytesToHex(payload)); LunarCore.getLogger().info(sendOrRecv + ": " + CmdIdUtils.getCmdIdName(opcode) + " (" + opcode + ")" + System.lineSeparator() + Utils.bytesToHex(payload));
} }
public void close() { public void close() {

View File

@@ -0,0 +1,12 @@
package emu.lunarcore.server.packet;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
/**
* Marks a BasePacket class as cacheable. Cacheable packets are created only once for all clients and stored in a map to be sent.
*/
@Retention(RetentionPolicy.RUNTIME)
public @interface CacheablePacket {
}

View File

@@ -4,7 +4,6 @@ import java.io.FileWriter;
import java.io.IOException; import java.io.IOException;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.util.Map; import java.util.Map;
import java.util.Set;
import java.util.TreeMap; import java.util.TreeMap;
import java.util.stream.Collectors; import java.util.stream.Collectors;
@@ -13,9 +12,11 @@ import emu.lunarcore.LunarCore;
import emu.lunarcore.util.JsonUtils; import emu.lunarcore.util.JsonUtils;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet;
public class CmdIdUtils { public class CmdIdUtils {
public static final Set<Integer> LOOP_PACKETS = Set.of( public static final IntSet LOOP_PACKETS = IntOpenHashSet.of(
CmdId.PlayerHeartBeatCsReq, CmdId.PlayerHeartBeatCsReq,
CmdId.PlayerHeartBeatScRsp, CmdId.PlayerHeartBeatScRsp,
CmdId.SceneEntityMoveCsReq, CmdId.SceneEntityMoveCsReq,
@@ -23,17 +24,17 @@ public class CmdIdUtils {
CmdId.GetQuestDataScRsp CmdId.GetQuestDataScRsp
); );
private static Int2ObjectMap<String> opcodeMap; private static Int2ObjectMap<String> cmdIdMap;
static { static {
opcodeMap = new Int2ObjectOpenHashMap<>(); cmdIdMap = new Int2ObjectOpenHashMap<>();
Field[] fields = CmdId.class.getFields(); Field[] fields = CmdId.class.getFields();
for (Field f : fields) { for (Field f : fields) {
if (f.getType().equals(int.class)) { if (f.getType().equals(int.class)) {
try { try {
opcodeMap.put(f.getInt(null), f.getName()); cmdIdMap.put(f.getInt(null), f.getName());
} catch (Exception e) { } catch (Exception e) {
e.printStackTrace(); e.printStackTrace();
} }
@@ -41,15 +42,15 @@ public class CmdIdUtils {
} }
} }
public static String getOpcodeName(int opcode) { public static String getCmdIdName(int opcode) {
if (opcode <= 0) return "UNKNOWN"; if (opcode <= 0) return "UNKNOWN";
return opcodeMap.getOrDefault(opcode, "UNKNOWN"); return cmdIdMap.getOrDefault(opcode, "UNKNOWN");
} }
public static void dumpPacketIds() { public static void dumpPacketIds() {
try (FileWriter writer = new FileWriter("./PacketIds_" + GameConstants.VERSION + ".json")) { try (FileWriter writer = new FileWriter("./PacketIds_" + GameConstants.VERSION + ".json")) {
// Create sorted tree map // Create sorted tree map
Map<Integer, String> packetIds = opcodeMap.int2ObjectEntrySet().stream() Map<Integer, String> packetIds = cmdIdMap.int2ObjectEntrySet().stream()
.filter(e -> e.getIntKey() > 0) .filter(e -> e.getIntKey() > 0)
.collect(Collectors.toMap(Int2ObjectMap.Entry::getIntKey, Int2ObjectMap.Entry::getValue, (k, v) -> v, TreeMap::new)); .collect(Collectors.toMap(Int2ObjectMap.Entry::getIntKey, Int2ObjectMap.Entry::getValue, (k, v) -> v, TreeMap::new));
// Write to file // Write to file

View File

@@ -4,14 +4,13 @@ import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes; import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler; import emu.lunarcore.server.packet.PacketHandler;
import emu.lunarcore.server.packet.send.PacketGetActivityScheduleConfigScRsp;
@Opcodes(CmdId.GetActivityScheduleConfigCsReq) @Opcodes(CmdId.GetActivityScheduleConfigCsReq)
public class HandlerGetActivityScheduleConfigCsReq extends PacketHandler { public class HandlerGetActivityScheduleConfigCsReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] data) throws Exception { public void handle(GameSession session, byte[] data) throws Exception {
session.send(new PacketGetActivityScheduleConfigScRsp()); session.send(CmdId.GetActivityScheduleConfigScRsp);
} }
} }

View File

@@ -4,7 +4,6 @@ import emu.lunarcore.server.game.GameSession;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes; import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler; import emu.lunarcore.server.packet.PacketHandler;
import emu.lunarcore.server.packet.send.PacketGetArchiveDataScRsp;
@Opcodes(CmdId.GetArchiveDataCsReq) @Opcodes(CmdId.GetArchiveDataCsReq)
public class HandlerGetArchiveDataCsReq extends PacketHandler { public class HandlerGetArchiveDataCsReq extends PacketHandler {
@@ -12,7 +11,7 @@ public class HandlerGetArchiveDataCsReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] data) throws Exception { public void handle(GameSession session, byte[] data) throws Exception {
// TODO The client does not send this packet right now to the server so we send it in HandlerPlayerLoginFinishCsReq instead // TODO The client does not send this packet right now to the server so we send it in HandlerPlayerLoginFinishCsReq instead
session.send(new PacketGetArchiveDataScRsp()); session.send(CmdId.GetArchiveDataScRsp);
} }
} }

View File

@@ -5,7 +5,6 @@ import emu.lunarcore.server.packet.CmdId;
import emu.lunarcore.server.packet.Opcodes; import emu.lunarcore.server.packet.Opcodes;
import emu.lunarcore.server.packet.PacketHandler; import emu.lunarcore.server.packet.PacketHandler;
import emu.lunarcore.server.packet.send.PacketBattlePassInfoNotify; import emu.lunarcore.server.packet.send.PacketBattlePassInfoNotify;
import emu.lunarcore.server.packet.send.PacketGetArchiveDataScRsp;
@Opcodes(CmdId.PlayerLoginFinishCsReq) @Opcodes(CmdId.PlayerLoginFinishCsReq)
public class HandlerPlayerLoginFinishCsReq extends PacketHandler { public class HandlerPlayerLoginFinishCsReq extends PacketHandler {
@@ -13,8 +12,8 @@ public class HandlerPlayerLoginFinishCsReq extends PacketHandler {
@Override @Override
public void handle(GameSession session, byte[] data) throws Exception { public void handle(GameSession session, byte[] data) throws Exception {
session.send(CmdId.PlayerLoginFinishScRsp); session.send(CmdId.PlayerLoginFinishScRsp);
session.send(CmdId.GetArchiveDataScRsp);
session.send(new PacketBattlePassInfoNotify()); session.send(new PacketBattlePassInfoNotify());
session.send(new PacketGetArchiveDataScRsp());
} }
} }

View File

@@ -4,8 +4,10 @@ import emu.lunarcore.data.GameData;
import emu.lunarcore.proto.ActivityScheduleInfoOuterClass.ActivityScheduleInfo; import emu.lunarcore.proto.ActivityScheduleInfoOuterClass.ActivityScheduleInfo;
import emu.lunarcore.proto.GetActivityScheduleConfigScRspOuterClass.GetActivityScheduleConfigScRsp; import emu.lunarcore.proto.GetActivityScheduleConfigScRspOuterClass.GetActivityScheduleConfigScRsp;
import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CacheablePacket;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
@CacheablePacket
public class PacketGetActivityScheduleConfigScRsp extends BasePacket { public class PacketGetActivityScheduleConfigScRsp extends BasePacket {
public PacketGetActivityScheduleConfigScRsp() { public PacketGetActivityScheduleConfigScRsp() {

View File

@@ -5,11 +5,12 @@ import emu.lunarcore.proto.GetArchiveDataScRspOuterClass.GetArchiveDataScRsp;
import emu.lunarcore.proto.MonsterArchiveOuterClass.MonsterArchive; import emu.lunarcore.proto.MonsterArchiveOuterClass.MonsterArchive;
import emu.lunarcore.proto.RelicArchiveOuterClass.RelicArchive; import emu.lunarcore.proto.RelicArchiveOuterClass.RelicArchive;
import emu.lunarcore.server.packet.BasePacket; import emu.lunarcore.server.packet.BasePacket;
import emu.lunarcore.server.packet.CacheablePacket;
import emu.lunarcore.server.packet.CmdId; import emu.lunarcore.server.packet.CmdId;
@CacheablePacket
public class PacketGetArchiveDataScRsp extends BasePacket { public class PacketGetArchiveDataScRsp extends BasePacket {
// TODO cache packet
public PacketGetArchiveDataScRsp() { public PacketGetArchiveDataScRsp() {
super(CmdId.GetArchiveDataScRsp); super(CmdId.GetArchiveDataScRsp);