Support CN Client

- Add Chinese region server key configuration
- Rename UserLoginEntity to OverseaUserLoginEntity and adjust package path
- Add ChinaUserLoginEntity entity class to support Chinese region user data structure
- Modify CommonConfigHandler to distinguish between Chinese and overseas configuration returns
- Update HandlerPlayerLoginReq to be compatible with Chinese region login token parsing
- Add /user/set-info and /user/send-sms interfaces in HttpServer
- Modify UserLoginHandler to support both Chinese and overseas user login logic
- Add mobile phone number + verification code login method support
- Add channel recognition logic to return corresponding regional user data
This commit is contained in:
HongchengQ
2025-12-07 18:54:37 +08:00
committed by Melledy
parent 467b7443f3
commit a7eddd2ed0
8 changed files with 248 additions and 59 deletions

View File

@@ -22,6 +22,9 @@ public class GameConstants {
RegionConfig.getRegion("tw") RegionConfig.getRegion("tw")
.setDataVersion(64); .setDataVersion(64);
RegionConfig.getRegion("cn")
.setDataVersion(64);
} }
public static final ZoneId UTC_ZONE = ZoneId.of("UTC"); public static final ZoneId UTC_ZONE = ZoneId.of("UTC");

View File

@@ -164,6 +164,8 @@ public class HttpServer {
getApp().post("/user/set", new UserSetDataHandler()); getApp().post("/user/set", new UserSetDataHandler());
getApp().post("/user/login", new UserLoginHandler()); getApp().post("/user/login", new UserLoginHandler());
getApp().post("/user/quick-login", new UserLoginHandler()); getApp().post("/user/quick-login", new UserLoginHandler());
getApp().post("/user/set-info", new HttpJsonResponse("{\"Code\":200,\"Data\":{},\"Msg\":\"OK\"}"));
getApp().post("/user/send-sms", new HttpJsonResponse("{\"Code\":200,\"Data\":{},\"Msg\":\"OK\"}"));
getApp().post("/yostar/get-auth", new GetAuthHandler()); getApp().post("/yostar/get-auth", new GetAuthHandler());
getApp().post("/yostar/send-code", new HttpJsonResponse("{\"Code\":200,\"Data\":{},\"Msg\":\"OK\"}")); // Dummy handler getApp().post("/yostar/send-code", new HttpJsonResponse("{\"Code\":200,\"Data\":{},\"Msg\":\"OK\"}")); // Dummy handler

View File

@@ -19,7 +19,15 @@ public class HandlerPlayerLoginReq extends NetHandler {
public byte[] handle(GameSession session, byte[] message) throws Exception { public byte[] handle(GameSession session, byte[] message) throws Exception {
// Parse request // Parse request
var req = LoginReq.parseFrom(message); var req = LoginReq.parseFrom(message);
var loginToken = req.getOfficialOverseas().getToken();
// os
String loginToken = req.getOfficialOverseas().getToken();
if (loginToken == null || loginToken.isEmpty()) {
// cn
loginToken = req.getOfficial().getToken();
}
// Login // Login
boolean result = session.login(loginToken); boolean result = session.login(loginToken);

View File

@@ -1,5 +1,6 @@
package emu.nebula.server.routes; package emu.nebula.server.routes;
import emu.nebula.util.JsonUtils;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import emu.nebula.server.HttpServer; import emu.nebula.server.HttpServer;
@@ -10,21 +11,47 @@ import lombok.Getter;
@Getter @Getter
public class CommonConfigHandler implements Handler { public class CommonConfigHandler implements Handler {
private String osConfig = "{\"Code\":200,\"Data\":{\"AppConfig\":{\"ACCOUNT_RETRIEVAL\":{\"FIRST_LOGIN_POPUP\":false,\"LOGIN_POPUP\":false,\"PAGE_URL\":\"\"},\"AGREEMENT_POPUP_TYPE\":\"Browser\",\"APPLE_CURRENCY_BLOCK_LIST\":null,\"APPLE_TYPE_KEY\":\"apple_hk\",\"APP_CLIENT_LANG\":[\"en\"],\"APP_DEBUG\":0,\"APP_GL\":\"en\",\"BIND_METHOD\":[\"google\",\"apple_hk\",\"facebook\"],\"CAPTCHA_ENABLED\":false,\"CLIENT_LOG_REPORTING\":{\"ENABLE\":false},\"CREDIT_INVESTIGATION\":\"0.0\",\"DESTROY_USER_DAYS\":15,\"DESTROY_USER_ENABLE\":1,\"DETECTION_ADDRESS\":{\"AUTO\":{\"DNS\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"],\"HTTP\":[\"${url}\",\"${url}\",\"${url}\"],\"MTR\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"],\"PING\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"],\"TCP\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"]},\"ENABLE\":true,\"ENABLE_MANUAL\":true,\"INTERNET\":\"https://www.google.com\",\"INTERNET_ADDRESS\":\"https://www.google.com\",\"NETWORK_ENDPORINT\":\"\",\"NETWORK_PROJECT\":\"\",\"NETWORK_SECRET_KEY\":\"\"},\"ENABLE_AGREEMENT\":true,\"ENABLE_MULTI_LANG_AGREEMENT\":false,\"ENABLE_TEXT_REVIEW\":true,\"ERROR_CODE\":\"4.4\",\"FILE_DOMAIN\":\"\",\"GEETEST_ENABLE\":false,\"GEETEST_ID\":\"\",\"GOOGLE_ANALYTICS_MEASUREMENT_ID\":\"\",\"MIGRATE_POPUP\":true,\"NICKNAME_REG\":\"^[A-Za-z0-9]{2,20}$\",\"POPUP\":{\"Data\":[{\"Lang\":\"ja\",\"Text\":\"YostarIDを作成\"},{\"Lang\":\"en\",\"Text\":\"CreateaYostaraccount\"},{\"Lang\":\"kr\",\"Text\":\"YOSTAR계정가입하기\"},{\"Lang\":\"fr\",\"Text\":\"CréezvotrecompteYostar\"},{\"Lang\":\"de\",\"Text\":\"EinenYostar-Accounterstellen\"}],\"Enable\":true},\"PRIVACY_AGREEMENT\":\"0.1\",\"RECHARGE_LIMIT\":{\"Enable\":false,\"IsOneLimit\":false,\"Items\":[],\"OneLimitAmount\":0},\"SHARE\":{\"CaptureScreen\":{\"AutoCloseDelay\":0,\"Enabled\":false},\"Facebook\":{\"AppID\":\"\",\"Enabled\":false},\"Instagram\":{\"Enabled\":false},\"Kakao\":{\"AppKey\":\"\",\"Enabled\":false},\"Naver\":{\"Enabled\":false},\"Twitter\":{\"Enabled\":false}},\"SLS\":{\"ACCESS_KEY_ID\":\"7b5d0ffd0943f26704fc547a871c68b1b5d56b5c9caeb354205b81f445d7af59\",\"ACCESS_KEY_SECRET\":\"4a5e9cc8a50819290c9bfa1fedc79da7c50e85189a05eb462a3d28a7688eabb0\",\"ENABLE\":false},\"SURVEY_POPUP_TYPE\":\"Browser\",\"UDATA\":{\"Enable\":false,\"URL\":\"${url}\"},\"USER_AGREEMENT\":\"0.1\",\"YOSTAR_PREFIX\":\"yoyo\"},\"EuropeUnion\":false,\"StoreConfig\":{\"ADJUST_APPID\":\"\",\"ADJUST_CHARGEEVENTTOKEN\":\"\",\"ADJUST_ENABLED\":0,\"ADJUST_EVENTTOKENS\":null,\"ADJUST_ISDEBUG\":0,\"AIRWALLEX_ENABLED\":false,\"AI_HELP\":{\"AihelpAppID\":\"yostar1_platform_2db52a57068b1ee3fe3652c8b53d581b\",\"AihelpAppKey\":\"YOSTAR1_app_bc226f4419a7447c9de95711f8a2d3d9\",\"AihelpDomain\":\"yostar1.aihelp.net\",\"CustomerServiceURL\":\"\",\"CustomerWay\":1,\"DisplayType\":\"Browser\",\"Enable\":1,\"Mode\":\"robot\"},\"APPLEID\":\"\",\"CODA_ENABLED\":false,\"ENABLED_PAY\":{\"AIRWALLEX_ENABLED\":false,\"CODA_ENABLED\":false,\"GMOAlipay\":false,\"GMOAu\":false,\"GMOCreditcard\":false,\"GMOCvs\":false,\"GMODocomo\":false,\"GMOPaypal\":false,\"GMOPaypay\":false,\"GMOSoftbank\":false,\"MYCARD_ENABLED\":false,\"PAYPAL_ENABLED\":true,\"RAZER_ENABLED\":false,\"STEAM_ENABLED\":false,\"STRIPE_ENABLED\":true,\"TOSS_ENABLED\":false,\"WEBMONEY_ENABLED\":false},\"FACEBOOK_APPID\":\"\",\"FACEBOOK_CLIENT_TOKEN\":\"\",\"FACEBOOK_SECRET\":\"\",\"FIREBASE_ENABLED\":0,\"GMO_CC_JS\":\"https://\",\"GMO_CC_KEY\":\"\",\"GMO_CC_SHOPID\":\"\",\"GMO_PAY_CHANNEL\":{\"GMOAlipay\":false,\"GMOAu\":false,\"GMOCreditcard\":false,\"GMOCvs\":false,\"GMODocomo\":false,\"GMOPaypal\":false,\"GMOPaypay\":false,\"GMOSoftbank\":false},\"GMO_PAY_ENABLED\":false,\"GOOGLE_CLIENT_ID\":\"\",\"GOOGLE_CLIENT_SECRET\":\"\",\"GUEST_CREATE_METHOD\":0,\"GUIDE_POPUP\":{\"DATA\":null,\"ENABLE\":0},\"LOGIN\":{\"DEFAULT\":\"yostar\",\"ICON_SIZE\":\"big\",\"SORT\":[\"google\",\"apple\",\"device\"]},\"MYCARD_ENABLED\":false,\"ONE_STORE_LICENSE_KEY\":\"\",\"PAYPAL_ENABLED\":false,\"RAZER_ENABLED\":false,\"REMOTE_CONFIG\":[],\"SAMSUNG_SANDBOX_MODE\":false,\"STEAM_APPID\":\"\",\"STEAM_ENABLED\":false,\"STEAM_PAY_APPID\":\"\",\"STRIPE_ENABLED\":false,\"TOSS_ENABLED\":false,\"TWITTER_KEY\":\"\",\"TWITTER_SECRET\":\"\",\"WEBMONEY_ENABLED\":false}},\"Msg\":\"OK\"}";
private String cnConfig = "{\"Code\":200,\"Data\":{\"AppConfig\":{\"AppropriateAge\":{\"Level\":\"18+\",\"Msg\":\"《星塔旅人》游戏适龄提示\\n1、本游戏是一款玩法简单的角色扮演游戏适用于年满18周岁及以上的用户。\\n2、本游戏基于架空的故事背景和幻想世界观剧情简单且积极向上没有基于真实历史和现实事件的改编内容。游戏玩法基于肢体操作鼓励玩家通过训练达成目标。游戏中有少量自定义文字系统该社交系统遵循相关法律法规进行管理。\\n3、本游戏中有用户实名认证系统对年满18周岁及以上的用户开放使用18周岁以下的身份信息认证账号将无法进入游戏。\"},\"Captcha\":{\"AppID\":191947906,\"Enable\":true},\"DestroyUser\":{\"Days\":15,\"Enable\":true},\"DetectionAddress\":{\"Auto\":{\"DNS\":[\"${url}/meta/serverlist.html\",\"${url}\"],\"HTTP\":[\"${url}/meta/serverlist.html\",\"${url}\"],\"MTR\":[\"${url}/meta/serverlist.html\",\"${url}\"],\"PING\":[\"${url}/meta/serverlist.html\",\"${url}\"],\"TCP\":[\"${url}/meta/serverlist.html\",\"${url}\"]},\"Enable\":true,\"Internet\":\"https://www.baidu.com\"},\"EnableTextReview\":true,\"NicknameReg\":\"^[A-Za-z0-9一-龥]{2,16}$\",\"Passport\":{\"AuthCodeCoolDownDays\":90,\"AuthCodeValidHour\":48,\"DestroyDays\":15,\"ModifyEmailDays\":30,\"ModifyMobileDays\":30,\"Prefix\":\"YS\"},\"PassportPopup\":{\"Enable\":false,\"Text\":\"\"},\"SLS\":{\"AccessKeyID\":\"7b5d0ffd0943f26704fc547a871c68b1b5d56b5c9caeb354205b81f445d7af59\",\"AccessKeySecret\":\"4a5e9cc8a50819290c9bfa1fedc79da7c50e85189a05eb462a3d28a7688eabb0\",\"ENABLE\":true},\"Share\":{\"CaptureScreen\":{\"AutoCloseDelay\":0,\"Enabled\":false},\"PengYouQuan\":{\"AppID\":\"\",\"Enabled\":false,\"UniversalLink\":\"\"},\"QQ\":{\"AppID\":\"\",\"Enabled\":false,\"UniversalLink\":\"\"},\"Qzone\":{\"AppID\":\"\",\"Enabled\":false,\"UniversalLink\":\"\"},\"Sort\":null,\"WeiXin\":{\"AppID\":\"\",\"Enabled\":false,\"UniversalLink\":\"\"},\"Weibo\":{\"AppKey\":\"\",\"Enabled\":false,\"RedirectURL\":\"\",\"UniversalLink\":\"\"}},\"ThirdInfoShareList\":\"https://${url}/cn-nova/shared_list\",\"Version\":{\"ChildPrivacyAgreement\":\"0.1\",\"ErrorCode\":\"5.3\",\"PassportPrivacyAgreement\":\"0.1\",\"PassportUserAgreement\":\"0.1\",\"PrivacyAgreement\":\"0.1\",\"UserAgreement\":\"0.1\",\"UserDestroy\":\"0.1\"}},\"ChannelConfig\":{\"Adjust\":{\"AppID\":\"\",\"Debug\":false,\"Enable\":false,\"EventTokens\":null},\"AiHelp\":{\"DisplayType\":\"WebView\",\"Enable\":true,\"ServiceInterfaceURL\":\"https://customer.yostar.net/\",\"ServiceURL\":\"https://customer-pc.yostar.net/#/\"},\"AntiAddiction\":{\"Enable\":true},\"Debug\":1,\"JPush\":{\"Debug\":false,\"Key\":\"\"},\"Login\":{\"Default\":\"mobile\",\"EnableList\":[\"mobile\",\"taptap\"]},\"OneKeyLoginSecret\":\"5c222d7c997339c921bd4fdcb7549ab4\",\"Taptap\":{\"ClientID\":\"9aeghiagor7hp43smv\",\"ClientPublicKey\":\"MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAwp10sKQjAn+kxSxZebHBgl3Tuqjapxdtqzy68y2CPzELHVeBQpK6jPnHyjvZcpgsW3/Rr4hyzPsxMHp7akNRfkOy2jqEGl/2hDeYpSsvK4vw9triXz4DTLESpU+RWfTglf3LRHB76RJggcGw0Pt+QAItHlOMQH+9LBuWtnS+bcf2YD+kC4jTmvr2dB6i3dhyaorVuT2OfnTRDZREU0WauWdACWHyaUELwA/JfZW+ir88k++qEjxaq76avRXzfJ0SuA8lqJKRirBc4dgMLvpjpjy1mVV3us64fSyAYwqUFCFNT5HT4/MMCbD4YZs20pgT8sUG04kbxlA1qu6sIh2BHwIDAQAB\",\"ClientToken\":\"ENWpPiooc3lI3ZNVNQNOXWZ7dE4YrVOsbMY7b1Li\"},\"Udata\":{\"Enable\":true}}},\"Msg\":\"OK\"}";
private HttpServer server; private HttpServer server;
private String json;
public CommonConfigHandler(HttpServer server) { public CommonConfigHandler(HttpServer server) {
this.server = server; this.server = server;
this.json = "{\"Code\":200,\"Data\":{\"AppConfig\":{\"ACCOUNT_RETRIEVAL\":{\"FIRST_LOGIN_POPUP\":false,\"LOGIN_POPUP\":false,\"PAGE_URL\":\"\"},\"AGREEMENT_POPUP_TYPE\":\"Browser\",\"APPLE_CURRENCY_BLOCK_LIST\":null,\"APPLE_TYPE_KEY\":\"apple_hk\",\"APP_CLIENT_LANG\":[\"en\"],\"APP_DEBUG\":0,\"APP_GL\":\"en\",\"BIND_METHOD\":[\"google\",\"apple_hk\",\"facebook\"],\"CAPTCHA_ENABLED\":false,\"CLIENT_LOG_REPORTING\":{\"ENABLE\":false},\"CREDIT_INVESTIGATION\":\"0.0\",\"DESTROY_USER_DAYS\":15,\"DESTROY_USER_ENABLE\":1,\"DETECTION_ADDRESS\":{\"AUTO\":{\"DNS\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"],\"HTTP\":[\"${url}\",\"${url}\",\"${url}\"],\"MTR\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"],\"PING\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"],\"TCP\":[\"${url}\",\"${url}\",\"${url}/meta/serverlist.html\"]},\"ENABLE\":true,\"ENABLE_MANUAL\":true,\"INTERNET\":\"https://www.google.com\",\"INTERNET_ADDRESS\":\"https://www.google.com\",\"NETWORK_ENDPORINT\":\"\",\"NETWORK_PROJECT\":\"\",\"NETWORK_SECRET_KEY\":\"\"},\"ENABLE_AGREEMENT\":true,\"ENABLE_MULTI_LANG_AGREEMENT\":false,\"ENABLE_TEXT_REVIEW\":true,\"ERROR_CODE\":\"4.4\",\"FILE_DOMAIN\":\"\",\"GEETEST_ENABLE\":false,\"GEETEST_ID\":\"\",\"GOOGLE_ANALYTICS_MEASUREMENT_ID\":\"\",\"MIGRATE_POPUP\":true,\"NICKNAME_REG\":\"^[A-Za-z0-9]{2,20}$\",\"POPUP\":{\"Data\":[{\"Lang\":\"ja\",\"Text\":\"YostarIDを作成\"},{\"Lang\":\"en\",\"Text\":\"CreateaYostaraccount\"},{\"Lang\":\"kr\",\"Text\":\"YOSTAR계정가입하기\"},{\"Lang\":\"fr\",\"Text\":\"CréezvotrecompteYostar\"},{\"Lang\":\"de\",\"Text\":\"EinenYostar-Accounterstellen\"}],\"Enable\":true},\"PRIVACY_AGREEMENT\":\"0.1\",\"RECHARGE_LIMIT\":{\"Enable\":false,\"IsOneLimit\":false,\"Items\":[],\"OneLimitAmount\":0},\"SHARE\":{\"CaptureScreen\":{\"AutoCloseDelay\":0,\"Enabled\":false},\"Facebook\":{\"AppID\":\"\",\"Enabled\":false},\"Instagram\":{\"Enabled\":false},\"Kakao\":{\"AppKey\":\"\",\"Enabled\":false},\"Naver\":{\"Enabled\":false},\"Twitter\":{\"Enabled\":false}},\"SLS\":{\"ACCESS_KEY_ID\":\"7b5d0ffd0943f26704fc547a871c68b1b5d56b5c9caeb354205b81f445d7af59\",\"ACCESS_KEY_SECRET\":\"4a5e9cc8a50819290c9bfa1fedc79da7c50e85189a05eb462a3d28a7688eabb0\",\"ENABLE\":false},\"SURVEY_POPUP_TYPE\":\"Browser\",\"UDATA\":{\"Enable\":false,\"URL\":\"${url}\"},\"USER_AGREEMENT\":\"0.1\",\"YOSTAR_PREFIX\":\"yoyo\"},\"EuropeUnion\":false,\"StoreConfig\":{\"ADJUST_APPID\":\"\",\"ADJUST_CHARGEEVENTTOKEN\":\"\",\"ADJUST_ENABLED\":0,\"ADJUST_EVENTTOKENS\":null,\"ADJUST_ISDEBUG\":0,\"AIRWALLEX_ENABLED\":false,\"AI_HELP\":{\"AihelpAppID\":\"yostar1_platform_2db52a57068b1ee3fe3652c8b53d581b\",\"AihelpAppKey\":\"YOSTAR1_app_bc226f4419a7447c9de95711f8a2d3d9\",\"AihelpDomain\":\"yostar1.aihelp.net\",\"CustomerServiceURL\":\"\",\"CustomerWay\":1,\"DisplayType\":\"Browser\",\"Enable\":1,\"Mode\":\"robot\"},\"APPLEID\":\"\",\"CODA_ENABLED\":false,\"ENABLED_PAY\":{\"AIRWALLEX_ENABLED\":false,\"CODA_ENABLED\":false,\"GMOAlipay\":false,\"GMOAu\":false,\"GMOCreditcard\":false,\"GMOCvs\":false,\"GMODocomo\":false,\"GMOPaypal\":false,\"GMOPaypay\":false,\"GMOSoftbank\":false,\"MYCARD_ENABLED\":false,\"PAYPAL_ENABLED\":true,\"RAZER_ENABLED\":false,\"STEAM_ENABLED\":false,\"STRIPE_ENABLED\":true,\"TOSS_ENABLED\":false,\"WEBMONEY_ENABLED\":false},\"FACEBOOK_APPID\":\"\",\"FACEBOOK_CLIENT_TOKEN\":\"\",\"FACEBOOK_SECRET\":\"\",\"FIREBASE_ENABLED\":0,\"GMO_CC_JS\":\"https://\",\"GMO_CC_KEY\":\"\",\"GMO_CC_SHOPID\":\"\",\"GMO_PAY_CHANNEL\":{\"GMOAlipay\":false,\"GMOAu\":false,\"GMOCreditcard\":false,\"GMOCvs\":false,\"GMODocomo\":false,\"GMOPaypal\":false,\"GMOPaypay\":false,\"GMOSoftbank\":false},\"GMO_PAY_ENABLED\":false,\"GOOGLE_CLIENT_ID\":\"\",\"GOOGLE_CLIENT_SECRET\":\"\",\"GUEST_CREATE_METHOD\":0,\"GUIDE_POPUP\":{\"DATA\":null,\"ENABLE\":0},\"LOGIN\":{\"DEFAULT\":\"yostar\",\"ICON_SIZE\":\"big\",\"SORT\":[\"google\",\"apple\",\"device\"]},\"MYCARD_ENABLED\":false,\"ONE_STORE_LICENSE_KEY\":\"\",\"PAYPAL_ENABLED\":false,\"RAZER_ENABLED\":false,\"REMOTE_CONFIG\":[],\"SAMSUNG_SANDBOX_MODE\":false,\"STEAM_APPID\":\"\",\"STEAM_ENABLED\":false,\"STEAM_PAY_APPID\":\"\",\"STRIPE_ENABLED\":false,\"TOSS_ENABLED\":false,\"TWITTER_KEY\":\"\",\"TWITTER_SECRET\":\"\",\"WEBMONEY_ENABLED\":false}},\"Msg\":\"OK\"}";
String address = server.getServerConfig().getDisplayAddress(); String address = server.getServerConfig().getDisplayAddress();
this.json = this.json.replaceAll("\\$\\{url}", address); this.osConfig = this.osConfig.replaceAll("\\$\\{url}", address);
this.cnConfig = this.cnConfig.replaceAll("\\$\\{url}", address);
} }
@Override @Override
public void handle(@NotNull Context ctx) throws Exception { public void handle(@NotNull Context ctx) throws Exception {
ctx.contentType(ContentType.APPLICATION_JSON); ctx.contentType(ContentType.APPLICATION_JSON);
ctx.result(this.json);
String Channel = "";
var req = JsonUtils.decode(ctx.header("Authorization"), authDataJson.class);
if (req != null) {
Channel = req.Head.Channel;
}
if (Channel != null && Channel.equals("official")) {
// cn
ctx.result(cnConfig);
return;
}
ctx.result(osConfig);
}
@SuppressWarnings("unused")
private static class authDataJson {
public handJson Head;
public String Sign;
protected static class handJson {
public String Channel;
}
} }
} }

