Add support for the Chinese client (#2076)

* Add CNREL support

* Improve logic

* Maintain spacing

* Remove language keys & switch to debug

* Improve Format
This commit is contained in:
rwx9032 2023-03-12 13:51:21 +08:00 committed by GitHub
parent fd60e66182
commit fdaa487b2a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 7 deletions

1
gradlew-clean.bat Normal file
View File

@ -0,0 +1 @@
./gradlew clean

View File

@ -17,6 +17,7 @@ import static emu.grasscutter.utils.Language.translate;
*/
public final class DispatchHandler implements Router {
@Override public void applyRoutes(Javalin javalin) {
// OS
// Username & Password login (from client).
javalin.post("/hk4e_global/mdk/shield/api/login", DispatchHandler::clientLogin);
// Cached token login (from registry).
@ -24,6 +25,14 @@ public final class DispatchHandler implements Router {
// Combo token login (from session key).
javalin.post("/hk4e_global/combo/granter/login/v2/login", DispatchHandler::sessionKeyLogin);
// CN
// Username & Password login (from client).
javalin.post("/hk4e_cn/mdk/shield/api/login", DispatchHandler::clientLogin);
// Cached token login (from registry).
javalin.post("/hk4e_cn/mdk/shield/api/verify", DispatchHandler::tokenLogin);
// Combo token login (from session key).
javalin.post("/hk4e_cn/combo/granter/login/v2/login", DispatchHandler::sessionKeyLogin);
// External login (from other clients).
javalin.get("/authentication/type", ctx -> ctx.result(Grasscutter.getAuthenticationSystem().getClass().getSimpleName()));
javalin.post("/authentication/login", ctx -> Grasscutter.getAuthenticationSystem().getExternalAuthenticator()

View File

@ -23,7 +23,10 @@ import java.util.concurrent.ConcurrentHashMap;
import java.security.Signature;
import java.util.regex.Pattern;
import org.slf4j.Logger;
import static emu.grasscutter.config.Configuration.*;
import static emu.grasscutter.utils.Language.translate;
/**
* Handles requests related to region queries.
@ -31,6 +34,7 @@ import static emu.grasscutter.config.Configuration.*;
public final class RegionHandler implements Router {
private static final Map<String, RegionData> regions = new ConcurrentHashMap<>();
private static String regionListResponse;
private static String regionListResponsecn;
public RegionHandler() {
try { // Read & initialize region data.
@ -97,23 +101,88 @@ public final class RegionHandler implements Router {
// Set the region list response.
regionListResponse = Utils.base64Encode(updatedRegionList.toByteString().toByteArray());
// CN
// Create a config object.
byte[] customConfigcn = "{\"sdkenv\":\"0\",\"checkdevice\":\"true\",\"loadPatch\":\"false\",\"showexception\":\"false\",\"regionConfig\":\"pm|fk|add\",\"downloadMode\":\"0\"}".getBytes();
Crypto.xor(customConfigcn, Crypto.DISPATCH_KEY); // XOR the config with the key.
// Create an updated region list.
QueryRegionListHttpRsp updatedRegionListcn = QueryRegionListHttpRsp.newBuilder()
.addAllRegionList(servers)
.setClientSecretKey(ByteString.copyFrom(Crypto.DISPATCH_SEED))
.setClientCustomConfigEncrypted(ByteString.copyFrom(customConfigcn))
.setEnableLoginPc(true).build();
// Set the region list response.
regionListResponsecn = Utils.base64Encode(updatedRegionListcn.toByteString().toByteArray());
}
@Override public void applyRoutes(Javalin javalin) {
@Override
public void applyRoutes(Javalin javalin) {
javalin.get("/query_region_list", RegionHandler::queryRegionList);
javalin.get("/query_cur_region/{region}", RegionHandler::queryCurrentRegion );
javalin.get("/query_cur_region/{region}", RegionHandler::queryCurrentRegion);
}
/**
* Handle query region list request.
*
* @param ctx The context object for handling the request.
* @route /query_region_list
*/
private static void queryRegionList(Context ctx) {
// Invoke event.
QueryAllRegionsEvent event = new QueryAllRegionsEvent(regionListResponse); event.call();
// Respond with event result.
ctx.result(event.getRegionList());
// Get logger and query parameters.
Logger logger = Grasscutter.getLogger();
if (ctx.queryParamMap().containsKey("version") && ctx.queryParamMap().containsKey("platform")) {
String versionName = ctx.queryParam("version");
String versionCode = versionName.replaceAll("[/.0-9]*", "");
String platformName = ctx.queryParam("platform");
// Log to console.
// Determine the region list to use based on the version and platform.
if ("CNRELiOS".equals(versionCode) || "CNRELWin".equals(versionCode)
|| "CNRELAndroid".equals(versionCode)) {
// Use the CN region list.
QueryAllRegionsEvent event = new QueryAllRegionsEvent(regionListResponsecn);
event.call();
logger.debug("Connect to Chinese version");
// Respond with the event result.
ctx.result(event.getRegionList());
} else if ("OSRELiOS".equals(versionCode) || "OSRELWin".equals(versionCode)
|| "OSRELAndroid".equals(versionCode)) {
// Use the OS region list.
QueryAllRegionsEvent event = new QueryAllRegionsEvent(regionListResponse);
event.call();
logger.debug("Connect to global version");
// Respond with the event result.
ctx.result(event.getRegionList());
} else {
/*
* String regionListResponse = "CP///////////wE=";
* QueryAllRegionsEvent event = new QueryAllRegionsEvent(regionListResponse);
* event.call();
* ctx.result(event.getRegionList());
* return;
*/
// Use the default region list.
QueryAllRegionsEvent event = new QueryAllRegionsEvent(regionListResponse);
event.call();
logger.debug("Connect to global version");
// Respond with the event result.
ctx.result(event.getRegionList());
}
} else {
// Use the default region list.
QueryAllRegionsEvent event = new QueryAllRegionsEvent(regionListResponse);
event.call();
logger.debug("Connect to global version");
// Respond with the event result.
ctx.result(event.getRegionList());
}
// Log the request to the console.
Grasscutter.getLogger().info(String.format("[Dispatch] Client %s request: query_region_list", ctx.ip()));
}