mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-12-19 10:24:47 +01:00
Merge remote-tracking branch 'origin/development' into development
This commit is contained in:
@@ -4,6 +4,7 @@ import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
import express.http.HttpContextHandler;
|
||||
import express.http.Request;
|
||||
import express.http.Response;
|
||||
@@ -30,8 +31,8 @@ public final class DispatchHttpJsonHandler implements HttpContextHandler {
|
||||
@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(Grasscutter.getConfig().DebugMode.equalsIgnoreCase("MISSING") && Arrays.stream(missingRoutes).anyMatch(x -> x == req.baseUrl())) {
|
||||
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s %s request: ", req.ip(), req.method(), req.baseUrl()) + (Grasscutter.getConfig().DebugMode.equalsIgnoreCase("MISSING") ? "(MISSING)" : ""));
|
||||
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING && Arrays.stream(missingRoutes).anyMatch(x -> x == req.baseUrl())) {
|
||||
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s %s request: ", req.ip(), req.method(), req.baseUrl()) + (Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING ? "(MISSING)" : ""));
|
||||
}
|
||||
res.send(response);
|
||||
}
|
||||
|
||||
@@ -6,6 +6,8 @@ import com.google.protobuf.ByteString;
|
||||
|
||||
import emu.grasscutter.Config;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
import emu.grasscutter.Grasscutter.ServerRunMode;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.net.proto.QueryCurrRegionHttpRspOuterClass.QueryCurrRegionHttpRsp;
|
||||
@@ -62,7 +64,7 @@ public final class DispatchServer {
|
||||
|
||||
public QueryCurrRegionHttpRsp getCurrRegion() {
|
||||
// Needs to be fixed by having the game servers connect to the dispatch server.
|
||||
if (Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) {
|
||||
if (Grasscutter.getConfig().RunMode == ServerRunMode.HYBRID) {
|
||||
return regions.get(defaultServerName).parsedRegionQuery;
|
||||
}
|
||||
|
||||
@@ -98,7 +100,7 @@ public final class DispatchServer {
|
||||
|
||||
List<RegionSimpleInfo> servers = new ArrayList<>();
|
||||
List<String> usedNames = new ArrayList<>(); // List to check for potential naming conflicts
|
||||
if (Grasscutter.getConfig().RunMode.equalsIgnoreCase("HYBRID")) { // Automatically add the game server if in
|
||||
if (Grasscutter.getConfig().RunMode == ServerRunMode.HYBRID) { // Automatically add the game server if in
|
||||
// hybrid mode
|
||||
RegionSimpleInfo server = RegionSimpleInfo.newBuilder()
|
||||
.setName("os_usa")
|
||||
@@ -233,7 +235,7 @@ public final class DispatchServer {
|
||||
});
|
||||
|
||||
config.enforceSsl = Grasscutter.getConfig().getDispatchOptions().UseSSL;
|
||||
if(Grasscutter.getConfig().DebugMode.equalsIgnoreCase("ALL")) {
|
||||
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.ALL) {
|
||||
config.enableDevLogging();
|
||||
}
|
||||
});
|
||||
@@ -241,7 +243,7 @@ public final class DispatchServer {
|
||||
httpServer.get("/", (req, res) -> res.send("Welcome to Grasscutter"));
|
||||
|
||||
httpServer.raw().error(404, ctx -> {
|
||||
if(Grasscutter.getConfig().DebugMode.equalsIgnoreCase("MISSING")) {
|
||||
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING) {
|
||||
Grasscutter.getLogger().info(String.format("[Dispatch] Potential unhandled %s request: %s", ctx.method(), ctx.url()));
|
||||
}
|
||||
ctx.contentType("text/html");
|
||||
@@ -317,6 +319,9 @@ public final class DispatchServer {
|
||||
responseData.data.account.uid = account.getId();
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
responseData.data.account.email = account.getEmail();
|
||||
if (responseData.data.account.email == null) {
|
||||
responseData.data.account.email = "";
|
||||
}
|
||||
|
||||
Grasscutter.getLogger()
|
||||
.info(String.format("[Dispatch] Client %s failed to log in: Account %s created",
|
||||
@@ -341,6 +346,9 @@ public final class DispatchServer {
|
||||
responseData.data.account.uid = account.getId();
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
responseData.data.account.email = account.getEmail();
|
||||
if (responseData.data.account.email == null) {
|
||||
responseData.data.account.email = "";
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in as %s", req.ip(),
|
||||
responseData.data.account.uid));
|
||||
@@ -381,6 +389,9 @@ public final class DispatchServer {
|
||||
responseData.data.account.uid = requestData.uid;
|
||||
responseData.data.account.token = requestData.token;
|
||||
responseData.data.account.email = account.getEmail();
|
||||
if (responseData.data.account.email == null) { // null will trigger crash in some client
|
||||
responseData.data.account.email = "";
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s logged in via token as %s",
|
||||
req.ip(), responseData.data.account.uid));
|
||||
@@ -437,7 +448,8 @@ public final class DispatchServer {
|
||||
// hk4e-sdk-os.hoyoverse.com
|
||||
httpServer.get("/hk4e_global/mdk/agreement/api/getAgreementInfos", new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"marketing_agreements\":[]}}"));
|
||||
// hk4e-sdk-os.hoyoverse.com
|
||||
httpServer.post("/hk4e_global/combo/granter/api/compareProtocolVersion", new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"modified\":true,\"protocol\":{\"id\":0,\"app_id\":4,\"language\":\"en\",\"user_proto\":\"\",\"priv_proto\":\"\",\"major\":7,\"minimum\":0,\"create_time\":\"0\",\"teenager_proto\":\"\",\"third_proto\":\"\"}}}"));
|
||||
// this could be either GET or POST based on the observation of different clients
|
||||
httpServer.all("/hk4e_global/combo/granter/api/compareProtocolVersion", new DispatchHttpJsonHandler("{\"retcode\":0,\"message\":\"OK\",\"data\":{\"modified\":true,\"protocol\":{\"id\":0,\"app_id\":4,\"language\":\"en\",\"user_proto\":\"\",\"priv_proto\":\"\",\"major\":7,\"minimum\":0,\"create_time\":\"0\",\"teenager_proto\":\"\",\"third_proto\":\"\"}}}"));
|
||||
|
||||
// Game data
|
||||
// hk4e-api-os.hoyoverse.com
|
||||
@@ -479,6 +491,9 @@ public final class DispatchServer {
|
||||
// log-upload-os.mihoyo.com
|
||||
httpServer.all("/crash/dataUpload", new ClientLogHandler());
|
||||
|
||||
// webstatic-sea.hoyoverse.com
|
||||
httpServer.get("/admin/mi18n/plat_oversea/m202003048/m202003048-version.json", new DispatchHttpJsonHandler("{\"version\":51}"));
|
||||
|
||||
httpServer.get("/gacha", (req, res) -> res.send("<!doctype html><html lang=\"en\"><head><title>Gacha</title></head><body></body></html>"));
|
||||
|
||||
httpServer.listen(Grasscutter.getConfig().getDispatchOptions().Port);
|
||||
|
||||
@@ -6,6 +6,7 @@ import emu.grasscutter.server.event.game.ReceivePacketEvent;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
@@ -88,7 +89,7 @@ public class GameServerPacketHandler {
|
||||
}
|
||||
|
||||
// Log unhandled packets
|
||||
if (Grasscutter.getConfig().DebugMode.equalsIgnoreCase("MISSING")) {
|
||||
if (Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING) {
|
||||
Grasscutter.getLogger().info("Unhandled packet (" + opcode + "): " + emu.grasscutter.net.packet.PacketOpcodesUtil.getOpcodeName(opcode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -7,6 +7,7 @@ import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
@@ -163,7 +164,7 @@ public class GameSession extends KcpChannel {
|
||||
}
|
||||
|
||||
// Log
|
||||
if (Grasscutter.getConfig().DebugMode.equalsIgnoreCase("ALL")) {
|
||||
if (Grasscutter.getConfig().DebugMode == ServerDebugMode.ALL) {
|
||||
logPacket(packet);
|
||||
}
|
||||
|
||||
@@ -230,7 +231,7 @@ public class GameSession extends KcpChannel {
|
||||
}
|
||||
|
||||
// Log packet
|
||||
if (Grasscutter.getConfig().DebugMode.equalsIgnoreCase("ALL")) {
|
||||
if (Grasscutter.getConfig().DebugMode == ServerDebugMode.ALL) {
|
||||
if (!loopPacket.contains(opcode)) {
|
||||
Grasscutter.getLogger().info("RECV: " + PacketOpcodesUtil.getOpcodeName(opcode) + " (" + opcode + ")");
|
||||
System.out.println(Utils.bytesToHex(payload));
|
||||
|
||||
@@ -0,0 +1,27 @@
|
||||
package emu.grasscutter.server.packet.recv;
|
||||
|
||||
import emu.grasscutter.net.packet.Opcodes;
|
||||
import emu.grasscutter.net.packet.PacketHandler;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.McoinExchangeHcoinReqOuterClass;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
import emu.grasscutter.server.packet.send.PacketMcoinExchangeHcoinRsp;
|
||||
|
||||
@Opcodes(PacketOpcodes.McoinExchangeHcoinReq)
|
||||
public class HandlerMcoinExchangeHcoinReq extends PacketHandler {
|
||||
|
||||
@Override
|
||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||
McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq exchangeReq = McoinExchangeHcoinReqOuterClass.McoinExchangeHcoinReq.parseFrom(payload);
|
||||
|
||||
if (session.getPlayer().getCrystals() < exchangeReq.getMCoinNum() && exchangeReq.getMCoinNum() == exchangeReq.getHCoinNum()) {
|
||||
return;
|
||||
}
|
||||
|
||||
session.getPlayer().setCrystals(session.getPlayer().getCrystals() - exchangeReq.getMCoinNum());
|
||||
session.getPlayer().setPrimogems(session.getPlayer().getPrimogems() + exchangeReq.getHCoinNum());
|
||||
session.getPlayer().save();
|
||||
|
||||
session.send(new PacketMcoinExchangeHcoinRsp(session.getPlayer().getCrystals(), session.getPlayer().getPrimogems()));
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.AvatarSkillMaxChargeCountNotifyOuterClass.AvatarSkillMaxChargeCountNotify;
|
||||
|
||||
public class PacketAvatarSkillMaxChargeCountNotify extends BasePacket {
|
||||
|
||||
public PacketAvatarSkillMaxChargeCountNotify(Avatar avatar, int skillId, int maxCharges) {
|
||||
super(PacketOpcodes.AvatarSkillMaxChargeCountNotify);
|
||||
|
||||
AvatarSkillMaxChargeCountNotify proto = AvatarSkillMaxChargeCountNotify.newBuilder()
|
||||
.setAvatarGuid(avatar.getGuid())
|
||||
.setSkillId(skillId)
|
||||
.setMaxChargeCount(maxCharges)
|
||||
.build();
|
||||
|
||||
this.setData(proto);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
package emu.grasscutter.server.packet.send;
|
||||
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.McoinExchangeHcoinRspOuterClass;
|
||||
|
||||
public class PacketMcoinExchangeHcoinRsp extends BasePacket {
|
||||
|
||||
public PacketMcoinExchangeHcoinRsp(int mcoin, int hcoin) {
|
||||
super(PacketOpcodes.McoinExchangeHcoinRsp);
|
||||
|
||||
McoinExchangeHcoinRspOuterClass.McoinExchangeHcoinRsp mcoinExchangeHcoinRsp = McoinExchangeHcoinRspOuterClass.McoinExchangeHcoinRsp.newBuilder()
|
||||
.setMCoinNum(mcoin)
|
||||
.setHCoinNum(hcoin).build();
|
||||
|
||||
this.setData(mcoinExchangeHcoinRsp);
|
||||
}
|
||||
}
|
||||
@@ -2,6 +2,8 @@ package emu.grasscutter.server.packet.send;
|
||||
|
||||
import com.google.protobuf.ByteString;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
import emu.grasscutter.Grasscutter.ServerRunMode;
|
||||
import emu.grasscutter.net.packet.BasePacket;
|
||||
import emu.grasscutter.net.packet.PacketOpcodes;
|
||||
import emu.grasscutter.net.proto.PlayerLoginRspOuterClass.PlayerLoginRsp;
|
||||
@@ -25,7 +27,7 @@ public class PacketPlayerLoginRsp extends BasePacket {
|
||||
|
||||
RegionInfo info;
|
||||
|
||||
if(Grasscutter.getConfig().RunMode.equalsIgnoreCase("GAME_ONLY")) {
|
||||
if (Grasscutter.getConfig().RunMode == ServerRunMode.GAME_ONLY) {
|
||||
if (regionCache == null) {
|
||||
try {
|
||||
File file = new File(Grasscutter.getConfig().DATA_FOLDER + "query_cur_region.txt");
|
||||
|
||||
Reference in New Issue
Block a user