diff --git a/pom.xml b/pom.xml
index 3a09830..757a91e 100644
--- a/pom.xml
+++ b/pom.xml
@@ -6,13 +6,13 @@
org.hff
grasscutter-plugin
- 1.2.2
+ 1.4.0
17
17
UTF-8
- 1.2.3
+ 1.3.2
0.11.5
0.5.10
1.18.24
@@ -25,7 +25,7 @@
grasscutter
${grasscutter.version}
system
- ${project.basedir}/lib/grasscutter-1.2.3-dev.jar
+ ${project.basedir}/lib/grasscutter-1.3.2-dev.jar
@@ -49,7 +49,7 @@
net.jodah
expiringmap
- ${expiringmap.version}
+ ${expiringMap.version}
diff --git a/src/main/java/org/hff/PluginHandler.java b/src/main/java/org/hff/PluginHandler.java
index 35fbe60..b212b01 100644
--- a/src/main/java/org/hff/PluginHandler.java
+++ b/src/main/java/org/hff/PluginHandler.java
@@ -13,8 +13,7 @@
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
import emu.grasscutter.utils.Position;
-import express.http.Request;
-import express.http.Response;
+import io.javalin.http.Context;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import org.hff.api.ApiCode;
@@ -39,29 +38,27 @@
public final class PluginHandler {
- private final Request request;
- private final Response response;
+ private final Context ctx;
private final Locale locale;
private final String token;
private final String adminToken;
- public PluginHandler(@NotNull Request request, @NotNull Response response) {
- this.request = request;
- this.response = response;
- this.locale = LanguageManager.getLocale(request.get("locale"));
- this.token = request.get("token");
- this.adminToken = request.get("admin_token");
+ public PluginHandler(@NotNull Context ctx) {
+ this.ctx = ctx;
+ this.locale = LanguageManager.getLocale(ctx.req.getHeader("locale"));
+ this.token = ctx.req.getHeader("token");
+ this.adminToken = ctx.req.getHeader("admin_token");
}
public void adminAuth() {
- String adminVoucher = request.body().get("adminVoucher").toString();
+ String adminVoucher = ctx.queryParam("adminVoucher");
if (adminVoucher == null) {
- response.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
+ ctx.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
return;
}
if (!AuthUtil.checkAdminVoucher(adminVoucher)) {
- response.json(ApiResult.result(ApiCode.AUTH_FAIL, locale));
+ ctx.json(ApiResult.result(ApiCode.AUTH_FAIL, locale));
return;
}
@@ -74,19 +71,19 @@ public void adminCreateAccount() {
return;
}
- AccountParam param = request.body(AccountParam.class);
+ AccountParam param = ctx.bodyAsClass(AccountParam.class);
if (checkParamFail(param)) {
return;
}
Account account = DatabaseHelper.getAccountByName(param.getUsername());
if (account != null) {
- response.json(ApiResult.result(ApiCode.ACCOUNT_IS_EXIST, locale));
+ ctx.json(ApiResult.result(ApiCode.ACCOUNT_IS_EXIST, locale));
return;
}
getAuthenticationSystem().createAccount(param.getUsername(), param.getPassword());
- response.json(ApiResult.success(locale));
+ ctx.json(ApiResult.success(locale));
}
public void adminCommand() {
@@ -95,9 +92,9 @@ public void adminCommand() {
return;
}
- String command = request.body().get("command").toString();
+ String command = ctx.queryParam("command");
if (command == null) {
- response.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
+ ctx.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
return;
}
@@ -105,9 +102,9 @@ public void adminCommand() {
}
public void mailVerifyCode() {
- String username = request.body().get("username").toString();
+ String username = ctx.queryParam("username");
if (username == null) {
- response.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
+ ctx.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
return;
}
@@ -118,15 +115,15 @@ public void mailVerifyCode() {
boolean flag = MailUtil.sendVerifyCodeMail(player, locale);
if (!flag) {
- response.json(ApiResult.result(ApiCode.MAIL_TIME_LIMIT, locale));
+ ctx.json(ApiResult.result(ApiCode.MAIL_TIME_LIMIT, locale));
return;
}
- response.json(ApiResult.success(locale));
+ ctx.json(ApiResult.success(locale));
}
public void playerAuthByVerifyCode() {
- AuthByVerifyCodeParam param = request.body(AuthByVerifyCodeParam.class);
+ AuthByVerifyCodeParam param = ctx.bodyAsClass(AuthByVerifyCodeParam.class);
if (checkParamFail(param)) {
return;
}
@@ -136,7 +133,7 @@ public void playerAuthByVerifyCode() {
return;
}
- boolean flag = MailUtil.checkVerifyCode(account.getId(), param.getVerifyCode(), locale, response);
+ boolean flag = MailUtil.checkVerifyCode(account.getId(), param.getVerifyCode(), locale, ctx);
if (!flag) {
return;
}
@@ -145,7 +142,7 @@ public void playerAuthByVerifyCode() {
}
public void playerAuthByPassword() {
- AccountParam param = request.body(AccountParam.class);
+ AccountParam param = ctx.bodyAsClass(AccountParam.class);
if (checkParamFail(param)) {
return;
}
@@ -156,7 +153,7 @@ public void playerAuthByPassword() {
}
if (!param.getPassword().equals(account.getPassword())) {
- response.json(ApiResult.result(ApiCode.AUTH_FAIL, locale));
+ ctx.json(ApiResult.result(ApiCode.AUTH_FAIL, locale));
return;
}
@@ -169,9 +166,9 @@ public void playerCommand() {
return;
}
- String command = request.body().get("command").toString();
+ String command = ctx.queryParam("command");
if (command == null) {
- response.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
+ ctx.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
return;
}
@@ -242,7 +239,7 @@ public void levelUpAllSkill() {
}
}
- response.json(ApiResult.success(locale));
+ ctx.json(ApiResult.success(locale));
}
public void getProps() {
@@ -279,7 +276,7 @@ public void getProps() {
.setConstellation(avatar.getCoreProudSkillLevel())
.setFetterLevel(avatar.getFetterLevel());
- response.json(ApiResult.success(locale, propsVo));
+ ctx.json(ApiResult.success(locale, propsVo));
}
public void cdr() {
@@ -306,13 +303,13 @@ public void cdr() {
avatar.save();
}
- response.json(ApiResult.success(locale));
+ ctx.json(ApiResult.success(locale));
}
private Claims parseAdminToken() {
if (adminToken == null) {
- response.json(ApiResult.result(ApiCode.TOKEN_NOT_FOUND, locale));
+ ctx.json(ApiResult.result(ApiCode.TOKEN_NOT_FOUND, locale));
return null;
}
Claims claims = parseToken(adminToken);
@@ -320,7 +317,7 @@ private Claims parseAdminToken() {
return null;
}
if (!RoleEnum.ADMIN.getDesc().equals(claims.get("role").toString())) {
- response.json(ApiResult.result(ApiCode.ROLE_ERROR, locale));
+ ctx.json(ApiResult.result(ApiCode.ROLE_ERROR, locale));
return null;
}
return claims;
@@ -328,7 +325,7 @@ private Claims parseAdminToken() {
private Claims parsePlayerToken() {
if (token == null) {
- response.json(ApiResult.result(ApiCode.TOKEN_NOT_FOUND, locale));
+ ctx.json(ApiResult.result(ApiCode.TOKEN_NOT_FOUND, locale));
return null;
}
return parseToken(token);
@@ -338,9 +335,9 @@ private Claims parseToken(String token) {
try {
return JwtUtil.parseToken(token);
} catch (ExpiredJwtException e) {
- response.json(ApiResult.result(ApiCode.TOKEN_EXPIRED, locale));
+ ctx.json(ApiResult.result(ApiCode.TOKEN_EXPIRED, locale));
} catch (Exception e) {
- response.json(ApiResult.result(ApiCode.TOKEN_PARSE_EXCEPTION, locale));
+ ctx.json(ApiResult.result(ApiCode.TOKEN_PARSE_EXCEPTION, locale));
}
return null;
}
@@ -348,9 +345,9 @@ private Claims parseToken(String token) {
private void generateToken(RoleEnum role, String accountId) {
try {
String token = JwtUtil.generateToken(role, accountId);
- response.json(ApiResult.success(locale, token));
+ ctx.json(ApiResult.success(locale, token));
} catch (Exception e) {
- response.json(ApiResult.result(ApiCode.TOKEN_GENERATE_FAIL, locale, token));
+ ctx.json(ApiResult.result(ApiCode.TOKEN_GENERATE_FAIL, locale, token));
}
}
@@ -361,11 +358,11 @@ private boolean checkParamFail(Object param) {
try {
Object object = field.get(param);
if (object == null || object.toString().isEmpty()) {
- response.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
+ ctx.json(ApiResult.result(ApiCode.PARAM_EMPTY_EXCEPTION, locale));
return true;
}
} catch (IllegalAccessException e) {
- response.json(ApiResult.result(ApiCode.PARAM_ILLEGAL_EXCEPTION, locale));
+ ctx.json(ApiResult.result(ApiCode.PARAM_ILLEGAL_EXCEPTION, locale));
return true;
}
}
@@ -375,7 +372,7 @@ private boolean checkParamFail(Object param) {
private Account getAccountByUsername(String username) {
Account account = DatabaseHelper.getAccountByName(username);
if (account == null) {
- response.json(ApiResult.result(ApiCode.ACCOUNT_NOT_EXIST, locale));
+ ctx.json(ApiResult.result(ApiCode.ACCOUNT_NOT_EXIST, locale));
}
return account;
}
@@ -383,7 +380,7 @@ private Account getAccountByUsername(String username) {
private Player getPlayerByAccountId(String accountId) {
Player player = getGameServer().getPlayerByAccountId(accountId);
if (player == null) {
- response.json(ApiResult.result(ApiCode.PLAYER_NOT_ONLINE, locale));
+ ctx.json(ApiResult.result(ApiCode.PLAYER_NOT_ONLINE, locale));
}
return player;
}
@@ -395,7 +392,7 @@ private Player getPlayerByUsername(String username) {
}
Player player = getGameServer().getPlayerByAccountId(account.getId());
if (player == null) {
- response.json(ApiResult.result(ApiCode.PLAYER_NOT_ONLINE, locale));
+ ctx.json(ApiResult.result(ApiCode.PLAYER_NOT_ONLINE, locale));
}
return player;
}
@@ -405,9 +402,9 @@ private void invokeCommand(Player player, String command, String accountId) {
CommandMap.getInstance().invoke(player, player, command);
String message = EventListeners.getMessage(accountId);
if (message != null) {
- response.json(ApiResult.success(message));
+ ctx.json(ApiResult.success(message));
} else {
- response.json(ApiResult.fail(locale));
+ ctx.json(ApiResult.fail(locale));
}
}
}
diff --git a/src/main/java/org/hff/PluginRouter.java b/src/main/java/org/hff/PluginRouter.java
index 92d160f..c426a51 100644
--- a/src/main/java/org/hff/PluginRouter.java
+++ b/src/main/java/org/hff/PluginRouter.java
@@ -1,41 +1,40 @@
package org.hff;
import emu.grasscutter.server.http.Router;
-import express.Express;
import io.javalin.Javalin;
public final class PluginRouter implements Router {
@Override
- public void applyRoutes(Express express, Javalin javalin) {
- express.get("/plugin/admin/auth",
- (request, response) -> new PluginHandler(request, response).adminAuth());
+ public void applyRoutes(Javalin javalin) {
+ javalin.get("/plugin/admin/auth",
+ ctx -> new PluginHandler(ctx).adminAuth());
- express.get("/plugin/admin/createAccount",
- (request, response) -> new PluginHandler(request, response).adminCreateAccount());
+ javalin.get("/plugin/admin/createAccount",
+ ctx -> new PluginHandler(ctx).adminCreateAccount());
- express.get("/plugin/admin/command",
- (request, response) -> new PluginHandler(request, response).adminCommand());
+ javalin.get("/plugin/admin/command",
+ ctx -> new PluginHandler(ctx).adminCommand());
- express.get("/plugin/mail/verifyCode",
- (request, response) -> new PluginHandler(request, response).mailVerifyCode());
+ javalin.get("/plugin/mail/verifyCode",
+ ctx -> new PluginHandler(ctx).mailVerifyCode());
- express.get("/plugin/player/authByVerifyCode",
- (request, response) -> new PluginHandler(request, response).playerAuthByVerifyCode());
+ javalin.get("/plugin/player/authByVerifyCode",
+ ctx -> new PluginHandler(ctx).playerAuthByVerifyCode());
- express.get("/plugin/player/authByPassword",
- (request, response) -> new PluginHandler(request, response).playerAuthByPassword());
+ javalin.get("/plugin/player/authByPassword",
+ ctx -> new PluginHandler(ctx).playerAuthByPassword());
- express.get("/plugin/player/command",
- (request, response) -> new PluginHandler(request, response).playerCommand());
+ javalin.get("/plugin/player/command",
+ ctx -> new PluginHandler(ctx).playerCommand());
- express.get("/plugin/player/levelUpAllSkill",
- (request, response) -> new PluginHandler(request, response).levelUpAllSkill());
+ javalin.get("/plugin/player/levelUpAllSkill",
+ ctx -> new PluginHandler(ctx).levelUpAllSkill());
- express.get("/plugin/player/getProps",
- (request, response) -> new PluginHandler(request, response).getProps());
+ javalin.get("/plugin/player/getProps",
+ ctx -> new PluginHandler(ctx).getProps());
- express.get("/plugin/player/cdr",
- (request, response) -> new PluginHandler(request, response).cdr());
+ javalin.get("/plugin/player/cdr",
+ ctx -> new PluginHandler(ctx).cdr());
}
}
diff --git a/src/main/java/org/hff/permission/Authentication.java b/src/main/java/org/hff/permission/Authentication.java
index db61604..9b17694 100644
--- a/src/main/java/org/hff/permission/Authentication.java
+++ b/src/main/java/org/hff/permission/Authentication.java
@@ -15,6 +15,7 @@ public class Authentication implements AuthenticationSystem {
private final Authenticator tokenAuthenticator = new DefaultAuthenticators.TokenAuthenticator();
private final Authenticator sessionKeyAuthenticator = new DefaultAuthenticators.SessionKeyAuthenticator();
private final ExternalAuthenticator externalAuthenticator = new DefaultAuthenticators.ExternalAuthentication();
+ private final OAuthAuthenticator oAuthAuthenticator = new DefaultAuthenticators.OAuthAuthentication();
@Override
public void createAccount(String username, String password) {
@@ -58,6 +59,6 @@ public emu.grasscutter.auth.ExternalAuthenticator getExternalAuthenticator() {
@Override
public OAuthAuthenticator getOAuthAuthenticator() {
- return null;
+ return this.oAuthAuthenticator;
}
}
diff --git a/src/main/java/org/hff/permission/PasswordAuthenticator.java b/src/main/java/org/hff/permission/PasswordAuthenticator.java
index 453b394..29fae0f 100644
--- a/src/main/java/org/hff/permission/PasswordAuthenticator.java
+++ b/src/main/java/org/hff/permission/PasswordAuthenticator.java
@@ -1,5 +1,6 @@
package org.hff.permission;
+import at.favre.lib.crypto.bcrypt.BCrypt;
import emu.grasscutter.auth.AuthenticationSystem;
import emu.grasscutter.auth.Authenticator;
import emu.grasscutter.database.DatabaseHelper;
@@ -21,7 +22,7 @@ public LoginResultJson authenticate(AuthenticationSystem.AuthenticationRequest r
assert requestData != null;
var response = new LoginResultJson();
- String address = request.getRequest().ip();
+ String address = request.getContext().ip();
response.retcode = -201;
if (getGameServer().getPlayers().size() >= ACCOUNT.maxPlayer && ACCOUNT.maxPlayer > -1) {
@@ -30,33 +31,44 @@ public LoginResultJson authenticate(AuthenticationSystem.AuthenticationRequest r
return response;
}
- Account account = DatabaseHelper.getAccountByName(requestData.account);
- if (account == null && !ACCOUNT.autoCreate) {
- getLogger().info(translate("messages.dispatch.account.account_login_exist_error", address));
- response.message = translate("messages.dispatch.account.username_error");
+ String password = requestData.password;
+ if (password == null) {
+ getLogger().info(translate("messages.dispatch.account.login_password_error", address));
+ response.message = translate("messages.dispatch.account.password_error");
return response;
}
+ try {
+ password = AuthUtil.decryptPassword(password);
+ } catch (Exception ignored) {
+ }
+
+ Account account = DatabaseHelper.getAccountByName(requestData.account);
if (account == null) {
+ if (!ACCOUNT.autoCreate) {
+ getLogger().info(translate("messages.dispatch.account.account_login_exist_error", address));
+ response.message = translate("messages.dispatch.account.username_error");
+ return response;
+ }
+
account = DatabaseHelper.createAccountWithUid(requestData.account, 0);
if (account == null) {
getLogger().info(translate("messages.dispatch.account.account_login_create_error", address));
response.message = translate("messages.dispatch.account.username_create_error");
return response;
- } else {
- getLogger().info(translate("messages.dispatch.account.account_login_create_success", address, response.data.account.uid));
}
- }
- if (account.getPassword() != null) {
- try {
- String password = AuthUtil.decryptPassword(requestData.password);
- if (!password.equals(account.getPassword())) {
+ account.setPassword(BCrypt.withDefaults().hashToString(12, password.toCharArray()));
+ account.save();
+ getLogger().info(translate("messages.dispatch.account.account_login_create_success", address, response.data.account.uid));
+ } else {
+ String accountPassword = account.getPassword();
+ if (accountPassword != null && !accountPassword.isEmpty()) {
+ if (!BCrypt.verifyer().verify(password.toCharArray(), accountPassword).verified && !accountPassword.equals(password)) {
+ getLogger().info(translate("messages.dispatch.account.login_password_error", address));
response.message = translate("messages.dispatch.account.password_error");
return response;
}
- } catch (Exception e) {
- getLogger().error("Error with decrypt password: " + e.getMessage());
}
}
diff --git a/src/main/java/org/hff/utils/MailUtil.java b/src/main/java/org/hff/utils/MailUtil.java
index f8c8b80..c2275ac 100644
--- a/src/main/java/org/hff/utils/MailUtil.java
+++ b/src/main/java/org/hff/utils/MailUtil.java
@@ -2,20 +2,21 @@
import emu.grasscutter.game.mail.Mail;
import emu.grasscutter.game.player.Player;
-import express.http.Response;
+import io.javalin.http.Context;
import lombok.Getter;
import lombok.Setter;
+import net.jodah.expiringmap.ExpiringMap;
import org.hff.api.ApiCode;
import org.hff.api.ApiResult;
import org.hff.i18n.LanguageManager;
import org.hff.i18n.Locale;
import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.TimeUnit;
public class MailUtil {
- private static final Map verifyCodeMailMap = new ConcurrentHashMap<>();
+ private static final Map verifyCodeMailMap = ExpiringMap.builder().expiration(2, TimeUnit.MINUTES).build();
public static boolean sendVerifyCodeMail(Player player, Locale locale) {
String accountId = player.getAccount().getId();
@@ -36,17 +37,17 @@ public static boolean sendVerifyCodeMail(Player player, Locale locale) {
return true;
}
- public static boolean checkVerifyCode(String accountId, String verifyCode, Locale locale, Response response) {
+ public static boolean checkVerifyCode(String accountId, String verifyCode, Locale locale, Context ctx) {
VerifyCodeMail verifyCodeMail = verifyCodeMailMap.get(accountId);
if (verifyCodeMail == null) {
- response.json(ApiResult.result(ApiCode.MAIL_VERIFY_NOT_FOUND, locale));
+ ctx.json(ApiResult.result(ApiCode.MAIL_VERIFY_NOT_FOUND, locale));
return false;
}
if (verifyCodeMail.getExpireTime() < System.currentTimeMillis()) {
verifyCodeMailMap.remove(accountId);
- response.json(ApiResult.result(ApiCode.MAIL_VERIFY_EXPIRED, locale));
+ ctx.json(ApiResult.result(ApiCode.MAIL_VERIFY_EXPIRED, locale));
return false;
}
@@ -55,7 +56,7 @@ public static boolean checkVerifyCode(String accountId, String verifyCode, Local
if (verifyCodeMail.getRetries() <= 0) {
verifyCodeMailMap.remove(accountId);
}
- response.json(ApiResult.result(ApiCode.MAIL_VERIFY_FAIL, locale).setArgs(verifyCodeMail.getRetries()));
+ ctx.json(ApiResult.result(ApiCode.MAIL_VERIFY_FAIL, locale).setArgs(verifyCodeMail.getRetries()));
return false;
}