⬆️ Support gc-dev-1.1.2 gcauth-2.4.0

This commit is contained in:
xtaodada 2022-06-04 20:36:48 +08:00
parent 33e02e2632
commit d94bbb2cb3
Signed by: xtaodada
GPG Key ID: 4CBB3F4FA8C85659
7 changed files with 76 additions and 50 deletions

View File

@ -10,7 +10,7 @@ sourceCompatibility = 17
targetCompatibility = 17 targetCompatibility = 17
group 'com.xtaolabs.gcauth_oauth' group 'com.xtaolabs.gcauth_oauth'
version '1.1.3' version '1.2.0'
repositories { repositories {
mavenCentral() mavenCentral()
@ -18,7 +18,7 @@ repositories {
dependencies { dependencies {
implementation files('lib/grasscutter-1.1.2-dev.jar') implementation files('lib/grasscutter-1.1.2-dev.jar')
implementation files('lib/gcauth-2.2.1.jar') implementation files('lib/gcauth-2.4.0.jar')
} }
test { test {

View File

@ -14,22 +14,26 @@ import java.io.File;
public class GCAuth_OAuth extends Plugin { public class GCAuth_OAuth extends Plugin {
public static GCAuth_OAuth getInstance() {
return (GCAuth_OAuth) Grasscutter.getPluginManager().getPlugin("GCAuth_OAuth");
}
@Override @Override
public void onEnable() { public void onEnable() {
String Login_Html_Path = PLUGIN("GCAuth/OAuth/login.html"); String Login_Html_Path = PLUGIN("GCAuth/OAuth/login.html");
File Login_Html = new File(Login_Html_Path); File Login_Html = new File(Login_Html_Path);
if(!Login_Html.exists()) { if(!Login_Html.exists()) {
Grasscutter.getLogger().warn(String.format("[GCAuth_OAuth] %s not found", Login_Html_Path)); getLogger().warn(String.format("%s not found", Login_Html_Path));
} else { } else {
loadTwitterLogin(); loadTwitterLogin();
Grasscutter.getLogger().info("[GCAuth_OAuth] Enabled"); getLogger().info("GCAuth_OAuth Enabled");
} }
} }
@Override @Override
public void onDisable() { public void onDisable() {
Grasscutter.setAuthenticationSystem(new DefaultAuthentication()); Grasscutter.setAuthenticationSystem(new DefaultAuthentication());
Grasscutter.getLogger().info("[GCAuth_OAuth] Disabled"); getLogger().info("GCAuth_OAuth Disabled");
} }
public void loadTwitterLogin() { public void loadTwitterLogin() {

View File

@ -10,11 +10,11 @@ import io.javalin.Javalin;
import static emu.grasscutter.Configuration.*; import static emu.grasscutter.Configuration.*;
public final class JsonHandler implements Router { public final class DesktopRedirectHandler implements Router {
@Override @Override
public void applyRoutes(Express express, Javalin javalin) { public void applyRoutes(Express express, Javalin javalin) {
express.get("/Api/twitter_login", JsonHandler::handle); express.get("/Api/twitter_login", DesktopRedirectHandler::handle);
} }
public static void handle(Request req, Response res) { public static void handle(Request req, Response res) {

View File

@ -1,11 +1,13 @@
package com.xtaolabs.gcauth_oauth.handler; package com.xtaolabs.gcauth_oauth.handler;
import emu.grasscutter.auth.*; import emu.grasscutter.auth.*;
import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.server.http.objects.ComboTokenResJson; import emu.grasscutter.server.http.objects.ComboTokenResJson;
import emu.grasscutter.server.http.objects.LoginResultJson; import emu.grasscutter.server.http.objects.LoginResultJson;
import me.exzork.gcauth.handler.GCAuthExternalAuthenticator; import me.exzork.gcauth.handler.GCAuthExternalAuthenticator;
import me.exzork.gcauth.utils.Authentication;
public class GCAuthAuthenticationHandler implements AuthenticationSystem { public class GCAuthAuthenticationHandler implements AuthenticationSystem {
private final Authenticator<LoginResultJson> gcAuthAuthenticator = new GCAuthenticators.GCAuthAuthenticator(); private final Authenticator<LoginResultJson> gcAuthAuthenticator = new GCAuthenticators.GCAuthAuthenticator();
@ -16,7 +18,8 @@ public class GCAuthAuthenticationHandler implements AuthenticationSystem {
@Override @Override
public void createAccount(String username, String password) { public void createAccount(String username, String password) {
// Unhandled. password = Authentication.generateHash(password);
DatabaseHelper.createAccountWithPassword(username, password);
} }
@Override @Override
@ -26,8 +29,11 @@ public class GCAuthAuthenticationHandler implements AuthenticationSystem {
@Override @Override
public Account verifyUser(String s) { public Account verifyUser(String s) {
// Unhandled. String uid = Authentication.getUsernameFromJwt(s);
return null; if (uid == null) {
return null;
}
return DatabaseHelper.getAccountById(uid);
} }
@Override @Override

View File

@ -1,5 +1,6 @@
package com.xtaolabs.gcauth_oauth.handler; package com.xtaolabs.gcauth_oauth.handler;
import com.xtaolabs.gcauth_oauth.GCAuth_OAuth;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.auth.AuthenticationSystem; import emu.grasscutter.auth.AuthenticationSystem;
import emu.grasscutter.auth.Authenticator; import emu.grasscutter.auth.Authenticator;
@ -7,11 +8,14 @@ import emu.grasscutter.auth.OAuthAuthenticator;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import emu.grasscutter.server.http.objects.LoginResultJson; import emu.grasscutter.server.http.objects.LoginResultJson;
import static emu.grasscutter.utils.Language.translate;
import me.exzork.gcauth.GCAuth;
import me.exzork.gcauth.utils.Authentication; import me.exzork.gcauth.utils.Authentication;
public class GCAuthenticators { import static emu.grasscutter.Configuration.ACCOUNT;
import static emu.grasscutter.utils.Language.translate;
public final class GCAuthenticators {
public static class GCAuthAuthenticator implements Authenticator<LoginResultJson> { public static class GCAuthAuthenticator implements Authenticator<LoginResultJson> {
@Override @Override
@ -21,11 +25,10 @@ public class GCAuthenticators {
var requestData = authenticationRequest.getPasswordRequest(); var requestData = authenticationRequest.getPasswordRequest();
assert requestData != null; // This should never be null. assert requestData != null; // This should never be null.
Account account = Authentication.getAccountByOneTimeToken(requestData.account); Account account = Authentication.getAccountByOTP(requestData.account);
if(account == null) { if(account == null) {
Grasscutter.getLogger().info("[GCAuth] Client " + requestData.account + " tried to login with invalid one time token.");
response.retcode = -201; response.retcode = -201;
response.message = "Token is invalid"; response.message = "OTP invalid";
return response; return response;
} }
@ -34,9 +37,8 @@ public class GCAuthenticators {
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();
response.data.account.twitter_name = account.getUsername();
Grasscutter.getLogger().info("[GCAuth] Client " + requestData.account + " logged in"); GCAuth.getInstance().getLogger().info("[GCAuth] Client " + requestData.account + " logged in");
return response; return response;
} }
} }
@ -54,34 +56,46 @@ public class GCAuthenticators {
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)); GCAuth_OAuth.getInstance().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);
// Check if account exists/token is valid. // Get account from database.
successfulLogin = account != null && account.getSessionKey().equals(requestData.token); Account account = DatabaseHelper.getAccountById(requestData.uid);
// Set response data. // Check if account exists/token is valid.
if(successfulLogin) { successfulLogin = account != null && account.getSessionKey().equals(requestData.token);
response.message = "OK";
response.data.account.uid = account.getId(); // Set response data.
response.data.account.token = account.getSessionKey(); if (successfulLogin) {
response.data.account.email = account.getEmail(); response.message = "OK";
response.data.account.twitter_name = account.getUsername(); response.data.account.uid = account.getId();
response.data.account.token = account.getSessionKey();
response.data.account.email = account.getEmail();
response.data.account.twitter_name = account.getUsername();
// 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);
}
// Log the login.
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_success", address, requestData.uid));
} 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));
} }
GCAuth_OAuth.getInstance().getLogger().info(loggerMessage);
return response; return response;
} }
} }
@ -95,18 +109,20 @@ public class GCAuthenticators {
assert request.getResponse() != null; assert request.getResponse() != null;
VerifyHandler.handle(request.getRequest(), request.getResponse()); VerifyHandler.handle(request.getRequest(), request.getResponse());
} }
/**
@Override public void handleDesktopRedirection(AuthenticationSystem.AuthenticationRequest request) { * The type of the client.
* Used for handling redirection.
*/
@Override
public void handleRedirection(AuthenticationSystem.AuthenticationRequest request, ClientType type) {
assert request.getResponse() != null; assert request.getResponse() != null;
JsonHandler.handle(request.getRequest(), request.getResponse()); switch (type) {
case DESKTOP -> DesktopRedirectHandler.handle(request.getRequest(), request.getResponse());
case MOBILE -> MobileRedirectHandler.handle(request.getRequest(), request.getResponse());
}
} }
@Override
@Override public void handleMobileRedirection(AuthenticationSystem.AuthenticationRequest request) { public void handleTokenProcess(AuthenticationSystem.AuthenticationRequest request) {
assert request.getResponse() != null;
sdkHandler.handle(request.getRequest(), request.getResponse());
}
@Override public void handleTokenProcess(AuthenticationSystem.AuthenticationRequest request) {
assert request.getResponse() != null; assert request.getResponse() != null;
request.getResponse().send("Authentication is not available with the default authentication method."); request.getResponse().send("Authentication is not available with the default authentication method.");
} }

View File

@ -10,11 +10,11 @@ import express.http.Response;
import io.javalin.Javalin; import io.javalin.Javalin;
public final class sdkHandler implements Router { public final class MobileRedirectHandler implements Router {
@Override @Override
public void applyRoutes(Express express, Javalin javalin) { public void applyRoutes(Express express, Javalin javalin) {
express.get("/sdkTwitterLogin.html", sdkHandler::handle); express.get("/sdkTwitterLogin.html", MobileRedirectHandler::handle);
} }
public static void handle(Request req, Response res) { public static void handle(Request req, Response res) {

View File

@ -2,12 +2,12 @@ package com.xtaolabs.gcauth_oauth.handler;
import com.auth0.jwt.interfaces.DecodedJWT; import com.auth0.jwt.interfaces.DecodedJWT;
import com.xtaolabs.gcauth_oauth.GCAuth_OAuth;
import com.xtaolabs.gcauth_oauth.json.VerifyJson; import com.xtaolabs.gcauth_oauth.json.VerifyJson;
import com.xtaolabs.gcauth_oauth.utils.parse; import com.xtaolabs.gcauth_oauth.utils.parse;
import emu.grasscutter.server.http.Router; import emu.grasscutter.server.http.Router;
import emu.grasscutter.server.http.objects.LoginResultJson; import emu.grasscutter.server.http.objects.LoginResultJson;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.Account; import emu.grasscutter.game.Account;
import express.Express; import express.Express;
@ -32,11 +32,11 @@ public final class VerifyHandler implements Router {
DecodedJWT jwt = parse.deToken(request.access_token); DecodedJWT jwt = parse.deToken(request.access_token);
Account account = null; Account account = null;
if (jwt != null) { if (jwt != null) {
account = Authentication.getAccountByOneTimeToken(jwt.getClaim("token").asString()); account = Authentication.getAccountByOTP(jwt.getClaim("token").asString());
} }
// Login // Login
if(account == null) { if(account == null) {
Grasscutter.getLogger().info("[GCAuth] Client " + req.ip() + " failed to log in"); GCAuth_OAuth.getInstance().getLogger().info("Client " + req.ip() + " failed to log in");
responseData.retcode = -201; responseData.retcode = -201;
responseData.message = "Token is invalid"; responseData.message = "Token is invalid";
res.send(responseData); res.send(responseData);
@ -50,7 +50,7 @@ public final class VerifyHandler implements Router {
responseData.data.account.email = account.getEmail(); responseData.data.account.email = account.getEmail();
responseData.data.account.twitter_name = account.getUsername(); responseData.data.account.twitter_name = account.getUsername();
Grasscutter.getLogger().info(String.format("[GCAuth] Client %s logged in as %s", req.ip(), responseData.data.account.uid)); GCAuth_OAuth.getInstance().getLogger().info(String.format("Client %s logged in as %s", req.ip(), responseData.data.account.uid));
res.send(responseData); res.send(responseData);
} }