mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2025-07-27 09:03:49 +00:00
Compare commits
6 Commits
8819cca3e2
...
d59e14e383
Author | SHA1 | Date | |
---|---|---|---|
d59e14e383 | |||
c683effead | |||
b9eef26d8b | |||
b60596f41f | |||
e2cb56ee28 | |||
b2a07044e2 |
@ -23,32 +23,42 @@ public final class DefaultAuthenticators {
|
|||||||
|
|
||||||
var requestData = request.getPasswordRequest();
|
var requestData = request.getPasswordRequest();
|
||||||
assert requestData != null; // This should never be null.
|
assert requestData != null; // This should never be null.
|
||||||
|
int playerCount = Grasscutter.getGameServer().getPlayers().size();
|
||||||
|
|
||||||
boolean successfulLogin = false;
|
boolean successfulLogin = false;
|
||||||
String address = request.getRequest().ip();
|
String address = request.getRequest().ip();
|
||||||
String responseMessage = translate("messages.dispatch.account.username_error");
|
String responseMessage = translate("messages.dispatch.account.username_error");
|
||||||
|
String loggerMessage = "";
|
||||||
|
|
||||||
// Get account from database.
|
// Get account from database.
|
||||||
Account account = DatabaseHelper.getAccountByName(requestData.account);
|
Account account = DatabaseHelper.getAccountByName(requestData.account);
|
||||||
|
if (ACCOUNT.maxPlayer <= -1 || playerCount < ACCOUNT.maxPlayer) {
|
||||||
// Check if account exists.
|
// Check if account exists.
|
||||||
if(account == null && ACCOUNT.autoCreate) {
|
if(account == null && ACCOUNT.autoCreate) {
|
||||||
// This account has been created AUTOMATICALLY. There will be no permissions added.
|
// This account has been created AUTOMATICALLY. There will be no permissions added.
|
||||||
account = DatabaseHelper.createAccountWithId(requestData.account, 0);
|
account = DatabaseHelper.createAccountWithId(requestData.account, 0);
|
||||||
|
|
||||||
// Check if the account was created successfully.
|
// Check if the account was created successfully.
|
||||||
if(account == null) {
|
if(account == null) {
|
||||||
responseMessage = translate("messages.dispatch.account.username_create_error");
|
responseMessage = translate("messages.dispatch.account.username_create_error");
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_error", address));
|
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_error", address));
|
||||||
} else {
|
} else {
|
||||||
// Continue with login.
|
// Continue with login.
|
||||||
successfulLogin = true;
|
successfulLogin = true;
|
||||||
|
|
||||||
|
// Log the creation.
|
||||||
|
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_success", address, response.data.account.uid));
|
||||||
|
}
|
||||||
|
} else if(account != null)
|
||||||
|
successfulLogin = true;
|
||||||
|
else
|
||||||
|
loggerMessage = translate("messages.dispatch.account.account_login_exist_error", address);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
responseMessage = translate("messages.dispatch.account.server_max_player_limit");
|
||||||
|
loggerMessage = translate("messages.dispatch.account.login_max_player_limit", address);
|
||||||
|
}
|
||||||
|
|
||||||
// Log the creation.
|
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_success", address, response.data.account.uid));
|
|
||||||
}
|
|
||||||
} else if(account != null)
|
|
||||||
successfulLogin = true;
|
|
||||||
|
|
||||||
// Set response data.
|
// Set response data.
|
||||||
if(successfulLogin) {
|
if(successfulLogin) {
|
||||||
@ -56,17 +66,15 @@ public final class DefaultAuthenticators {
|
|||||||
response.data.account.uid = account.getId();
|
response.data.account.uid = account.getId();
|
||||||
response.data.account.token = account.generateSessionKey();
|
response.data.account.token = account.generateSessionKey();
|
||||||
response.data.account.email = account.getEmail();
|
response.data.account.email = account.getEmail();
|
||||||
|
|
||||||
// Log the login.
|
loggerMessage = translate("messages.dispatch.account.login_success", address, account.getId());
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_success", address, account.getId()));
|
|
||||||
} else {
|
} else {
|
||||||
response.retcode = -201;
|
response.retcode = -201;
|
||||||
response.message = responseMessage;
|
response.message = responseMessage;
|
||||||
|
|
||||||
// Log the failure.
|
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_exist_error", address));
|
|
||||||
}
|
}
|
||||||
|
Grasscutter.getLogger().info(loggerMessage);
|
||||||
|
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -80,36 +88,48 @@ public final class DefaultAuthenticators {
|
|||||||
|
|
||||||
var requestData = request.getTokenRequest();
|
var requestData = request.getTokenRequest();
|
||||||
assert requestData != null;
|
assert requestData != null;
|
||||||
|
|
||||||
boolean successfulLogin;
|
boolean successfulLogin;
|
||||||
String address = request.getRequest().ip();
|
String address = request.getRequest().ip();
|
||||||
|
String loggerMessage;
|
||||||
|
int playerCount = Grasscutter.getGameServer().getPlayers().size();
|
||||||
|
|
||||||
// Log the attempt.
|
// Log the attempt.
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_attempt", address));
|
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_attempt", address));
|
||||||
|
|
||||||
// Get account from database.
|
if (ACCOUNT.maxPlayer <= -1 || playerCount < ACCOUNT.maxPlayer) {
|
||||||
Account account = DatabaseHelper.getAccountById(requestData.uid);
|
|
||||||
|
// Get account from database.
|
||||||
// Check if account exists/token is valid.
|
Account account = DatabaseHelper.getAccountById(requestData.uid);
|
||||||
successfulLogin = account != null && account.getSessionKey().equals(requestData.token);
|
|
||||||
|
// Check if account exists/token is valid.
|
||||||
// Set response data.
|
successfulLogin = account != null && account.getSessionKey().equals(requestData.token);
|
||||||
if(successfulLogin) {
|
|
||||||
response.message = "OK";
|
// Set response data.
|
||||||
response.data.account.uid = account.getId();
|
if(successfulLogin) {
|
||||||
response.data.account.token = account.getSessionKey();
|
response.message = "OK";
|
||||||
response.data.account.email = account.getEmail();
|
response.data.account.uid = account.getId();
|
||||||
|
response.data.account.token = account.getSessionKey();
|
||||||
// Log the login.
|
response.data.account.email = account.getEmail();
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_success", address, requestData.uid));
|
|
||||||
|
// Log the login.
|
||||||
|
loggerMessage = translate("messages.dispatch.account.login_token_success", address, requestData.uid);
|
||||||
|
} else {
|
||||||
|
response.retcode = -201;
|
||||||
|
response.message = translate("messages.dispatch.account.account_cache_error");
|
||||||
|
|
||||||
|
// Log the failure.
|
||||||
|
loggerMessage = translate("messages.dispatch.account.login_token_error", address);
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
response.retcode = -201;
|
response.retcode = -201;
|
||||||
response.message = translate("messages.dispatch.account.account_cache_error");
|
response.message = translate("messages.dispatch.account.server_max_player_limit");
|
||||||
|
|
||||||
// Log the failure.
|
loggerMessage = translate("messages.dispatch.account.login_max_player_limit", address);
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_error", address));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Grasscutter.getLogger().info(loggerMessage);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -127,30 +147,41 @@ public final class DefaultAuthenticators {
|
|||||||
|
|
||||||
boolean successfulLogin;
|
boolean successfulLogin;
|
||||||
String address = request.getRequest().ip();
|
String address = request.getRequest().ip();
|
||||||
|
String loggerMessage;
|
||||||
// Get account from database.
|
int playerCount = Grasscutter.getGameServer().getPlayers().size();
|
||||||
Account account = DatabaseHelper.getAccountById(loginData.uid);
|
|
||||||
|
if (ACCOUNT.maxPlayer <= -1 || playerCount < ACCOUNT.maxPlayer) {
|
||||||
// Check if account exists/token is valid.
|
// Get account from database.
|
||||||
successfulLogin = account != null && account.getSessionKey().equals(loginData.token);
|
Account account = DatabaseHelper.getAccountById(loginData.uid);
|
||||||
|
|
||||||
// Set response data.
|
// Check if account exists/token is valid.
|
||||||
if(successfulLogin) {
|
successfulLogin = account != null && account.getSessionKey().equals(loginData.token);
|
||||||
response.message = "OK";
|
|
||||||
response.data.open_id = account.getId();
|
// Set response data.
|
||||||
response.data.combo_id = "157795300";
|
if(successfulLogin) {
|
||||||
response.data.combo_token = account.generateLoginToken();
|
response.message = "OK";
|
||||||
|
response.data.open_id = account.getId();
|
||||||
// Log the login.
|
response.data.combo_id = "157795300";
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.combo_token_success", address));
|
response.data.combo_token = account.generateLoginToken();
|
||||||
|
|
||||||
|
// Log the login.
|
||||||
|
loggerMessage = translate("messages.dispatch.account.combo_token_success", address);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
response.retcode = -201;
|
||||||
|
response.message = translate("messages.dispatch.account.session_key_error");
|
||||||
|
|
||||||
|
// Log the failure.
|
||||||
|
loggerMessage = translate("messages.dispatch.account.combo_token_error", address);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
response.retcode = -201;
|
response.retcode = -201;
|
||||||
response.message = translate("messages.dispatch.account.session_key_error");
|
response.message = translate("messages.dispatch.account.server_max_player_limit");
|
||||||
|
|
||||||
// Log the failure.
|
loggerMessage = translate("messages.dispatch.account.login_max_player_limit", address);
|
||||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.combo_token_error", address));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Grasscutter.getLogger().info(loggerMessage);
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -143,7 +143,7 @@ public class GachaBanner {
|
|||||||
String details = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
|
String details = "http" + (HTTP_ENCRYPTION.useInRouting ? "s" : "") + "://"
|
||||||
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
|
+ lr(HTTP_INFO.accessAddress, HTTP_INFO.bindAddress) + ":"
|
||||||
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
+ lr(HTTP_INFO.accessPort, HTTP_INFO.bindPort)
|
||||||
+ "/gacha/details?s=" + sessionKey + "&gachaType=" + gachaType;
|
+ "/gacha/details?s=" + sessionKey + "&scheduleId=" + scheduleId;
|
||||||
|
|
||||||
// Grasscutter.getLogger().info("record = " + record);
|
// Grasscutter.getLogger().info("record = " + record);
|
||||||
ItemParamData costItem1 = this.getCost(1);
|
ItemParamData costItem1 = this.getCost(1);
|
||||||
|
@ -21,6 +21,7 @@ import emu.grasscutter.data.common.ItemParamData;
|
|||||||
import emu.grasscutter.data.def.ItemData;
|
import emu.grasscutter.data.def.ItemData;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.avatar.Avatar;
|
import emu.grasscutter.game.avatar.Avatar;
|
||||||
|
import emu.grasscutter.game.gacha.GachaBanner.BannerType;
|
||||||
import emu.grasscutter.game.inventory.GameItem;
|
import emu.grasscutter.game.inventory.GameItem;
|
||||||
import emu.grasscutter.game.inventory.Inventory;
|
import emu.grasscutter.game.inventory.Inventory;
|
||||||
import emu.grasscutter.game.inventory.ItemType;
|
import emu.grasscutter.game.inventory.ItemType;
|
||||||
@ -82,7 +83,7 @@ public class GachaManager {
|
|||||||
List<GachaBanner> banners = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, GachaBanner.class).getType());
|
List<GachaBanner> banners = Grasscutter.getGsonFactory().fromJson(fileReader, TypeToken.getParameterized(Collection.class, GachaBanner.class).getType());
|
||||||
if(banners.size() > 0) {
|
if(banners.size() > 0) {
|
||||||
for (GachaBanner banner : banners) {
|
for (GachaBanner banner : banners) {
|
||||||
getGachaBanners().put(banner.getGachaType(), banner);
|
getGachaBanners().put(banner.getScheduleId(), banner);
|
||||||
}
|
}
|
||||||
Grasscutter.getLogger().info("Banners successfully loaded.");
|
Grasscutter.getLogger().info("Banners successfully loaded.");
|
||||||
|
|
||||||
@ -236,7 +237,7 @@ public class GachaManager {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public synchronized void doPulls(Player player, int gachaType, int times) {
|
public synchronized void doPulls(Player player, int scheduleId, int times) {
|
||||||
// Sanity check
|
// Sanity check
|
||||||
if (times != 10 && times != 1) {
|
if (times != 10 && times != 1) {
|
||||||
return;
|
return;
|
||||||
@ -248,7 +249,7 @@ public class GachaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Get banner
|
// Get banner
|
||||||
GachaBanner banner = this.getGachaBanners().get(gachaType);
|
GachaBanner banner = this.getGachaBanners().get(scheduleId);
|
||||||
if (banner == null) {
|
if (banner == null) {
|
||||||
player.sendPacket(new PacketDoGachaRsp());
|
player.sendPacket(new PacketDoGachaRsp());
|
||||||
return;
|
return;
|
||||||
@ -285,7 +286,7 @@ public class GachaManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Write gacha record
|
// Write gacha record
|
||||||
GachaRecord gachaRecord = new GachaRecord(itemId, player.getUid(), gachaType);
|
GachaRecord gachaRecord = new GachaRecord(itemId, player.getUid(), banner.getGachaType());
|
||||||
DatabaseHelper.saveGachaRecord(gachaRecord);
|
DatabaseHelper.saveGachaRecord(gachaRecord);
|
||||||
|
|
||||||
// Create gacha item
|
// Create gacha item
|
||||||
@ -411,8 +412,13 @@ public class GachaManager {
|
|||||||
private synchronized GetGachaInfoRsp createProto(String sessionKey) {
|
private synchronized GetGachaInfoRsp createProto(String sessionKey) {
|
||||||
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
GetGachaInfoRsp.Builder proto = GetGachaInfoRsp.newBuilder().setGachaRandom(12345);
|
||||||
|
|
||||||
|
long currentTime = System.currentTimeMillis() / 1000L;
|
||||||
|
|
||||||
for (GachaBanner banner : getGachaBanners().values()) {
|
for (GachaBanner banner : getGachaBanners().values()) {
|
||||||
proto.addGachaInfoList(banner.toProto(sessionKey));
|
if ((banner.getEndTime() >= currentTime && banner.getBeginTime() <= currentTime) || (banner.getBannerType() == BannerType.STANDARD))
|
||||||
|
{
|
||||||
|
proto.addGachaInfoList(banner.toProto(sessionKey));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return proto.build();
|
return proto.build();
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
package emu.grasscutter.server.event.internal;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.core.AppenderBase;
|
||||||
|
import emu.grasscutter.server.event.types.ServerEvent;
|
||||||
|
|
||||||
|
public class ServerLogEvent extends ServerEvent {
|
||||||
|
ILoggingEvent loggingEvent;
|
||||||
|
String consoleMessage;
|
||||||
|
|
||||||
|
public ServerLogEvent(Type type, ILoggingEvent loggingEvent, String consoleMessage) {
|
||||||
|
super(type);
|
||||||
|
this.loggingEvent = loggingEvent;
|
||||||
|
this.consoleMessage = consoleMessage;
|
||||||
|
}
|
||||||
|
|
||||||
|
public ILoggingEvent getLoggingEvent() { return loggingEvent; }
|
||||||
|
|
||||||
|
public String getConsoleMessage() {
|
||||||
|
return consoleMessage;
|
||||||
|
}
|
||||||
|
}
|
@ -104,9 +104,9 @@ public final class GachaHandler implements Router {
|
|||||||
.replace("{{LANGUAGE}}", Utils.getLanguageCode(account.getLocale()));
|
.replace("{{LANGUAGE}}", Utils.getLanguageCode(account.getLocale()));
|
||||||
|
|
||||||
// Get the banner info for the banner we want.
|
// Get the banner info for the banner we want.
|
||||||
int gachaType = Integer.parseInt(request.query("gachaType"));
|
int scheduleId = Integer.parseInt(request.query("scheduleId"));
|
||||||
GachaManager manager = Grasscutter.getGameServer().getGachaManager();
|
GachaManager manager = Grasscutter.getGameServer().getGachaManager();
|
||||||
GachaBanner banner = manager.getGachaBanners().get(gachaType);
|
GachaBanner banner = manager.getGachaBanners().get(scheduleId);
|
||||||
|
|
||||||
// Add 5-star items.
|
// Add 5-star items.
|
||||||
Set<String> fiveStarItems = new LinkedHashSet<>();
|
Set<String> fiveStarItems = new LinkedHashSet<>();
|
||||||
|
@ -4,11 +4,14 @@ import emu.grasscutter.GameConstants;
|
|||||||
import emu.grasscutter.Grasscutter;
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.server.http.objects.HttpJsonResponse;
|
import emu.grasscutter.server.http.objects.HttpJsonResponse;
|
||||||
import emu.grasscutter.server.http.Router;
|
import emu.grasscutter.server.http.Router;
|
||||||
|
import emu.grasscutter.server.http.objects.WebStaticVersionResponse;
|
||||||
import express.Express;
|
import express.Express;
|
||||||
import express.http.Request;
|
import express.http.Request;
|
||||||
import express.http.Response;
|
import express.http.Response;
|
||||||
import io.javalin.Javalin;
|
import io.javalin.Javalin;
|
||||||
|
|
||||||
|
import static emu.grasscutter.Configuration.ACCOUNT;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Handles all generic, hard-coded responses.
|
* Handles all generic, hard-coded responses.
|
||||||
*/
|
*/
|
||||||
@ -41,15 +44,16 @@ public final class GenericHandler implements Router {
|
|||||||
express.all("/perf/config/verify", new HttpJsonResponse("{\"code\":0}"));
|
express.all("/perf/config/verify", new HttpJsonResponse("{\"code\":0}"));
|
||||||
|
|
||||||
// webstatic-sea.hoyoverse.com
|
// webstatic-sea.hoyoverse.com
|
||||||
express.get("/admin/mi18n/plat_oversea/*", new HttpJsonResponse("{\"version\":51}"));
|
express.get("/admin/mi18n/plat_oversea/*", new WebStaticVersionResponse());
|
||||||
|
|
||||||
express.get("/status/server", GenericHandler::serverStatus);
|
express.get("/status/server", GenericHandler::serverStatus);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void serverStatus(Request request, Response response) {
|
private static void serverStatus(Request request, Response response) {
|
||||||
int playerCount = Grasscutter.getGameServer().getPlayers().size();
|
int playerCount = Grasscutter.getGameServer().getPlayers().size();
|
||||||
|
int maxPlayer = ACCOUNT.maxPlayer;
|
||||||
String version = GameConstants.VERSION;
|
String version = GameConstants.VERSION;
|
||||||
|
|
||||||
response.send("{\"retcode\":0,\"status\":{\"playerCount\":" + playerCount + ",\"version\":\"" + version + "\"}}");
|
response.send("{\"retcode\":0,\"status\":{\"playerCount\":" + playerCount + ",\"maxPlayer\":" + maxPlayer + ",\"version\":\"" + version + "\"}}");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,41 @@
|
|||||||
|
package emu.grasscutter.server.http.objects;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
|
import emu.grasscutter.data.DataLoader;
|
||||||
|
import emu.grasscutter.utils.FileUtils;
|
||||||
|
import emu.grasscutter.utils.Utils;
|
||||||
|
import express.http.HttpContextHandler;
|
||||||
|
import express.http.MediaType;
|
||||||
|
import express.http.Request;
|
||||||
|
import express.http.Response;
|
||||||
|
import io.javalin.core.util.FileUtil;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
|
||||||
|
import static emu.grasscutter.Configuration.DATA;
|
||||||
|
|
||||||
|
public class WebStaticVersionResponse implements HttpContextHandler {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void handle(Request request, Response response) throws IOException {
|
||||||
|
if(request.path().contains("version")) {
|
||||||
|
getPageResources("/webstatic/version.json", response);
|
||||||
|
return;
|
||||||
|
} else { // TODO other versions
|
||||||
|
getPageResources("/webstatic/en.json", response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void getPageResources(String path, Response response) {
|
||||||
|
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) {
|
||||||
|
Grasscutter.getLogger().warn("File does not exist: " + path);
|
||||||
|
response.status(404);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -12,6 +12,6 @@ public class HandlerDoGachaReq extends PacketHandler {
|
|||||||
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
public void handle(GameSession session, byte[] header, byte[] payload) throws Exception {
|
||||||
DoGachaReq req = DoGachaReq.parseFrom(payload);
|
DoGachaReq req = DoGachaReq.parseFrom(payload);
|
||||||
|
|
||||||
session.getServer().getGachaManager().doPulls(session.getPlayer(), req.getGachaType(), req.getGachaTimes());
|
session.getServer().getGachaManager().doPulls(session.getPlayer(), req.getGachaScheduleId(), req.getGachaTimes());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
package emu.grasscutter.server.packet.recv;
|
package emu.grasscutter.server.packet.recv;
|
||||||
|
|
||||||
|
import emu.grasscutter.Grasscutter;
|
||||||
import emu.grasscutter.database.DatabaseHelper;
|
import emu.grasscutter.database.DatabaseHelper;
|
||||||
import emu.grasscutter.game.player.Player;
|
import emu.grasscutter.game.player.Player;
|
||||||
import emu.grasscutter.net.packet.BasePacket;
|
import emu.grasscutter.net.packet.BasePacket;
|
||||||
@ -12,6 +13,8 @@ import emu.grasscutter.server.game.GameSession.SessionState;
|
|||||||
import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp;
|
import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp;
|
||||||
import emu.grasscutter.server.packet.send.PacketTakeAchievementRewardReq;
|
import emu.grasscutter.server.packet.send.PacketTakeAchievementRewardReq;
|
||||||
|
|
||||||
|
import static emu.grasscutter.Configuration.ACCOUNT;
|
||||||
|
|
||||||
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
|
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
|
||||||
public class HandlerPlayerLoginReq extends PacketHandler {
|
public class HandlerPlayerLoginReq extends PacketHandler {
|
||||||
|
|
||||||
@ -21,7 +24,12 @@ public class HandlerPlayerLoginReq extends PacketHandler {
|
|||||||
if (session.getAccount() == null) {
|
if (session.getAccount() == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Max players limit
|
||||||
|
if (ACCOUNT.maxPlayer > -1 && Grasscutter.getGameServer().getPlayers().size() >= ACCOUNT.maxPlayer) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
// Parse request
|
// Parse request
|
||||||
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
|
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
|
||||||
|
|
||||||
|
@ -110,6 +110,7 @@ public class ConfigContainer {
|
|||||||
public static class Account {
|
public static class Account {
|
||||||
public boolean autoCreate = false;
|
public boolean autoCreate = false;
|
||||||
public String[] defaultPermissions = {};
|
public String[] defaultPermissions = {};
|
||||||
|
public int maxPlayer = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Server options. */
|
/* Server options. */
|
||||||
|
@ -97,7 +97,7 @@ public final class FileUtils {
|
|||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
// Eclipse puts resources in its bin folder
|
// Eclipse puts resources in its bin folder
|
||||||
File f = new File(jarPath + "defaults/data/");
|
File f = new File(System.getProperty("user.dir") + folder);
|
||||||
|
|
||||||
if (!f.exists() || f.listFiles().length == 0) {
|
if (!f.exists() || f.listFiles().length == 0) {
|
||||||
return null;
|
return null;
|
||||||
|
@ -0,0 +1,31 @@
|
|||||||
|
package emu.grasscutter.utils;
|
||||||
|
|
||||||
|
import ch.qos.logback.classic.spi.ILoggingEvent;
|
||||||
|
import ch.qos.logback.core.AppenderBase;
|
||||||
|
import ch.qos.logback.core.encoder.Encoder;
|
||||||
|
import ch.qos.logback.core.spi.DeferredProcessingAware;
|
||||||
|
import ch.qos.logback.core.status.ErrorStatus;
|
||||||
|
import emu.grasscutter.server.event.internal.ServerLogEvent;
|
||||||
|
import emu.grasscutter.server.event.types.ServerEvent;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.nio.charset.StandardCharsets;
|
||||||
|
|
||||||
|
public class ServerLogEventAppender<E> extends AppenderBase<E> {
|
||||||
|
protected Encoder<E> encoder;
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void append(E event) {
|
||||||
|
byte[] byteArray = this.encoder.encode(event);
|
||||||
|
ServerLogEvent sle = new ServerLogEvent(ServerEvent.Type.GAME, (ILoggingEvent) event, new String(byteArray, StandardCharsets.UTF_8));
|
||||||
|
sle.call();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Encoder<E> getEncoder() {
|
||||||
|
return encoder;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setEncoder(Encoder<E> encoder) {
|
||||||
|
this.encoder = encoder;
|
||||||
|
}
|
||||||
|
}
|
@ -24,6 +24,7 @@
|
|||||||
"account": {
|
"account": {
|
||||||
"login_attempt": "[Dispatch] Client %s is trying to log in.",
|
"login_attempt": "[Dispatch] Client %s is trying to log in.",
|
||||||
"login_success": "[Dispatch] Client %s logged in as %s.",
|
"login_success": "[Dispatch] Client %s logged in as %s.",
|
||||||
|
"login_max_player_limit": "[Dispatch] Client %s failed to log in: The number of online players has reached the limit",
|
||||||
"login_token_attempt": "[Dispatch] Client %s is trying to log in via token.",
|
"login_token_attempt": "[Dispatch] Client %s is trying to log in via token.",
|
||||||
"login_token_error": "[Dispatch] Client %s failed to log in via token.",
|
"login_token_error": "[Dispatch] Client %s failed to log in via token.",
|
||||||
"login_token_success": "[Dispatch] Client %s logged in via token as %s.",
|
"login_token_success": "[Dispatch] Client %s logged in via token as %s.",
|
||||||
@ -35,7 +36,8 @@
|
|||||||
"account_cache_error": "Game account cache information error.",
|
"account_cache_error": "Game account cache information error.",
|
||||||
"session_key_error": "Wrong session key.",
|
"session_key_error": "Wrong session key.",
|
||||||
"username_error": "Username not found.",
|
"username_error": "Username not found.",
|
||||||
"username_create_error": "Username not found, create failed."
|
"username_create_error": "Username not found, create failed.",
|
||||||
|
"server_max_player_limit": "The number of online players has reached the limit"
|
||||||
},
|
},
|
||||||
"router_error": "[Dispatch] Unable to attach router."
|
"router_error": "[Dispatch] Unable to attach router."
|
||||||
},
|
},
|
||||||
|
@ -21,6 +21,7 @@
|
|||||||
"account": {
|
"account": {
|
||||||
"login_attempt": "[Dispatch] Klient %s próbuje się zalogować",
|
"login_attempt": "[Dispatch] Klient %s próbuje się zalogować",
|
||||||
"login_success": "[Dispatch] Klient %s zalogował się jako %s",
|
"login_success": "[Dispatch] Klient %s zalogował się jako %s",
|
||||||
|
"login_max_player_limit": "[Dispatch] Klient %s nie powiodło się: Liczba graczy online osiągnęła limit",
|
||||||
"login_token_attempt": "[Dispatch] Klient %s próbuje się zalogować poprzez token",
|
"login_token_attempt": "[Dispatch] Klient %s próbuje się zalogować poprzez token",
|
||||||
"login_token_error": "[Dispatch] Klient %s nie mógł się zalogować poprzez token",
|
"login_token_error": "[Dispatch] Klient %s nie mógł się zalogować poprzez token",
|
||||||
"login_token_success": "[Dispatch] Klient %s zalogował się poprzez token jako %s",
|
"login_token_success": "[Dispatch] Klient %s zalogował się poprzez token jako %s",
|
||||||
@ -32,7 +33,8 @@
|
|||||||
"account_cache_error": "Błąd pamięci cache konta gry",
|
"account_cache_error": "Błąd pamięci cache konta gry",
|
||||||
"session_key_error": "Błędny klucz sesji.",
|
"session_key_error": "Błędny klucz sesji.",
|
||||||
"username_error": "Nazwa użytkownika nie znaleziona.",
|
"username_error": "Nazwa użytkownika nie znaleziona.",
|
||||||
"username_create_error": "Nazwa użytkownika nie znaleziona, tworzenie nie powiodło się."
|
"username_create_error": "Nazwa użytkownika nie znaleziona, tworzenie nie powiodło się.",
|
||||||
|
"server_max_player_limit": "Liczba graczy online osiągnęła limit"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"account": {
|
"account": {
|
||||||
"login_attempt": "[Dispatch] 客户端 %s 正在尝试登录",
|
"login_attempt": "[Dispatch] 客户端 %s 正在尝试登录",
|
||||||
"login_success": "[Dispatch] 客户端 %s 已登录,UID 为 %s",
|
"login_success": "[Dispatch] 客户端 %s 已登录,UID 为 %s",
|
||||||
|
"login_max_player_limit": "[Dispatch] 客户端 %s 登录失败:在线人数已满",
|
||||||
"login_token_attempt": "[Dispatch] 客户端 %s 正在尝试使用 token 登录",
|
"login_token_attempt": "[Dispatch] 客户端 %s 正在尝试使用 token 登录",
|
||||||
"login_token_error": "[Dispatch] 客户端 %s 使用 token 登录失败",
|
"login_token_error": "[Dispatch] 客户端 %s 使用 token 登录失败",
|
||||||
"login_token_success": "[Dispatch] 客户端 %s 已通过 token 登录,UID 为 %s",
|
"login_token_success": "[Dispatch] 客户端 %s 已通过 token 登录,UID 为 %s",
|
||||||
@ -35,7 +36,8 @@
|
|||||||
"account_cache_error": "游戏账号缓存信息错误",
|
"account_cache_error": "游戏账号缓存信息错误",
|
||||||
"session_key_error": "会话密钥错误",
|
"session_key_error": "会话密钥错误",
|
||||||
"username_error": "未找到此用户名",
|
"username_error": "未找到此用户名",
|
||||||
"username_create_error": "未找到用户名,建立连接失败"
|
"username_create_error": "未找到用户名,建立连接失败",
|
||||||
|
"server_max_player_limit": "服务器在线人数已满"
|
||||||
},
|
},
|
||||||
"router_error": "[Dispatch] 无法连接路由"
|
"router_error": "[Dispatch] 无法连接路由"
|
||||||
},
|
},
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
"account": {
|
"account": {
|
||||||
"login_attempt": "[Dispatch] 客戶端 %s 正在嘗試登入",
|
"login_attempt": "[Dispatch] 客戶端 %s 正在嘗試登入",
|
||||||
"login_success": "[Dispatch] 客戶端 %s 已登入,UID為 %s",
|
"login_success": "[Dispatch] 客戶端 %s 已登入,UID為 %s",
|
||||||
|
"login_max_player_limit": "[Dispatch] 客戶端 %s 登入失敗:在綫人數已滿",
|
||||||
"login_token_attempt": "[Dispatch] 客戶端 %s 正在嘗試用憑證登入",
|
"login_token_attempt": "[Dispatch] 客戶端 %s 正在嘗試用憑證登入",
|
||||||
"login_token_error": "[Dispatch] 客戶端 %s 使用憑證登入失敗",
|
"login_token_error": "[Dispatch] 客戶端 %s 使用憑證登入失敗",
|
||||||
"login_token_success": "[Dispatch] 客戶端 %s 已透過憑證登入,UID為 %s",
|
"login_token_success": "[Dispatch] 客戶端 %s 已透過憑證登入,UID為 %s",
|
||||||
@ -35,7 +36,8 @@
|
|||||||
"account_cache_error": "遊戲帳號緩存資訊錯誤",
|
"account_cache_error": "遊戲帳號緩存資訊錯誤",
|
||||||
"session_key_error": "對話密鑰不符。",
|
"session_key_error": "對話密鑰不符。",
|
||||||
"username_error": "未找到此用戶名。",
|
"username_error": "未找到此用戶名。",
|
||||||
"username_create_error": "未找到用戶名,建立失敗。"
|
"username_create_error": "未找到用戶名,建立失敗。",
|
||||||
|
"server_max_player_limit": "服務器在綫人數已滿"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"status": {
|
"status": {
|
||||||
|
@ -16,6 +16,11 @@
|
|||||||
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss'Z'} <%level:%class> %m%n</pattern>
|
<pattern>%d{yyyy-MM-dd'T'HH:mm:ss'Z'} <%level:%class> %m%n</pattern>
|
||||||
</encoder>
|
</encoder>
|
||||||
</appender>
|
</appender>
|
||||||
|
<appender name="SERVEREVENT" class="emu.grasscutter.utils.ServerLogEventAppender">
|
||||||
|
<encoder>
|
||||||
|
<pattern>%d{HH:mm:ss} <%highlight(%level):%gray(%class{0})> %msg%n</pattern>
|
||||||
|
</encoder>
|
||||||
|
</appender>
|
||||||
|
|
||||||
<logger name="org.reflections" level="OFF" />
|
<logger name="org.reflections" level="OFF" />
|
||||||
<logger name="emu.grasscutter" level="${LOG_LEVEL}" />
|
<logger name="emu.grasscutter" level="${LOG_LEVEL}" />
|
||||||
@ -23,5 +28,6 @@
|
|||||||
<root level="INFO">
|
<root level="INFO">
|
||||||
<appender-ref ref="STDOUT" />
|
<appender-ref ref="STDOUT" />
|
||||||
<appender-ref ref="FILE" />
|
<appender-ref ref="FILE" />
|
||||||
|
<appender-ref ref="SERVEREVENT" />
|
||||||
</root>
|
</root>
|
||||||
</Configuration>
|
</Configuration>
|
||||||
|
290
src/main/resources/webstatic/en.json
Normal file
290
src/main/resources/webstatic/en.json
Normal file
@ -0,0 +1,290 @@
|
|||||||
|
{
|
||||||
|
"Apple": "Apple",
|
||||||
|
"Game Center": "Game Center",
|
||||||
|
"accept": "Accept",
|
||||||
|
"account_deactive": "Your current account is in the process of being deleted.",
|
||||||
|
"account_empty": "",
|
||||||
|
"account_login": "Log in using account & password",
|
||||||
|
"agree": "Agree",
|
||||||
|
"another_account": "Log in to another account",
|
||||||
|
"back": "",
|
||||||
|
"bind": "Link",
|
||||||
|
"bind_email": "Link email",
|
||||||
|
"bind_email_oversea": "Link Email",
|
||||||
|
"bind_email_success": "Email linked successfully",
|
||||||
|
"bind_request": "Linking...",
|
||||||
|
"cancel": "Cancel",
|
||||||
|
"cancel_pay": "Leave",
|
||||||
|
"captcha_empty": "Please enter SMS verification code",
|
||||||
|
"captcha_mail_empty": "Please enter the verification code from the email",
|
||||||
|
"captcha_success": "Verification code sent",
|
||||||
|
"change_password_success": "Password successfully changed",
|
||||||
|
"check_network": "Please check your Internet connection or refresh the page and try again",
|
||||||
|
"combo_download_downloading": "Downloading...",
|
||||||
|
"combo_download_failed_title": "Download Failed",
|
||||||
|
"combo_download_finish_content": "Download complete",
|
||||||
|
"combo_download_pause": "Pause",
|
||||||
|
"combo_download_speed": "Download speed: %s Time remaining: %s",
|
||||||
|
"combo_download_title": "Download Complete",
|
||||||
|
"combo_ensure_login": "Confirm login",
|
||||||
|
"combo_ensure_login_tips": "Logging in to desktop version of %s. Please confirm that this is you.",
|
||||||
|
"combo_expired_qrcode": "QR code expired",
|
||||||
|
"combo_go_setting": "Open Camera",
|
||||||
|
"combo_invalid_qrcode": "QR code invalid",
|
||||||
|
"combo_login_first": "Please log in first",
|
||||||
|
"combo_notice_auth_key_failed": "Failed to load Notices",
|
||||||
|
"combo_platform_cancel": "Cancel",
|
||||||
|
"combo_platform_ensure": "OK",
|
||||||
|
"combo_platform_ensure_exit": "Do you want to exit?",
|
||||||
|
"combo_platform_ensure_logout": "Select \"OK\" to log out",
|
||||||
|
"combo_qrcode_failed": "Login error, please try again",
|
||||||
|
"combo_qrcode_goto_setting": "Settings",
|
||||||
|
"combo_qrcode_goto_setting_tips": "Go to Settings > Apps and enable camera permissions in order to log in using the scan function.",
|
||||||
|
"combo_qrcode_notice_permission": "Please give this app permission to access your camera. You can do this in your phone's settings.",
|
||||||
|
"combo_qrcode_notice_scan": "Place the QR code within the frame",
|
||||||
|
"combo_qrcode_success": "Login successful",
|
||||||
|
"combo_qrcode_tips": "In order to log in via QR code scan, you must allow access to your camera.",
|
||||||
|
"combo_qrcode_title": "Scan",
|
||||||
|
"combo_re_login": "Please log in again",
|
||||||
|
"confirm_order": "Confirming payment...",
|
||||||
|
"continue_login": "",
|
||||||
|
"continue_pay": "Continue Payment",
|
||||||
|
"createOrder_failed": "Failed to create order",
|
||||||
|
"currency": "$",
|
||||||
|
"delete_account_notice": "Delete account login records? (Does not delete other account data)",
|
||||||
|
"delete_ensure": "Delete",
|
||||||
|
"determine_reactivate_account_or_not": "Would you like to reactivate it?",
|
||||||
|
"email_empty": "Please enter your email address",
|
||||||
|
"email_exist": "Email already registered. Log in?",
|
||||||
|
"email_register_tips": "Email not registered. Register now?",
|
||||||
|
"ensure": "OK",
|
||||||
|
"ensure_back": "Confirm and return",
|
||||||
|
"ensure_email": "Confirm registration email:\\n%s",
|
||||||
|
"enter_game": "Log in",
|
||||||
|
"existing_account": "Bind Account",
|
||||||
|
"exit": "Exit",
|
||||||
|
"facebook": "Facebook",
|
||||||
|
"fast_game": "Guest",
|
||||||
|
"fatigue_reminder_tip": "",
|
||||||
|
"file_upload_setting_camera_tip": "Go to \"Settings - Apps\" and allow camera permissions in order to use camera features.",
|
||||||
|
"file_upload_setting_microphone_tip": "Go to Settings > Apps and allow access to your microphone in order to use the video recording function in the feedback center.",
|
||||||
|
"file_upload_setting_photos_tip": "Go to Settings > Apps and enable photo permissions in order to upload images.",
|
||||||
|
"forget_pwd": "Forgot password?",
|
||||||
|
"gamecenter_tips": "Log in to Game Center in Settings",
|
||||||
|
"go_login": "Log in",
|
||||||
|
"go_pay": "Confirm and pay",
|
||||||
|
"go_register": "Register",
|
||||||
|
"guest_account": "Guest",
|
||||||
|
"guest_bind_email": "You are about to link the following email address: %s",
|
||||||
|
"guest_bind_failed": "Current account is not a guest account or user is not logged in",
|
||||||
|
"guest_bind_phone_notice": "To protect your data, please link at least one other account.",
|
||||||
|
"guest_login": "Guest login",
|
||||||
|
"guest_login_request": "Logging in as guest...",
|
||||||
|
"guest_login_tips": "Welcome, guest.",
|
||||||
|
"guest_pay_error": "Guest accounts cannot make purchases",
|
||||||
|
"http_time_out": "Connection failed. Try again later.",
|
||||||
|
"http_unknow_host": "Network error",
|
||||||
|
"if_cancel_pay": "Leave payment screen?",
|
||||||
|
"init_first": "Please complete initialization first.",
|
||||||
|
"input_account": "Enter mobile number or email address",
|
||||||
|
"input_code_number": "Enter SMS verification code",
|
||||||
|
"input_email": "Enter email address",
|
||||||
|
"input_get_code": "Get Code",
|
||||||
|
"input_mail_capture": "Verification Code",
|
||||||
|
"input_mail_code": "",
|
||||||
|
"input_mi_email": "Enter email address",
|
||||||
|
"input_password": "Enter password",
|
||||||
|
"input_password_ensure": "Enter password again",
|
||||||
|
"input_phone_number": "Enter mobile number to register/log in",
|
||||||
|
"input_phone_number_bind": "Enter mobile number",
|
||||||
|
"input_re_get_code": "Try again",
|
||||||
|
"invaild_captcha": "Invalid SMS verification code, please check",
|
||||||
|
"invaild_mail_captcha": "Verification code invalid, please check",
|
||||||
|
"invaild_name": "Please enter your name correctly",
|
||||||
|
"invaild_password": "Please enter the correct password",
|
||||||
|
"invaild_phone": "Please provide a valid mobile phone number",
|
||||||
|
"invaild_realname": "Please provide a valid ID Card number",
|
||||||
|
"last_login_day_number": "Last login %s days ago",
|
||||||
|
"last_login_hour_number": "Last login %s hours ago",
|
||||||
|
"last_login_just_now": "Last login just now",
|
||||||
|
"last_login_minute_number": "Last login %s minutes ago",
|
||||||
|
"last_login_month_number": "Last login six months ago",
|
||||||
|
"last_login_time": "Last login on %s",
|
||||||
|
"login": "Log In",
|
||||||
|
"login_again": "Please log in again",
|
||||||
|
"login_bind_mobile": "",
|
||||||
|
"login_bind_mobile_verify_mail": "",
|
||||||
|
"login_bind_safe_notice": "Before logging in to the game, please link your account with a security phone number",
|
||||||
|
"login_failed": "Login failed",
|
||||||
|
"login_first": "Please log in first",
|
||||||
|
"login_request": "Logging in...",
|
||||||
|
"login_verify_by_bind": "Verify using linked number",
|
||||||
|
"login_verify_by_bind_phone": "Verify using linked number: %s",
|
||||||
|
"login_verify_by_safety": "Verify using security phone number",
|
||||||
|
"login_verify_by_safety_phone": "Verify using security phone number: %s",
|
||||||
|
"login_verify_notice": "Verification is required when you log in using a new device.",
|
||||||
|
"meet_problem": "Having Problems?",
|
||||||
|
"more": "More",
|
||||||
|
"name_empty": "Please enter your full name",
|
||||||
|
"network_json_error": "System error. Please try again later.",
|
||||||
|
"network_time_out": "Connection failed. Try again later.",
|
||||||
|
"next": "Next",
|
||||||
|
"no_account": "Haven't signed up yet?",
|
||||||
|
"no_captcha": "Please obtain a verification code",
|
||||||
|
"no_more_interruptions_today": "Don't show again today",
|
||||||
|
"other_device_know": "OK",
|
||||||
|
"other_device_login_day_number": "Logged in %s day(s) ago",
|
||||||
|
"other_device_login_device_info": "Login Device Information:",
|
||||||
|
"other_device_login_hour_number": "Logged in %s hour(s) ago",
|
||||||
|
"other_device_login_minute_number": "Logged in %s minute(s) ago",
|
||||||
|
"other_device_login_month_number": "Logged in %s month(s) ago",
|
||||||
|
"other_device_suggest": "If this was not you, we recommend that you link an email to your account.",
|
||||||
|
"other_device_title": "Your account was logged into on another device.",
|
||||||
|
"other_way_verification": "Other Verification Methods",
|
||||||
|
"oversea_guardian": "접속하신 아이디는 만 14세 미만 법정대리인 동의가 필요한 아이디로써 관련 규정에 따라 법정대리인의 동의가 필요합니다. \\\\n관련 정보를 입력하고 인증해 주세요",
|
||||||
|
"oversea_input_account": "Enter email/username",
|
||||||
|
"oversea_pay": "Pay",
|
||||||
|
"oversea_pay_button": "Proceed to payment",
|
||||||
|
"oversea_pay_card_payment": "Credit card",
|
||||||
|
"oversea_pay_error": "Loading failed",
|
||||||
|
"oversea_pay_error_btn": "Reload",
|
||||||
|
"oversea_pay_error_tips": "Try again later.",
|
||||||
|
"oversea_pay_operator": "Select payment method",
|
||||||
|
"oversea_pay_product_name": "Product",
|
||||||
|
"oversea_pay_success": "Payment successful",
|
||||||
|
"oversea_pay_success_btn": "Return to game",
|
||||||
|
"oversea_pay_success_tips": "Please enter game to access product",
|
||||||
|
"oversea_pay_type": "Select payment type",
|
||||||
|
"oversea_realname": "관련 규정에 따라 실명인증을 완료해 주세요\\\\n궁금하신 점이 있을 경우 고객센터로 문의하세요",
|
||||||
|
"password_empty": "Enter password",
|
||||||
|
"pay": "Pay",
|
||||||
|
"pay_aid_uid_mismatch_tips": "Your account login status has expired, please log in again.",
|
||||||
|
"pay_back_game": "Return to game %s",
|
||||||
|
"pay_bind_notice": "Guest accounts must be linked to another account before making payment",
|
||||||
|
"pay_choose_new_way": "Payment incomplete. Please select another payment method to continue.",
|
||||||
|
"pay_failed": "Payment failed. Try again later.",
|
||||||
|
"pay_failed_notice": "Payment failed. Please try again.",
|
||||||
|
"pay_limit_amount_tips": "",
|
||||||
|
"pay_loading_notice": "If payment was successful, please check your account shortly.",
|
||||||
|
"pay_loading_time": "(%s)",
|
||||||
|
"pay_success": "Payment successful",
|
||||||
|
"pay_success_notice": "You have successfully purchased: %s",
|
||||||
|
"pay_time_out": "Payment timeout",
|
||||||
|
"pay_turn": "Proceed to payment",
|
||||||
|
"phone_empty": "Enter mobile number",
|
||||||
|
"phone_login": "Log in using phone",
|
||||||
|
"phone_message_request": "Verifying...",
|
||||||
|
"phone_message_request_fail": "Failed to send verification code. Please try again.",
|
||||||
|
"phone_register_tips": "Mobile number not yet registered. Register now?",
|
||||||
|
"phone_registered": "Number already registered. Enter verification code to log in.",
|
||||||
|
"privacy": "Privacy Policy",
|
||||||
|
"product_name": "Product",
|
||||||
|
"re_login": "Please log in again",
|
||||||
|
"re_read": "Read Again",
|
||||||
|
"re_register": "Enter again",
|
||||||
|
"reactivate_accoun_notice_cn": "Your account is currently in the \"deletion confirmation period.\"\\nDo you want to reactivate your account and log in?\\nPlease note that the deletion process will be canceled after reactivation.\\n※The deletion confirmation period is 3 days from the date on which you request the deletion.",
|
||||||
|
"reactivate_accoun_notice_os": "Your account is currently in the \"deletion confirmation period.\"\\nDo you want to reactivate your account and log in?\\nPlease note that the deletion process will be canceled after reactivation.\\n※The deletion confirmation period is 30 days from the date on which you request the deletion.",
|
||||||
|
"reactivate_account": "Reactivate Account",
|
||||||
|
"read_user_agreement_first": "Please read and agree to the Terms of Service",
|
||||||
|
"real_name_request": "Verifying real name...",
|
||||||
|
"real_people_agree": "",
|
||||||
|
"real_people_agreement": "",
|
||||||
|
"real_people_anti_addiction_pc_tip": "",
|
||||||
|
"real_people_anti_addiction_rule_click": "",
|
||||||
|
"real_people_anti_addiction_tip": "",
|
||||||
|
"real_people_back_tip": "",
|
||||||
|
"real_people_continue_verify": "",
|
||||||
|
"real_people_message": "",
|
||||||
|
"real_people_minor_privacy": "",
|
||||||
|
"real_people_modify": "",
|
||||||
|
"real_people_not_verify": "",
|
||||||
|
"real_people_pc_tip": "",
|
||||||
|
"real_people_real_name_full_name": "",
|
||||||
|
"real_people_real_name_identity_card": "",
|
||||||
|
"real_people_real_name_info_tip": "",
|
||||||
|
"real_people_request_camera_tip": "",
|
||||||
|
"real_people_search_result": "",
|
||||||
|
"real_people_service_agreement": "",
|
||||||
|
"real_people_setting_camera_tip": "",
|
||||||
|
"real_people_start_verify": "",
|
||||||
|
"real_people_title": "",
|
||||||
|
"real_people_verify_cancel": "",
|
||||||
|
"real_people_verify_fail": "",
|
||||||
|
"real_people_verify_success": "",
|
||||||
|
"real_people_wait_search_result": "",
|
||||||
|
"realname_account": "Name on ID Card",
|
||||||
|
"realname_account_notice": "Last name\\u3000First name",
|
||||||
|
"realname_button_finish": "Complete verification",
|
||||||
|
"realname_close_notice": "To finish account registration, you must complete real-name verification. Otherwise, you will be returned to the %s screen.",
|
||||||
|
"realname_continue": "Continue verification",
|
||||||
|
"realname_empty": "Please enter your ID Card number",
|
||||||
|
"realname_failed": "Real-name verification failed. Please try again.",
|
||||||
|
"realname_notice": "Users must provide an ID to play online. For a smooth, uninterrupted gaming experience, please enter your ID information below.",
|
||||||
|
"realname_number": "ID Card Number",
|
||||||
|
"realname_number_notice": "ID Card",
|
||||||
|
"realname_pay_close_notice": "Real-name verification must be completed before payment can be made. Are you sure you want to cancel?",
|
||||||
|
"realname_success": "Real-name verification successful",
|
||||||
|
"refresh": "Refresh",
|
||||||
|
"refuse": "Refuse",
|
||||||
|
"register_bind": "Register and link",
|
||||||
|
"register_email": "Register with email address",
|
||||||
|
"register_login": "Register and log in",
|
||||||
|
"register_new_account": "Register",
|
||||||
|
"register_now": "Register now",
|
||||||
|
"register_phone": "Register with phone number",
|
||||||
|
"register_request": "Registering...",
|
||||||
|
"second_real_name_hint": "",
|
||||||
|
"second_real_name_verify_hint": "",
|
||||||
|
"send_mail_success": "A verification code has been sent to your email address (%s). Please check your email.",
|
||||||
|
"share_image_request_photos_tip": "Access to your photos is required in order to use the photo sharing function.",
|
||||||
|
"share_image_setting_photos_tip": "Go to Settings > Apps and allow access to your photos in order to use the photo sharing function.",
|
||||||
|
"sign_in_with": "Log in with",
|
||||||
|
"status_code_429": "Network busy. Please try again later.",
|
||||||
|
"status_code_4xx": "Network busy. Please try again later.",
|
||||||
|
"status_code_5xx": "Server busy. Please try again later.",
|
||||||
|
"suggest_bind_email": "To improve your account security, it is strongly recommended that you link your email address",
|
||||||
|
"suggest_device_grant": "You must complete security verification when logging in on a new device",
|
||||||
|
"suggest_verify_phone": "To improve your account security, it is strongly recommended that you link your email address.\nPlease complete the security verification first.",
|
||||||
|
"tips_bind_account": "Please link at least one account as soon as possible to protect your data and to avoid losing it.",
|
||||||
|
"tips_bind_success": "Sucessfully linked with: %s",
|
||||||
|
"tips_enter_game": "Welcome, %s!",
|
||||||
|
"tips_exprience_full": "Dear player, guest accounts provide a limited experience of up to n miHoYo games.\\n\\nFor a better gaming experience, it is highly recommended to register a full account.",
|
||||||
|
"tips_mail_capture": "Verification code sent to: %s",
|
||||||
|
"tips_ok": "OK",
|
||||||
|
"tips_prefix_verify_email": "Verify linked email:",
|
||||||
|
"tips_prefix_verify_mobile": "Verify using linked number:",
|
||||||
|
"tips_request_camera_permission": "In order to upload images in the Feedback Center, you must allow access to your camera.",
|
||||||
|
"tips_request_microphone_permission": "In order to use the video recording function in the feedback center, you must allow recording permissions.",
|
||||||
|
"tips_request_photos_permission": "In order to take and upload photos in the feedback center, you must allow access to your photos and camera.",
|
||||||
|
"title_realname": "Real-name Verification",
|
||||||
|
"token_invalid": "Login expired, please log in again",
|
||||||
|
"twitter": "Twitter",
|
||||||
|
"twitter_login": "Twitter",
|
||||||
|
"update_notice": "The Terms of Service or Privacy Policy has been updated",
|
||||||
|
"user_agreement": "Terms of Service",
|
||||||
|
"user_agreement_agree_tips": "Please carefully read the Terms of Service and Privacy Policy, and tick to agree",
|
||||||
|
"user_agreement_all_agree": "Agree to all the following",
|
||||||
|
"user_agreement_content": "Please read carefully and understand the terms before agreeing.",
|
||||||
|
"user_agreement_link_click_desc": "Tap the following link to read the full terms:",
|
||||||
|
"user_agreement_marketing_content": "After carefully reading and agreeing to the policies, please select Accept",
|
||||||
|
"user_agreement_marketing_update_title": "Marketing Agreement Update Notice",
|
||||||
|
"user_agreement_notice": "I have read and agree to the %s and %s",
|
||||||
|
"user_agreement_notice_content": "",
|
||||||
|
"user_agreement_notice_content_with_third_privacy": "",
|
||||||
|
"user_agreement_notice_minors": "",
|
||||||
|
"user_agreement_notice_privacy": "Privacy Policy",
|
||||||
|
"user_agreement_notice_third_privacy": "",
|
||||||
|
"user_agreement_notice_ua": "Terms of Service",
|
||||||
|
"user_agreement_optional": "(Optional)",
|
||||||
|
"user_agreement_refuse_tips": "Please read and accept our Terms of Service and Privacy Policy before you continue playing.",
|
||||||
|
"user_agreement_required": "(Required)",
|
||||||
|
"user_agreement_title": "Terms of Service and Privacy Policy Notice",
|
||||||
|
"user_agreement_update_content": "Please read carefully and understand the terms before agreeing.",
|
||||||
|
"user_agreement_update_title": "Terms of Service and Privacy Policy Update Notice",
|
||||||
|
"user_center": "User Center",
|
||||||
|
"username_empty": "Please enter email address/username",
|
||||||
|
"verify_email": "",
|
||||||
|
"verify_finish": "",
|
||||||
|
"verify_other": "",
|
||||||
|
"verify_phone": ""
|
||||||
|
}
|
3
src/main/resources/webstatic/version.json
Normal file
3
src/main/resources/webstatic/version.json
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
{
|
||||||
|
"version": 51
|
||||||
|
}
|
Reference in New Issue
Block a user