mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-02-07 02:26:43 +01:00
Fix whitespace [skip actions]
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,22 +30,22 @@ public final class HttpServer {
|
||||
this.express = new Express(config -> {
|
||||
// Set the Express HTTP server.
|
||||
config.server(HttpServer::createServer);
|
||||
|
||||
|
||||
// Configure encryption/HTTPS/SSL.
|
||||
config.enforceSsl = HTTP_ENCRYPTION.useEncryption;
|
||||
|
||||
|
||||
// Configure HTTP policies.
|
||||
if(HTTP_POLICIES.cors.enabled) {
|
||||
if (HTTP_POLICIES.cors.enabled) {
|
||||
var allowedOrigins = HTTP_POLICIES.cors.allowedOrigins;
|
||||
if (allowedOrigins.length > 0)
|
||||
config.enableCorsForOrigin(allowedOrigins);
|
||||
else config.enableCorsForAllOrigins();
|
||||
}
|
||||
|
||||
|
||||
// Configure debug logging.
|
||||
if(DISPATCH_INFO.logRequests == ServerDebugMode.ALL)
|
||||
if (DISPATCH_INFO.logRequests == ServerDebugMode.ALL)
|
||||
config.enableDevLogging();
|
||||
|
||||
|
||||
// Disable compression on static files.
|
||||
config.precompressStaticFiles = false;
|
||||
});
|
||||
@@ -60,26 +60,26 @@ public final class HttpServer {
|
||||
Server server = new Server();
|
||||
ServerConnector serverConnector
|
||||
= new ServerConnector(server);
|
||||
|
||||
if(HTTP_ENCRYPTION.useEncryption) {
|
||||
|
||||
if (HTTP_ENCRYPTION.useEncryption) {
|
||||
var sslContextFactory = new SslContextFactory.Server();
|
||||
var keystoreFile = new File(HTTP_ENCRYPTION.keystore);
|
||||
|
||||
if(!keystoreFile.exists()) {
|
||||
|
||||
if (!keystoreFile.exists()) {
|
||||
HTTP_ENCRYPTION.useEncryption = false;
|
||||
HTTP_ENCRYPTION.useInRouting = false;
|
||||
|
||||
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.no_keystore_error"));
|
||||
} else try {
|
||||
sslContextFactory.setKeyStorePath(keystoreFile.getPath());
|
||||
sslContextFactory.setKeyStorePassword(HTTP_ENCRYPTION.keystorePassword);
|
||||
} catch (Exception ignored) {
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.password_error"));
|
||||
|
||||
|
||||
try {
|
||||
sslContextFactory.setKeyStorePath(keystoreFile.getPath());
|
||||
sslContextFactory.setKeyStorePassword("123456");
|
||||
|
||||
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.default_password"));
|
||||
} catch (Exception exception) {
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.general_error"), exception);
|
||||
@@ -88,10 +88,10 @@ public final class HttpServer {
|
||||
serverConnector = new ServerConnector(server, sslContextFactory);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
serverConnector.setPort(HTTP_INFO.bindPort);
|
||||
server.setConnectors(new ServerConnector[]{serverConnector});
|
||||
|
||||
|
||||
return server;
|
||||
}
|
||||
|
||||
@@ -112,9 +112,9 @@ public final class HttpServer {
|
||||
public HttpServer addRouter(Class<? extends Router> router, Object... args) {
|
||||
// Get all constructor parameters.
|
||||
Class<?>[] types = new Class<?>[args.length];
|
||||
for(var argument : args)
|
||||
for (var argument : args)
|
||||
types[args.length - 1] = argument.getClass();
|
||||
|
||||
|
||||
try { // Create a router instance & apply routes.
|
||||
var constructor = router.getDeclaredConstructor(types); // Get the constructor.
|
||||
var routerInstance = constructor.newInstance(args); // Create instance.
|
||||
@@ -130,9 +130,9 @@ public final class HttpServer {
|
||||
*/
|
||||
public void start() throws UnsupportedEncodingException {
|
||||
// Attempt to start the HTTP server.
|
||||
if(HTTP_INFO.bindAddress.equals("")){
|
||||
if (HTTP_INFO.bindAddress.equals("")) {
|
||||
this.express.listen(HTTP_INFO.bindPort);
|
||||
}else{
|
||||
}else {
|
||||
this.express.listen(HTTP_INFO.bindAddress, HTTP_INFO.bindPort);
|
||||
}
|
||||
|
||||
@@ -147,7 +147,7 @@ public final class HttpServer {
|
||||
@Override public void applyRoutes(Express express, Javalin handle) {
|
||||
express.get("/", (request, response) -> {
|
||||
File file = new File(HTTP_STATIC_FILES.indexFile);
|
||||
if(!file.exists())
|
||||
if (!file.exists())
|
||||
response.send("""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
@@ -173,19 +173,19 @@ public final class HttpServer {
|
||||
public static class UnhandledRequestRouter implements Router {
|
||||
@Override public void applyRoutes(Express express, Javalin handle) {
|
||||
handle.error(404, context -> {
|
||||
if(DISPATCH_INFO.logRequests == ServerDebugMode.MISSING)
|
||||
if (DISPATCH_INFO.logRequests == ServerDebugMode.MISSING)
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.unhandled_request_error", context.method(), context.url()));
|
||||
context.contentType("text/html");
|
||||
|
||||
|
||||
File file = new File(HTTP_STATIC_FILES.errorFile);
|
||||
if(!file.exists())
|
||||
if (!file.exists())
|
||||
context.result("""
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset="utf8">
|
||||
</head>
|
||||
|
||||
|
||||
<body>
|
||||
<img src="https://http.cat/404" />
|
||||
</body>
|
||||
|
||||
@@ -60,7 +60,7 @@ public final class RegionHandler implements Router {
|
||||
List<String> usedNames = new ArrayList<>(); // List to check for potential naming conflicts.
|
||||
|
||||
var configuredRegions = new ArrayList<>(List.of(DISPATCH_INFO.regions));
|
||||
if(SERVER.runMode != ServerRunMode.HYBRID && configuredRegions.size() == 0) {
|
||||
if (SERVER.runMode != ServerRunMode.HYBRID && configuredRegions.size() == 0) {
|
||||
Grasscutter.getLogger().error("[Dispatch] There are no game servers available. Exiting due to unplayable state.");
|
||||
System.exit(1);
|
||||
} else if (configuredRegions.size() == 0)
|
||||
@@ -136,11 +136,11 @@ public final class RegionHandler implements Router {
|
||||
// Get region data.
|
||||
String regionData = "CAESGE5vdCBGb3VuZCB2ZXJzaW9uIGNvbmZpZw==";
|
||||
if (request.query().values().size() > 0) {
|
||||
if(region != null)
|
||||
if (region != null)
|
||||
regionData = region.getBase64();
|
||||
}
|
||||
|
||||
if( versionName.contains("2.7.5") || versionName.contains("2.8.")) {
|
||||
if ( versionName.contains("2.7.5") || versionName.contains("2.8.")) {
|
||||
try {
|
||||
QueryCurrentRegionEvent event = new QueryCurrentRegionEvent(regionData); event.call();
|
||||
|
||||
@@ -227,4 +227,4 @@ public final class RegionHandler implements Router {
|
||||
public static QueryCurrRegionHttpRsp getCurrentRegion() {
|
||||
return SERVER.runMode == ServerRunMode.HYBRID ? regions.get("os_usa").getRegionQuery() : null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -39,14 +39,14 @@ public final class AnnouncementsHandler implements Router {
|
||||
|
||||
express.get("/hk4e/announcement/*", AnnouncementsHandler::getPageResources);
|
||||
}
|
||||
|
||||
|
||||
private static void getAnnouncement(Request request, Response response) {
|
||||
String data = "";
|
||||
if (Objects.equals(request.baseUrl(), "/common/hk4e_global/announcement/api/getAnnContent")) {
|
||||
try {
|
||||
data = FileUtils.readToString(DataLoader.load("GameAnnouncement.json"));
|
||||
} catch (Exception e) {
|
||||
if(e.getClass() == IOException.class) {
|
||||
if (e.getClass() == IOException.class) {
|
||||
Grasscutter.getLogger().info("Unable to read file 'GameAnnouncementList.json'. \n" + e);
|
||||
}
|
||||
}
|
||||
@@ -54,7 +54,7 @@ public final class AnnouncementsHandler implements Router {
|
||||
try {
|
||||
data = FileUtils.readToString(DataLoader.load("GameAnnouncementList.json"));
|
||||
} catch (Exception e) {
|
||||
if(e.getClass() == IOException.class) {
|
||||
if (e.getClass() == IOException.class) {
|
||||
Grasscutter.getLogger().info("Unable to read file 'GameAnnouncementList.json'. \n" + e);
|
||||
}
|
||||
}
|
||||
@@ -76,9 +76,9 @@ public final class AnnouncementsHandler implements Router {
|
||||
.replace("{{SYSTEM_TIME}}", String.valueOf(System.currentTimeMillis()));
|
||||
response.send("{\"retcode\":0,\"message\":\"OK\",\"data\": " + data + "}");
|
||||
}
|
||||
|
||||
|
||||
private static void getPageResources(Request request, Response response) {
|
||||
try(InputStream filestream = DataLoader.load(request.path())) {
|
||||
try (InputStream filestream = DataLoader.load(request.path())) {
|
||||
String possibleFilename = Utils.toFilePath(DATA(request.path()));
|
||||
|
||||
MediaType fromExtension = MediaType.getByExtension(possibleFilename.substring(possibleFilename.lastIndexOf(".") + 1));
|
||||
|
||||
@@ -30,14 +30,14 @@ import static emu.grasscutter.utils.Language.translate;
|
||||
*/
|
||||
public final class GachaHandler implements Router {
|
||||
public static final String gachaMappings = DATA(Utils.toFilePath("gacha/mappings.js"));
|
||||
|
||||
|
||||
@Override public void applyRoutes(Express express, Javalin handle) {
|
||||
express.get("/gacha", GachaHandler::gachaRecords);
|
||||
express.get("/gacha/details", GachaHandler::gachaDetails);
|
||||
|
||||
|
||||
express.useStaticFallback("/gacha/mappings", gachaMappings, Location.EXTERNAL);
|
||||
}
|
||||
|
||||
|
||||
private static void gachaRecords(Request request, Response response) {
|
||||
File recordsTemplate = new File(Utils.toFilePath(DATA("gacha/records.html")));
|
||||
if (!recordsTemplate.exists()) {
|
||||
@@ -48,7 +48,7 @@ public final class GachaHandler implements Router {
|
||||
|
||||
String sessionKey = request.query("s");
|
||||
Account account = DatabaseHelper.getAccountBySessionKey(sessionKey);
|
||||
if(account == null) {
|
||||
if (account == null) {
|
||||
response.status(403).send("Requested account was not found");
|
||||
return;
|
||||
}
|
||||
@@ -59,9 +59,9 @@ public final class GachaHandler implements Router {
|
||||
}
|
||||
|
||||
int page = 0, gachaType = 0;
|
||||
if(request.query("p") != null)
|
||||
if (request.query("p") != null)
|
||||
page = Integer.parseInt(request.query("p"));
|
||||
if(request.query("gachaType") != null)
|
||||
if (request.query("gachaType") != null)
|
||||
gachaType = Integer.parseInt(request.query("gachaType"));
|
||||
|
||||
String records = DatabaseHelper.getGachaRecords(player.getUid(), page, gachaType).toString();
|
||||
@@ -76,7 +76,7 @@ public final class GachaHandler implements Router {
|
||||
.replace("{{LANGUAGE}}", Utils.getLanguageCode(account.getLocale()));
|
||||
response.send(template);
|
||||
}
|
||||
|
||||
|
||||
private static void gachaDetails(Request request, Response response) {
|
||||
File detailsTemplate = new File(Utils.toFilePath(DATA("gacha/details.html")));
|
||||
if (!detailsTemplate.exists()) {
|
||||
@@ -87,7 +87,7 @@ public final class GachaHandler implements Router {
|
||||
|
||||
String sessionKey = request.query("s");
|
||||
Account account = DatabaseHelper.getAccountBySessionKey(sessionKey);
|
||||
if(account == null) {
|
||||
if (account == null) {
|
||||
response.status(403).send("Requested account was not found");
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -25,7 +25,7 @@ public final class GenericHandler implements Router {
|
||||
|
||||
// api-account-os.hoyoverse.com
|
||||
express.post("/account/risky/api/check", new HttpJsonResponse("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"id\":\"none\",\"action\":\"ACTION_NONE\",\"geetest\":null}}"));
|
||||
|
||||
|
||||
// sdk-os-static.hoyoverse.com
|
||||
express.get("/combo/box/api/config/sdk/combo", new HttpJsonResponse("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"vals\":{\"disable_email_bind_skip\":\"false\",\"email_bind_remind_interval\":\"7\",\"email_bind_remind\":\"true\"}}}"));
|
||||
// hk4e-sdk-os-static.hoyoverse.com
|
||||
@@ -35,7 +35,7 @@ public final class GenericHandler implements Router {
|
||||
// Test api?
|
||||
// abtest-api-data-sg.hoyoverse.com
|
||||
express.post("/data_abtest_api/config/experiment/list", new HttpJsonResponse("{\"retcode\":0,\"success\":true,\"message\":\"\",\"data\":[{\"code\":1000,\"type\":2,\"config_id\":\"14\",\"period_id\":\"6036_99\",\"version\":\"1\",\"configs\":{\"cardType\":\"old\"}}]}"));
|
||||
|
||||
|
||||
// log-upload-os.mihoyo.com
|
||||
express.all("/log/sdk/upload", new HttpJsonResponse("{\"code\":0}"));
|
||||
express.all("/sdk/upload", new HttpJsonResponse("{\"code\":0}"));
|
||||
@@ -45,10 +45,10 @@ public final class GenericHandler implements Router {
|
||||
|
||||
// webstatic-sea.hoyoverse.com
|
||||
express.get("/admin/mi18n/plat_oversea/*", new WebStaticVersionResponse());
|
||||
|
||||
|
||||
express.get("/status/server", GenericHandler::serverStatus);
|
||||
}
|
||||
|
||||
|
||||
private static void serverStatus(Request request, Response response) {
|
||||
int playerCount = Grasscutter.getGameServer().getPlayers().size();
|
||||
int maxPlayer = ACCOUNT.maxPlayer;
|
||||
|
||||
@@ -14,30 +14,30 @@ import static emu.grasscutter.config.Configuration.*;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public final class HttpJsonResponse implements HttpContextHandler {
|
||||
private final String response;
|
||||
private final String[] missingRoutes = { // TODO: When http requests for theses routes are found please remove it from this list and update the route request type in the DispatchServer
|
||||
"/common/hk4e_global/announcement/api/getAlertPic",
|
||||
"/common/hk4e_global/announcement/api/getAlertAnn",
|
||||
"/common/hk4e_global/announcement/api/getAnnList",
|
||||
"/common/hk4e_global/announcement/api/getAnnContent",
|
||||
"/hk4e_global/mdk/shopwindow/shopwindow/listPriceTier",
|
||||
"/log/sdk/upload",
|
||||
"/sdk/upload",
|
||||
"/perf/config/verify",
|
||||
"/log",
|
||||
"/crash/dataUpload"
|
||||
};
|
||||
|
||||
public HttpJsonResponse(String response) {
|
||||
this.response = response;
|
||||
}
|
||||
private final String response;
|
||||
private final String[] missingRoutes = { // TODO: When http requests for theses routes are found please remove it from this list and update the route request type in the DispatchServer
|
||||
"/common/hk4e_global/announcement/api/getAlertPic",
|
||||
"/common/hk4e_global/announcement/api/getAlertAnn",
|
||||
"/common/hk4e_global/announcement/api/getAnnList",
|
||||
"/common/hk4e_global/announcement/api/getAnnContent",
|
||||
"/hk4e_global/mdk/shopwindow/shopwindow/listPriceTier",
|
||||
"/log/sdk/upload",
|
||||
"/sdk/upload",
|
||||
"/perf/config/verify",
|
||||
"/log",
|
||||
"/crash/dataUpload"
|
||||
};
|
||||
|
||||
@Override
|
||||
public void handle(Request req, Response res) throws IOException {
|
||||
// Checking for ALL here isn't required as when ALL is enabled enableDevLogging() gets enabled
|
||||
if(DISPATCH_INFO.logRequests == ServerDebugMode.MISSING && Arrays.stream(missingRoutes).anyMatch(x -> Objects.equals(x, req.baseUrl()))) {
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.request", req.ip(), req.method(), req.baseUrl()) + (DISPATCH_INFO.logRequests == ServerDebugMode.MISSING ? "(MISSING)" : ""));
|
||||
}
|
||||
res.send(response);
|
||||
}
|
||||
public HttpJsonResponse(String response) {
|
||||
this.response = response;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(Request req, Response res) throws IOException {
|
||||
// Checking for ALL here isn't required as when ALL is enabled enableDevLogging() gets enabled
|
||||
if (DISPATCH_INFO.logRequests == ServerDebugMode.MISSING && Arrays.stream(missingRoutes).anyMatch(x -> Objects.equals(x, req.baseUrl()))) {
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.request", req.ip(), req.method(), req.baseUrl()) + (DISPATCH_INFO.logRequests == ServerDebugMode.MISSING ? "(MISSING)" : ""));
|
||||
}
|
||||
res.send(response);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,13 +27,13 @@ public class WebStaticVersionResponse implements HttpContextHandler {
|
||||
}
|
||||
|
||||
private static void getPageResources(String path, Response response) {
|
||||
try(InputStream filestream = FileUtils.readResourceAsStream(path)) {
|
||||
try (InputStream filestream = FileUtils.readResourceAsStream(path)) {
|
||||
|
||||
MediaType fromExtension = MediaType.getByExtension(path.substring(path.lastIndexOf(".") + 1));
|
||||
response.type((fromExtension != null) ? fromExtension.getMIME() : "application/octet-stream");
|
||||
response.send(filestream.readAllBytes());
|
||||
} catch (Exception e) {
|
||||
if(DISPATCH_INFO.logRequests == Grasscutter.ServerDebugMode.MISSING) {
|
||||
if (DISPATCH_INFO.logRequests == Grasscutter.ServerDebugMode.MISSING) {
|
||||
Grasscutter.getLogger().warn("Webstatic File Missing: " + path);
|
||||
}
|
||||
response.status(404);
|
||||
|
||||
@@ -36,11 +36,11 @@ public class HandlerAvatarExpeditionGetRewardReq extends PacketHandler {
|
||||
|
||||
if (session.getServer().getExpeditionSystem().getExpeditionRewardDataList().containsKey(expInfo.getExpId())) {
|
||||
for (ExpeditionRewardDataList RewardDataList : session.getServer().getExpeditionSystem().getExpeditionRewardDataList().get(expInfo.getExpId())) {
|
||||
if(RewardDataList.getHourTime() == expInfo.getHourTime()){
|
||||
if(!RewardDataList.getExpeditionRewardData().isEmpty()){
|
||||
if (RewardDataList.getHourTime() == expInfo.getHourTime()) {
|
||||
if (!RewardDataList.getExpeditionRewardData().isEmpty()) {
|
||||
for (ExpeditionRewardData RewardData :RewardDataList.getExpeditionRewardData()) {
|
||||
int num = RewardData.getMinCount();
|
||||
if(RewardData.getMinCount() != RewardData.getMaxCount()){
|
||||
if (RewardData.getMinCount() != RewardData.getMaxCount()) {
|
||||
num = Utils.randomRange(RewardData.getMinCount(), RewardData.getMaxCount());
|
||||
}
|
||||
items.add(new GameItem(RewardData.getItemId(), num));
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarPromoteReq)
|
||||
public class HandlerAvatarPromoteReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarPromoteReq req = AvatarPromoteReq.parseFrom(payload);
|
||||
|
||||
// Ascend avatar
|
||||
session.getServer().getInventorySystem().promoteAvatar(session.getPlayer(), req.getGuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarPromoteReq req = AvatarPromoteReq.parseFrom(payload);
|
||||
|
||||
// Ascend avatar
|
||||
session.getServer().getInventorySystem().promoteAvatar(session.getPlayer(), req.getGuid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarSkillUpgradeReq)
|
||||
public class HandlerAvatarSkillUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarSkillUpgradeReq req = AvatarSkillUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up avatar talent
|
||||
session.getServer().getInventorySystem().upgradeAvatarSkill(session.getPlayer(), req.getAvatarGuid(), req.getAvatarSkillId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarSkillUpgradeReq req = AvatarSkillUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up avatar talent
|
||||
session.getServer().getInventorySystem().upgradeAvatarSkill(session.getPlayer(), req.getAvatarGuid(), req.getAvatarSkillId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,18 +8,18 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.AvatarUpgradeReq)
|
||||
public class HandlerAvatarUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarUpgradeReq req = AvatarUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up avatar
|
||||
session.getServer().getInventorySystem().upgradeAvatar(
|
||||
session.getPlayer(),
|
||||
req.getAvatarGuid(),
|
||||
req.getItemId(),
|
||||
req.getCount()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
AvatarUpgradeReq req = AvatarUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up avatar
|
||||
session.getServer().getInventorySystem().upgradeAvatar(
|
||||
session.getPlayer(),
|
||||
req.getAvatarGuid(),
|
||||
req.getItemId(),
|
||||
req.getCount()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -12,23 +12,23 @@ import emu.grasscutter.server.packet.send.PacketCalcWeaponUpgradeReturnItemsRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.CalcWeaponUpgradeReturnItemsReq)
|
||||
public class HandlerCalcWeaponUpgradeReturnItemsReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
CalcWeaponUpgradeReturnItemsReq req = CalcWeaponUpgradeReturnItemsReq.parseFrom(payload);
|
||||
|
||||
List<ItemParam> returnOres = session.getServer().getInventorySystem().calcWeaponUpgradeReturnItems(
|
||||
session.getPlayer(),
|
||||
req.getTargetWeaponGuid(),
|
||||
req.getFoodWeaponGuidListList(),
|
||||
req.getItemParamListList()
|
||||
);
|
||||
|
||||
if (returnOres != null) {
|
||||
session.send(new PacketCalcWeaponUpgradeReturnItemsRsp(req.getTargetWeaponGuid(), returnOres));
|
||||
} else {
|
||||
session.send(new PacketCalcWeaponUpgradeReturnItemsRsp());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
CalcWeaponUpgradeReturnItemsReq req = CalcWeaponUpgradeReturnItemsReq.parseFrom(payload);
|
||||
|
||||
List<ItemParam> returnOres = session.getServer().getInventorySystem().calcWeaponUpgradeReturnItems(
|
||||
session.getPlayer(),
|
||||
req.getTargetWeaponGuid(),
|
||||
req.getFoodWeaponGuidListList(),
|
||||
req.getItemParamListList()
|
||||
);
|
||||
|
||||
if (returnOres != null) {
|
||||
session.send(new PacketCalcWeaponUpgradeReturnItemsRsp(req.getTargetWeaponGuid(), returnOres));
|
||||
} else {
|
||||
session.send(new PacketCalcWeaponUpgradeReturnItemsRsp());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -24,7 +24,7 @@ public class HandlerCombineReq extends PacketHandler {
|
||||
var result = session.getServer().getCombineSystem()
|
||||
.combineItem(session.getPlayer(), req.getCombineId(), req.getCombineCount());
|
||||
|
||||
if(result == null){
|
||||
if (result == null) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,7 @@ public class HandlerCombineReq extends PacketHandler {
|
||||
toItemParamList(result.getBack())));
|
||||
}
|
||||
|
||||
private List<ItemParamOuterClass.ItemParam> toItemParamList(List<ItemParamData> list){
|
||||
private List<ItemParamOuterClass.ItemParam> toItemParamList(List<ItemParamData> list) {
|
||||
return list.stream()
|
||||
.map(item -> ItemParamOuterClass.ItemParam.newBuilder()
|
||||
.setItemId(item.getId())
|
||||
|
||||
@@ -8,11 +8,11 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DestroyMaterialReq)
|
||||
public class HandlerDestroyMaterialReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DestroyMaterialReq req = DestroyMaterialReq.parseFrom(payload);
|
||||
|
||||
// Delete items
|
||||
session.getServer().getInventorySystem().destroyMaterial(session.getPlayer(), req.getMaterialListList());
|
||||
}
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DestroyMaterialReq req = DestroyMaterialReq.parseFrom(payload);
|
||||
|
||||
// Delete items
|
||||
session.getServer().getInventorySystem().destroyMaterial(session.getPlayer(), req.getMaterialListList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,10 +8,10 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DoGachaReq)
|
||||
public class HandlerDoGachaReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DoGachaReq req = DoGachaReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getGachaSystem().doPulls(session.getPlayer(), req.getGachaScheduleId(), req.getGachaTimes());
|
||||
}
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DoGachaReq req = DoGachaReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getGachaSystem().doPulls(session.getPlayer(), req.getGachaScheduleId(), req.getGachaTimes());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.DungeonEntryInfoReq)
|
||||
public class HandlerDungeonEntryInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DungeonEntryInfoReq req = DungeonEntryInfoReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getDungeonSystem().getEntryInfo(session.getPlayer(), req.getPointId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
DungeonEntryInfoReq req = DungeonEntryInfoReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getDungeonSystem().getEntryInfo(session.getPlayer(), req.getPointId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,10 +11,10 @@ import emu.grasscutter.server.packet.send.PacketGetGachaInfoRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetGachaInfoReq)
|
||||
public class HandlerGetGachaInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketGetGachaInfoRsp(session.getServer().getGachaSystem(), session.getPlayer()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketGetGachaInfoRsp(session.getServer().getGachaSystem(), session.getPlayer()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,16 +9,16 @@ import emu.grasscutter.server.packet.send.PacketGetInvestigationMonsterRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.GetInvestigationMonsterReq)
|
||||
public class HandlerGetInvestigationMonsterReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = GetInvestigationMonsterReqOuterClass.GetInvestigationMonsterReq.parseFrom(payload);
|
||||
|
||||
session.send(new PacketGetInvestigationMonsterRsp(
|
||||
session.getPlayer(),
|
||||
session.getServer().getWorldDataSystem(),
|
||||
req.getCityIdListList()));
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = GetInvestigationMonsterReqOuterClass.GetInvestigationMonsterReq.parseFrom(payload);
|
||||
|
||||
}
|
||||
session.send(new PacketGetInvestigationMonsterRsp(
|
||||
session.getPlayer(),
|
||||
session.getServer().getWorldDataSystem(),
|
||||
req.getCityIdListList()));
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -27,77 +27,77 @@ import java.security.Signature;
|
||||
@Opcodes(PacketOpcodes.GetPlayerTokenReq)
|
||||
public class HandlerGetPlayerTokenReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
GetPlayerTokenReq req = GetPlayerTokenReq.parseFrom(payload);
|
||||
@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 || !account.getToken().equals(req.getAccountToken())) {
|
||||
return;
|
||||
}
|
||||
// Authenticate
|
||||
Account account = DatabaseHelper.getAccountById(req.getAccountUid());
|
||||
if (account == null || !account.getToken().equals(req.getAccountToken())) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Set account
|
||||
session.setAccount(account);
|
||||
// Set account
|
||||
session.setAccount(account);
|
||||
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
//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;
|
||||
}
|
||||
}
|
||||
//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;
|
||||
}
|
||||
}
|
||||
|
||||
// Call creation event.
|
||||
PlayerCreationEvent event = new PlayerCreationEvent(session, Player.class); event.call();
|
||||
|
||||
// Get player.
|
||||
Player player = DatabaseHelper.getPlayerByAccount(account, event.getPlayerClass());
|
||||
// Get player.
|
||||
Player player = DatabaseHelper.getPlayerByAccount(account, event.getPlayerClass());
|
||||
|
||||
if (player == null) {
|
||||
int nextPlayerUid = DatabaseHelper.getNextPlayerId(session.getAccount().getReservedPlayerUid());
|
||||
if (player == null) {
|
||||
int nextPlayerUid = DatabaseHelper.getNextPlayerId(session.getAccount().getReservedPlayerUid());
|
||||
|
||||
// Create player instance from event.
|
||||
player = event.getPlayerClass().getDeclaredConstructor(GameSession.class).newInstance(session);
|
||||
// Create player instance from event.
|
||||
player = event.getPlayerClass().getDeclaredConstructor(GameSession.class).newInstance(session);
|
||||
|
||||
// Save to db
|
||||
DatabaseHelper.generatePlayerUid(player, nextPlayerUid);
|
||||
}
|
||||
// Save to db
|
||||
DatabaseHelper.generatePlayerUid(player, nextPlayerUid);
|
||||
}
|
||||
|
||||
// Set player object for session
|
||||
session.setPlayer(player);
|
||||
// Set player object for session
|
||||
session.setPlayer(player);
|
||||
|
||||
// Checks if the player is banned
|
||||
if (session.getAccount().isBanned()) {
|
||||
session.send(new PacketGetPlayerTokenRsp(session, 21, "FORBID_CHEATING_PLUGINS", session.getAccount().getBanEndTime()));
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
// Checks if the player is banned
|
||||
if (session.getAccount().isBanned()) {
|
||||
session.send(new PacketGetPlayerTokenRsp(session, 21, "FORBID_CHEATING_PLUGINS", session.getAccount().getBanEndTime()));
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Load player from database
|
||||
player.loadFromDatabase();
|
||||
// Load player from database
|
||||
player.loadFromDatabase();
|
||||
|
||||
// Set session state
|
||||
session.setUseSecretKey(true);
|
||||
session.setState(SessionState.WAITING_FOR_LOGIN);
|
||||
// Set session state
|
||||
session.setUseSecretKey(true);
|
||||
session.setState(SessionState.WAITING_FOR_LOGIN);
|
||||
|
||||
// Only >= 2.7.50 has this
|
||||
if (req.getKeyId() > 0) {
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.packet.send.PacketHomeUnknown2Rsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.Unk2700_ACILPONNGGK_ClientReq)
|
||||
public class HandlerHomeUnknown2Req extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
/*
|
||||
* This packet is about the edit mode
|
||||
*/
|
||||
session.send(new PacketHomeUnknown2Rsp());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
/*
|
||||
* This packet is about the edit mode
|
||||
*/
|
||||
session.send(new PacketHomeUnknown2Rsp());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerApplyEnterMpReq)
|
||||
public class HandlerPlayerApplyEnterMpReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerApplyEnterMpReq req = PlayerApplyEnterMpReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getMultiplayerSystem().applyEnterMp(session.getPlayer(), req.getTargetUid());
|
||||
session.send(new PacketPlayerApplyEnterMpRsp(req.getTargetUid()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerApplyEnterMpReq req = PlayerApplyEnterMpReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getMultiplayerSystem().applyEnterMp(session.getPlayer(), req.getTargetUid());
|
||||
session.send(new PacketPlayerApplyEnterMpRsp(req.getTargetUid()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,13 +9,13 @@ import emu.grasscutter.server.packet.send.PacketPlayerApplyEnterMpResultRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerApplyEnterMpResultReq)
|
||||
public class HandlerPlayerApplyEnterMpResultReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerApplyEnterMpResultReq req = PlayerApplyEnterMpResultReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getMultiplayerSystem().applyEnterMpReply(session.getPlayer(), req.getApplyUid(), req.getIsAgreed());
|
||||
session.send(new PacketPlayerApplyEnterMpResultRsp(req.getApplyUid(), req.getIsAgreed()));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PlayerApplyEnterMpResultReq req = PlayerApplyEnterMpResultReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getMultiplayerSystem().applyEnterMpReply(session.getPlayer(), req.getApplyUid(), req.getIsAgreed());
|
||||
session.send(new PacketPlayerApplyEnterMpResultRsp(req.getApplyUid(), req.getIsAgreed()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerEnterDungeonReq)
|
||||
public class HandlerPlayerEnterDungeonReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
PlayerEnterDungeonReq req = PlayerEnterDungeonReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getDungeonSystem().enterDungeon(session.getPlayer(), req.getPointId(), req.getDungeonId());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Auto template
|
||||
PlayerEnterDungeonReq req = PlayerEnterDungeonReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getDungeonSystem().enterDungeon(session.getPlayer(), req.getPointId(), req.getDungeonId());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,17 +9,17 @@ import emu.grasscutter.server.packet.send.PacketPlayerGetForceQuitBanInfoRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerGetForceQuitBanInfoReq)
|
||||
public class HandlerPlayerGetForceQuitBanInfoReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
|
||||
if (session.getServer().getMultiplayerSystem().leaveCoop(session.getPlayer())) {
|
||||
// Success
|
||||
session.send(new PacketPlayerGetForceQuitBanInfoRsp(RetcodeOuterClass.Retcode.RET_SUCC_VALUE));
|
||||
} else {
|
||||
// Fail
|
||||
session.send(new PacketPlayerGetForceQuitBanInfoRsp(RetcodeOuterClass.Retcode.RET_SVR_ERROR_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
|
||||
if (session.getServer().getMultiplayerSystem().leaveCoop(session.getPlayer())) {
|
||||
// Success
|
||||
session.send(new PacketPlayerGetForceQuitBanInfoRsp(RetcodeOuterClass.Retcode.RET_SUCC_VALUE));
|
||||
} else {
|
||||
// Fail
|
||||
session.send(new PacketPlayerGetForceQuitBanInfoRsp(RetcodeOuterClass.Retcode.RET_SVR_ERROR_VALUE));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -18,39 +18,39 @@ import emu.grasscutter.server.packet.send.PacketTakeAchievementRewardReq;
|
||||
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
|
||||
public class HandlerPlayerLoginReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
// Check
|
||||
if (session.getAccount() == null) {
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
@Override
|
||||
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);
|
||||
// Parse request
|
||||
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
|
||||
|
||||
// Authenticate session
|
||||
if (!req.getToken().equals(session.getAccount().getToken())) {
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
// Authenticate session
|
||||
if (!req.getToken().equals(session.getAccount().getToken())) {
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Load character from db
|
||||
Player player = session.getPlayer();
|
||||
// Load character from db
|
||||
Player player = session.getPlayer();
|
||||
|
||||
// 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 {
|
||||
// Login done
|
||||
session.getPlayer().onLogin();
|
||||
}
|
||||
// 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 {
|
||||
// Login done
|
||||
session.getPlayer().onLogin();
|
||||
}
|
||||
|
||||
// Final packet to tell client logging in is done
|
||||
session.send(new PacketPlayerLoginRsp(session));
|
||||
session.send(new PacketTakeAchievementRewardReq(session));
|
||||
}
|
||||
// Final packet to tell client logging in is done
|
||||
session.send(new PacketPlayerLoginRsp(session));
|
||||
session.send(new PacketTakeAchievementRewardReq(session));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -7,10 +7,10 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.PlayerQuitDungeonReq)
|
||||
public class HandlerPlayerQuitDungeonReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.getPlayer().getServer().getDungeonSystem().exitDungeon(session.getPlayer());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.getPlayer().getServer().getDungeonSystem().exitDungeon(session.getPlayer());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,14 +9,14 @@ import emu.grasscutter.server.packet.send.PacketPullPrivateChatRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PullPrivateChatReq)
|
||||
public class HandlerPullPrivateChatReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PullPrivateChatReq req = PullPrivateChatReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getChatManager().handlePullPrivateChatReq(session.getPlayer(), req.getTargetUid());
|
||||
|
||||
// session.send(new PacketPullPrivateChatRsp(req.getTargetUid()));
|
||||
}
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
PullPrivateChatReq req = PullPrivateChatReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getChatManager().handlePullPrivateChatReq(session.getPlayer(), req.getTargetUid());
|
||||
|
||||
// session.send(new PacketPullPrivateChatRsp(req.getTargetUid()));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,8 +8,8 @@ import emu.grasscutter.server.packet.send.PacketPullRecentChatRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.PullRecentChatReq)
|
||||
public class HandlerPullRecentChatReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.getServer().getChatManager().handlePullRecentChatReq(session.getPlayer());
|
||||
}
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.getServer().getChatManager().handlePullRecentChatReq(session.getPlayer());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,17 +11,17 @@ import emu.grasscutter.server.packet.send.PacketQueryPathRsp;
|
||||
@Opcodes(PacketOpcodes.QueryPathReq)
|
||||
public class HandlerQueryPathReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = QueryPathReq.parseFrom(payload);
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
var req = QueryPathReq.parseFrom(payload);
|
||||
|
||||
/**
|
||||
* It is not the actual work
|
||||
*/
|
||||
|
||||
|
||||
if (req.getDestinationPosList().size() > 0) {
|
||||
session.send(new PacketQueryPathRsp(req));
|
||||
session.send(new PacketQueryPathRsp(req));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,9 +8,9 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ReliquaryDecomposeReq)
|
||||
public class HandlerReliquaryDecomposeReq extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ReliquaryDecomposeReq req = ReliquaryDecomposeReq.parseFrom(payload);
|
||||
session.getServer().getCombineSystem().decomposeReliquaries(session.getPlayer(), req.getConfigId(), req.getTargetCount(), req.getGuidListList());
|
||||
}
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ReliquaryDecomposeReq req = ReliquaryDecomposeReq.parseFrom(payload);
|
||||
session.getServer().getCombineSystem().decomposeReliquaries(session.getPlayer(), req.getConfigId(), req.getTargetCount(), req.getGuidListList());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.ReliquaryUpgradeReq)
|
||||
public class HandlerReliquaryUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ReliquaryUpgradeReq req = ReliquaryUpgradeReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getInventorySystem().upgradeRelic(session.getPlayer(), req.getTargetReliquaryGuid(), req.getFoodReliquaryGuidListList(), req.getItemParamListList());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
ReliquaryUpgradeReq req = ReliquaryUpgradeReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getInventorySystem().upgradeRelic(session.getPlayer(), req.getTargetReliquaryGuid(), req.getFoodReliquaryGuidListList(), req.getItemParamListList());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,18 +9,18 @@ import emu.grasscutter.server.packet.send.PacketSceneKickPlayerRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.SceneKickPlayerReq)
|
||||
public class HandlerSceneKickPlayerReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SceneKickPlayerReq req = SceneKickPlayerReq.parseFrom(payload);
|
||||
|
||||
if (session.getServer().getMultiplayerSystem().kickPlayer(session.getPlayer(), req.getTargetUid())) {
|
||||
// Success
|
||||
session.send(new PacketSceneKickPlayerRsp(req.getTargetUid()));
|
||||
} else {
|
||||
// Fail
|
||||
session.send(new PacketSceneKickPlayerRsp());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SceneKickPlayerReq req = SceneKickPlayerReq.parseFrom(payload);
|
||||
|
||||
if (session.getServer().getMultiplayerSystem().kickPlayer(session.getPlayer(), req.getTargetUid())) {
|
||||
// Success
|
||||
session.send(new PacketSceneKickPlayerRsp(req.getTargetUid()));
|
||||
} else {
|
||||
// Fail
|
||||
session.send(new PacketSceneKickPlayerRsp());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,12 +8,12 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetEquipLockStateReq)
|
||||
public class HandlerSetEquipLockStateReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetEquipLockStateReq req = SetEquipLockStateReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getInventorySystem().lockEquip(session.getPlayer(), req.getTargetEquipGuid(), req.getIsLocked());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetEquipLockStateReq req = SetEquipLockStateReq.parseFrom(payload);
|
||||
|
||||
session.getServer().getInventorySystem().lockEquip(session.getPlayer(), req.getTargetEquipGuid(), req.getIsLocked());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -23,4 +23,4 @@ public class HandlerSetOpenStateReq extends PacketHandler {
|
||||
session.send(new PacketSetOpenStateRsp(openState,value));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,62 +23,62 @@ import java.util.Arrays;
|
||||
|
||||
@Opcodes(PacketOpcodes.SetPlayerBornDataReq)
|
||||
public class HandlerSetPlayerBornDataReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetPlayerBornDataReq req = SetPlayerBornDataReq.parseFrom(payload);
|
||||
|
||||
// Sanity checks
|
||||
int avatarId = req.getAvatarId();
|
||||
int startingSkillDepot;
|
||||
if (avatarId == GameConstants.MAIN_CHARACTER_MALE) {
|
||||
startingSkillDepot = 504;
|
||||
} else if (avatarId == GameConstants.MAIN_CHARACTER_FEMALE) {
|
||||
startingSkillDepot = 704;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure resources folder is set
|
||||
if (!GameData.getAvatarDataMap().containsKey(avatarId)) {
|
||||
Grasscutter.getLogger().error("No avatar data found! Please check your ExcelBinOutput folder.");
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Login done
|
||||
session.getPlayer().onLogin();
|
||||
|
||||
// Born resp packet
|
||||
session.send(new BasePacket(PacketOpcodes.SetPlayerBornDataRsp));
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
SetPlayerBornDataReq req = SetPlayerBornDataReq.parseFrom(payload);
|
||||
|
||||
// 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);
|
||||
}
|
||||
// Sanity checks
|
||||
int avatarId = req.getAvatarId();
|
||||
int startingSkillDepot;
|
||||
if (avatarId == GameConstants.MAIN_CHARACTER_MALE) {
|
||||
startingSkillDepot = 504;
|
||||
} else if (avatarId == GameConstants.MAIN_CHARACTER_FEMALE) {
|
||||
startingSkillDepot = 704;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure resources folder is set
|
||||
if (!GameData.getAvatarDataMap().containsKey(avatarId)) {
|
||||
Grasscutter.getLogger().error("No avatar data found! Please check your ExcelBinOutput folder.");
|
||||
session.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// 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;
|
||||
}
|
||||
|
||||
// Login done
|
||||
session.getPlayer().onLogin();
|
||||
|
||||
// Born resp packet
|
||||
session.send(new BasePacket(PacketOpcodes.SetPlayerBornDataRsp));
|
||||
|
||||
// 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);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.packet.send.PacketTowerAllDataRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.TowerAllDataReq)
|
||||
public class HandlerTowerAllDataReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketTowerAllDataRsp(
|
||||
session.getServer().getTowerSystem(),
|
||||
session.getPlayer().getTowerManager()
|
||||
));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
session.send(new PacketTowerAllDataRsp(
|
||||
session.getServer().getTowerSystem(),
|
||||
session.getPlayer().getTowerManager()
|
||||
));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -13,28 +13,28 @@ import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
|
||||
@Opcodes(PacketOpcodes.UnionCmdNotify)
|
||||
public class HandlerUnionCmdNotify extends PacketHandler {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UnionCmdNotify req = UnionCmdNotify.parseFrom(payload);
|
||||
for (UnionCmd cmd : req.getCmdListList()) {
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UnionCmdNotify req = UnionCmdNotify.parseFrom(payload);
|
||||
for (UnionCmd cmd : req.getCmdListList()) {
|
||||
int cmdOpcode = cmd.getMessageId();
|
||||
byte[] cmdPayload = cmd.getBody().toByteArray();
|
||||
if(GAME_INFO.logPackets == ServerDebugMode.WHITELIST && SERVER.debugWhitelist.contains(cmd.getMessageId())) {
|
||||
if (GAME_INFO.logPackets == ServerDebugMode.WHITELIST && SERVER.debugWhitelist.contains(cmd.getMessageId())) {
|
||||
session.logPacket("RECV in Union", cmdOpcode, cmdPayload);
|
||||
} else if (GAME_INFO.logPackets == ServerDebugMode.BLACKLIST && !SERVER.debugBlacklist.contains(cmd.getMessageId())) {
|
||||
session.logPacket("RECV in Union", cmdOpcode, cmdPayload);
|
||||
}
|
||||
//debugLevel ALL ignores UnionCmdNotify, so we will also ignore the contained opcodes
|
||||
session.getServer().getPacketHandler().handle(session, cmd.getMessageId(), EMPTY_BYTE_ARRAY, cmd.getBody().toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
// Update
|
||||
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
|
||||
session.getPlayer().getAbilityInvokeHandler().update(session.getPlayer());
|
||||
// Update
|
||||
session.getPlayer().getCombatInvokeHandler().update(session.getPlayer());
|
||||
session.getPlayer().getAbilityInvokeHandler().update(session.getPlayer());
|
||||
|
||||
// Handle attack results last
|
||||
while (!session.getPlayer().getAttackResults().isEmpty()) {
|
||||
session.getPlayer().getScene().handleAttack(session.getPlayer().getAttackResults().poll());
|
||||
}
|
||||
}
|
||||
while (!session.getPlayer().getAttackResults().isEmpty()) {
|
||||
session.getPlayer().getScene().handleAttack(session.getPlayer().getAttackResults().poll());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.UnlockAvatarTalentReq)
|
||||
public class HandlerUnlockAvatarTalentReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UnlockAvatarTalentReq req = UnlockAvatarTalentReq.parseFrom(payload);
|
||||
|
||||
// Unlock avatar const
|
||||
session.getServer().getInventorySystem().unlockAvatarConstellation(session.getPlayer(), req.getAvatarGuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UnlockAvatarTalentReq req = UnlockAvatarTalentReq.parseFrom(payload);
|
||||
|
||||
// Unlock avatar const
|
||||
session.getServer().getInventorySystem().unlockAvatarConstellation(session.getPlayer(), req.getAvatarGuid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -10,17 +10,17 @@ import emu.grasscutter.server.packet.send.PacketUseItemRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.UseItemReq)
|
||||
public class HandlerUseItemReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UseItemReq req = UseItemReq.parseFrom(payload);
|
||||
|
||||
GameItem useItem = session.getServer().getInventorySystem().useItem(session.getPlayer(), req.getTargetGuid(), req.getGuid(), req.getCount(), req.getOptionIdx());
|
||||
if (useItem != null) {
|
||||
session.send(new PacketUseItemRsp(req.getTargetGuid(), useItem));
|
||||
} else {
|
||||
session.send(new PacketUseItemRsp());
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
UseItemReq req = UseItemReq.parseFrom(payload);
|
||||
|
||||
GameItem useItem = session.getServer().getInventorySystem().useItem(session.getPlayer(), req.getTargetGuid(), req.getGuid(), req.getCount(), req.getOptionIdx());
|
||||
if (useItem != null) {
|
||||
session.send(new PacketUseItemRsp(req.getTargetGuid(), useItem));
|
||||
} else {
|
||||
session.send(new PacketUseItemRsp());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.WeaponAwakenReq)
|
||||
public class HandlerWeaponAwakenReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponAwakenReq req = WeaponAwakenReq.parseFrom(payload);
|
||||
|
||||
// Weapon refinement
|
||||
session.getServer().getInventorySystem().refineWeapon(session.getPlayer(), req.getTargetWeaponGuid(), req.getItemGuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponAwakenReq req = WeaponAwakenReq.parseFrom(payload);
|
||||
|
||||
// Weapon refinement
|
||||
session.getServer().getInventorySystem().refineWeapon(session.getPlayer(), req.getTargetWeaponGuid(), req.getItemGuid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,13 +8,13 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.WeaponPromoteReq)
|
||||
public class HandlerWeaponPromoteReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponPromoteReq req = WeaponPromoteReq.parseFrom(payload);
|
||||
|
||||
// Ascend weapon
|
||||
session.getServer().getInventorySystem().promoteWeapon(session.getPlayer(), req.getTargetWeaponGuid());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponPromoteReq req = WeaponPromoteReq.parseFrom(payload);
|
||||
|
||||
// Ascend weapon
|
||||
session.getServer().getInventorySystem().promoteWeapon(session.getPlayer(), req.getTargetWeaponGuid());
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -8,18 +8,18 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Opcodes(PacketOpcodes.WeaponUpgradeReq)
|
||||
public class HandlerWeaponUpgradeReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponUpgradeReq req = WeaponUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up weapon
|
||||
session.getServer().getInventorySystem().upgradeWeapon(
|
||||
session.getPlayer(),
|
||||
req.getTargetWeaponGuid(),
|
||||
req.getFoodWeaponGuidListList(),
|
||||
req.getItemParamListList()
|
||||
);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
WeaponUpgradeReq req = WeaponUpgradeReq.parseFrom(payload);
|
||||
|
||||
// Level up weapon
|
||||
session.getServer().getInventorySystem().upgradeWeapon(
|
||||
session.getPlayer(),
|
||||
req.getTargetWeaponGuid(),
|
||||
req.getFoodWeaponGuidListList(),
|
||||
req.getItemParamListList()
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -32,9 +32,9 @@ public class PacketGetAllMailRsp extends BasePacket {
|
||||
List<MailData> mailDataList = new ArrayList<MailData>();
|
||||
|
||||
for (Mail message : player.getAllMail()) {
|
||||
if(message.stateValue == 1) { // Make sure it isn't a gift
|
||||
if (message.stateValue == 1) { // Make sure it isn't a gift
|
||||
if (message.expireTime > (int) Instant.now().getEpochSecond()) { // Make sure the message isn't expired (The game won't show expired mail, but I don't want to send unnecessary information).
|
||||
if(mailDataList.size() <= 1000) { // Make sure that there isn't over 1000 messages in the mailbox. (idk what will happen if there is but the game probably won't like it.)
|
||||
if (mailDataList.size() <= 1000) { // Make sure that there isn't over 1000 messages in the mailbox. (idk what will happen if there is but the game probably won't like it.)
|
||||
MailTextContent.Builder mailTextContent = MailTextContent.newBuilder();
|
||||
mailTextContent.setTitle(message.mailContent.title);
|
||||
mailTextContent.setContent(message.mailContent.content);
|
||||
|
||||
@@ -6,11 +6,11 @@ import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
|
||||
public class PacketGetGachaInfoRsp extends BasePacket {
|
||||
|
||||
public PacketGetGachaInfoRsp(GachaSystem manager, Player player) {
|
||||
super(PacketOpcodes.GetGachaInfoRsp);
|
||||
|
||||
this.setData(manager.toProto(player));
|
||||
}
|
||||
|
||||
public PacketGetGachaInfoRsp(GachaSystem manager, Player player) {
|
||||
super(PacketOpcodes.GetGachaInfoRsp);
|
||||
|
||||
this.setData(manager.toProto(player));
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -11,15 +11,15 @@ import java.util.List;
|
||||
|
||||
public class PacketGetInvestigationMonsterRsp extends BasePacket {
|
||||
|
||||
public PacketGetInvestigationMonsterRsp(Player player, WorldDataSystem worldDataManager, List<Integer> cityIdListList) {
|
||||
public PacketGetInvestigationMonsterRsp(Player player, WorldDataSystem worldDataManager, List<Integer> cityIdListList) {
|
||||
|
||||
super(PacketOpcodes.GetInvestigationMonsterRsp);
|
||||
super(PacketOpcodes.GetInvestigationMonsterRsp);
|
||||
|
||||
var resp = GetInvestigationMonsterRspOuterClass.GetInvestigationMonsterRsp.newBuilder();
|
||||
var resp = GetInvestigationMonsterRspOuterClass.GetInvestigationMonsterRsp.newBuilder();
|
||||
|
||||
cityIdListList.forEach(id -> resp.addAllMonsterList(worldDataManager.getInvestigationMonstersByCityId(player, id)));
|
||||
cityIdListList.forEach(id -> resp.addAllMonsterList(worldDataManager.getInvestigationMonstersByCityId(player, id)));
|
||||
|
||||
|
||||
this.setData(resp.build());
|
||||
}
|
||||
this.setData(resp.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,32 +14,32 @@ import emu.grasscutter.net.proto.ProfilePictureOuterClass.ProfilePicture;
|
||||
import emu.grasscutter.net.proto.PlatformTypeOuterClass;
|
||||
|
||||
public class PacketGetPlayerFriendListRsp extends BasePacket {
|
||||
|
||||
public PacketGetPlayerFriendListRsp(Player player) {
|
||||
super(PacketOpcodes.GetPlayerFriendListRsp);
|
||||
|
||||
var serverAccount = GAME_INFO.serverAccount;
|
||||
FriendBrief serverFriend = FriendBrief.newBuilder()
|
||||
.setUid(GameConstants.SERVER_CONSOLE_UID)
|
||||
.setNickname(serverAccount.nickName)
|
||||
.setLevel(serverAccount.adventureRank)
|
||||
.setProfilePicture(ProfilePicture.newBuilder().setAvatarId(serverAccount.avatarId))
|
||||
.setWorldLevel(serverAccount.worldLevel)
|
||||
.setSignature(serverAccount.signature)
|
||||
.setLastActiveTime((int) (System.currentTimeMillis() / 1000f))
|
||||
.setNameCardId(serverAccount.nameCardId)
|
||||
.setOnlineState(FriendOnlineState.FRIEND_ONLINE_STATE_ONLINE)
|
||||
.setParam(1)
|
||||
.setIsGameSource(true)
|
||||
.setPlatformType(PlatformTypeOuterClass.PlatformType.PLATFORM_TYPE_PC)
|
||||
.build();
|
||||
|
||||
GetPlayerFriendListRsp.Builder proto = GetPlayerFriendListRsp.newBuilder().addFriendList(serverFriend);
|
||||
|
||||
for (Friendship friendship : player.getFriendsList().getFriends().values()) {
|
||||
proto.addFriendList(friendship.toProto());
|
||||
}
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
public PacketGetPlayerFriendListRsp(Player player) {
|
||||
super(PacketOpcodes.GetPlayerFriendListRsp);
|
||||
|
||||
var serverAccount = GAME_INFO.serverAccount;
|
||||
FriendBrief serverFriend = FriendBrief.newBuilder()
|
||||
.setUid(GameConstants.SERVER_CONSOLE_UID)
|
||||
.setNickname(serverAccount.nickName)
|
||||
.setLevel(serverAccount.adventureRank)
|
||||
.setProfilePicture(ProfilePicture.newBuilder().setAvatarId(serverAccount.avatarId))
|
||||
.setWorldLevel(serverAccount.worldLevel)
|
||||
.setSignature(serverAccount.signature)
|
||||
.setLastActiveTime((int) (System.currentTimeMillis() / 1000f))
|
||||
.setNameCardId(serverAccount.nameCardId)
|
||||
.setOnlineState(FriendOnlineState.FRIEND_ONLINE_STATE_ONLINE)
|
||||
.setParam(1)
|
||||
.setIsGameSource(true)
|
||||
.setPlatformType(PlatformTypeOuterClass.PlatformType.PLATFORM_TYPE_PC)
|
||||
.build();
|
||||
|
||||
GetPlayerFriendListRsp.Builder proto = GetPlayerFriendListRsp.newBuilder().addFriendList(serverFriend);
|
||||
|
||||
for (Friendship friendship : player.getFriendsList().getFriends().values()) {
|
||||
proto.addFriendList(friendship.toProto());
|
||||
}
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,20 +9,20 @@ import emu.grasscutter.net.proto.CityInfoOuterClass.CityInfo;
|
||||
import emu.grasscutter.net.proto.GetSceneAreaRspOuterClass.GetSceneAreaRsp;
|
||||
|
||||
public class PacketGetSceneAreaRsp extends BasePacket {
|
||||
|
||||
public PacketGetSceneAreaRsp(int sceneId) {
|
||||
super(PacketOpcodes.GetSceneAreaRsp);
|
||||
|
||||
this.buildHeader(0);
|
||||
|
||||
GetSceneAreaRsp p = GetSceneAreaRsp.newBuilder()
|
||||
.setSceneId(sceneId)
|
||||
.addAllAreaIdList(Arrays.stream(new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,18,19,100,101,102,103,200,210,300,400,401,402,403}).boxed().collect(Collectors.toList()))
|
||||
.addCityInfoList(CityInfo.newBuilder().setCityId(1).setLevel(1).build())
|
||||
.addCityInfoList(CityInfo.newBuilder().setCityId(2).setLevel(1).build())
|
||||
.addCityInfoList(CityInfo.newBuilder().setCityId(3).setLevel(1).build())
|
||||
.build();
|
||||
|
||||
this.setData(p);
|
||||
}
|
||||
|
||||
public PacketGetSceneAreaRsp(int sceneId) {
|
||||
super(PacketOpcodes.GetSceneAreaRsp);
|
||||
|
||||
this.buildHeader(0);
|
||||
|
||||
GetSceneAreaRsp p = GetSceneAreaRsp.newBuilder()
|
||||
.setSceneId(sceneId)
|
||||
.addAllAreaIdList(Arrays.stream(new int[] {1,2,3,4,5,6,7,8,9,10,11,12,13,14,17,18,19,100,101,102,103,200,210,300,400,401,402,403}).boxed().collect(Collectors.toList()))
|
||||
.addCityInfoList(CityInfo.newBuilder().setCityId(1).setLevel(1).build())
|
||||
.addCityInfoList(CityInfo.newBuilder().setCityId(2).setLevel(1).build())
|
||||
.addCityInfoList(CityInfo.newBuilder().setCityId(3).setLevel(1).build())
|
||||
.build();
|
||||
|
||||
this.setData(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,61 +18,61 @@ import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public class PacketGetShopRsp extends BasePacket {
|
||||
public PacketGetShopRsp(Player inv, int shopType) {
|
||||
super(PacketOpcodes.GetShopRsp);
|
||||
public PacketGetShopRsp(Player inv, int shopType) {
|
||||
super(PacketOpcodes.GetShopRsp);
|
||||
|
||||
// TODO: CityReputationLevel
|
||||
Shop.Builder shop = Shop.newBuilder()
|
||||
.setShopType(shopType)
|
||||
.setCityId(1) //mock
|
||||
.setCityReputationLevel(10); //mock
|
||||
// TODO: CityReputationLevel
|
||||
Shop.Builder shop = Shop.newBuilder()
|
||||
.setShopType(shopType)
|
||||
.setCityId(1) //mock
|
||||
.setCityReputationLevel(10); //mock
|
||||
|
||||
ShopSystem manager = Grasscutter.getGameServer().getShopSystem();
|
||||
if (manager.getShopData().get(shopType) != null) {
|
||||
List<ShopInfo> list = manager.getShopData().get(shopType);
|
||||
List<ShopGoods> goodsList = new ArrayList<>();
|
||||
for (ShopInfo info : list) {
|
||||
ShopGoods.Builder goods = ShopGoods.newBuilder()
|
||||
.setGoodsId(info.getGoodsId())
|
||||
.setGoodsItem(ItemParamOuterClass.ItemParam.newBuilder().setItemId(info.getGoodsItem().getId()).setCount(info.getGoodsItem().getCount()).build())
|
||||
.setScoin(info.getScoin())
|
||||
.setHcoin(info.getHcoin())
|
||||
.setBuyLimit(info.getBuyLimit())
|
||||
.setBeginTime(info.getBeginTime())
|
||||
.setEndTime(info.getEndTime())
|
||||
.setMinLevel(info.getMinLevel())
|
||||
.setMaxLevel(info.getMaxLevel())
|
||||
.setMcoin(info.getMcoin())
|
||||
.setDisableType(info.getDisableType())
|
||||
.setSecondarySheetId(info.getSecondarySheetId());
|
||||
if (info.getCostItemList() != null) {
|
||||
goods.addAllCostItemList(info.getCostItemList().stream().map(x -> ItemParamOuterClass.ItemParam.newBuilder().setItemId(x.getId()).setCount(x.getCount()).build()).collect(Collectors.toList()));
|
||||
}
|
||||
if (info.getPreGoodsIdList() != null) {
|
||||
goods.addAllPreGoodsIdList(info.getPreGoodsIdList());
|
||||
}
|
||||
ShopSystem manager = Grasscutter.getGameServer().getShopSystem();
|
||||
if (manager.getShopData().get(shopType) != null) {
|
||||
List<ShopInfo> list = manager.getShopData().get(shopType);
|
||||
List<ShopGoods> goodsList = new ArrayList<>();
|
||||
for (ShopInfo info : list) {
|
||||
ShopGoods.Builder goods = ShopGoods.newBuilder()
|
||||
.setGoodsId(info.getGoodsId())
|
||||
.setGoodsItem(ItemParamOuterClass.ItemParam.newBuilder().setItemId(info.getGoodsItem().getId()).setCount(info.getGoodsItem().getCount()).build())
|
||||
.setScoin(info.getScoin())
|
||||
.setHcoin(info.getHcoin())
|
||||
.setBuyLimit(info.getBuyLimit())
|
||||
.setBeginTime(info.getBeginTime())
|
||||
.setEndTime(info.getEndTime())
|
||||
.setMinLevel(info.getMinLevel())
|
||||
.setMaxLevel(info.getMaxLevel())
|
||||
.setMcoin(info.getMcoin())
|
||||
.setDisableType(info.getDisableType())
|
||||
.setSecondarySheetId(info.getSecondarySheetId());
|
||||
if (info.getCostItemList() != null) {
|
||||
goods.addAllCostItemList(info.getCostItemList().stream().map(x -> ItemParamOuterClass.ItemParam.newBuilder().setItemId(x.getId()).setCount(x.getCount()).build()).collect(Collectors.toList()));
|
||||
}
|
||||
if (info.getPreGoodsIdList() != null) {
|
||||
goods.addAllPreGoodsIdList(info.getPreGoodsIdList());
|
||||
}
|
||||
|
||||
int currentTs = Utils.getCurrentSeconds();
|
||||
ShopLimit currentShopLimit = inv.getGoodsLimit(info.getGoodsId());
|
||||
int nextRefreshTime = ShopSystem.getShopNextRefreshTime(info);
|
||||
if (currentShopLimit != null) {
|
||||
if (currentShopLimit.getNextRefreshTime() < currentTs) { // second game day
|
||||
currentShopLimit.setHasBoughtInPeriod(0);
|
||||
currentShopLimit.setNextRefreshTime(nextRefreshTime);
|
||||
}
|
||||
goods.setBoughtNum(currentShopLimit.getHasBoughtInPeriod());
|
||||
goods.setNextRefreshTime(currentShopLimit.getNextRefreshTime());
|
||||
} else {
|
||||
inv.addShopLimit(goods.getGoodsId(), 0, nextRefreshTime); // save generated refresh time
|
||||
goods.setNextRefreshTime(nextRefreshTime);
|
||||
}
|
||||
int currentTs = Utils.getCurrentSeconds();
|
||||
ShopLimit currentShopLimit = inv.getGoodsLimit(info.getGoodsId());
|
||||
int nextRefreshTime = ShopSystem.getShopNextRefreshTime(info);
|
||||
if (currentShopLimit != null) {
|
||||
if (currentShopLimit.getNextRefreshTime() < currentTs) { // second game day
|
||||
currentShopLimit.setHasBoughtInPeriod(0);
|
||||
currentShopLimit.setNextRefreshTime(nextRefreshTime);
|
||||
}
|
||||
goods.setBoughtNum(currentShopLimit.getHasBoughtInPeriod());
|
||||
goods.setNextRefreshTime(currentShopLimit.getNextRefreshTime());
|
||||
} else {
|
||||
inv.addShopLimit(goods.getGoodsId(), 0, nextRefreshTime); // save generated refresh time
|
||||
goods.setNextRefreshTime(nextRefreshTime);
|
||||
}
|
||||
|
||||
goodsList.add(goods.build());
|
||||
}
|
||||
shop.addAllGoodsList(goodsList);
|
||||
}
|
||||
goodsList.add(goods.build());
|
||||
}
|
||||
shop.addAllGoodsList(goodsList);
|
||||
}
|
||||
|
||||
inv.save();
|
||||
this.setData(GetShopRspOuterClass.GetShopRsp.newBuilder().setShop(shop).build());
|
||||
}
|
||||
inv.save();
|
||||
this.setData(GetShopRspOuterClass.GetShopRsp.newBuilder().setShop(shop).build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,28 +10,28 @@ import emu.grasscutter.net.proto.VectorOuterClass;
|
||||
|
||||
public class PacketHomeBasicInfoNotify extends BasePacket {
|
||||
|
||||
public PacketHomeBasicInfoNotify(Player player, boolean editMode) {
|
||||
super(PacketOpcodes.HomeBasicInfoNotify);
|
||||
public PacketHomeBasicInfoNotify(Player player, boolean editMode) {
|
||||
super(PacketOpcodes.HomeBasicInfoNotify);
|
||||
|
||||
if (player.getCurrentRealmId() <= 0) {
|
||||
return;
|
||||
}
|
||||
if (player.getCurrentRealmId() <= 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
var proto = HomeBasicInfoNotifyOuterClass.HomeBasicInfoNotify.newBuilder();
|
||||
var proto = HomeBasicInfoNotifyOuterClass.HomeBasicInfoNotify.newBuilder();
|
||||
|
||||
var sceneId = player.getCurrentRealmId() + 2000;
|
||||
var homeScene = player.getHome().getHomeSceneItem(sceneId);
|
||||
var sceneId = player.getCurrentRealmId() + 2000;
|
||||
var homeScene = player.getHome().getHomeSceneItem(sceneId);
|
||||
|
||||
proto.setBasicInfo(HomeBasicInfoOuterClass.HomeBasicInfo.newBuilder()
|
||||
.setCurModuleId(player.getCurrentRealmId())
|
||||
.setCurRoomSceneId(homeScene.getRoomSceneId())
|
||||
.setIsInEditMode(editMode)
|
||||
.setHomeOwnerUid(player.getUid())
|
||||
.setLevel(player.getHome().getLevel())
|
||||
.setOwnerNickName(player.getNickname())
|
||||
// TODO limit shop
|
||||
.build());
|
||||
proto.setBasicInfo(HomeBasicInfoOuterClass.HomeBasicInfo.newBuilder()
|
||||
.setCurModuleId(player.getCurrentRealmId())
|
||||
.setCurRoomSceneId(homeScene.getRoomSceneId())
|
||||
.setIsInEditMode(editMode)
|
||||
.setHomeOwnerUid(player.getUid())
|
||||
.setLevel(player.getHome().getLevel())
|
||||
.setOwnerNickName(player.getNickname())
|
||||
// TODO limit shop
|
||||
.build());
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,7 +14,7 @@ import java.util.List;
|
||||
public class PacketMailChangeNotify extends BasePacket {
|
||||
|
||||
public PacketMailChangeNotify(Player player, Mail message) {
|
||||
this (player, new ArrayList<Mail>(){{add(message);}});
|
||||
this (player, new ArrayList<Mail>() {{add(message);}});
|
||||
}
|
||||
|
||||
public PacketMailChangeNotify(Player player, List<Mail> mailList) {
|
||||
@@ -60,10 +60,10 @@ public class PacketMailChangeNotify extends BasePacket {
|
||||
}
|
||||
}
|
||||
|
||||
if(delMailIdList != null) {
|
||||
if (delMailIdList != null) {
|
||||
proto.addAllDelMailIdList(delMailIdList);
|
||||
}
|
||||
|
||||
this.setData(proto.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -40,4 +40,4 @@ public class PacketMarkMapRsp extends BasePacket {
|
||||
MarkMapRspOuterClass.MarkMapRsp data = proto.build();
|
||||
this.setData(data);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,4 +16,4 @@ public class PacketOpenStateChangeNotify extends BasePacket {
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,20 +13,20 @@ import emu.grasscutter.net.proto.OpenStateUpdateNotifyOuterClass.OpenStateUpdate
|
||||
public class PacketOpenStateUpdateNotify extends BasePacket {
|
||||
|
||||
public PacketOpenStateUpdateNotify(PlayerOpenStateManager manager) {
|
||||
super(PacketOpcodes.OpenStateUpdateNotify);
|
||||
super(PacketOpcodes.OpenStateUpdateNotify);
|
||||
|
||||
OpenStateUpdateNotify.Builder proto = OpenStateUpdateNotify.newBuilder();
|
||||
OpenStateUpdateNotify.Builder proto = OpenStateUpdateNotify.newBuilder();
|
||||
|
||||
for (OpenState state : OpenState.values()) {
|
||||
// If the player has an open state stored in their map, then it would always override any default value
|
||||
if (manager.getOpenStateMap().containsKey(state.getValue())) {
|
||||
proto.putOpenStateMap(state.getValue(), manager.getOpenState(state));
|
||||
} else if (PlayerOpenStateManager.DEV_OPEN_STATES.contains(state)) {
|
||||
// Add default value here. TODO properly put default values somewhere
|
||||
proto.putOpenStateMap(state.getValue(), 1);
|
||||
}
|
||||
}
|
||||
for (OpenState state : OpenState.values()) {
|
||||
// If the player has an open state stored in their map, then it would always override any default value
|
||||
if (manager.getOpenStateMap().containsKey(state.getValue())) {
|
||||
proto.putOpenStateMap(state.getValue(), manager.getOpenState(state));
|
||||
} else if (PlayerOpenStateManager.DEV_OPEN_STATES.contains(state)) {
|
||||
// Add default value here. TODO properly put default values somewhere
|
||||
proto.putOpenStateMap(state.getValue(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,60 +11,60 @@ import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
public class PacketPlayerEnterSceneNotify extends BasePacket {
|
||||
|
||||
// Login
|
||||
public PacketPlayerEnterSceneNotify(Player player) {
|
||||
super(PacketOpcodes.PlayerEnterSceneNotify);
|
||||
|
||||
player.setSceneLoadState(SceneLoadState.LOADING);
|
||||
player.setEnterSceneToken(Utils.randomRange(1000, 99999));
|
||||
|
||||
PlayerEnterSceneNotify proto = PlayerEnterSceneNotify.newBuilder()
|
||||
.setSceneId(player.getSceneId())
|
||||
.setPos(player.getPosition().toProto())
|
||||
.setSceneBeginTime(System.currentTimeMillis())
|
||||
.setType(EnterType.ENTER_TYPE_SELF)
|
||||
.setTargetUid(player.getUid())
|
||||
.setEnterSceneToken(player.getEnterSceneToken())
|
||||
.setWorldLevel(player.getWorldLevel())
|
||||
.setEnterReason(EnterReason.Login.getValue())
|
||||
.setIsFirstLoginEnterScene(player.isFirstLoginEnterScene())
|
||||
.setWorldType(1)
|
||||
.setSceneTransaction("3-" + player.getUid() + "-" + (int) (System.currentTimeMillis() / 1000) + "-" + 18402)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketPlayerEnterSceneNotify(Player player, EnterType type, EnterReason reason, int newScene, Position newPos) {
|
||||
this(player, player, type, reason, newScene, newPos);
|
||||
}
|
||||
|
||||
// Teleport or go somewhere
|
||||
public PacketPlayerEnterSceneNotify(Player player, Player target, EnterType type, EnterReason reason, int newScene, Position newPos) {
|
||||
super(PacketOpcodes.PlayerEnterSceneNotify);
|
||||
|
||||
player.setSceneLoadState(SceneLoadState.LOADING);
|
||||
player.setEnterSceneToken(Utils.randomRange(1000, 99999));
|
||||
// Login
|
||||
public PacketPlayerEnterSceneNotify(Player player) {
|
||||
super(PacketOpcodes.PlayerEnterSceneNotify);
|
||||
|
||||
PlayerEnterSceneNotify.Builder proto = PlayerEnterSceneNotify.newBuilder()
|
||||
.setPrevSceneId(player.getSceneId())
|
||||
.setPrevPos(player.getPosition().toProto())
|
||||
.setSceneId(newScene)
|
||||
.setPos(newPos.toProto())
|
||||
.setSceneBeginTime(System.currentTimeMillis())
|
||||
.setType(type)
|
||||
.setTargetUid(target.getUid())
|
||||
.setEnterSceneToken(player.getEnterSceneToken())
|
||||
.setWorldLevel(target.getWorld().getWorldLevel())
|
||||
.setEnterReason(reason.getValue())
|
||||
.setWorldType(1)
|
||||
.setSceneTransaction(newScene + "-" + target.getUid() + "-" + (int) (System.currentTimeMillis() / 1000) + "-" + 18402);
|
||||
player.setSceneLoadState(SceneLoadState.LOADING);
|
||||
player.setEnterSceneToken(Utils.randomRange(1000, 99999));
|
||||
|
||||
for(int i = 0; i < 3000; i++) {
|
||||
proto.addSceneTagIdList(i);
|
||||
}
|
||||
PlayerEnterSceneNotify proto = PlayerEnterSceneNotify.newBuilder()
|
||||
.setSceneId(player.getSceneId())
|
||||
.setPos(player.getPosition().toProto())
|
||||
.setSceneBeginTime(System.currentTimeMillis())
|
||||
.setType(EnterType.ENTER_TYPE_SELF)
|
||||
.setTargetUid(player.getUid())
|
||||
.setEnterSceneToken(player.getEnterSceneToken())
|
||||
.setWorldLevel(player.getWorldLevel())
|
||||
.setEnterReason(EnterReason.Login.getValue())
|
||||
.setIsFirstLoginEnterScene(player.isFirstLoginEnterScene())
|
||||
.setWorldType(1)
|
||||
.setSceneTransaction("3-" + player.getUid() + "-" + (int) (System.currentTimeMillis() / 1000) + "-" + 18402)
|
||||
.build();
|
||||
|
||||
this.setData(proto.build());
|
||||
}
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketPlayerEnterSceneNotify(Player player, EnterType type, EnterReason reason, int newScene, Position newPos) {
|
||||
this(player, player, type, reason, newScene, newPos);
|
||||
}
|
||||
|
||||
// Teleport or go somewhere
|
||||
public PacketPlayerEnterSceneNotify(Player player, Player target, EnterType type, EnterReason reason, int newScene, Position newPos) {
|
||||
super(PacketOpcodes.PlayerEnterSceneNotify);
|
||||
|
||||
player.setSceneLoadState(SceneLoadState.LOADING);
|
||||
player.setEnterSceneToken(Utils.randomRange(1000, 99999));
|
||||
|
||||
PlayerEnterSceneNotify.Builder proto = PlayerEnterSceneNotify.newBuilder()
|
||||
.setPrevSceneId(player.getSceneId())
|
||||
.setPrevPos(player.getPosition().toProto())
|
||||
.setSceneId(newScene)
|
||||
.setPos(newPos.toProto())
|
||||
.setSceneBeginTime(System.currentTimeMillis())
|
||||
.setType(type)
|
||||
.setTargetUid(target.getUid())
|
||||
.setEnterSceneToken(player.getEnterSceneToken())
|
||||
.setWorldLevel(target.getWorld().getWorldLevel())
|
||||
.setEnterReason(reason.getValue())
|
||||
.setWorldType(1)
|
||||
.setSceneTransaction(newScene + "-" + target.getUid() + "-" + (int) (System.currentTimeMillis() / 1000) + "-" + 18402);
|
||||
|
||||
for (int i = 0; i < 3000; i++) {
|
||||
proto.addSceneTagIdList(i);
|
||||
}
|
||||
|
||||
this.setData(proto.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -21,53 +21,53 @@ import java.util.Objects;
|
||||
|
||||
public class PacketPlayerLoginRsp extends BasePacket {
|
||||
|
||||
private static QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp regionCache;
|
||||
private static QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp regionCache;
|
||||
|
||||
public PacketPlayerLoginRsp(GameSession session) {
|
||||
super(PacketOpcodes.PlayerLoginRsp, 1);
|
||||
|
||||
this.setUseDispatchKey(true);
|
||||
public PacketPlayerLoginRsp(GameSession session) {
|
||||
super(PacketOpcodes.PlayerLoginRsp, 1);
|
||||
|
||||
RegionInfo info;
|
||||
this.setUseDispatchKey(true);
|
||||
|
||||
if (SERVER.runMode == ServerRunMode.GAME_ONLY) {
|
||||
if (regionCache == null) {
|
||||
try {
|
||||
// todo: we might want to push custom config to client
|
||||
RegionInfo serverRegion = RegionInfo.newBuilder()
|
||||
.setGateserverIp(lr(GAME_INFO.accessAddress, GAME_INFO.bindAddress))
|
||||
.setGateserverPort(lr(GAME_INFO.accessPort, GAME_INFO.bindPort))
|
||||
.setSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
||||
.build();
|
||||
RegionInfo info;
|
||||
|
||||
regionCache = QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp.newBuilder().setRegionInfo(serverRegion).build();
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Error while initializing region cache!", e);
|
||||
}
|
||||
}
|
||||
if (SERVER.runMode == ServerRunMode.GAME_ONLY) {
|
||||
if (regionCache == null) {
|
||||
try {
|
||||
// todo: we might want to push custom config to client
|
||||
RegionInfo serverRegion = RegionInfo.newBuilder()
|
||||
.setGateserverIp(lr(GAME_INFO.accessAddress, GAME_INFO.bindAddress))
|
||||
.setGateserverPort(lr(GAME_INFO.accessPort, GAME_INFO.bindPort))
|
||||
.setSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
|
||||
.build();
|
||||
|
||||
info = regionCache.getRegionInfo();
|
||||
} else {
|
||||
info = Objects.requireNonNull(RegionHandler.getCurrentRegion()).getRegionInfo();
|
||||
}
|
||||
regionCache = QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp.newBuilder().setRegionInfo(serverRegion).build();
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Error while initializing region cache!", e);
|
||||
}
|
||||
}
|
||||
|
||||
PlayerLoginRsp p = PlayerLoginRsp.newBuilder()
|
||||
.setIsUseAbilityHash(true) // true
|
||||
.setAbilityHashCode(1844674) // 1844674
|
||||
.setGameBiz("hk4e_global")
|
||||
.setClientDataVersion(info.getClientDataVersion())
|
||||
.setClientSilenceDataVersion(info.getClientSilenceDataVersion())
|
||||
.setClientMd5(info.getClientDataMd5())
|
||||
.setClientSilenceMd5(info.getClientSilenceDataMd5())
|
||||
.setResVersionConfig(info.getResVersionConfig())
|
||||
.setClientVersionSuffix(info.getClientVersionSuffix())
|
||||
.setClientSilenceVersionSuffix(info.getClientSilenceVersionSuffix())
|
||||
.setIsScOpen(false)
|
||||
//.setScInfo(ByteString.copyFrom(new byte[] {}))
|
||||
.setRegisterCps("mihoyo")
|
||||
.setCountryCode("US")
|
||||
.build();
|
||||
|
||||
this.setData(p.toByteArray());
|
||||
}
|
||||
info = regionCache.getRegionInfo();
|
||||
} else {
|
||||
info = Objects.requireNonNull(RegionHandler.getCurrentRegion()).getRegionInfo();
|
||||
}
|
||||
|
||||
PlayerLoginRsp p = PlayerLoginRsp.newBuilder()
|
||||
.setIsUseAbilityHash(true) // true
|
||||
.setAbilityHashCode(1844674) // 1844674
|
||||
.setGameBiz("hk4e_global")
|
||||
.setClientDataVersion(info.getClientDataVersion())
|
||||
.setClientSilenceDataVersion(info.getClientSilenceDataVersion())
|
||||
.setClientMd5(info.getClientDataMd5())
|
||||
.setClientSilenceMd5(info.getClientSilenceDataMd5())
|
||||
.setResVersionConfig(info.getResVersionConfig())
|
||||
.setClientVersionSuffix(info.getClientVersionSuffix())
|
||||
.setClientSilenceVersionSuffix(info.getClientSilenceVersionSuffix())
|
||||
.setIsScOpen(false)
|
||||
//.setScInfo(ByteString.copyFrom(new byte[] {}))
|
||||
.setRegisterCps("mihoyo")
|
||||
.setCountryCode("US")
|
||||
.build();
|
||||
|
||||
this.setData(p.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,21 +11,21 @@ import emu.grasscutter.net.proto.PlayerStoreNotifyOuterClass.PlayerStoreNotify;
|
||||
import emu.grasscutter.net.proto.StoreTypeOuterClass.StoreType;
|
||||
|
||||
public class PacketPlayerStoreNotify extends BasePacket {
|
||||
|
||||
public PacketPlayerStoreNotify(Player player) {
|
||||
super(PacketOpcodes.PlayerStoreNotify);
|
||||
|
||||
this.buildHeader(2);
|
||||
|
||||
PlayerStoreNotify.Builder p = PlayerStoreNotify.newBuilder()
|
||||
.setStoreType(StoreType.STORE_TYPE_PACK)
|
||||
.setWeightLimit(GAME_OPTIONS.inventoryLimits.all);
|
||||
|
||||
for (GameItem item : player.getInventory()) {
|
||||
Item itemProto = item.toProto();
|
||||
p.addItemList(itemProto);
|
||||
}
|
||||
|
||||
this.setData(p.build());
|
||||
}
|
||||
|
||||
public PacketPlayerStoreNotify(Player player) {
|
||||
super(PacketOpcodes.PlayerStoreNotify);
|
||||
|
||||
this.buildHeader(2);
|
||||
|
||||
PlayerStoreNotify.Builder p = PlayerStoreNotify.newBuilder()
|
||||
.setStoreType(StoreType.STORE_TYPE_PACK)
|
||||
.setWeightLimit(GAME_OPTIONS.inventoryLimits.all);
|
||||
|
||||
for (GameItem item : player.getInventory()) {
|
||||
Item itemProto = item.toProto();
|
||||
p.addItemList(itemProto);
|
||||
}
|
||||
|
||||
this.setData(p.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,64 +9,64 @@ import emu.grasscutter.net.proto.SceneUnlockInfoOuterClass.SceneUnlockInfo;
|
||||
import static emu.grasscutter.net.proto.PlayerWorldSceneInfoOuterClass.*;
|
||||
|
||||
public class PacketPlayerWorldSceneInfoListNotify extends BasePacket {
|
||||
|
||||
public PacketPlayerWorldSceneInfoListNotify() {
|
||||
super(PacketOpcodes.PlayerWorldSceneInfoListNotify); // Rename opcode later
|
||||
|
||||
PlayerWorldSceneInfoListNotify.Builder proto = PlayerWorldSceneInfoListNotify.newBuilder()
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(1)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(3)
|
||||
.setIsLocked(false)
|
||||
.addSceneTagIdList(102)
|
||||
.addSceneTagIdList(113)
|
||||
.addSceneTagIdList(117)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(4)
|
||||
.setIsLocked(false)
|
||||
.addSceneTagIdList(106)
|
||||
.addSceneTagIdList(109)
|
||||
.addSceneTagIdList(117)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(5)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(6)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(7)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
);
|
||||
public PacketPlayerWorldSceneInfoListNotify() {
|
||||
super(PacketOpcodes.PlayerWorldSceneInfoListNotify); // Rename opcode later
|
||||
|
||||
var gaa = PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(9)
|
||||
.setIsLocked(false);
|
||||
PlayerWorldSceneInfoListNotify.Builder proto = PlayerWorldSceneInfoListNotify.newBuilder()
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(1)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(3)
|
||||
.setIsLocked(false)
|
||||
.addSceneTagIdList(102)
|
||||
.addSceneTagIdList(113)
|
||||
.addSceneTagIdList(117)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(4)
|
||||
.setIsLocked(false)
|
||||
.addSceneTagIdList(106)
|
||||
.addSceneTagIdList(109)
|
||||
.addSceneTagIdList(117)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(5)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(6)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
)
|
||||
.addInfoList(
|
||||
PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(7)
|
||||
.setIsLocked(false)
|
||||
.build()
|
||||
);
|
||||
|
||||
for(int i = 0; i < 3000; i++) {
|
||||
gaa.addSceneTagIdList(i);
|
||||
}
|
||||
var gaa = PlayerWorldSceneInfo.newBuilder()
|
||||
.setSceneId(9)
|
||||
.setIsLocked(false);
|
||||
|
||||
proto.addInfoList(gaa);
|
||||
for (int i = 0; i < 3000; i++) {
|
||||
gaa.addSceneTagIdList(i);
|
||||
}
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
proto.addInfoList(gaa);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,45 +6,45 @@ import emu.grasscutter.net.proto.ChatInfoOuterClass.ChatInfo;
|
||||
import emu.grasscutter.net.proto.PrivateChatNotifyOuterClass.PrivateChatNotify;
|
||||
|
||||
public class PacketPrivateChatNotify extends BasePacket {
|
||||
private ChatInfo info;
|
||||
private ChatInfo info;
|
||||
|
||||
public PacketPrivateChatNotify(int senderId, int recvId, String message) {
|
||||
super(PacketOpcodes.PrivateChatNotify);
|
||||
|
||||
ChatInfo info = ChatInfo.newBuilder()
|
||||
.setTime((int) (System.currentTimeMillis() / 1000))
|
||||
.setUid(senderId)
|
||||
.setToUid(recvId)
|
||||
.setText(message)
|
||||
.build();
|
||||
this.info = info;
|
||||
public PacketPrivateChatNotify(int senderId, int recvId, String message) {
|
||||
super(PacketOpcodes.PrivateChatNotify);
|
||||
|
||||
PrivateChatNotify proto = PrivateChatNotify.newBuilder()
|
||||
.setChatInfo(info)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketPrivateChatNotify(int senderId, int recvId, int emote) {
|
||||
super(PacketOpcodes.PrivateChatNotify);
|
||||
|
||||
ChatInfo info = ChatInfo.newBuilder()
|
||||
.setTime((int) (System.currentTimeMillis() / 1000))
|
||||
.setUid(senderId)
|
||||
.setToUid(recvId)
|
||||
.setIcon(emote)
|
||||
.build();
|
||||
this.info = info;
|
||||
|
||||
PrivateChatNotify proto = PrivateChatNotify.newBuilder()
|
||||
.setChatInfo(info)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
ChatInfo info = ChatInfo.newBuilder()
|
||||
.setTime((int) (System.currentTimeMillis() / 1000))
|
||||
.setUid(senderId)
|
||||
.setToUid(recvId)
|
||||
.setText(message)
|
||||
.build();
|
||||
this.info = info;
|
||||
|
||||
public ChatInfo getChatInfo() {
|
||||
return this.info;
|
||||
}
|
||||
PrivateChatNotify proto = PrivateChatNotify.newBuilder()
|
||||
.setChatInfo(info)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public PacketPrivateChatNotify(int senderId, int recvId, int emote) {
|
||||
super(PacketOpcodes.PrivateChatNotify);
|
||||
|
||||
ChatInfo info = ChatInfo.newBuilder()
|
||||
.setTime((int) (System.currentTimeMillis() / 1000))
|
||||
.setUid(senderId)
|
||||
.setToUid(recvId)
|
||||
.setIcon(emote)
|
||||
.build();
|
||||
this.info = info;
|
||||
|
||||
PrivateChatNotify proto = PrivateChatNotify.newBuilder()
|
||||
.setChatInfo(info)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
public ChatInfo getChatInfo() {
|
||||
return this.info;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,21 +9,21 @@ import emu.grasscutter.net.proto.PullPrivateChatRspOuterClass.PullPrivateChatRsp
|
||||
import emu.grasscutter.net.proto.RetcodeOuterClass.Retcode;
|
||||
|
||||
public class PacketPullPrivateChatRsp extends BasePacket {
|
||||
|
||||
public PacketPullPrivateChatRsp(List<ChatInfo> history) {
|
||||
super(PacketOpcodes.PullPrivateChatRsp);
|
||||
|
||||
PullPrivateChatRsp.Builder builder = PullPrivateChatRsp.newBuilder();
|
||||
public PacketPullPrivateChatRsp(List<ChatInfo> history) {
|
||||
super(PacketOpcodes.PullPrivateChatRsp);
|
||||
|
||||
if (history == null) {
|
||||
builder.setRetcode(Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
else {
|
||||
for (var info : history) {
|
||||
builder.addChatInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
this.setData(builder.build());
|
||||
}
|
||||
PullPrivateChatRsp.Builder builder = PullPrivateChatRsp.newBuilder();
|
||||
|
||||
if (history == null) {
|
||||
builder.setRetcode(Retcode.RET_FAIL_VALUE);
|
||||
}
|
||||
else {
|
||||
for (var info : history) {
|
||||
builder.addChatInfo(info);
|
||||
}
|
||||
}
|
||||
|
||||
this.setData(builder.build());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,12 +13,12 @@ import static emu.grasscutter.config.Configuration.*;
|
||||
import java.util.List;
|
||||
|
||||
public class PacketPullRecentChatRsp extends BasePacket {
|
||||
public PacketPullRecentChatRsp(List<ChatInfo> messages) {
|
||||
super(PacketOpcodes.PullRecentChatRsp);
|
||||
|
||||
PullRecentChatRsp.Builder proto = PullRecentChatRsp.newBuilder()
|
||||
.addAllChatInfo(messages);
|
||||
public PacketPullRecentChatRsp(List<ChatInfo> messages) {
|
||||
super(PacketOpcodes.PullRecentChatRsp);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
PullRecentChatRsp.Builder proto = PullRecentChatRsp.newBuilder()
|
||||
.addAllChatInfo(messages);
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -15,4 +15,4 @@ public class PacketSetOpenStateRsp extends BasePacket {
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,19 +8,19 @@ import emu.grasscutter.net.proto.StoreTypeOuterClass.StoreType;
|
||||
import emu.grasscutter.net.proto.StoreWeightLimitNotifyOuterClass.StoreWeightLimitNotify;
|
||||
|
||||
public class PacketStoreWeightLimitNotify extends BasePacket {
|
||||
|
||||
public PacketStoreWeightLimitNotify() {
|
||||
super(PacketOpcodes.StoreWeightLimitNotify);
|
||||
|
||||
StoreWeightLimitNotify p = StoreWeightLimitNotify.newBuilder()
|
||||
.setStoreType(StoreType.STORE_TYPE_PACK)
|
||||
.setWeightLimit(INVENTORY_LIMITS.all)
|
||||
.setWeaponCountLimit(INVENTORY_LIMITS.weapons)
|
||||
.setReliquaryCountLimit(INVENTORY_LIMITS.relics)
|
||||
.setMaterialCountLimit(INVENTORY_LIMITS.materials)
|
||||
.setFurnitureCountLimit(INVENTORY_LIMITS.furniture)
|
||||
.build();
|
||||
|
||||
this.setData(p);
|
||||
}
|
||||
public PacketStoreWeightLimitNotify() {
|
||||
super(PacketOpcodes.StoreWeightLimitNotify);
|
||||
|
||||
StoreWeightLimitNotify p = StoreWeightLimitNotify.newBuilder()
|
||||
.setStoreType(StoreType.STORE_TYPE_PACK)
|
||||
.setWeightLimit(INVENTORY_LIMITS.all)
|
||||
.setWeaponCountLimit(INVENTORY_LIMITS.weapons)
|
||||
.setReliquaryCountLimit(INVENTORY_LIMITS.relics)
|
||||
.setMaterialCountLimit(INVENTORY_LIMITS.materials)
|
||||
.setFurnitureCountLimit(INVENTORY_LIMITS.furniture)
|
||||
.build();
|
||||
|
||||
this.setData(p);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,49 +16,49 @@ import java.util.stream.Collectors;
|
||||
import java.util.stream.IntStream;
|
||||
|
||||
public class PacketTowerAllDataRsp extends BasePacket {
|
||||
|
||||
public PacketTowerAllDataRsp(TowerSystem towerScheduleManager, TowerManager towerManager) {
|
||||
super(PacketOpcodes.TowerAllDataRsp);
|
||||
|
||||
var recordList = towerManager.getRecordMap().values().stream()
|
||||
.map(rec -> TowerFloorRecord.newBuilder()
|
||||
.setFloorId(rec.getFloorId())
|
||||
.setFloorStarRewardProgress(rec.getFloorStarRewardProgress())
|
||||
.putAllPassedLevelMap(rec.getPassedLevelMap())
|
||||
.addAllPassedLevelRecordList(buildFromPassedLevelMap(rec.getPassedLevelMap()))
|
||||
.build()
|
||||
)
|
||||
.toList();
|
||||
public PacketTowerAllDataRsp(TowerSystem towerScheduleManager, TowerManager towerManager) {
|
||||
super(PacketOpcodes.TowerAllDataRsp);
|
||||
|
||||
var openTimeMap = towerScheduleManager.getScheduleFloors().stream()
|
||||
.collect(Collectors.toMap(x -> x,
|
||||
y -> DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
|
||||
.getScheduleStartTime()))
|
||||
);
|
||||
var recordList = towerManager.getRecordMap().values().stream()
|
||||
.map(rec -> TowerFloorRecord.newBuilder()
|
||||
.setFloorId(rec.getFloorId())
|
||||
.setFloorStarRewardProgress(rec.getFloorStarRewardProgress())
|
||||
.putAllPassedLevelMap(rec.getPassedLevelMap())
|
||||
.addAllPassedLevelRecordList(buildFromPassedLevelMap(rec.getPassedLevelMap()))
|
||||
.build()
|
||||
)
|
||||
.toList();
|
||||
|
||||
TowerAllDataRsp proto = TowerAllDataRsp.newBuilder()
|
||||
.setTowerScheduleId(towerScheduleManager.getCurrentTowerScheduleData().getScheduleId())
|
||||
.addAllTowerFloorRecordList(recordList)
|
||||
.setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true))
|
||||
.setScheduleStartTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
|
||||
.getScheduleStartTime()))
|
||||
.setNextScheduleChangeTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
|
||||
.getNextScheduleChangeTime()))
|
||||
.putAllFloorOpenTimeMap(openTimeMap)
|
||||
.setIsFinishedEntranceFloor(towerManager.canEnterScheduleFloor())
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
var openTimeMap = towerScheduleManager.getScheduleFloors().stream()
|
||||
.collect(Collectors.toMap(x -> x,
|
||||
y -> DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
|
||||
.getScheduleStartTime()))
|
||||
);
|
||||
|
||||
private List<TowerLevelRecordOuterClass.TowerLevelRecord> buildFromPassedLevelMap(Map<Integer, Integer> map){
|
||||
return map.entrySet().stream()
|
||||
.map(item -> TowerLevelRecordOuterClass.TowerLevelRecord.newBuilder()
|
||||
.setLevelId(item.getKey())
|
||||
.addAllSatisfiedCondList(IntStream.range(1, item.getValue() + 1).boxed().toList())
|
||||
.build())
|
||||
.toList();
|
||||
TowerAllDataRsp proto = TowerAllDataRsp.newBuilder()
|
||||
.setTowerScheduleId(towerScheduleManager.getCurrentTowerScheduleData().getScheduleId())
|
||||
.addAllTowerFloorRecordList(recordList)
|
||||
.setCurLevelRecord(TowerCurLevelRecord.newBuilder().setIsEmpty(true))
|
||||
.setScheduleStartTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
|
||||
.getScheduleStartTime()))
|
||||
.setNextScheduleChangeTime(DateHelper.getUnixTime(towerScheduleManager.getTowerScheduleConfig()
|
||||
.getNextScheduleChangeTime()))
|
||||
.putAllFloorOpenTimeMap(openTimeMap)
|
||||
.setIsFinishedEntranceFloor(towerManager.canEnterScheduleFloor())
|
||||
.build();
|
||||
|
||||
}
|
||||
this.setData(proto);
|
||||
}
|
||||
|
||||
private List<TowerLevelRecordOuterClass.TowerLevelRecord> buildFromPassedLevelMap(Map<Integer, Integer> map) {
|
||||
return map.entrySet().stream()
|
||||
.map(item -> TowerLevelRecordOuterClass.TowerLevelRecord.newBuilder()
|
||||
.setLevelId(item.getKey())
|
||||
.addAllSatisfiedCondList(IntStream.range(1, item.getValue() + 1).boxed().toList())
|
||||
.build())
|
||||
.toList();
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user