View File

@@ -2,14 +2,13 @@ package emu.nebula.server.routes;
import java.util.ArrayList; import java.util.ArrayList;
import emu.nebula.Nebula;
import emu.nebula.server.routes.entity.ChinaUserLoginEntity;
import emu.nebula.server.routes.entity.OverseaUserLoginEntity;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
import emu.nebula.game.account.Account; import emu.nebula.game.account.Account;
import emu.nebula.game.account.AccountHelper; import emu.nebula.game.account.AccountHelper;
import emu.nebula.server.routes.UserLoginEntity.LoginYostarJson;
import emu.nebula.server.routes.UserLoginEntity.UserDetailJson;
import emu.nebula.server.routes.UserLoginEntity.UserInfoJson;
import emu.nebula.server.routes.UserLoginEntity.UserKeyJson;
import emu.nebula.util.JsonUtils; import emu.nebula.util.JsonUtils;
import io.javalin.http.ContentType; import io.javalin.http.ContentType;
import io.javalin.http.Context; import io.javalin.http.Context;
@@ -29,54 +28,120 @@ public class UserLoginHandler implements Handler {
account = this.getAccountFromBody(ctx); account = this.getAccountFromBody(ctx);
} }
// Check
if (account == null) {
ctx.contentType(ContentType.APPLICATION_JSON);
ctx.result("{\"Code\":100403,\"Data\":{},\"Msg\":\"Error\"}"); // TOKEN_AUTH_FAILED
return;
}
// Create response
var response = new UserLoginEntity();
response.Code = 200;
response.Msg = "OK";
response.Data = new UserDetailJson();
response.Data.Keys = new ArrayList<>();
response.Data.UserInfo = new UserInfoJson();
response.Data.Yostar = new LoginYostarJson();
response.Data.UserInfo.ID = account.getUid();
response.Data.UserInfo.UID2 = 0;
response.Data.UserInfo.PID = "NEBULA";
response.Data.UserInfo.Token = account.getLoginToken();
response.Data.UserInfo.Birthday = "";
response.Data.UserInfo.RegChannel = "pc";
response.Data.UserInfo.TransCode = "";
response.Data.UserInfo.State = 1;
response.Data.UserInfo.DeviceID = "";
response.Data.UserInfo.CreatedAt = account.getCreatedAt();
response.Data.Yostar.ID = account.getUid();
response.Data.Yostar.Country = "US";
response.Data.Yostar.Nickname = account.getNickname();
response.Data.Yostar.Picture = account.getPicture();
response.Data.Yostar.State = 1;
response.Data.Yostar.AgreeAd = 0;
response.Data.Yostar.CreatedAt = account.getCreatedAt();
var key = new UserKeyJson();
key.ID = account.getUid();
key.Type = "yostar";
key.Key = account.getEmail();
key.NickName = account.getEmail();
key.CreatedAt = account.getCreatedAt();
response.Data.Keys.add(key);
// Result // Result
ctx.contentType(ContentType.APPLICATION_JSON); ctx.contentType(ContentType.APPLICATION_JSON);
ctx.result(JsonUtils.encode(response, true)); ctx.result(getJsonResult(ctx, account));
}
private String getJsonResult(Context ctx, Account account) {
if (account == null) {
return "{\"Code\":100403,\"Data\":{},\"Msg\":\"Error\"}";
}
String Channel = "";
var req = JsonUtils.decode(ctx.header("Authorization"), UserAuthDataJson.class);
if (req != null) {
Channel = req.Head.Channel;
}
String token = account.getLoginToken();
if (token == null || token.isEmpty()) {
account.generateLoginToken();
}
String nickName = account.getNickname();
if (nickName == null || nickName.isEmpty()) {
account.setNickname(account.getEmail());
}
// Check if it's a CN channel
// The data required by CN channels is somewhat different from other regional servers
if (Channel != null && Channel.equals("official")) {
// CN
var response = new ChinaUserLoginEntity();
response.Code = 200;
response.Msg = "OK";
response.Data = new ChinaUserLoginEntity.UserDetailJson();
response.Data.IsNew = false;
response.Data.IsTestAccount = false;
response.Data.Keys = new ArrayList<>();
response.Data.User = new ChinaUserLoginEntity.UserJson();
response.Data.Yostar = new ChinaUserLoginEntity.LoginYostarJson();
response.Data.Identity = new ChinaUserLoginEntity.IdentityJson();
response.Data.TaptapProfile = null;
response.Data.User.ID = Long.parseLong(account.getUid());
response.Data.User.PID = "NEBULA";
response.Data.User.Token = account.getLoginToken();
response.Data.User.State = 1;
response.Data.User.RegChannel = "pc_official";
response.Data.User.DestroyState = 0;
response.Data.Yostar.ID = Long.parseLong(account.getUid());
response.Data.Yostar.NickName = account.getNickname();
response.Data.Yostar.Picture = account.getPicture();
response.Data.Yostar.State = 1;
response.Data.Yostar.CreatedAt = account.getCreatedAt();
response.Data.Yostar.DefaultNickName = "";
response.Data.Identity.Type = 0;
response.Data.Identity.RealName = "***";
response.Data.Identity.IDCard = "******************";
response.Data.Identity.Underage = false;
response.Data.Identity.PI = "";
response.Data.Identity.BirthDate = "";
response.Data.Identity.State = 1;
var key = new ChinaUserLoginEntity.UserKeyJson();
key.Type = "mobile";
key.NickName = account.getEmail();
key.NickNameEnc = "";
response.Data.Keys.add(key);
return JsonUtils.encode(response, true);
} else {
// OS
var response = new OverseaUserLoginEntity();
response.Code = 200;
response.Msg = "OK";
response.Data = new OverseaUserLoginEntity.UserDetailJson();
response.Data.Keys = new ArrayList<>();
response.Data.UserInfo = new OverseaUserLoginEntity.UserInfoJson();
response.Data.Yostar = new OverseaUserLoginEntity.LoginYostarJson();
response.Data.UserInfo.ID = account.getUid();
response.Data.UserInfo.UID2 = 0;
response.Data.UserInfo.PID = "NEBULA";
response.Data.UserInfo.Token = account.getLoginToken();
response.Data.UserInfo.Birthday = "";
response.Data.UserInfo.RegChannel = "pc";
response.Data.UserInfo.TransCode = "";
response.Data.UserInfo.State = 1;
response.Data.UserInfo.DeviceID = "";
response.Data.UserInfo.CreatedAt = account.getCreatedAt();
response.Data.Yostar.ID = account.getUid();
response.Data.Yostar.Country = "US";
response.Data.Yostar.Nickname = account.getNickname();
response.Data.Yostar.Picture = account.getPicture();
response.Data.Yostar.State = 1;
response.Data.Yostar.AgreeAd = 0;
response.Data.Yostar.CreatedAt = account.getCreatedAt();
var key = new OverseaUserLoginEntity.UserKeyJson();
key.ID = account.getUid();
key.Type = "yostar";
key.Key = account.getEmail();
key.NickName = account.getEmail();
key.CreatedAt = account.getCreatedAt();
response.Data.Keys.add(key);
return JsonUtils.encode(response, true);
}
} }
protected Account getAccountFromBody(Context ctx) { protected Account getAccountFromBody(Context ctx) {
@@ -86,9 +151,32 @@ public class UserLoginHandler implements Handler {
if (req == null || req.OpenID == null || req.Token == null) { if (req == null || req.OpenID == null || req.Token == null) {
return null; return null;
} }
Account account = AccountHelper.getAccountByLoginToken(req.Token);
if (account != null) return account;
// In CN region, login method is mobile phone + MFA verification code
// OpenID is mobile phone number, Token is a six-digit verification code
// These are stored in the body
{
// CN region requires an OpenID query
account = AccountHelper.getAccountByEmail(req.OpenID);
if (account == null) {
// Create an account if were allowed to
if (Nebula.getConfig().getServerOptions().isAutoCreateAccount()) {
account = AccountHelper.createAccount(req.OpenID, null, 0);
}
} else {
// Check passcode sent by email
if (!account.verifyCode(req.Token)) {
account = null;
}
}
}
// Get account // Get account
return AccountHelper.getAccountByLoginToken(req.Token); return account;
} }
protected Account getAccountFromHeader(Context ctx) { protected Account getAccountFromHeader(Context ctx) {
@@ -121,6 +209,7 @@ public class UserLoginHandler implements Handler {
protected static class UserAuthHeadJson { protected static class UserAuthHeadJson {
public String UID; public String UID;
public String Token; public String Token;
public String Channel;
} }
} }

View File

@@ -0,0 +1,56 @@
package emu.nebula.server.routes.entity;
import java.util.List;
public class ChinaUserLoginEntity {
public int Code;
public UserDetailJson Data;
public String Msg;
public static class UserDetailJson {
public Object Destroy;
public Object YostarDestroy;
public boolean IsNew;
public boolean IsTestAccount;
public List<UserKeyJson> Keys;
public UserJson User;
public LoginYostarJson Yostar;
public Object TaptapProfile;
public IdentityJson Identity;
}
public static class UserJson {
public long ID;
public String PID;
public String Token;
public int State;
public String RegChannel;
public int DestroyState;
}
public static class UserKeyJson {
public String Type;
public String NickName;
public String NickNameEnc;
}
public static class LoginYostarJson {
public long ID;
public String NickName;
public String Picture;
public int State;
public long CreatedAt;
public String DefaultNickName;
}
public static class IdentityJson {
public int Type;
public String RealName;
public String IDCard;
public boolean Underage;
public String PI;
public String BirthDate;
public int State;
}
}

View File

@@ -1,8 +1,8 @@
package emu.nebula.server.routes; package emu.nebula.server.routes.entity;
import java.util.List; import java.util.List;
public class UserLoginEntity { public class OverseaUserLoginEntity {
public int Code; public int Code;
public UserDetailJson Data; public UserDetailJson Data;
public String Msg; public String Msg;

View File

@@ -49,6 +49,10 @@ public class AeadHelper {
RegionConfig.getRegion("tw") RegionConfig.getRegion("tw")
.setServerMetaKey("owGYVDmfHrxi^4pm") .setServerMetaKey("owGYVDmfHrxi^4pm")
.setServerGarbleKey("N&mfco452ZH5!nE3s&o5uxB57UGPENVo"); .setServerGarbleKey("N&mfco452ZH5!nE3s&o5uxB57UGPENVo");
RegionConfig.getRegion("cn")
.setServerMetaKey("Xf&FRcsYm48cJ2A@")
.setServerGarbleKey("QW*Wi7fKjLk!T82Qf2nEGZA%nSC!D9qV");
} }
public static void loadKeys() { public static void loadKeys() {