Commit 9125bacf authored by ButterCookies's avatar ButterCookies Committed by GitHub
Browse files

Set the maximum number of player on the server through the config.json (#1001)

* Show server status to three-party game launcher

* Set the maximum number of player on the server through the config.json

* modify the logical order and show the number of maxplayer to API /status/server

* Now even players who have token already cannot bypass the maxPlayer check
parent 2a467a48
......@@ -23,14 +23,16 @@ public final class DefaultAuthenticators {
var requestData = request.getPasswordRequest();
assert requestData != null; // This should never be null.
int playerCount = Grasscutter.getGameServer().getPlayers().size();
boolean successfulLogin = false;
String address = request.getRequest().ip();
String responseMessage = translate("messages.dispatch.account.username_error");
String loggerMessage = "";
// Get account from database.
Account account = DatabaseHelper.getAccountByName(requestData.account);
if (ACCOUNT.maxPlayer <= -1 || playerCount < ACCOUNT.maxPlayer) {
// Check if account exists.
if(account == null && ACCOUNT.autoCreate) {
// This account has been created AUTOMATICALLY. There will be no permissions added.
......@@ -49,6 +51,14 @@ public final class DefaultAuthenticators {
}
} 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);
}
// Set response data.
if(successfulLogin) {
......@@ -57,15 +67,13 @@ public final class DefaultAuthenticators {
response.data.account.token = account.generateSessionKey();
response.data.account.email = account.getEmail();
// Log the login.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_success", address, account.getId()));
loggerMessage = translate("messages.dispatch.account.login_success", address, account.getId());
} else {
response.retcode = -201;
response.message = responseMessage;
// Log the failure.
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_exist_error", address));
}
Grasscutter.getLogger().info(loggerMessage);
return response;
}
......@@ -83,10 +91,14 @@ public final class DefaultAuthenticators {
boolean successfulLogin;
String address = request.getRequest().ip();
String loggerMessage;
int playerCount = Grasscutter.getGameServer().getPlayers().size();
// Log the attempt.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_attempt", address));
if (ACCOUNT.maxPlayer <= -1 || playerCount < ACCOUNT.maxPlayer) {
// Get account from database.
Account account = DatabaseHelper.getAccountById(requestData.uid);
......@@ -101,15 +113,23 @@ public final class DefaultAuthenticators {
response.data.account.email = account.getEmail();
// Log the login.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_success", address, requestData.uid));
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.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_error", address));
loggerMessage = translate("messages.dispatch.account.login_token_error", address);
}
} else {
response.retcode = -201;
response.message = translate("messages.dispatch.account.server_max_player_limit");
loggerMessage = translate("messages.dispatch.account.login_max_player_limit", address);
}
Grasscutter.getLogger().info(loggerMessage);
return response;
}
}
......@@ -127,7 +147,10 @@ public final class DefaultAuthenticators {
boolean successfulLogin;
String address = request.getRequest().ip();
String loggerMessage;
int playerCount = Grasscutter.getGameServer().getPlayers().size();
if (ACCOUNT.maxPlayer <= -1 || playerCount < ACCOUNT.maxPlayer) {
// Get account from database.
Account account = DatabaseHelper.getAccountById(loginData.uid);
......@@ -142,15 +165,23 @@ public final class DefaultAuthenticators {
response.data.combo_token = account.generateLoginToken();
// Log the login.
Grasscutter.getLogger().info(translate("messages.dispatch.account.combo_token_success", address));
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.
Grasscutter.getLogger().info(translate("messages.dispatch.account.combo_token_error", address));
loggerMessage = translate("messages.dispatch.account.combo_token_error", address);
}
} else {
response.retcode = -201;
response.message = translate("messages.dispatch.account.server_max_player_limit");
loggerMessage = translate("messages.dispatch.account.login_max_player_limit", address);
}
Grasscutter.getLogger().info(loggerMessage);
return response;
}
}
......
......@@ -9,6 +9,8 @@ import express.http.Request;
import express.http.Response;
import io.javalin.Javalin;
import static emu.grasscutter.Configuration.ACCOUNT;
/**
* Handles all generic, hard-coded responses.
*/
......@@ -48,8 +50,9 @@ public final class GenericHandler implements Router {
private static void serverStatus(Request request, Response response) {
int playerCount = Grasscutter.getGameServer().getPlayers().size();
int maxPlayer = ACCOUNT.maxPlayer;
String version = GameConstants.VERSION;
response.send("{\"retcode\":0,\"status\":{\"playerCount\":" + playerCount + ",\"version\":\"" + version + "\"}}");
response.send("{\"retcode\":0,\"status\":{\"playerCount\":" + playerCount + ",\"maxPlayer\":" + maxPlayer + ",\"version\":\"" + version + "\"}}");
}
}
package emu.grasscutter.server.packet.recv;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.player.Player;
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.PacketTakeAchievementRewardReq;
import static emu.grasscutter.Configuration.ACCOUNT;
@Opcodes(PacketOpcodes.PlayerLoginReq) // Sends initial data packets
public class HandlerPlayerLoginReq extends PacketHandler {
......@@ -22,6 +25,11 @@ public class HandlerPlayerLoginReq extends PacketHandler {
return;
}
// Max players limit
if (ACCOUNT.maxPlayer > -1 && Grasscutter.getGameServer().getPlayers().size() >= ACCOUNT.maxPlayer) {
return;
}
// Parse request
PlayerLoginReq req = PlayerLoginReq.parseFrom(payload);
......
......@@ -110,6 +110,7 @@ public class ConfigContainer {
public static class Account {
public boolean autoCreate = false;
public String[] defaultPermissions = {};
public int maxPlayer = -1;
}
/* Server options. */
......
......@@ -24,6 +24,7 @@
"account": {
"login_attempt": "[Dispatch] Client %s is trying to log in.",
"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_error": "[Dispatch] Client %s failed to log in via token.",
"login_token_success": "[Dispatch] Client %s logged in via token as %s.",
......@@ -35,7 +36,8 @@
"account_cache_error": "Game account cache information error.",
"session_key_error": "Wrong session key.",
"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."
},
......
......@@ -21,6 +21,7 @@
"account": {
"login_attempt": "[Dispatch] Klient %s próbuje się zalogować",
"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_error": "[Dispatch] Klient %s nie mógł się zalogować poprzez token",
"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",
"session_key_error": "Błędny klucz sesji.",
"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": {
......
......@@ -24,6 +24,7 @@
"account": {
"login_attempt": "[Dispatch] 客户端 %s 正在尝试登录",
"login_success": "[Dispatch] 客户端 %s 已登录,UID 为 %s",
"login_max_player_limit": "[Dispatch] 客户端 %s 登录失败:在线人数已满",
"login_token_attempt": "[Dispatch] 客户端 %s 正在尝试使用 token 登录",
"login_token_error": "[Dispatch] 客户端 %s 使用 token 登录失败",
"login_token_success": "[Dispatch] 客户端 %s 已通过 token 登录,UID 为 %s",
......@@ -35,7 +36,8 @@
"account_cache_error": "游戏账号缓存信息错误",
"session_key_error": "会话密钥错误",
"username_error": "未找到此用户名",
"username_create_error": "未找到用户名,建立连接失败"
"username_create_error": "未找到用户名,建立连接失败",
"server_max_player_limit": "服务器在线人数已满"
},
"router_error": "[Dispatch] 无法连接路由"
},
......
......@@ -24,6 +24,7 @@
"account": {
"login_attempt": "[Dispatch] 客戶端 %s 正在嘗試登入",
"login_success": "[Dispatch] 客戶端 %s 已登入,UID為 %s",
"login_max_player_limit": "[Dispatch] 客戶端 %s 登入失敗:在綫人數已滿",
"login_token_attempt": "[Dispatch] 客戶端 %s 正在嘗試用憑證登入",
"login_token_error": "[Dispatch] 客戶端 %s 使用憑證登入失敗",
"login_token_success": "[Dispatch] 客戶端 %s 已透過憑證登入,UID為 %s",
......@@ -35,7 +36,8 @@
"account_cache_error": "遊戲帳號緩存資訊錯誤",
"session_key_error": "對話密鑰不符。",
"username_error": "未找到此用戶名。",
"username_create_error": "未找到用戶名,建立失敗。"
"username_create_error": "未找到用戶名,建立失敗。",
"server_max_player_limit": "服務器在綫人數已滿"
}
},
"status": {
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment