mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-02-06 10:06:51 +01:00
Run Spotless on src/main
This commit is contained in:
@@ -2,7 +2,6 @@ package emu.grasscutter;
|
||||
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
import java.util.Arrays;
|
||||
|
||||
public final class GameConstants {
|
||||
@@ -21,10 +20,16 @@ public final class GameConstants {
|
||||
public static final int BATTLE_PASS_CURRENT_INDEX = 2;
|
||||
// Default entity ability hashes.
|
||||
public static final String[] DEFAULT_ABILITY_STRINGS = {
|
||||
"Avatar_DefaultAbility_VisionReplaceDieInvincible", "Avatar_DefaultAbility_AvartarInShaderChange", "Avatar_SprintBS_Invincible",
|
||||
"Avatar_Freeze_Duration_Reducer", "Avatar_Attack_ReviveEnergy", "Avatar_Component_Initializer", "Avatar_FallAnthem_Achievement_Listener"
|
||||
"Avatar_DefaultAbility_VisionReplaceDieInvincible",
|
||||
"Avatar_DefaultAbility_AvartarInShaderChange",
|
||||
"Avatar_SprintBS_Invincible",
|
||||
"Avatar_Freeze_Duration_Reducer",
|
||||
"Avatar_Attack_ReviveEnergy",
|
||||
"Avatar_Component_Initializer",
|
||||
"Avatar_FallAnthem_Achievement_Listener"
|
||||
};
|
||||
public static final int[] DEFAULT_ABILITY_HASHES = Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
|
||||
public static final int[] DEFAULT_ABILITY_HASHES =
|
||||
Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
|
||||
public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default");
|
||||
public static String VERSION = "3.5.0";
|
||||
}
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package emu.grasscutter;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import emu.grasscutter.auth.AuthenticationSystem;
|
||||
@@ -24,6 +27,12 @@ import emu.grasscutter.server.http.handlers.GenericHandler;
|
||||
import emu.grasscutter.server.http.handlers.LogHandler;
|
||||
import emu.grasscutter.tools.Tools;
|
||||
import emu.grasscutter.utils.*;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import org.jline.reader.EndOfFileException;
|
||||
@@ -35,21 +44,10 @@ import org.jline.terminal.TerminalBuilder;
|
||||
import org.reflections.Reflections;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.File;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOError;
|
||||
import java.io.IOException;
|
||||
import java.util.Calendar;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public final class Grasscutter {
|
||||
public static final File configFile = new File("./config.json");
|
||||
public static final Reflections reflector = new Reflections("emu.grasscutter");
|
||||
@Getter private static final Logger logger =
|
||||
(Logger) LoggerFactory.getLogger(Grasscutter.class);
|
||||
@Getter private static final Logger logger = (Logger) LoggerFactory.getLogger(Grasscutter.class);
|
||||
|
||||
@Getter public static ConfigContainer config;
|
||||
|
||||
@@ -165,13 +163,10 @@ public final class Grasscutter {
|
||||
Grasscutter.startConsole();
|
||||
}
|
||||
|
||||
/**
|
||||
* Server shutdown event.
|
||||
*/
|
||||
/** Server shutdown event. */
|
||||
private static void onShutdown() {
|
||||
// Disable all plugins.
|
||||
if (pluginManager != null)
|
||||
pluginManager.disablePlugins();
|
||||
if (pluginManager != null) pluginManager.disablePlugins();
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -187,9 +182,7 @@ public final class Grasscutter {
|
||||
* Methods for the configuration system component.
|
||||
*/
|
||||
|
||||
/**
|
||||
* Attempts to load the configuration from a file.
|
||||
*/
|
||||
/** Attempts to load the configuration from a file. */
|
||||
public static void loadConfig() {
|
||||
// Check if config.json exists. If not, we generate a new config.
|
||||
if (!configFile.exists()) {
|
||||
@@ -203,7 +196,9 @@ public final class Grasscutter {
|
||||
try {
|
||||
config = JsonUtils.loadToClass(configFile.toPath(), ConfigContainer.class);
|
||||
} catch (Exception exception) {
|
||||
getLogger().error("There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
||||
getLogger()
|
||||
.error(
|
||||
"There was an error while trying to load the configuration from config.json. Please make sure that there are no syntax errors. If you want to start with a default configuration, delete your existing config.json.");
|
||||
System.exit(1);
|
||||
}
|
||||
}
|
||||
@@ -251,9 +246,7 @@ public final class Grasscutter {
|
||||
}
|
||||
}
|
||||
|
||||
consoleLineReader = LineReaderBuilder.builder()
|
||||
.terminal(terminal)
|
||||
.build();
|
||||
consoleLineReader = LineReaderBuilder.builder().terminal(terminal).build();
|
||||
}
|
||||
|
||||
return consoleLineReader;
|
||||
@@ -314,10 +307,16 @@ public final class Grasscutter {
|
||||
*/
|
||||
|
||||
public enum ServerRunMode {
|
||||
HYBRID, DISPATCH_ONLY, GAME_ONLY
|
||||
HYBRID,
|
||||
DISPATCH_ONLY,
|
||||
GAME_ONLY
|
||||
}
|
||||
|
||||
public enum ServerDebugMode {
|
||||
ALL, MISSING, WHITELIST, BLACKLIST, NONE
|
||||
ALL,
|
||||
MISSING,
|
||||
WHITELIST,
|
||||
BLACKLIST,
|
||||
NONE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,60 +3,50 @@ package emu.grasscutter.auth;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.server.http.objects.*;
|
||||
import io.javalin.http.Context;
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.Builder;
|
||||
import lombok.Getter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
/**
|
||||
* Defines an authenticator for the server.
|
||||
* Can be changed by plugins.
|
||||
*/
|
||||
/** Defines an authenticator for the server. Can be changed by plugins. */
|
||||
public interface AuthenticationSystem {
|
||||
|
||||
/**
|
||||
* Generates an authentication request from a {@link LoginAccountRequestJson} object.
|
||||
*
|
||||
* @param ctx The Javalin context.
|
||||
* @param ctx The Javalin context.
|
||||
* @param jsonData The JSON data.
|
||||
* @return An authentication request.
|
||||
*/
|
||||
static AuthenticationRequest fromPasswordRequest(Context ctx, LoginAccountRequestJson jsonData) {
|
||||
return AuthenticationRequest.builder()
|
||||
.context(ctx)
|
||||
.passwordRequest(jsonData)
|
||||
.build();
|
||||
return AuthenticationRequest.builder().context(ctx).passwordRequest(jsonData).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an authentication request from a {@link LoginTokenRequestJson} object.
|
||||
*
|
||||
* @param ctx The Javalin context.
|
||||
* @param ctx The Javalin context.
|
||||
* @param jsonData The JSON data.
|
||||
* @return An authentication request.
|
||||
*/
|
||||
static AuthenticationRequest fromTokenRequest(Context ctx, LoginTokenRequestJson jsonData) {
|
||||
return AuthenticationRequest.builder()
|
||||
.context(ctx)
|
||||
.tokenRequest(jsonData)
|
||||
.build();
|
||||
return AuthenticationRequest.builder().context(ctx).tokenRequest(jsonData).build();
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates an authentication request from a {@link ComboTokenReqJson} object.
|
||||
*
|
||||
* @param ctx The Javalin context.
|
||||
* @param ctx The Javalin context.
|
||||
* @param jsonData The JSON data.
|
||||
* @return An authentication request.
|
||||
*/
|
||||
static AuthenticationRequest fromComboTokenRequest(Context ctx, ComboTokenReqJson jsonData,
|
||||
ComboTokenReqJson.LoginTokenData tokenData) {
|
||||
static AuthenticationRequest fromComboTokenRequest(
|
||||
Context ctx, ComboTokenReqJson jsonData, ComboTokenReqJson.LoginTokenData tokenData) {
|
||||
return AuthenticationRequest.builder()
|
||||
.context(ctx)
|
||||
.sessionKeyRequest(jsonData)
|
||||
.sessionKeyData(tokenData)
|
||||
.build();
|
||||
.context(ctx)
|
||||
.sessionKeyRequest(jsonData)
|
||||
.sessionKeyData(tokenData)
|
||||
.build();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -88,7 +78,8 @@ public interface AuthenticationSystem {
|
||||
* Called by plugins to internally verify a user's identity.
|
||||
*
|
||||
* @param details A unique identifier to identify the user. (For example: a JWT token)
|
||||
* @return The user's account if the verification was successful, null if the user was unable to be verified.
|
||||
* @return The user's account if the verification was successful, null if the user was unable to
|
||||
* be verified.
|
||||
*/
|
||||
Account verifyUser(String details);
|
||||
|
||||
@@ -127,22 +118,16 @@ public interface AuthenticationSystem {
|
||||
*/
|
||||
OAuthAuthenticator getOAuthAuthenticator();
|
||||
|
||||
/**
|
||||
* A data container that holds relevant data for authenticating a client.
|
||||
*/
|
||||
/** A data container that holds relevant data for authenticating a client. */
|
||||
@Builder
|
||||
@AllArgsConstructor
|
||||
@Getter
|
||||
class AuthenticationRequest {
|
||||
private final Context context;
|
||||
|
||||
@Nullable
|
||||
private final LoginAccountRequestJson passwordRequest;
|
||||
@Nullable
|
||||
private final LoginTokenRequestJson tokenRequest;
|
||||
@Nullable
|
||||
private final ComboTokenReqJson sessionKeyRequest;
|
||||
@Nullable
|
||||
private final ComboTokenReqJson.LoginTokenData sessionKeyData;
|
||||
@Nullable private final LoginAccountRequestJson passwordRequest;
|
||||
@Nullable private final LoginTokenRequestJson tokenRequest;
|
||||
@Nullable private final ComboTokenReqJson sessionKeyRequest;
|
||||
@Nullable private final ComboTokenReqJson.LoginTokenData sessionKeyData;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,14 +6,16 @@ import emu.grasscutter.server.http.objects.LoginResultJson;
|
||||
/**
|
||||
* Handles username/password authentication from the client.
|
||||
*
|
||||
* @param <T> The response object type. Should be {@link LoginResultJson} or {@link ComboTokenResJson}
|
||||
* @param <T> The response object type. Should be {@link LoginResultJson} or {@link
|
||||
* ComboTokenResJson}
|
||||
*/
|
||||
public interface Authenticator<T> {
|
||||
|
||||
/**
|
||||
* Attempt to authenticate the client with the provided credentials.
|
||||
*
|
||||
* @param request The authentication request wrapped in a {@link AuthenticationSystem.AuthenticationRequest} object.
|
||||
* @param request The authentication request wrapped in a {@link
|
||||
* AuthenticationSystem.AuthenticationRequest} object.
|
||||
* @return The result of the login in an object.
|
||||
*/
|
||||
T authenticate(AuthenticationSystem.AuthenticationRequest request);
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package emu.grasscutter.auth;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.ACCOUNT;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.auth.DefaultAuthenticators.*;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.server.http.objects.ComboTokenResJson;
|
||||
import emu.grasscutter.server.http.objects.LoginResultJson;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.ACCOUNT;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
/**
|
||||
* The default Grasscutter authentication implementation.
|
||||
* Allows all users to access any account.
|
||||
* The default Grasscutter authentication implementation. Allows all users to access any account.
|
||||
*/
|
||||
public final class DefaultAuthentication implements AuthenticationSystem {
|
||||
private final Authenticator<LoginResultJson> passwordAuthenticator;
|
||||
private final Authenticator<LoginResultJson> tokenAuthenticator = new TokenAuthenticator();
|
||||
private final Authenticator<ComboTokenResJson> sessionKeyAuthenticator = new SessionKeyAuthenticator();
|
||||
private final Authenticator<ComboTokenResJson> sessionKeyAuthenticator =
|
||||
new SessionKeyAuthenticator();
|
||||
private final ExternalAuthenticator externalAuthenticator = new ExternalAuthentication();
|
||||
private final OAuthAuthenticator oAuthAuthenticator = new OAuthAuthentication();
|
||||
|
||||
@@ -40,7 +40,8 @@ public final class DefaultAuthentication implements AuthenticationSystem {
|
||||
|
||||
@Override
|
||||
public Account verifyUser(String details) {
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.authentication.default_unable_to_verify"));
|
||||
Grasscutter.getLogger()
|
||||
.info(translate("messages.dispatch.authentication.default_unable_to_verify"));
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,8 @@
|
||||
package emu.grasscutter.auth;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.ACCOUNT;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest;
|
||||
@@ -9,24 +12,16 @@ import emu.grasscutter.server.http.objects.ComboTokenResJson;
|
||||
import emu.grasscutter.server.http.objects.LoginResultJson;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
import javax.crypto.Cipher;
|
||||
import java.nio.charset.StandardCharsets;
|
||||
import java.security.KeyFactory;
|
||||
import java.security.interfaces.RSAPrivateKey;
|
||||
import java.security.spec.PKCS8EncodedKeySpec;
|
||||
import javax.crypto.Cipher;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.ACCOUNT;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
/**
|
||||
* A class containing default authenticators.
|
||||
*/
|
||||
/** A class containing default authenticators. */
|
||||
public final class DefaultAuthenticators {
|
||||
|
||||
/**
|
||||
* Handles the authentication request from the username and password form.
|
||||
*/
|
||||
/** Handles the authentication request from the username and password form. */
|
||||
public static class PasswordAuthenticator implements Authenticator<LoginResultJson> {
|
||||
@Override
|
||||
public LoginResultJson authenticate(AuthenticationRequest request) {
|
||||
@@ -52,16 +47,21 @@ public final class DefaultAuthenticators {
|
||||
// Check if the account was created successfully.
|
||||
if (account == null) {
|
||||
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 {
|
||||
// Continue with login.
|
||||
successfulLogin = true;
|
||||
|
||||
// Log the creation.
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_success", address, response.data.account.uid));
|
||||
Grasscutter.getLogger()
|
||||
.info(
|
||||
translate(
|
||||
"messages.dispatch.account.account_login_create_success",
|
||||
address,
|
||||
response.data.account.uid));
|
||||
}
|
||||
} else if (account != null)
|
||||
successfulLogin = true;
|
||||
} else if (account != null) successfulLogin = true;
|
||||
else
|
||||
loggerMessage = translate("messages.dispatch.account.account_login_exist_error", address);
|
||||
|
||||
@@ -70,7 +70,6 @@ public final class DefaultAuthenticators {
|
||||
loggerMessage = translate("messages.dispatch.account.login_max_player_limit", address);
|
||||
}
|
||||
|
||||
|
||||
// Set response data.
|
||||
if (successfulLogin) {
|
||||
response.message = "OK";
|
||||
@@ -78,11 +77,11 @@ public final class DefaultAuthenticators {
|
||||
response.data.account.token = account.generateSessionKey();
|
||||
response.data.account.email = account.getEmail();
|
||||
|
||||
loggerMessage = 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;
|
||||
|
||||
}
|
||||
Grasscutter.getLogger().info(loggerMessage);
|
||||
|
||||
@@ -114,7 +113,10 @@ public final class DefaultAuthenticators {
|
||||
|
||||
cipher.init(Cipher.DECRYPT_MODE, private_key);
|
||||
|
||||
decryptedPassword = new String(cipher.doFinal(Utils.base64Decode(request.getPasswordRequest().password)), StandardCharsets.UTF_8);
|
||||
decryptedPassword =
|
||||
new String(
|
||||
cipher.doFinal(Utils.base64Decode(request.getPasswordRequest().password)),
|
||||
StandardCharsets.UTF_8);
|
||||
} catch (Exception ignored) {
|
||||
decryptedPassword = request.getPasswordRequest().password;
|
||||
}
|
||||
@@ -133,19 +135,26 @@ public final class DefaultAuthenticators {
|
||||
// This account has been created AUTOMATICALLY. There will be no permissions added.
|
||||
if (decryptedPassword.length() >= 8) {
|
||||
account = DatabaseHelper.createAccountWithUid(requestData.account, 0);
|
||||
account.setPassword(BCrypt.withDefaults().hashToString(12, decryptedPassword.toCharArray()));
|
||||
account.setPassword(
|
||||
BCrypt.withDefaults().hashToString(12, decryptedPassword.toCharArray()));
|
||||
account.save();
|
||||
|
||||
// Check if the account was created successfully.
|
||||
if (account == null) {
|
||||
responseMessage = translate("messages.dispatch.account.username_create_error");
|
||||
loggerMessage = translate("messages.dispatch.account.account_login_create_error", address);
|
||||
loggerMessage =
|
||||
translate("messages.dispatch.account.account_login_create_error", address);
|
||||
} else {
|
||||
// Continue with login.
|
||||
successfulLogin = true;
|
||||
|
||||
// Log the creation.
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_success", address, response.data.account.uid));
|
||||
Grasscutter.getLogger()
|
||||
.info(
|
||||
translate(
|
||||
"messages.dispatch.account.account_login_create_success",
|
||||
address,
|
||||
response.data.account.uid));
|
||||
}
|
||||
} else {
|
||||
successfulLogin = false;
|
||||
@@ -154,7 +163,9 @@ public final class DefaultAuthenticators {
|
||||
}
|
||||
} else if (account != null) {
|
||||
if (account.getPassword() != null && !account.getPassword().isEmpty()) {
|
||||
if (BCrypt.verifyer().verify(decryptedPassword.toCharArray(), account.getPassword()).verified) {
|
||||
if (BCrypt.verifyer()
|
||||
.verify(decryptedPassword.toCharArray(), account.getPassword())
|
||||
.verified) {
|
||||
successfulLogin = true;
|
||||
} else {
|
||||
successfulLogin = false;
|
||||
@@ -163,7 +174,8 @@ public final class DefaultAuthenticators {
|
||||
}
|
||||
} else {
|
||||
successfulLogin = false;
|
||||
loggerMessage = translate("messages.dispatch.account.login_password_storage_error", address);
|
||||
loggerMessage =
|
||||
translate("messages.dispatch.account.login_password_storage_error", address);
|
||||
responseMessage = translate("messages.dispatch.account.password_storage_error");
|
||||
}
|
||||
} else {
|
||||
@@ -174,7 +186,6 @@ public final class DefaultAuthenticators {
|
||||
loggerMessage = translate("messages.dispatch.account.login_max_player_limit", address);
|
||||
}
|
||||
|
||||
|
||||
// Set response data.
|
||||
if (successfulLogin) {
|
||||
response.message = "OK";
|
||||
@@ -182,11 +193,11 @@ public final class DefaultAuthenticators {
|
||||
response.data.account.token = account.generateSessionKey();
|
||||
response.data.account.email = account.getEmail();
|
||||
|
||||
loggerMessage = 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;
|
||||
|
||||
}
|
||||
Grasscutter.getLogger().info(loggerMessage);
|
||||
|
||||
@@ -194,9 +205,7 @@ public final class DefaultAuthenticators {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the authentication request from the game when using a registry token.
|
||||
*/
|
||||
/** Handles the authentication request from the game when using a registry token. */
|
||||
public static class TokenAuthenticator implements Authenticator<LoginResultJson> {
|
||||
@Override
|
||||
public LoginResultJson authenticate(AuthenticationRequest request) {
|
||||
@@ -211,7 +220,8 @@ public final class DefaultAuthenticators {
|
||||
int playerCount = Grasscutter.getGameServer().getPlayers().size();
|
||||
|
||||
// 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));
|
||||
|
||||
if (ACCOUNT.maxPlayer <= -1 || playerCount < ACCOUNT.maxPlayer) {
|
||||
|
||||
@@ -229,7 +239,8 @@ public final class DefaultAuthenticators {
|
||||
response.data.account.email = account.getEmail();
|
||||
|
||||
// Log the login.
|
||||
loggerMessage = 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");
|
||||
@@ -250,9 +261,7 @@ public final class DefaultAuthenticators {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles the authentication request from the game when using a combo token/session key.
|
||||
*/
|
||||
/** Handles the authentication request from the game when using a combo token/session key. */
|
||||
public static class SessionKeyAuthenticator implements Authenticator<ComboTokenResJson> {
|
||||
@Override
|
||||
public ComboTokenResJson authenticate(AuthenticationRequest request) {
|
||||
@@ -304,43 +313,51 @@ public final class DefaultAuthenticators {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles authentication requests from external sources.
|
||||
*/
|
||||
/** Handles authentication requests from external sources. */
|
||||
public static class ExternalAuthentication implements ExternalAuthenticator {
|
||||
@Override
|
||||
public void handleLogin(AuthenticationRequest request) {
|
||||
request.getContext().result("Authentication is not available with the default authentication method.");
|
||||
request
|
||||
.getContext()
|
||||
.result("Authentication is not available with the default authentication method.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleAccountCreation(AuthenticationRequest request) {
|
||||
request.getContext().result("Authentication is not available with the default authentication method.");
|
||||
request
|
||||
.getContext()
|
||||
.result("Authentication is not available with the default authentication method.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handlePasswordReset(AuthenticationRequest request) {
|
||||
request.getContext().result("Authentication is not available with the default authentication method.");
|
||||
request
|
||||
.getContext()
|
||||
.result("Authentication is not available with the default authentication method.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles authentication requests from OAuth sources.Zenlith
|
||||
*/
|
||||
/** Handles authentication requests from OAuth sources.Zenlith */
|
||||
public static class OAuthAuthentication implements OAuthAuthenticator {
|
||||
@Override
|
||||
public void handleLogin(AuthenticationRequest request) {
|
||||
request.getContext().result("Authentication is not available with the default authentication method.");
|
||||
request
|
||||
.getContext()
|
||||
.result("Authentication is not available with the default authentication method.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleRedirection(AuthenticationRequest request, ClientType type) {
|
||||
request.getContext().result("Authentication is not available with the default authentication method.");
|
||||
request
|
||||
.getContext()
|
||||
.result("Authentication is not available with the default authentication method.");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleTokenProcess(AuthenticationRequest request) {
|
||||
request.getContext().result("Authentication is not available with the default authentication method.");
|
||||
request
|
||||
.getContext()
|
||||
.result("Authentication is not available with the default authentication method.");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package emu.grasscutter.auth;
|
||||
|
||||
import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest;
|
||||
|
||||
/**
|
||||
* Handles authentication via external routes.
|
||||
*/
|
||||
/** Handles authentication via external routes. */
|
||||
public interface ExternalAuthenticator {
|
||||
|
||||
/**
|
||||
@@ -18,9 +16,8 @@ public interface ExternalAuthenticator {
|
||||
* Called when an external account creation request is made.
|
||||
*
|
||||
* @param request The authentication request.
|
||||
* <p>
|
||||
* For developers: Use AuthenticationRequest#getRequest() to get the request body.
|
||||
* Use AuthenticationRequest#getResponse() to get the response body.
|
||||
* <p>For developers: Use AuthenticationRequest#getRequest() to get the request body. Use
|
||||
* AuthenticationRequest#getResponse() to get the response body.
|
||||
*/
|
||||
void handleAccountCreation(AuthenticationRequest request);
|
||||
|
||||
@@ -28,9 +25,8 @@ public interface ExternalAuthenticator {
|
||||
* Called when an external password reset request is made.
|
||||
*
|
||||
* @param request The authentication request.
|
||||
* <p>
|
||||
* For developers: Use AuthenticationRequest#getRequest() to get the request body.
|
||||
* Use AuthenticationRequest#getResponse() to get the response body.
|
||||
* <p>For developers: Use AuthenticationRequest#getRequest() to get the request body. Use
|
||||
* AuthenticationRequest#getResponse() to get the response body.
|
||||
*/
|
||||
void handlePasswordReset(AuthenticationRequest request);
|
||||
}
|
||||
|
||||
@@ -2,9 +2,7 @@ package emu.grasscutter.auth;
|
||||
|
||||
import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest;
|
||||
|
||||
/**
|
||||
* Handles authentication via OAuth routes.
|
||||
*/
|
||||
/** Handles authentication via OAuth routes. */
|
||||
public interface OAuthAuthenticator {
|
||||
|
||||
/**
|
||||
@@ -28,11 +26,9 @@ public interface OAuthAuthenticator {
|
||||
*/
|
||||
void handleTokenProcess(AuthenticationRequest request);
|
||||
|
||||
/**
|
||||
* The type of the client.
|
||||
* Used for handling redirection.
|
||||
*/
|
||||
/** The type of the client. Used for handling redirection. */
|
||||
enum ClientType {
|
||||
DESKTOP, MOBILE
|
||||
DESKTOP,
|
||||
MOBILE
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,9 +20,9 @@ public @interface Command {
|
||||
boolean threading() default false;
|
||||
|
||||
enum TargetRequirement {
|
||||
NONE, // targetPlayer is not required
|
||||
OFFLINE, // targetPlayer must be offline
|
||||
PLAYER, // targetPlayer can be online or offline
|
||||
ONLINE // targetPlayer must be online
|
||||
NONE, // targetPlayer is not required
|
||||
OFFLINE, // targetPlayer must be offline
|
||||
PLAYER, // targetPlayer can be online or offline
|
||||
ONLINE // targetPlayer must be online
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
package emu.grasscutter.command;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public interface CommandHandler {
|
||||
|
||||
/**
|
||||
* Send a message to the target.
|
||||
*
|
||||
* @param player The player to send the message to, or null for the server console.
|
||||
* @param player The player to send the message to, or null for the server console.
|
||||
* @param message The message to send.
|
||||
*/
|
||||
static void sendMessage(Player player, String message) {
|
||||
@@ -42,23 +41,23 @@ public interface CommandHandler {
|
||||
String usage_prefix = translate(player, "commands.execution.usage_prefix");
|
||||
String command = annotation.label();
|
||||
for (String alias : annotation.aliases()) {
|
||||
if (alias.length() < command.length())
|
||||
command = alias;
|
||||
if (alias.length() < command.length()) command = alias;
|
||||
}
|
||||
if (player != null) {
|
||||
command = "/" + command;
|
||||
}
|
||||
String target = switch (annotation.targetRequirement()) {
|
||||
case NONE -> "";
|
||||
case OFFLINE -> "@<UID> "; // TODO: make translation keys for offline and online players
|
||||
case ONLINE ->
|
||||
(player == null) ? "@<UID> " : "[@<UID>] "; // TODO: make translation keys for offline and online players
|
||||
case PLAYER -> (player == null) ? "@<UID> " : "[@<UID>] ";
|
||||
};
|
||||
String target =
|
||||
switch (annotation.targetRequirement()) {
|
||||
case NONE -> "";
|
||||
case OFFLINE -> "@<UID> "; // TODO: make translation keys for offline and online players
|
||||
case ONLINE -> (player == null)
|
||||
? "@<UID> "
|
||||
: "[@<UID>] "; // TODO: make translation keys for offline and online players
|
||||
case PLAYER -> (player == null) ? "@<UID> " : "[@<UID>] ";
|
||||
};
|
||||
String[] usages = annotation.usage();
|
||||
StringJoiner joiner = new StringJoiner("\n\t");
|
||||
for (String usage : usages)
|
||||
joiner.add(usage_prefix + command + " " + target + usage);
|
||||
for (String usage : usages) joiner.add(usage_prefix + command + " " + target + usage);
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
@@ -83,8 +82,7 @@ public interface CommandHandler {
|
||||
* Called when a player/console invokes a command.
|
||||
*
|
||||
* @param sender The player/console that invoked the command.
|
||||
* @param args The arguments to the command.
|
||||
* @param args The arguments to the command.
|
||||
*/
|
||||
default void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
}
|
||||
default void execute(Player sender, Player targetPlayer, List<String> args) {}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package emu.grasscutter.command;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.annotation.Nonnull;
|
||||
|
||||
public class CommandHelpers {
|
||||
public static final Pattern lvlRegex = Pattern.compile("(?<!\\w)l(?:vl?)?(\\d+)"); // Java doesn't have raw string literals :(
|
||||
public static final Pattern amountRegex = Pattern.compile("((?<=(?<!\\w)x)\\d+|\\d+(?=x)(?!x\\d))");
|
||||
public static final Pattern lvlRegex =
|
||||
Pattern.compile("(?<!\\w)l(?:vl?)?(\\d+)"); // Java doesn't have raw string literals :(
|
||||
public static final Pattern amountRegex =
|
||||
Pattern.compile("((?<=(?<!\\w)x)\\d+|\\d+(?=x)(?!x\\d))");
|
||||
public static final Pattern refineRegex = Pattern.compile("(?<!\\w)r(\\d+)");
|
||||
public static final Pattern rankRegex = Pattern.compile("(\\d+)\\*");
|
||||
public static final Pattern constellationRegex = Pattern.compile("(?<!\\w)c(\\d+)");
|
||||
@@ -27,24 +29,29 @@ public class CommandHelpers {
|
||||
public static int matchIntOrNeg(Pattern pattern, String arg) {
|
||||
Matcher match = pattern.matcher(arg);
|
||||
if (match.find()) {
|
||||
return Integer.parseInt(match.group(1)); // This should be exception-safe as only \d+ can be passed to it (i.e. non-empty string of pure digits)
|
||||
return Integer.parseInt(
|
||||
match.group(
|
||||
1)); // This should be exception-safe as only \d+ can be passed to it (i.e. non-empty
|
||||
// string of pure digits)
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
public static <T> List<String> parseIntParameters(List<String> args, @Nonnull T params, Map<Pattern, BiConsumer<T, Integer>> map) {
|
||||
args.removeIf(arg -> {
|
||||
var argL = arg.toLowerCase();
|
||||
boolean deleteArg = false;
|
||||
for (var entry : map.entrySet()) {
|
||||
int argNum = matchIntOrNeg(entry.getKey(), argL);
|
||||
if (argNum != -1) {
|
||||
entry.getValue().accept(params, argNum);
|
||||
deleteArg = true;
|
||||
}
|
||||
}
|
||||
return deleteArg;
|
||||
});
|
||||
public static <T> List<String> parseIntParameters(
|
||||
List<String> args, @Nonnull T params, Map<Pattern, BiConsumer<T, Integer>> map) {
|
||||
args.removeIf(
|
||||
arg -> {
|
||||
var argL = arg.toLowerCase();
|
||||
boolean deleteArg = false;
|
||||
for (var entry : map.entrySet()) {
|
||||
int argNum = matchIntOrNeg(entry.getKey(), argL);
|
||||
if (argNum != -1) {
|
||||
entry.getValue().accept(params, argNum);
|
||||
deleteArg = true;
|
||||
}
|
||||
}
|
||||
return deleteArg;
|
||||
});
|
||||
return args;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,14 @@
|
||||
package emu.grasscutter.command;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2IntOpenHashMap;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.SERVER;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
@SuppressWarnings({"UnusedReturnValue", "unused"})
|
||||
public final class CommandMap {
|
||||
@@ -49,7 +48,7 @@ public final class CommandMap {
|
||||
/**
|
||||
* Register a command handler.
|
||||
*
|
||||
* @param label The command label.
|
||||
* @param label The command label.
|
||||
* @param command The command handler.
|
||||
* @return Instance chaining.
|
||||
*/
|
||||
@@ -131,7 +130,8 @@ public final class CommandMap {
|
||||
return handler;
|
||||
}
|
||||
|
||||
private Player getTargetPlayer(String playerId, Player player, Player targetPlayer, List<String> args) {
|
||||
private Player getTargetPlayer(
|
||||
String playerId, Player player, Player targetPlayer, List<String> args) {
|
||||
// Top priority: If any @UID argument is present, override targetPlayer with it.
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
String arg = args.get(i);
|
||||
@@ -139,7 +139,8 @@ public final class CommandMap {
|
||||
arg = args.remove(i).substring(1);
|
||||
if (arg.equals("")) {
|
||||
// This is a special case to target nothing, distinct from failing to assign a target.
|
||||
// This is specifically to allow in-game players to run a command without targeting themselves or anyone else.
|
||||
// This is specifically to allow in-game players to run a command without targeting
|
||||
// themselves or anyone else.
|
||||
return null;
|
||||
}
|
||||
int uid = getUidFromString(arg);
|
||||
@@ -164,7 +165,8 @@ public final class CommandMap {
|
||||
|
||||
// Next priority: Use previously-set target. (see /target [[@]UID])
|
||||
if (targetPlayerIds.containsKey(playerId)) {
|
||||
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(targetPlayerIds.getInt(playerId), true);
|
||||
targetPlayer =
|
||||
Grasscutter.getGameServer().getPlayerByUid(targetPlayerIds.getInt(playerId), true);
|
||||
// We check every time in case the target is deleted after being targeted
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error");
|
||||
@@ -173,7 +175,8 @@ public final class CommandMap {
|
||||
return targetPlayer;
|
||||
}
|
||||
|
||||
// Lowest priority: Target the player invoking the command. In the case of the console, this will return null.
|
||||
// Lowest priority: Target the player invoking the command. In the case of the console, this
|
||||
// will return null.
|
||||
return player;
|
||||
}
|
||||
|
||||
@@ -199,21 +202,33 @@ public final class CommandMap {
|
||||
targetPlayerIds.put(playerId, uid);
|
||||
String target = uid + " (" + targetPlayer.getAccount().getUsername() + ")";
|
||||
CommandHandler.sendTranslatedMessage(player, "commands.execution.set_target", target);
|
||||
CommandHandler.sendTranslatedMessage(player, targetPlayer.isOnline() ? "commands.execution.set_target_online" : "commands.execution.set_target_offline", target);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
player,
|
||||
targetPlayer.isOnline()
|
||||
? "commands.execution.set_target_online"
|
||||
: "commands.execution.set_target_offline",
|
||||
target);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Invoke a command handler with the given arguments.
|
||||
*
|
||||
* @param player The player invoking the command or null for the server console.
|
||||
* @param player The player invoking the command or null for the server console.
|
||||
* @param rawMessage The messaged used to invoke the command.
|
||||
*/
|
||||
public void invoke(Player player, Player targetPlayer, String rawMessage) {
|
||||
// The console outputs in-game command. [{Account Username} (Player UID: {Player Uid})]
|
||||
if (SERVER.logCommands) {
|
||||
if (player != null) {
|
||||
Grasscutter.getLogger().info("Command used by [" + player.getAccount().getUsername() + " (Player UID: " + player.getUid() + ")]: " + rawMessage);
|
||||
Grasscutter.getLogger()
|
||||
.info(
|
||||
"Command used by ["
|
||||
+ player.getAccount().getUsername()
|
||||
+ " (Player UID: "
|
||||
+ player.getUid()
|
||||
+ ")]: "
|
||||
+ rawMessage);
|
||||
} else {
|
||||
Grasscutter.getLogger().info("Command used by server console: " + rawMessage);
|
||||
}
|
||||
@@ -269,7 +284,12 @@ public final class CommandMap {
|
||||
}
|
||||
|
||||
// Check for permissions.
|
||||
if (!Grasscutter.getPermissionHandler().checkPermission(player, targetPlayer, annotation.permission(), this.annotations.get(label).permissionTargeted())) {
|
||||
if (!Grasscutter.getPermissionHandler()
|
||||
.checkPermission(
|
||||
player,
|
||||
targetPlayer,
|
||||
annotation.permission(),
|
||||
this.annotations.get(label).permissionTargeted())) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -308,23 +328,27 @@ public final class CommandMap {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scans for all classes annotated with {@link Command} and registers them.
|
||||
*/
|
||||
/** Scans for all classes annotated with {@link Command} and registers them. */
|
||||
private void scan() {
|
||||
Reflections reflector = Grasscutter.reflector;
|
||||
Set<Class<?>> classes = reflector.getTypesAnnotatedWith(Command.class);
|
||||
|
||||
classes.forEach(annotated -> {
|
||||
try {
|
||||
Command cmdData = annotated.getAnnotation(Command.class);
|
||||
Object object = annotated.getDeclaredConstructor().newInstance();
|
||||
if (object instanceof CommandHandler)
|
||||
this.registerCommand(cmdData.label(), (CommandHandler) object);
|
||||
else Grasscutter.getLogger().error("Class " + annotated.getName() + " is not a CommandHandler!");
|
||||
} catch (Exception exception) {
|
||||
Grasscutter.getLogger().error("Failed to register command handler for " + annotated.getSimpleName(), exception);
|
||||
}
|
||||
});
|
||||
classes.forEach(
|
||||
annotated -> {
|
||||
try {
|
||||
Command cmdData = annotated.getAnnotation(Command.class);
|
||||
Object object = annotated.getDeclaredConstructor().newInstance();
|
||||
if (object instanceof CommandHandler)
|
||||
this.registerCommand(cmdData.label(), (CommandHandler) object);
|
||||
else
|
||||
Grasscutter.getLogger()
|
||||
.error("Class " + annotated.getName() + " is not a CommandHandler!");
|
||||
} catch (Exception exception) {
|
||||
Grasscutter.getLogger()
|
||||
.error(
|
||||
"Failed to register command handler for " + annotated.getSimpleName(),
|
||||
exception);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,13 +10,14 @@ public class DefaultPermissionHandler implements PermissionHandler {
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean checkPermission(Player player, Player targetPlayer, String permissionNode, String permissionNodeTargeted) {
|
||||
public boolean checkPermission(
|
||||
Player player, Player targetPlayer, String permissionNode, String permissionNodeTargeted) {
|
||||
if (player == null) {
|
||||
return true;
|
||||
}
|
||||
|
||||
Account account = player.getAccount();
|
||||
if (player != targetPlayer) { // Additional permission required for targeting another player
|
||||
if (player != targetPlayer) { // Additional permission required for targeting another player
|
||||
if (!permissionNodeTargeted.isEmpty() && !account.hasPermission(permissionNodeTargeted)) {
|
||||
CommandHandler.sendTranslatedMessage(player, "commands.generic.permission_error");
|
||||
return false;
|
||||
|
||||
@@ -5,5 +5,6 @@ import emu.grasscutter.game.player.Player;
|
||||
public interface PermissionHandler {
|
||||
boolean EnablePermissionCommand();
|
||||
|
||||
boolean checkPermission(Player player, Player targetPlayer, String permissionNode, String permissionNodeTargeted);
|
||||
boolean checkPermission(
|
||||
Player player, Player targetPlayer, String permissionNode, String permissionNodeTargeted);
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
@@ -8,19 +10,17 @@ import emu.grasscutter.config.Configuration;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(
|
||||
label = "account",
|
||||
usage = {
|
||||
"create <username> [<UID>]", // Only with EXPERIMENTAL_RealPassword == false
|
||||
"delete <username>",
|
||||
"create <username> <password> [<UID>]", // Only with EXPERIMENTAL_RealPassword == true
|
||||
"resetpass <username> <password>"}, // Only with EXPERIMENTAL_RealPassword == true
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
label = "account",
|
||||
usage = {
|
||||
"create <username> [<UID>]", // Only with EXPERIMENTAL_RealPassword == false
|
||||
"delete <username>",
|
||||
"create <username> <password> [<UID>]", // Only with EXPERIMENTAL_RealPassword == true
|
||||
"resetpass <username> <password>"
|
||||
}, // Only with EXPERIMENTAL_RealPassword == true
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class AccountCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
@@ -47,7 +47,8 @@ public final class AccountCommand implements CommandHandler {
|
||||
|
||||
if (Configuration.ACCOUNT.EXPERIMENTAL_RealPassword) {
|
||||
if (args.size() < 3) {
|
||||
CommandHandler.sendMessage(sender, "EXPERIMENTAL_RealPassword requires a password argument");
|
||||
CommandHandler.sendMessage(
|
||||
sender, "EXPERIMENTAL_RealPassword requires a password argument");
|
||||
CommandHandler.sendMessage(sender, "Usage: account create <username> <password> [uid]");
|
||||
return;
|
||||
}
|
||||
@@ -59,8 +60,11 @@ public final class AccountCommand implements CommandHandler {
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.invalid"));
|
||||
if (Configuration.ACCOUNT.EXPERIMENTAL_RealPassword) {
|
||||
CommandHandler.sendMessage(sender, "EXPERIMENTAL_RealPassword requires argument 2 to be a password, not a uid");
|
||||
CommandHandler.sendMessage(sender, "Usage: account create <username> <password> [uid]");
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
"EXPERIMENTAL_RealPassword requires argument 2 to be a password, not a uid");
|
||||
CommandHandler.sendMessage(
|
||||
sender, "Usage: account create <username> <password> [uid]");
|
||||
}
|
||||
return;
|
||||
}
|
||||
@@ -87,7 +91,8 @@ public final class AccountCommand implements CommandHandler {
|
||||
account.addPermission("*");
|
||||
account.save(); // Save account to database.
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.create", account.getReservedPlayerUid()));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.account.create", account.getReservedPlayerUid()));
|
||||
}
|
||||
return;
|
||||
case "delete":
|
||||
@@ -104,7 +109,8 @@ public final class AccountCommand implements CommandHandler {
|
||||
return;
|
||||
case "resetpass":
|
||||
if (!Configuration.ACCOUNT.EXPERIMENTAL_RealPassword) {
|
||||
CommandHandler.sendMessage(sender, "resetpass requires EXPERIMENTAL_RealPassword to be true.");
|
||||
CommandHandler.sendMessage(
|
||||
sender, "resetpass requires EXPERIMENTAL_RealPassword to be true.");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,22 +7,27 @@ import emu.grasscutter.data.excels.AchievementData;
|
||||
import emu.grasscutter.game.achievement.AchievementControlReturns;
|
||||
import emu.grasscutter.game.achievement.Achievements;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.atomic.AtomicInteger;
|
||||
|
||||
@Command(
|
||||
label = "achievement",
|
||||
usage = {"(grant|revoke) <achievementId>", "progress <achievementId> <progress>", "grantall", "revokeall"},
|
||||
aliases = {"am"},
|
||||
permission = "player.achievement",
|
||||
permissionTargeted = "player.achievement.others",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER,
|
||||
threading = true)
|
||||
label = "achievement",
|
||||
usage = {
|
||||
"(grant|revoke) <achievementId>",
|
||||
"progress <achievementId> <progress>",
|
||||
"grantall",
|
||||
"revokeall"
|
||||
},
|
||||
aliases = {"am"},
|
||||
permission = "player.achievement",
|
||||
permissionTargeted = "player.achievement.others",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER,
|
||||
threading = true)
|
||||
public class AchievementCommand implements CommandHandler {
|
||||
private static void sendSuccessMessage(Player sender, String cmd, Object... args) {
|
||||
CommandHandler.sendTranslatedMessage(sender, AchievementControlReturns.Return.SUCCESS.getKey() + cmd, args);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, AchievementControlReturns.Return.SUCCESS.getKey() + cmd, args);
|
||||
}
|
||||
|
||||
private static Optional<Integer> parseInt(String s) {
|
||||
@@ -36,14 +41,15 @@ public class AchievementCommand implements CommandHandler {
|
||||
private static void grantAll(Player sender, Player targetPlayer, Achievements achievements) {
|
||||
var counter = new AtomicInteger();
|
||||
GameData.getAchievementDataMap().values().stream()
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(data -> {
|
||||
var success = achievements.grant(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(
|
||||
data -> {
|
||||
var success = achievements.grant(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
|
||||
sendSuccessMessage(sender, "grantall", counter.intValue(), targetPlayer.getNickname());
|
||||
}
|
||||
@@ -51,14 +57,15 @@ public class AchievementCommand implements CommandHandler {
|
||||
private static void revokeAll(Player sender, Player targetPlayer, Achievements achievements) {
|
||||
var counter = new AtomicInteger();
|
||||
GameData.getAchievementDataMap().values().stream()
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(data -> {
|
||||
var success = achievements.revoke(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
.filter(AchievementData::isUsed)
|
||||
.filter(AchievementData::isParent)
|
||||
.forEach(
|
||||
data -> {
|
||||
var success = achievements.revoke(data.getId());
|
||||
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
|
||||
counter.addAndGet(success.getChangedAchievementStatusNum());
|
||||
}
|
||||
});
|
||||
|
||||
sendSuccessMessage(sender, "revokeall", counter.intValue(), targetPlayer.getNickname());
|
||||
}
|
||||
@@ -82,52 +89,70 @@ public class AchievementCommand implements CommandHandler {
|
||||
}
|
||||
}
|
||||
|
||||
private void grant(Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
private void grant(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0)).ifPresentOrElse(integer -> {
|
||||
var ret = achievements.grant(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "grant", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(sender, ret.getRet().getKey());
|
||||
case ALREADY_ACHIEVED ->
|
||||
CommandHandler.sendTranslatedMessage(sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
}, () -> this.sendUsageMessage(sender));
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
var ret = achievements.grant(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "grant", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
case ALREADY_ACHIEVED -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
|
||||
private void revoke(Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
private void revoke(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0)).ifPresentOrElse(integer -> {
|
||||
var ret = achievements.revoke(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "revoke", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(sender, ret.getRet().getKey());
|
||||
case NOT_YET_ACHIEVED ->
|
||||
CommandHandler.sendTranslatedMessage(sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
}, () -> this.sendUsageMessage(sender));
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
var ret = achievements.revoke(integer);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(sender, "revoke", targetPlayer.getNickname());
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
case NOT_YET_ACHIEVED -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey(), targetPlayer.getNickname());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
|
||||
private void progress(Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
private void progress(
|
||||
Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
this.sendUsageMessage(sender);
|
||||
}
|
||||
|
||||
parseInt(args.remove(0)).ifPresentOrElse(integer -> {
|
||||
parseInt(args.remove(0)).ifPresentOrElse(progress -> {
|
||||
var ret = achievements.progress(integer, progress);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS ->
|
||||
sendSuccessMessage(sender, "progress", targetPlayer.getNickname(), integer, progress);
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(sender, ret.getRet().getKey());
|
||||
}
|
||||
}, () -> this.sendUsageMessage(sender));
|
||||
}, () -> this.sendUsageMessage(sender));
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
integer -> {
|
||||
parseInt(args.remove(0))
|
||||
.ifPresentOrElse(
|
||||
progress -> {
|
||||
var ret = achievements.progress(integer, progress);
|
||||
switch (ret.getRet()) {
|
||||
case SUCCESS -> sendSuccessMessage(
|
||||
sender, "progress", targetPlayer.getNickname(), integer, progress);
|
||||
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
|
||||
sender, ret.getRet().getKey());
|
||||
}
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
},
|
||||
() -> this.sendUsageMessage(sender));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,22 +1,22 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.PacketServerAnnounceNotify;
|
||||
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "announce",
|
||||
usage = {"<content>", "refresh", "(tpl|revoke) <templateId>"},
|
||||
permission = "server.announce",
|
||||
aliases = {"a"},
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "announce",
|
||||
usage = {"<content>", "refresh", "(tpl|revoke) <templateId>"},
|
||||
permission = "server.announce",
|
||||
aliases = {"a"},
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class AnnounceCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -37,17 +37,20 @@ public final class AnnounceCommand implements CommandHandler {
|
||||
var templateId = Integer.parseInt(args.get(1));
|
||||
var tpl = manager.getAnnounceConfigItemMap().get(templateId);
|
||||
if (tpl == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.announce.not_found", templateId));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.announce.not_found", templateId));
|
||||
return;
|
||||
}
|
||||
|
||||
manager.broadcast(Collections.singletonList(tpl));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.announce.send_success", tpl.getTemplateId()));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.announce.send_success", tpl.getTemplateId()));
|
||||
break;
|
||||
|
||||
case "refresh":
|
||||
var num = manager.refresh();
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.announce.refresh_success", num));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.announce.refresh_success", num));
|
||||
break;
|
||||
|
||||
case "revoke":
|
||||
@@ -58,16 +61,18 @@ public final class AnnounceCommand implements CommandHandler {
|
||||
|
||||
var templateId1 = Integer.parseInt(args.get(1));
|
||||
manager.revoke(templateId1);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.announce.revoke_done", templateId1));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.announce.revoke_done", templateId1));
|
||||
break;
|
||||
|
||||
default:
|
||||
var id = new Random().nextInt(10000, 99999);
|
||||
var text = String.join(" ", args);
|
||||
manager.getOnlinePlayers().forEach(i -> i.sendPacket(new PacketServerAnnounceNotify(text, id)));
|
||||
manager
|
||||
.getOnlinePlayers()
|
||||
.forEach(i -> i.sendPacket(new PacketServerAnnounceNotify(text, id)));
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.announce.send_success", id));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,15 +5,13 @@ import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "ban",
|
||||
usage = {"[<time> [<reason>]]"},
|
||||
permission = "server.ban",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER
|
||||
)
|
||||
label = "ban",
|
||||
usage = {"[<time> [<reason>]]"},
|
||||
permission = "server.ban",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER)
|
||||
public final class BanCommand implements CommandHandler {
|
||||
|
||||
private boolean banAccount(Player targetPlayer, int time, String reason) {
|
||||
@@ -43,14 +41,14 @@ public final class BanCommand implements CommandHandler {
|
||||
|
||||
switch (args.size()) {
|
||||
case 2:
|
||||
reason = args.get(1); // Fall-through
|
||||
reason = args.get(1); // Fall-through
|
||||
case 1:
|
||||
try {
|
||||
time = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.ban.invalid_time");
|
||||
return;
|
||||
} // Fall-through, unimportant
|
||||
} // Fall-through, unimportant
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -1,50 +1,50 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.inventory.Inventory;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import lombok.Setter;
|
||||
|
||||
@Command(
|
||||
label = "clear",
|
||||
usage = {"(all|wp|art|mat) [lv<max level>] [r<max refinement>] [<max rarity>*]"},
|
||||
permission = "player.clearinv",
|
||||
permissionTargeted = "player.clearinv.others")
|
||||
label = "clear",
|
||||
usage = {"(all|wp|art|mat) [lv<max level>] [r<max refinement>] [<max rarity>*]"},
|
||||
permission = "player.clearinv",
|
||||
permissionTargeted = "player.clearinv.others")
|
||||
public final class ClearCommand implements CommandHandler {
|
||||
|
||||
private static final Map<Pattern, BiConsumer<ClearItemParameters, Integer>> intCommandHandlers = Map.ofEntries(
|
||||
Map.entry(lvlRegex, ClearItemParameters::setLvl),
|
||||
Map.entry(refineRegex, ClearItemParameters::setRefinement),
|
||||
Map.entry(rankRegex, ClearItemParameters::setRank)
|
||||
);
|
||||
private static final Map<Pattern, BiConsumer<ClearItemParameters, Integer>> intCommandHandlers =
|
||||
Map.ofEntries(
|
||||
Map.entry(lvlRegex, ClearItemParameters::setLvl),
|
||||
Map.entry(refineRegex, ClearItemParameters::setRefinement),
|
||||
Map.entry(rankRegex, ClearItemParameters::setRank));
|
||||
|
||||
private Stream<GameItem> getOther(ItemType type, Inventory playerInventory, ClearItemParameters param) {
|
||||
private Stream<GameItem> getOther(
|
||||
ItemType type, Inventory playerInventory, ClearItemParameters param) {
|
||||
return playerInventory.getItems().values().stream()
|
||||
.filter(item -> item.getItemType() == type)
|
||||
.filter(item -> item.getItemData().getRankLevel() <= param.rank)
|
||||
.filter(item -> !item.isLocked() && !item.isEquipped());
|
||||
.filter(item -> item.getItemType() == type)
|
||||
.filter(item -> item.getItemData().getRankLevel() <= param.rank)
|
||||
.filter(item -> !item.isLocked() && !item.isEquipped());
|
||||
}
|
||||
|
||||
private Stream<GameItem> getWeapons(Inventory playerInventory, ClearItemParameters param) {
|
||||
return getOther(ItemType.ITEM_WEAPON, playerInventory, param)
|
||||
.filter(item -> item.getLevel() <= param.lvl)
|
||||
.filter(item -> item.getRefinement() < param.refinement);
|
||||
.filter(item -> item.getLevel() <= param.lvl)
|
||||
.filter(item -> item.getRefinement() < param.refinement);
|
||||
}
|
||||
|
||||
private Stream<GameItem> getRelics(Inventory playerInventory, ClearItemParameters param) {
|
||||
return getOther(ItemType.ITEM_RELIQUARY, playerInventory, param)
|
||||
.filter(item -> item.getLevel() <= param.lvl + 1);
|
||||
.filter(item -> item.getLevel() <= param.lvl + 1);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -60,7 +60,7 @@ public final class ClearCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
String playerString = targetPlayer.getNickname(); // Should probably be UID instead but whatever
|
||||
String playerString = targetPlayer.getNickname(); // Should probably be UID instead but whatever
|
||||
switch (args.get(0)) {
|
||||
case "wp" -> {
|
||||
playerInventory.removeItems(getWeapons(playerInventory, param).toList());
|
||||
@@ -71,7 +71,8 @@ public final class ClearCommand implements CommandHandler {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.artifacts", playerString);
|
||||
}
|
||||
case "mat" -> {
|
||||
playerInventory.removeItems(getOther(ItemType.ITEM_MATERIAL, playerInventory, param).toList());
|
||||
playerInventory.removeItems(
|
||||
getOther(ItemType.ITEM_MATERIAL, playerInventory, param).toList());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.materials", playerString);
|
||||
}
|
||||
case "all" -> {
|
||||
@@ -79,13 +80,17 @@ public final class ClearCommand implements CommandHandler {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.artifacts", playerString);
|
||||
playerInventory.removeItems(getWeapons(playerInventory, param).toList());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.weapons", playerString);
|
||||
playerInventory.removeItems(getOther(ItemType.ITEM_MATERIAL, playerInventory, param).toList());
|
||||
playerInventory.removeItems(
|
||||
getOther(ItemType.ITEM_MATERIAL, playerInventory, param).toList());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.materials", playerString);
|
||||
playerInventory.removeItems(getOther(ItemType.ITEM_FURNITURE, playerInventory, param).toList());
|
||||
playerInventory.removeItems(
|
||||
getOther(ItemType.ITEM_FURNITURE, playerInventory, param).toList());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.furniture", playerString);
|
||||
playerInventory.removeItems(getOther(ItemType.ITEM_DISPLAY, playerInventory, param).toList());
|
||||
playerInventory.removeItems(
|
||||
getOther(ItemType.ITEM_DISPLAY, playerInventory, param).toList());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.displays", playerString);
|
||||
playerInventory.removeItems(getOther(ItemType.ITEM_VIRTUAL, playerInventory, param).toList());
|
||||
playerInventory.removeItems(
|
||||
getOther(ItemType.ITEM_VIRTUAL, playerInventory, param).toList());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.virtuals", playerString);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.everything", playerString);
|
||||
}
|
||||
@@ -93,11 +98,8 @@ public final class ClearCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
private static class ClearItemParameters {
|
||||
@Setter
|
||||
public int lvl = 1;
|
||||
@Setter
|
||||
public int refinement = 1;
|
||||
@Setter
|
||||
public int rank = 4;
|
||||
@Setter public int lvl = 1;
|
||||
@Setter public int refinement = 1;
|
||||
@Setter public int rank = 4;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,23 +4,26 @@ import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(label = "coop", usage = {"[<host UID>]"}, permission = "server.coop", permissionTargeted = "server.coop.others")
|
||||
@Command(
|
||||
label = "coop",
|
||||
usage = {"[<host UID>]"},
|
||||
permission = "server.coop",
|
||||
permissionTargeted = "server.coop.others")
|
||||
public final class CoopCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
Player host = sender;
|
||||
switch (args.size()) {
|
||||
case 0: // Summon target to self
|
||||
case 0: // Summon target to self
|
||||
if (sender == null) { // Console doesn't have a self to summon to
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 1: // Summon target to argument
|
||||
case 1: // Summon target to argument
|
||||
try {
|
||||
int hostId = Integer.parseInt(args.get(0));
|
||||
host = Grasscutter.getGameServer().getPlayerByUid(hostId);
|
||||
@@ -38,12 +41,17 @@ public final class CoopCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
// There's no target==host check but this just places them in multiplayer in their own world which seems fine.
|
||||
// There's no target==host check but this just places them in multiplayer in their own world
|
||||
// which seems fine.
|
||||
if (targetPlayer.isInMultiplayer()) {
|
||||
targetPlayer.getServer().getMultiplayerSystem().leaveCoop(targetPlayer);
|
||||
}
|
||||
host.getServer().getMultiplayerSystem().applyEnterMp(targetPlayer, host.getUid());
|
||||
targetPlayer.getServer().getMultiplayerSystem().applyEnterMpReply(host, targetPlayer.getUid(), true);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.coop.success", targetPlayer.getNickname(), host.getNickname());
|
||||
targetPlayer
|
||||
.getServer()
|
||||
.getMultiplayerSystem()
|
||||
.applyEnterMpReply(host, targetPlayer.getUid(), true);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.coop.success", targetPlayer.getNickname(), host.getNickname());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,14 +1,18 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "enter_dungeon", aliases = {"enterdungeon", "dungeon"}, usage = {"<dungeonId>"}, permission = "player.enterdungeon", permissionTargeted = "player.enterdungeon.others")
|
||||
@Command(
|
||||
label = "enter_dungeon",
|
||||
aliases = {"enterdungeon", "dungeon"},
|
||||
usage = {"<dungeonId>"},
|
||||
permission = "player.enterdungeon",
|
||||
permissionTargeted = "player.enterdungeon.others")
|
||||
public final class EnterDungeonCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -21,16 +25,23 @@ public final class EnterDungeonCommand implements CommandHandler {
|
||||
try {
|
||||
int dungeonId = Integer.parseInt(args.get(0));
|
||||
if (dungeonId == targetPlayer.getSceneId()) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.in_dungeon_error"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.enter_dungeon.in_dungeon_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = targetPlayer.getServer().getDungeonSystem().enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId);
|
||||
boolean result =
|
||||
targetPlayer
|
||||
.getServer()
|
||||
.getDungeonSystem()
|
||||
.enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId);
|
||||
|
||||
if (!result) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.not_found_error"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.enter_dungeon.not_found_error"));
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.changed", dungeonId));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.enter_dungeon.changed", dungeonId));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
sendUsageMessage(sender);
|
||||
|
||||
@@ -1,32 +1,44 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarFightPropUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "heal", aliases = {"h"}, permission = "player.heal", permissionTargeted = "player.heal.others")
|
||||
@Command(
|
||||
label = "heal",
|
||||
aliases = {"h"},
|
||||
permission = "player.heal",
|
||||
permissionTargeted = "player.heal.others")
|
||||
public final class HealCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
targetPlayer.getTeamManager().getActiveTeam().forEach(entity -> {
|
||||
boolean isAlive = entity.isAlive();
|
||||
entity.setFightProperty(
|
||||
FightProperty.FIGHT_PROP_CUR_HP,
|
||||
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP)
|
||||
);
|
||||
entity.getWorld().broadcastPacket(new PacketAvatarFightPropUpdateNotify(entity.getAvatar(), FightProperty.FIGHT_PROP_CUR_HP));
|
||||
if (!isAlive) {
|
||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||
}
|
||||
});
|
||||
targetPlayer
|
||||
.getTeamManager()
|
||||
.getActiveTeam()
|
||||
.forEach(
|
||||
entity -> {
|
||||
boolean isAlive = entity.isAlive();
|
||||
entity.setFightProperty(
|
||||
FightProperty.FIGHT_PROP_CUR_HP,
|
||||
entity.getFightProperty(FightProperty.FIGHT_PROP_MAX_HP));
|
||||
entity
|
||||
.getWorld()
|
||||
.broadcastPacket(
|
||||
new PacketAvatarFightPropUpdateNotify(
|
||||
entity.getAvatar(), FightProperty.FIGHT_PROP_CUR_HP));
|
||||
if (!isAlive) {
|
||||
entity
|
||||
.getWorld()
|
||||
.broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||
}
|
||||
});
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.heal.success"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,26 +1,30 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "help", usage = {"[<command>]"}, targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "help",
|
||||
usage = {"[<command>]"},
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class HelpCommand implements CommandHandler {
|
||||
private final boolean SHOW_COMMANDS_WITHOUT_PERMISSIONS = false; // TODO: Make this into a server config key
|
||||
private final boolean SHOW_COMMANDS_WITHOUT_PERMISSIONS =
|
||||
false; // TODO: Make this into a server config key
|
||||
|
||||
private String createCommand(Player player, CommandHandler command, List<String> args) {
|
||||
StringBuilder builder = new StringBuilder(command.getLabel())
|
||||
.append(" - ")
|
||||
.append(command.getDescriptionString(player))
|
||||
.append("\n\t")
|
||||
.append(command.getUsageString(player, args.toArray(new String[0])));
|
||||
StringBuilder builder =
|
||||
new StringBuilder(command.getLabel())
|
||||
.append(" - ")
|
||||
.append(command.getDescriptionString(player))
|
||||
.append("\n\t")
|
||||
.append(command.getUsageString(player, args.toArray(new String[0])));
|
||||
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
if (annotation.aliases().length > 0) {
|
||||
@@ -39,7 +43,9 @@ public final class HelpCommand implements CommandHandler {
|
||||
|
||||
if (!annotation.permissionTargeted().isEmpty()) {
|
||||
String permissionTargeted = annotation.permissionTargeted();
|
||||
builder.append(" ").append(translate(player, "commands.help.tip_permission_targeted", permissionTargeted));
|
||||
builder
|
||||
.append(" ")
|
||||
.append(translate(player, "commands.help.tip_permission_targeted", permissionTargeted));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
@@ -51,14 +57,17 @@ public final class HelpCommand implements CommandHandler {
|
||||
List<String> commands = new ArrayList<>();
|
||||
List<String> commands_no_permission = new ArrayList<>();
|
||||
if (args.isEmpty()) {
|
||||
commandMap.getHandlers().forEach((key, command) -> {
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
if (player == null || account.hasPermission(annotation.permission())) {
|
||||
commands.add(createCommand(player, command, args));
|
||||
} else if (SHOW_COMMANDS_WITHOUT_PERMISSIONS) {
|
||||
commands_no_permission.add(createCommand(player, command, args));
|
||||
}
|
||||
});
|
||||
commandMap
|
||||
.getHandlers()
|
||||
.forEach(
|
||||
(key, command) -> {
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
if (player == null || account.hasPermission(annotation.permission())) {
|
||||
commands.add(createCommand(player, command, args));
|
||||
} else if (SHOW_COMMANDS_WITHOUT_PERMISSIONS) {
|
||||
commands_no_permission.add(createCommand(player, command, args));
|
||||
}
|
||||
});
|
||||
CommandHandler.sendTranslatedMessage(player, "commands.help.available_commands");
|
||||
} else {
|
||||
String command_str = args.remove(0).toLowerCase();
|
||||
|
||||
@@ -3,21 +3,30 @@ package emu.grasscutter.command.commands;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(label = "kick", aliases = {"restart"}, permissionTargeted = "server.kick")
|
||||
@Command(
|
||||
label = "kick",
|
||||
aliases = {"restart"},
|
||||
permissionTargeted = "server.kick")
|
||||
public final class KickCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (sender != null) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.kick.player_kick_player",
|
||||
sender.getUid(), sender.getAccount().getUsername(),
|
||||
targetPlayer.getUid(), targetPlayer.getAccount().getUsername());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender,
|
||||
"commands.kick.player_kick_player",
|
||||
sender.getUid(),
|
||||
sender.getAccount().getUsername(),
|
||||
targetPlayer.getUid(),
|
||||
targetPlayer.getAccount().getUsername());
|
||||
} else {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.kick.server_kick_player",
|
||||
targetPlayer.getUid(), targetPlayer.getAccount().getUsername());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender,
|
||||
"commands.kick.server_kick_player",
|
||||
targetPlayer.getUid(),
|
||||
targetPlayer.getAccount().getUsername());
|
||||
}
|
||||
|
||||
targetPlayer.getSession().close();
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.entity.EntityMonster;
|
||||
import emu.grasscutter.game.entity.GameEntity;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "killall", usage = {"[<sceneId>]"}, permission = "server.killall", permissionTargeted = "server.killall.others")
|
||||
@Command(
|
||||
label = "killall",
|
||||
usage = {"[<sceneId>]"},
|
||||
permission = "server.killall",
|
||||
permissionTargeted = "server.killall.others")
|
||||
public final class KillAllCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -32,16 +35,20 @@ public final class KillAllCommand implements CommandHandler {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
|
||||
}
|
||||
if (scene == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.killall.scene_not_found_in_player_world"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.killall.scene_not_found_in_player_world"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Separate into list to avoid concurrency issue
|
||||
final Scene sceneF = scene;
|
||||
List<GameEntity> toKill = sceneF.getEntities().values().stream()
|
||||
.filter(entity -> entity instanceof EntityMonster)
|
||||
.toList();
|
||||
List<GameEntity> toKill =
|
||||
sceneF.getEntities().values().stream()
|
||||
.filter(entity -> entity instanceof EntityMonster)
|
||||
.toList();
|
||||
toKill.forEach(entity -> sceneF.killEntity(entity, 0));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.killall.kill_monsters_in_scene", toKill.size(), scene.getId()));
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(sender, "commands.killall.kill_monsters_in_scene", toKill.size(), scene.getId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
@@ -8,12 +10,13 @@ import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.props.LifeState;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "killCharacter", aliases = {"suicide", "kill"}, permission = "player.killcharacter", permissionTargeted = "player.killcharacter.others")
|
||||
@Command(
|
||||
label = "killCharacter",
|
||||
aliases = {"suicide", "kill"},
|
||||
permission = "player.killcharacter",
|
||||
permissionTargeted = "player.killcharacter.others")
|
||||
public final class KillCharacterCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -21,12 +24,18 @@ public final class KillCharacterCommand implements CommandHandler {
|
||||
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
|
||||
// Packets
|
||||
entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
||||
entity.getWorld().broadcastPacket(new PacketLifeStateChangeNotify(0, entity, LifeState.LIFE_DEAD));
|
||||
entity
|
||||
.getWorld()
|
||||
.broadcastPacket(
|
||||
new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
|
||||
entity
|
||||
.getWorld()
|
||||
.broadcastPacket(new PacketLifeStateChangeNotify(0, entity, LifeState.LIFE_DEAD));
|
||||
// remove
|
||||
targetPlayer.getScene().removeEntity(entity);
|
||||
entity.onDeath(0);
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.killCharacter.success", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.killCharacter.success", targetPlayer.getNickname()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,17 +1,20 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "language", usage = {"[<language code>]"}, aliases = {"lang"}, targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "language",
|
||||
usage = {"[<language code>]"},
|
||||
aliases = {"lang"},
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class LanguageCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -23,7 +26,8 @@ public final class LanguageCommand implements CommandHandler {
|
||||
} else {
|
||||
curLangCode = Grasscutter.getLanguage().getLanguageCode();
|
||||
}
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.language.current_language", curLangCode));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.language.current_language", curLangCode));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -44,10 +48,11 @@ public final class LanguageCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
if (!langCode.equals(actualLangCode)) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.language.language_not_found", langCode));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.language.language_not_found", langCode));
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.language.language_changed", actualLangCode));
|
||||
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.language.language_changed", actualLangCode));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,16 +1,19 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "list", aliases = {"players"}, usage = {"[<UID>]"}, targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "list",
|
||||
aliases = {"players"},
|
||||
usage = {"[<UID>]"},
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class ListCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -22,29 +25,29 @@ public final class ListCommand implements CommandHandler {
|
||||
needUID = args.get(0).equals("uid");
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.list.success", playersMap.size()));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.list.success", playersMap.size()));
|
||||
|
||||
if (playersMap.size() != 0) {
|
||||
StringBuilder playerSet = new StringBuilder();
|
||||
boolean finalNeedUID = needUID;
|
||||
|
||||
playersMap.values().forEach(player -> {
|
||||
playerSet.append(player.getNickname());
|
||||
playersMap
|
||||
.values()
|
||||
.forEach(
|
||||
player -> {
|
||||
playerSet.append(player.getNickname());
|
||||
|
||||
if (finalNeedUID) {
|
||||
if (sender != null) {
|
||||
playerSet.append(" <color=green>(")
|
||||
.append(player.getUid())
|
||||
.append(")</color>");
|
||||
} else {
|
||||
playerSet.append(" (")
|
||||
.append(player.getUid())
|
||||
.append(")");
|
||||
}
|
||||
}
|
||||
if (finalNeedUID) {
|
||||
if (sender != null) {
|
||||
playerSet.append(" <color=green>(").append(player.getUid()).append(")</color>");
|
||||
} else {
|
||||
playerSet.append(" (").append(player.getUid()).append(")");
|
||||
}
|
||||
}
|
||||
|
||||
playerSet.append(", ");
|
||||
});
|
||||
playerSet.append(", ");
|
||||
});
|
||||
|
||||
String players = playerSet.toString();
|
||||
CommandHandler.sendMessage(sender, players.substring(0, players.length() - 2));
|
||||
|
||||
@@ -1,22 +1,20 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.Command.TargetRequirement;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "permission", usage = {
|
||||
"add <permission>",
|
||||
"remove <permission>",
|
||||
"clear",
|
||||
"list"
|
||||
}, permission = "permission", targetRequirement = TargetRequirement.PLAYER)
|
||||
@Command(
|
||||
label = "permission",
|
||||
usage = {"add <permission>", "remove <permission>", "clear", "list"},
|
||||
permission = "permission",
|
||||
targetRequirement = TargetRequirement.PLAYER)
|
||||
public final class PermissionCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -52,12 +50,15 @@ public final class PermissionCommand implements CommandHandler {
|
||||
sendUsageMessage(sender);
|
||||
} else if (account.addPermission(permission)) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.permission.add"));
|
||||
} else CommandHandler.sendMessage(sender, translate(sender, "commands.permission.has_error"));
|
||||
} else
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.permission.has_error"));
|
||||
break;
|
||||
case "remove":
|
||||
if (account.removePermission(permission)) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.permission.remove"));
|
||||
} else CommandHandler.sendMessage(sender, translate(sender, "commands.permission.not_have_error"));
|
||||
} else
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.permission.not_have_error"));
|
||||
break;
|
||||
case "clear":
|
||||
account.clearPermission();
|
||||
|
||||
@@ -4,17 +4,26 @@ import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(label = "position", aliases = {"pos"})
|
||||
@Command(
|
||||
label = "position",
|
||||
aliases = {"pos"})
|
||||
public final class PositionCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
Position pos = targetPlayer.getPosition();
|
||||
Position rot = targetPlayer.getRotation();
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.position.success",
|
||||
pos.getX(), pos.getY(), pos.getZ(), rot.getX(), rot.getY(), rot.getZ(), targetPlayer.getSceneId());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender,
|
||||
"commands.position.success",
|
||||
pos.getX(),
|
||||
pos.getY(),
|
||||
pos.getZ(),
|
||||
rot.getX(),
|
||||
rot.getY(),
|
||||
rot.getZ(),
|
||||
targetPlayer.getSceneId());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,19 +1,19 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.quest.GameQuest;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "quest",
|
||||
aliases = {"q"},
|
||||
usage = {"(add|finish) [<questId>]"},
|
||||
permission = "player.quest",
|
||||
permissionTargeted = "player.quest.others")
|
||||
@Command(
|
||||
label = "quest",
|
||||
aliases = {"q"},
|
||||
usage = {"(add|finish) [<questId>]"},
|
||||
permission = "player.quest",
|
||||
permissionTargeted = "player.quest.others")
|
||||
public final class QuestCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,15 +1,17 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "reload", permission = "server.reload", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "reload",
|
||||
permission = "server.reload",
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class ReloadCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(
|
||||
label = "resetConst",
|
||||
aliases = {"resetconstellation"},
|
||||
usage = "[all]",
|
||||
permission = "player.resetconstellation",
|
||||
permissionTargeted = "player.resetconstellation.others")
|
||||
label = "resetConst",
|
||||
aliases = {"resetconstellation"},
|
||||
usage = "[all]",
|
||||
permission = "player.resetconstellation",
|
||||
permissionTargeted = "player.resetconstellation.others")
|
||||
public final class ResetConstCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -32,7 +31,9 @@ public final class ResetConstCommand implements CommandHandler {
|
||||
Avatar avatar = entity.getAvatar();
|
||||
this.resetConstellation(avatar);
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.resetConst.success", avatar.getAvatarData().getName()));
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(sender, "commands.resetConst.success", avatar.getAvatarData().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,14 +1,17 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "resetShopLimit", aliases = {"resetshop"}, permission = "server.resetshop", permissionTargeted = "server.resetshop.others")
|
||||
@Command(
|
||||
label = "resetShopLimit",
|
||||
aliases = {"resetshop"},
|
||||
permission = "server.resetshop",
|
||||
permissionTargeted = "server.resetshop.others")
|
||||
public final class ResetShopLimitCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,32 +1,34 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.mail.Mail;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Command(
|
||||
label = "sendMail",
|
||||
usage = {"(<userId>|all) [<templateId>]", "help"},
|
||||
permission = "server.sendmail",
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
label = "sendMail",
|
||||
usage = {"(<userId>|all) [<templateId>]", "help"},
|
||||
permission = "server.sendmail",
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class SendMailCommand implements CommandHandler {
|
||||
|
||||
// TODO: You should be able to do /sendmail and then just send subsequent messages until you finish
|
||||
// However, due to the current nature of the command system, I don't think this is possible without rewriting
|
||||
// TODO: You should be able to do /sendmail and then just send subsequent messages until you
|
||||
// finish
|
||||
// However, due to the current nature of the command system, I don't think this is possible
|
||||
// without rewriting
|
||||
// the command system (again). For now this will do
|
||||
|
||||
// Key = User that is constructing the mail.
|
||||
private static final HashMap<Integer, MailBuilder> mailBeingConstructed = new HashMap<Integer, MailBuilder>();
|
||||
private static final HashMap<Integer, MailBuilder> mailBeingConstructed =
|
||||
new HashMap<Integer, MailBuilder>();
|
||||
|
||||
// Yes this is awful and I hate it.
|
||||
@Override
|
||||
@@ -52,16 +54,20 @@ public final class SendMailCommand implements CommandHandler {
|
||||
if (DatabaseHelper.getPlayerByUid(Integer.parseInt(args.get(0))) != null) {
|
||||
mailBuilder = new MailBuilder(Integer.parseInt(args.get(0)), new Mail());
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.user_not_exist", args.get(0)));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.user_not_exist", args.get(0)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
mailBeingConstructed.put(senderId, mailBuilder);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.start_composition"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.start_composition"));
|
||||
}
|
||||
case 2 -> CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.templates"));
|
||||
default -> CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.invalid_arguments"));
|
||||
case 2 -> CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.templates"));
|
||||
default -> CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.invalid_arguments"));
|
||||
}
|
||||
} else {
|
||||
MailBuilder mailBuilder = mailBeingConstructed.get(senderId);
|
||||
@@ -75,41 +81,63 @@ public final class SendMailCommand implements CommandHandler {
|
||||
case "finish" -> {
|
||||
if (mailBuilder.constructionStage == 3) {
|
||||
if (!mailBuilder.sendToAll) {
|
||||
Grasscutter.getGameServer().getPlayerByUid(mailBuilder.recipient, true).sendMail(mailBuilder.mail);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_done", mailBuilder.recipient));
|
||||
Grasscutter.getGameServer()
|
||||
.getPlayerByUid(mailBuilder.recipient, true)
|
||||
.sendMail(mailBuilder.mail);
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(sender, "commands.sendMail.send_done", mailBuilder.recipient));
|
||||
} else {
|
||||
DatabaseHelper.getByGameClass(Player.class).forEach(player -> {
|
||||
var onlinePlayer = Grasscutter.getGameServer().getPlayerByUid(player.getUid(), false);
|
||||
Objects.requireNonNullElse(onlinePlayer, player).sendMail(mailBuilder.mail);
|
||||
});
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send_all_done"));
|
||||
DatabaseHelper.getByGameClass(Player.class)
|
||||
.forEach(
|
||||
player -> {
|
||||
var onlinePlayer =
|
||||
Grasscutter.getGameServer().getPlayerByUid(player.getUid(), false);
|
||||
Objects.requireNonNullElse(onlinePlayer, player)
|
||||
.sendMail(mailBuilder.mail);
|
||||
});
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.send_all_done"));
|
||||
}
|
||||
mailBeingConstructed.remove(senderId);
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.not_composition_end", getConstructionArgs(mailBuilder.constructionStage, sender)));
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender,
|
||||
"commands.sendMail.not_composition_end",
|
||||
getConstructionArgs(mailBuilder.constructionStage, sender)));
|
||||
}
|
||||
}
|
||||
case "help" -> {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.please_use", getConstructionArgs(mailBuilder.constructionStage, sender)));
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender,
|
||||
"commands.sendMail.please_use",
|
||||
getConstructionArgs(mailBuilder.constructionStage, sender)));
|
||||
}
|
||||
default -> {
|
||||
switch (mailBuilder.constructionStage) {
|
||||
case 0 -> {
|
||||
String title = String.join(" ", args.subList(0, args.size()));
|
||||
mailBuilder.mail.mailContent.title = title;
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.set_title", title));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.set_title", title));
|
||||
mailBuilder.constructionStage++;
|
||||
}
|
||||
case 1 -> {
|
||||
String contents = String.join(" ", args.subList(0, args.size()));
|
||||
mailBuilder.mail.mailContent.content = contents;
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.set_contents", contents));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.set_contents", contents));
|
||||
mailBuilder.constructionStage++;
|
||||
}
|
||||
case 2 -> {
|
||||
String msgSender = String.join(" ", args.subList(0, args.size()));
|
||||
mailBuilder.mail.mailContent.sender = msgSender;
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.set_message_sender", msgSender));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.set_message_sender", msgSender));
|
||||
mailBuilder.constructionStage++;
|
||||
}
|
||||
case 3 -> {
|
||||
@@ -118,33 +146,38 @@ public final class SendMailCommand implements CommandHandler {
|
||||
int amount = 1;
|
||||
int refinement = 0;
|
||||
switch (args.size()) {
|
||||
case 4: // <itemId|itemName> [amount] [level] [refinement] // TODO: this requires Mail support but there's no harm leaving it here for now
|
||||
case 4: // <itemId|itemName> [amount] [level] [refinement] // TODO: this requires
|
||||
// Mail support but there's no harm leaving it here for now
|
||||
try {
|
||||
refinement = Integer.parseInt(args.get(3));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemRefinement"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.generic.invalid.itemRefinement"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
} // Fallthrough
|
||||
case 3: // <itemId|itemName> [amount] [level]
|
||||
try {
|
||||
lvl = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemLevel"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.generic.invalid.itemLevel"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
} // Fallthrough
|
||||
case 2: // <itemId|itemName> [amount]
|
||||
try {
|
||||
amount = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.amount"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.generic.invalid.amount"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
} // Fallthrough
|
||||
case 1: // <itemId|itemName>
|
||||
try {
|
||||
item = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// TODO: Parse from item name using GM Handbook.
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemId"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.generic.invalid.itemId"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
@@ -153,13 +186,19 @@ public final class SendMailCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
mailBuilder.mail.itemList.add(new Mail.MailItem(item, amount, lvl));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.send", amount, item, lvl));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.sendMail.send", amount, item, lvl));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.invalid_arguments_please_use", getConstructionArgs(mailBuilder.constructionStage, sender)));
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender,
|
||||
"commands.sendMail.invalid_arguments_please_use",
|
||||
getConstructionArgs(mailBuilder.constructionStage, sender)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -5,16 +5,15 @@ import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.Command.TargetRequirement;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "sendMessage",
|
||||
aliases = {"say", "sendservmsg", "sendservermessage", "b", "broadcast"},
|
||||
usage = {"<message>"},
|
||||
permission = "server.sendmessage",
|
||||
permissionTargeted = "server.sendmessage.others",
|
||||
targetRequirement = TargetRequirement.NONE)
|
||||
label = "sendMessage",
|
||||
aliases = {"say", "sendservmsg", "sendservermessage", "b", "broadcast"},
|
||||
usage = {"<message>"},
|
||||
permission = "server.sendmessage",
|
||||
permissionTargeted = "server.sendmessage.others",
|
||||
targetRequirement = TargetRequirement.NONE)
|
||||
public final class SendMessageCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,15 +9,14 @@ import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.game.world.World;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "setConst",
|
||||
aliases = {"setconstellation"},
|
||||
usage = {"<constellation level> [all]"},
|
||||
permission = "player.setconstellation",
|
||||
permissionTargeted = "player.setconstellation.others")
|
||||
label = "setConst",
|
||||
aliases = {"setconstellation"},
|
||||
usage = {"<constellation level> [all]"},
|
||||
permission = "player.setconstellation",
|
||||
permissionTargeted = "player.setconstellation.others")
|
||||
public final class SetConstCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
@@ -38,10 +37,12 @@ public final class SetConstCommand implements CommandHandler {
|
||||
if (entity == null) return;
|
||||
Avatar avatar = entity.getAvatar();
|
||||
this.setConstellation(targetPlayer, avatar, constLevel);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.success", avatar.getAvatarData().getName(), constLevel);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.setConst.success", avatar.getAvatarData().getName(), constLevel);
|
||||
return;
|
||||
}
|
||||
// Check if there's an additional argument which is "all", if it does then go setAllConstellation
|
||||
// Check if there's an additional argument which is "all", if it does then go
|
||||
// setAllConstellation
|
||||
if (args.size() > 1 && args.get(1).equalsIgnoreCase("all")) {
|
||||
this.setAllConstellation(targetPlayer, constLevel);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setConst.successall", constLevel);
|
||||
@@ -67,12 +68,15 @@ public final class SetConstCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
private void setAllConstellation(Player player, int constLevel) {
|
||||
player.getAvatars().forEach(avatar -> {
|
||||
avatar.forceConstellationLevel(constLevel);
|
||||
avatar.recalcConstellations();
|
||||
avatar.recalcStats(true);
|
||||
avatar.save();
|
||||
});
|
||||
player
|
||||
.getAvatars()
|
||||
.forEach(
|
||||
avatar -> {
|
||||
avatar.forceConstellationLevel(constLevel);
|
||||
avatar.recalcConstellations();
|
||||
avatar.recalcStats(true);
|
||||
avatar.save();
|
||||
});
|
||||
// Just reload scene once, shorter than having to check for each constLevel < currentConstLevel
|
||||
this.reloadScene(player);
|
||||
}
|
||||
|
||||
@@ -1,22 +1,21 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(
|
||||
label = "setFetterLevel",
|
||||
usage = {"<level>"},
|
||||
aliases = {"setfetterlvl", "setfriendship"},
|
||||
permission = "player.setfetterlevel",
|
||||
permissionTargeted = "player.setfetterlevel.others")
|
||||
label = "setFetterLevel",
|
||||
usage = {"<level>"},
|
||||
aliases = {"setfetterlvl", "setfriendship"},
|
||||
permission = "player.setfetterlevel",
|
||||
permissionTargeted = "player.setfetterlevel.others")
|
||||
public final class SetFetterLevelCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -29,7 +28,8 @@ public final class SetFetterLevelCommand implements CommandHandler {
|
||||
try {
|
||||
int fetterLevel = Integer.parseInt(args.get(0));
|
||||
if (fetterLevel < 0 || fetterLevel > 10) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.setFetterLevel.range_error"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.setFetterLevel.range_error"));
|
||||
return;
|
||||
}
|
||||
Avatar avatar = targetPlayer.getTeamManager().getCurrentAvatarEntity().getAvatar();
|
||||
@@ -41,10 +41,10 @@ public final class SetFetterLevelCommand implements CommandHandler {
|
||||
avatar.save();
|
||||
|
||||
targetPlayer.sendPacket(new PacketAvatarFetterDataNotify(avatar));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.setFetterLevel.success", fetterLevel));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.setFetterLevel.success", fetterLevel));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.setFetterLevel.level_error"));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,27 +9,36 @@ import emu.grasscutter.game.tower.TowerLevelRecord;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketSceneAreaUnlockNotify;
|
||||
import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Command(label = "setProp", aliases = {"prop"}, usage = {"<prop> <value>"}, permission = "player.setprop", permissionTargeted = "player.setprop.others")
|
||||
@Command(
|
||||
label = "setProp",
|
||||
aliases = {"prop"},
|
||||
usage = {"<prop> <value>"},
|
||||
permission = "player.setprop",
|
||||
permissionTargeted = "player.setprop.others")
|
||||
public final class SetPropCommand implements CommandHandler {
|
||||
// List of map areas. Unfortunately, there is no readily available source for them in excels or bins.
|
||||
private static final List<Integer> sceneAreas = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 32, 100, 101, 102, 103, 200, 210, 300, 400, 401, 402, 403);
|
||||
// List of map areas. Unfortunately, there is no readily available source for them in excels or
|
||||
// bins.
|
||||
private static final List<Integer> sceneAreas =
|
||||
List.of(
|
||||
1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27,
|
||||
28, 29, 32, 100, 101, 102, 103, 200, 210, 300, 400, 401, 402, 403);
|
||||
Map<String, Prop> props;
|
||||
|
||||
public SetPropCommand() {
|
||||
this.props = new HashMap<>();
|
||||
// Full PlayerProperty enum that won't be advertised but can be used by devs
|
||||
for (PlayerProperty prop : PlayerProperty.values()) {
|
||||
String name = prop.toString().substring(5); // PROP_EXP -> EXP
|
||||
String key = name.toLowerCase(); // EXP -> exp
|
||||
String name = prop.toString().substring(5); // PROP_EXP -> EXP
|
||||
String key = name.toLowerCase(); // EXP -> exp
|
||||
this.props.put(key, new Prop(name, prop));
|
||||
}
|
||||
// Add special props
|
||||
Prop worldlevel = new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL);
|
||||
Prop worldlevel =
|
||||
new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL);
|
||||
this.props.put("worldlevel", worldlevel);
|
||||
this.props.put("wl", worldlevel);
|
||||
|
||||
@@ -89,12 +98,13 @@ public final class SetPropCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
try {
|
||||
value = switch (valueStr.toLowerCase()) {
|
||||
case "on", "true" -> 1;
|
||||
case "off", "false" -> 0;
|
||||
case "toggle" -> -1;
|
||||
default -> Integer.parseInt(valueStr);
|
||||
};
|
||||
value =
|
||||
switch (valueStr.toLowerCase()) {
|
||||
case "on", "true" -> 1;
|
||||
case "off", "false" -> 0;
|
||||
case "toggle" -> -1;
|
||||
default -> Integer.parseInt(valueStr);
|
||||
};
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
|
||||
return;
|
||||
@@ -103,30 +113,35 @@ public final class SetPropCommand implements CommandHandler {
|
||||
boolean success = false;
|
||||
Prop prop = props.get(propStr);
|
||||
|
||||
success = switch (prop.pseudoProp) {
|
||||
case WORLD_LEVEL -> targetPlayer.setWorldLevel(value);
|
||||
case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value);
|
||||
case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value);
|
||||
case GOD_MODE, UNLIMITED_STAMINA, UNLIMITED_ENERGY ->
|
||||
this.setBool(sender, targetPlayer, prop.pseudoProp, value);
|
||||
case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1);
|
||||
case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0);
|
||||
case UNLOCK_MAP -> unlockMap(targetPlayer);
|
||||
default -> targetPlayer.setProperty(prop.prop, value);
|
||||
};
|
||||
success =
|
||||
switch (prop.pseudoProp) {
|
||||
case WORLD_LEVEL -> targetPlayer.setWorldLevel(value);
|
||||
case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value);
|
||||
case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value);
|
||||
case GOD_MODE, UNLIMITED_STAMINA, UNLIMITED_ENERGY -> this.setBool(
|
||||
sender, targetPlayer, prop.pseudoProp, value);
|
||||
case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1);
|
||||
case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0);
|
||||
case UNLOCK_MAP -> unlockMap(targetPlayer);
|
||||
default -> targetPlayer.setProperty(prop.prop, value);
|
||||
};
|
||||
|
||||
if (success) {
|
||||
if (targetPlayer == sender) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_to", prop.name, valueStr);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.set_to", prop.name, valueStr);
|
||||
} else {
|
||||
String uidStr = targetPlayer.getAccount().getId();
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr);
|
||||
}
|
||||
} else {
|
||||
if (prop.prop != PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages
|
||||
if (prop.prop
|
||||
!= PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages
|
||||
int min = targetPlayer.getPropertyMin(prop.prop);
|
||||
int max = targetPlayer.getPropertyMax(prop.prop);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.value_between", prop.name, min, max);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.invalid.value_between", prop.name, min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -134,7 +149,8 @@ public final class SetPropCommand implements CommandHandler {
|
||||
private boolean setTowerLevel(Player sender, Player targetPlayer, int topFloor) {
|
||||
List<Integer> floorIds = targetPlayer.getServer().getTowerSystem().getAllFloors();
|
||||
if (topFloor < 0 || topFloor > floorIds.size()) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.value_between", "Tower Level", 0, floorIds.size());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.generic.invalid.value_between", "Tower Level", 0, floorIds.size());
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -151,23 +167,30 @@ public final class SetPropCommand implements CommandHandler {
|
||||
}
|
||||
// Six stars required on Floor 8 to unlock Floor 9+
|
||||
if (topFloor > 8) {
|
||||
recordMap.get(floorIds.get(7)).setLevelStars(0, 6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at all
|
||||
recordMap
|
||||
.get(floorIds.get(7))
|
||||
.setLevelStars(
|
||||
0,
|
||||
6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at
|
||||
// all
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setBool(Player sender, Player targetPlayer, PseudoProp pseudoProp, int value) {
|
||||
boolean enabled = switch (pseudoProp) {
|
||||
case GOD_MODE -> targetPlayer.inGodmode();
|
||||
case UNLIMITED_STAMINA -> targetPlayer.getUnlimitedStamina();
|
||||
case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().getEnergyUsage();
|
||||
default -> false;
|
||||
};
|
||||
enabled = switch (value) {
|
||||
case -1 -> !enabled;
|
||||
case 0 -> false;
|
||||
default -> true;
|
||||
};
|
||||
boolean enabled =
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE -> targetPlayer.inGodmode();
|
||||
case UNLIMITED_STAMINA -> targetPlayer.getUnlimitedStamina();
|
||||
case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().getEnergyUsage();
|
||||
default -> false;
|
||||
};
|
||||
enabled =
|
||||
switch (value) {
|
||||
case -1 -> !enabled;
|
||||
case 0 -> false;
|
||||
default -> true;
|
||||
};
|
||||
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE:
|
||||
@@ -192,18 +215,24 @@ public final class SetPropCommand implements CommandHandler {
|
||||
|
||||
private boolean unlockMap(Player targetPlayer) {
|
||||
// Unlock.
|
||||
GameData.getScenePointsPerScene().forEach((sceneId, scenePoints) -> {
|
||||
// Unlock trans points.
|
||||
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints);
|
||||
GameData.getScenePointsPerScene()
|
||||
.forEach(
|
||||
(sceneId, scenePoints) -> {
|
||||
// Unlock trans points.
|
||||
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints);
|
||||
|
||||
// Unlock map areas.
|
||||
targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas);
|
||||
});
|
||||
// Unlock map areas.
|
||||
targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas);
|
||||
});
|
||||
|
||||
// Send notify.
|
||||
int playerScene = targetPlayer.getSceneId();
|
||||
targetPlayer.sendPacket(new PacketScenePointUnlockNotify(playerScene, targetPlayer.getUnlockedScenePoints(playerScene)));
|
||||
targetPlayer.sendPacket(new PacketSceneAreaUnlockNotify(playerScene, targetPlayer.getUnlockedSceneAreas(playerScene)));
|
||||
targetPlayer.sendPacket(
|
||||
new PacketScenePointUnlockNotify(
|
||||
playerScene, targetPlayer.getUnlockedScenePoints(playerScene)));
|
||||
targetPlayer.sendPacket(
|
||||
new PacketSceneAreaUnlockNotify(
|
||||
playerScene, targetPlayer.getUnlockedSceneAreas(playerScene)));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,20 +7,20 @@ import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
@Command(
|
||||
label = "setStats",
|
||||
aliases = {"stats", "stat"},
|
||||
usage = {
|
||||
"[set] <stat> <value>",
|
||||
"(lock|freeze) <stat> [<value>]", // Can lock to current value
|
||||
"(unlock|unfreeze) <stat>"},
|
||||
permission = "player.setstats",
|
||||
permissionTargeted = "player.setstats.others")
|
||||
label = "setStats",
|
||||
aliases = {"stats", "stat"},
|
||||
usage = {
|
||||
"[set] <stat> <value>",
|
||||
"(lock|freeze) <stat> [<value>]", // Can lock to current value
|
||||
"(unlock|unfreeze) <stat>"
|
||||
},
|
||||
permission = "player.setstats",
|
||||
permissionTargeted = "player.setstats.others")
|
||||
public final class SetStatsCommand implements CommandHandler {
|
||||
private final Map<String, Stat> stats;
|
||||
|
||||
@@ -32,18 +32,22 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
// Full FightProperty enum that won't be advertised but can be used by devs
|
||||
// They have a prefix to avoid the "hp" clash
|
||||
for (FightProperty prop : FightProperty.values()) {
|
||||
String name = prop.toString().substring(10); // FIGHT_PROP_BASE_HP -> _BASE_HP
|
||||
String key = name.toLowerCase(); // _BASE_HP -> _base_hp
|
||||
name = name.substring(1); // _BASE_HP -> BASE_HP
|
||||
String name = prop.toString().substring(10); // FIGHT_PROP_BASE_HP -> _BASE_HP
|
||||
String key = name.toLowerCase(); // _BASE_HP -> _base_hp
|
||||
name = name.substring(1); // _BASE_HP -> BASE_HP
|
||||
this.stats.put(key, new Stat(name, prop));
|
||||
}
|
||||
|
||||
// Compatibility aliases
|
||||
this.stats.put("mhp", this.stats.get("maxhp"));
|
||||
this.stats.put("hp", this.stats.get("_cur_hp")); // Overrides FIGHT_PROP_HP
|
||||
this.stats.put("atk", this.stats.get("_cur_attack")); // Overrides FIGHT_PROP_ATTACK
|
||||
this.stats.put("def", this.stats.get("_cur_defense")); // Overrides FIGHT_PROP_DEFENSE
|
||||
this.stats.put("atkb", this.stats.get("_base_attack")); // This doesn't seem to get used to recalculate ATK, so it's only useful for stuff like Bennett's buff.
|
||||
this.stats.put("hp", this.stats.get("_cur_hp")); // Overrides FIGHT_PROP_HP
|
||||
this.stats.put("atk", this.stats.get("_cur_attack")); // Overrides FIGHT_PROP_ATTACK
|
||||
this.stats.put("def", this.stats.get("_cur_defense")); // Overrides FIGHT_PROP_DEFENSE
|
||||
this.stats.put(
|
||||
"atkb",
|
||||
this.stats.get(
|
||||
"_base_attack")); // This doesn't seem to get used to recalculate ATK, so it's only
|
||||
// useful for stuff like Bennett's buff.
|
||||
this.stats.put("eanemo", this.stats.get("anemo%"));
|
||||
this.stats.put("ecryo", this.stats.get("cryo%"));
|
||||
this.stats.put("edendro", this.stats.get("dendro%"));
|
||||
@@ -78,20 +82,21 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
|
||||
// Get the action and stat
|
||||
String arg0 = args.remove(0).toLowerCase();
|
||||
Action action = switch (arg0) {
|
||||
default -> {
|
||||
statStr = arg0;
|
||||
yield Action.ACTION_SET;
|
||||
} // Implicit set command
|
||||
case "set" -> Action.ACTION_SET; // Explicit set command
|
||||
case "lock", "freeze" -> Action.ACTION_LOCK;
|
||||
case "unlock", "unfreeze" -> Action.ACTION_UNLOCK;
|
||||
};
|
||||
Action action =
|
||||
switch (arg0) {
|
||||
default -> {
|
||||
statStr = arg0;
|
||||
yield Action.ACTION_SET;
|
||||
} // Implicit set command
|
||||
case "set" -> Action.ACTION_SET; // Explicit set command
|
||||
case "lock", "freeze" -> Action.ACTION_LOCK;
|
||||
case "unlock", "unfreeze" -> Action.ACTION_UNLOCK;
|
||||
};
|
||||
if (statStr == null) {
|
||||
statStr = args.remove(0).toLowerCase();
|
||||
}
|
||||
if (!stats.containsKey(statStr)) {
|
||||
sendUsageMessage(sender); // Invalid stat or action
|
||||
sendUsageMessage(sender); // Invalid stat or action
|
||||
return;
|
||||
}
|
||||
Stat stat = stats.get(statStr);
|
||||
@@ -102,10 +107,10 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
try {
|
||||
switch (action) {
|
||||
case ACTION_LOCK:
|
||||
if (args.isEmpty()) { // Lock to current value
|
||||
if (args.isEmpty()) { // Lock to current value
|
||||
value = avatar.getFightProperty(stat.prop);
|
||||
break;
|
||||
} // Else fall-through and lock to supplied value
|
||||
} // Else fall-through and lock to supplied value
|
||||
case ACTION_SET:
|
||||
value = parsePercent(args.remove(0));
|
||||
break;
|
||||
@@ -120,7 +125,7 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
if (!args.isEmpty()) { // Leftover arguments!
|
||||
if (!args.isEmpty()) { // Leftover arguments!
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
@@ -150,7 +155,8 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
CommandHandler.sendTranslatedMessage(sender, action.messageKeySelf, stat.name, valueStr);
|
||||
} else {
|
||||
String uidStr = targetPlayer.getAccount().getId();
|
||||
CommandHandler.sendTranslatedMessage(sender, action.messageKeyOther, stat.name, uidStr, valueStr);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, action.messageKeyOther, stat.name, uidStr, valueStr);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
@@ -12,40 +16,36 @@ import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.BiConsumer;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
import static emu.grasscutter.command.CommandHelpers.*;
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
import lombok.Setter;
|
||||
|
||||
@Command(
|
||||
label = "spawn",
|
||||
aliases = {"drop", "s"},
|
||||
usage = {
|
||||
"<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<gadgetId> [x<amount>] [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<monsterId> [x<amount>] [lv<level>] [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>"},
|
||||
permission = "server.spawn",
|
||||
permissionTargeted = "server.spawn.others")
|
||||
label = "spawn",
|
||||
aliases = {"drop", "s"},
|
||||
usage = {
|
||||
"<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<gadgetId> [x<amount>] [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>",
|
||||
"<monsterId> [x<amount>] [lv<level>] [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>"
|
||||
},
|
||||
permission = "server.spawn",
|
||||
permissionTargeted = "server.spawn.others")
|
||||
public final class SpawnCommand implements CommandHandler {
|
||||
private static final Map<Pattern, BiConsumer<SpawnParameters, Integer>> intCommandHandlers = Map.ofEntries(
|
||||
Map.entry(lvlRegex, SpawnParameters::setLvl),
|
||||
Map.entry(amountRegex, SpawnParameters::setAmount),
|
||||
Map.entry(stateRegex, SpawnParameters::setState),
|
||||
Map.entry(blockRegex, SpawnParameters::setBlockId),
|
||||
Map.entry(groupRegex, SpawnParameters::setGroupId),
|
||||
Map.entry(configRegex, SpawnParameters::setConfigId),
|
||||
Map.entry(maxHPRegex, SpawnParameters::setMaxHP),
|
||||
Map.entry(hpRegex, SpawnParameters::setHp),
|
||||
Map.entry(defRegex, SpawnParameters::setDef),
|
||||
Map.entry(atkRegex, SpawnParameters::setAtk),
|
||||
Map.entry(aiRegex, SpawnParameters::setAi)
|
||||
);
|
||||
private static final Map<Pattern, BiConsumer<SpawnParameters, Integer>> intCommandHandlers =
|
||||
Map.ofEntries(
|
||||
Map.entry(lvlRegex, SpawnParameters::setLvl),
|
||||
Map.entry(amountRegex, SpawnParameters::setAmount),
|
||||
Map.entry(stateRegex, SpawnParameters::setState),
|
||||
Map.entry(blockRegex, SpawnParameters::setBlockId),
|
||||
Map.entry(groupRegex, SpawnParameters::setGroupId),
|
||||
Map.entry(configRegex, SpawnParameters::setConfigId),
|
||||
Map.entry(maxHPRegex, SpawnParameters::setMaxHP),
|
||||
Map.entry(hpRegex, SpawnParameters::setHp),
|
||||
Map.entry(defRegex, SpawnParameters::setDef),
|
||||
Map.entry(atkRegex, SpawnParameters::setAtk),
|
||||
Map.entry(aiRegex, SpawnParameters::setAi));
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
@@ -55,7 +55,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
|
||||
// At this point, first remaining argument MUST be the id and the rest the pos
|
||||
if (args.size() < 1) {
|
||||
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
|
||||
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
switch (args.size()) {
|
||||
@@ -67,13 +67,15 @@ public final class SpawnCommand implements CommandHandler {
|
||||
z = Float.parseFloat(args.get(3));
|
||||
param.pos = new Position(x, y, z);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
case 1:
|
||||
try {
|
||||
param.id = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.generic.invalid.entityId"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -92,8 +94,13 @@ public final class SpawnCommand implements CommandHandler {
|
||||
param.scene = targetPlayer.getScene();
|
||||
|
||||
if (param.scene.getEntities().size() + param.amount > GAME_OPTIONS.sceneEntityLimit) {
|
||||
param.amount = Math.max(Math.min(GAME_OPTIONS.sceneEntityLimit - param.scene.getEntities().size(), param.amount), 0);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.limit_reached", param.amount));
|
||||
param.amount =
|
||||
Math.max(
|
||||
Math.min(
|
||||
GAME_OPTIONS.sceneEntityLimit - param.scene.getEntities().size(), param.amount),
|
||||
0);
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.spawn.limit_reached", param.amount));
|
||||
if (param.amount <= 0) {
|
||||
return;
|
||||
}
|
||||
@@ -121,14 +128,16 @@ public final class SpawnCommand implements CommandHandler {
|
||||
|
||||
param.scene.addEntity(entity);
|
||||
}
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.success", param.amount, param.id));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.spawn.success", param.amount, param.id));
|
||||
}
|
||||
|
||||
private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) {
|
||||
return new EntityItem(param.scene, null, itemData, pos, 1, true);
|
||||
}
|
||||
|
||||
private EntityMonster createMonster(MonsterData monsterData, SpawnParameters param, Position pos) {
|
||||
private EntityMonster createMonster(
|
||||
MonsterData monsterData, SpawnParameters param, Position pos) {
|
||||
var entity = new EntityMonster(param.scene, monsterData, pos, param.lvl);
|
||||
if (param.ai != -1) {
|
||||
entity.setAiId(param.ai);
|
||||
@@ -136,10 +145,13 @@ public final class SpawnCommand implements CommandHandler {
|
||||
return entity;
|
||||
}
|
||||
|
||||
private EntityBaseGadget createGadget(GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) {
|
||||
private EntityBaseGadget createGadget(
|
||||
GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) {
|
||||
EntityBaseGadget entity;
|
||||
if (gadgetData.getType() == EntityType.Vehicle) {
|
||||
entity = new EntityVehicle(param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
|
||||
entity =
|
||||
new EntityVehicle(
|
||||
param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
|
||||
} else {
|
||||
entity = new EntityGadget(param.scene, param.id, pos, targetPlayer.getRotation());
|
||||
if (param.state != -1) {
|
||||
@@ -165,7 +177,8 @@ public final class SpawnCommand implements CommandHandler {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, param.maxHP);
|
||||
}
|
||||
if (param.hp != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, param.hp == 0 ? Float.MAX_VALUE : param.hp);
|
||||
entity.setFightProperty(
|
||||
FightProperty.FIGHT_PROP_CUR_HP, param.hp == 0 ? Float.MAX_VALUE : param.hp);
|
||||
}
|
||||
if (param.atk != -1) {
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_ATTACK, param.atk);
|
||||
@@ -186,32 +199,19 @@ public final class SpawnCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
private static class SpawnParameters {
|
||||
@Setter
|
||||
public int id;
|
||||
@Setter
|
||||
public int lvl = 1;
|
||||
@Setter
|
||||
public int amount = 1;
|
||||
@Setter
|
||||
public int blockId = -1;
|
||||
@Setter
|
||||
public int groupId = -1;
|
||||
@Setter
|
||||
public int configId = -1;
|
||||
@Setter
|
||||
public int state = -1;
|
||||
@Setter
|
||||
public int hp = -1;
|
||||
@Setter
|
||||
public int maxHP = -1;
|
||||
@Setter
|
||||
public int atk = -1;
|
||||
@Setter
|
||||
public int def = -1;
|
||||
@Setter
|
||||
public int ai = -1;
|
||||
@Setter
|
||||
public Position pos = null;
|
||||
@Setter public int id;
|
||||
@Setter public int lvl = 1;
|
||||
@Setter public int amount = 1;
|
||||
@Setter public int blockId = -1;
|
||||
@Setter public int groupId = -1;
|
||||
@Setter public int configId = -1;
|
||||
@Setter public int state = -1;
|
||||
@Setter public int hp = -1;
|
||||
@Setter public int maxHP = -1;
|
||||
@Setter public int atk = -1;
|
||||
@Setter public int def = -1;
|
||||
@Setter public int ai = -1;
|
||||
@Setter public Position pos = null;
|
||||
public Scene scene = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "stop", aliases = {"shutdown"}, permission = "server.stop", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "stop",
|
||||
aliases = {"shutdown"},
|
||||
permission = "server.stop",
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class StopCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -7,20 +7,20 @@ import emu.grasscutter.data.excels.AvatarSkillDepotData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.utils.Language;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "talent",
|
||||
usage = {"set <talentId> <level>", "(n|e|q|all) <level>", "getid"},
|
||||
permission = "player.settalent",
|
||||
permissionTargeted = "player.settalent.others")
|
||||
label = "talent",
|
||||
usage = {"set <talentId> <level>", "(n|e|q|all) <level>", "getid"},
|
||||
permission = "player.settalent",
|
||||
permissionTargeted = "player.settalent.others")
|
||||
public final class TalentCommand implements CommandHandler {
|
||||
private void setTalentLevel(Player sender, Avatar avatar, int skillId, int newLevel) {
|
||||
if (avatar.setSkillLevel(skillId, newLevel)) {
|
||||
long nameHash = GameData.getAvatarSkillDataMap().get(skillId).getNameTextMapHash();
|
||||
var name = Language.getTextMapKey(nameHash);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.set_id", skillId, name, newLevel);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.talent.set_id", skillId, name, newLevel);
|
||||
} else {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range");
|
||||
}
|
||||
@@ -35,7 +35,9 @@ public final class TalentCommand implements CommandHandler {
|
||||
|
||||
Avatar avatar = targetPlayer.getTeamManager().getCurrentAvatarEntity().getAvatar();
|
||||
AvatarSkillDepotData skillDepot = avatar.getSkillDepot();
|
||||
if (skillDepot == null) { // Avatars without skill depots aren't a suitable target even with manual skillId specified
|
||||
if (skillDepot
|
||||
== null) { // Avatars without skill depots aren't a suitable target even with manual skillId
|
||||
// specified
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id");
|
||||
return;
|
||||
}
|
||||
@@ -79,11 +81,12 @@ public final class TalentCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
skillId = switch (cmdSwitch) {
|
||||
default -> skillDepot.getSkills().get(0);
|
||||
case "e" -> skillDepot.getSkills().get(1);
|
||||
case "q" -> skillDepot.getEnergySkill();
|
||||
};
|
||||
skillId =
|
||||
switch (cmdSwitch) {
|
||||
default -> skillDepot.getSkills().get(0);
|
||||
case "e" -> skillDepot.getSkills().get(1);
|
||||
case "q" -> skillDepot.getEnergySkill();
|
||||
};
|
||||
setTalentLevel(sender, avatar, skillId, newLevel);
|
||||
}
|
||||
case "all" -> {
|
||||
@@ -103,17 +106,23 @@ public final class TalentCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
int finalNewLevel = newLevel;
|
||||
skillDepot.getSkillsAndEnergySkill().forEach(id -> setTalentLevel(sender, avatar, id, finalNewLevel));
|
||||
skillDepot
|
||||
.getSkillsAndEnergySkill()
|
||||
.forEach(id -> setTalentLevel(sender, avatar, id, finalNewLevel));
|
||||
}
|
||||
case "getid" -> {
|
||||
var map = GameData.getAvatarSkillDataMap();
|
||||
skillDepot.getSkillsAndEnergySkill().forEach(id -> {
|
||||
var talent = map.get(id);
|
||||
if (talent == null) return;
|
||||
var talentName = Language.getTextMapKey(talent.getNameTextMapHash());
|
||||
var talentDesc = Language.getTextMapKey(talent.getDescTextMapHash());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.talent.id_desc", id, talentName, talentDesc);
|
||||
});
|
||||
skillDepot
|
||||
.getSkillsAndEnergySkill()
|
||||
.forEach(
|
||||
id -> {
|
||||
var talent = map.get(id);
|
||||
if (talent == null) return;
|
||||
var talentName = Language.getTextMapKey(talent.getNameTextMapHash());
|
||||
var talentDesc = Language.getTextMapKey(talent.getDescTextMapHash());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.talent.id_desc", id, talentName, talentDesc);
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,21 +1,20 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
|
||||
|
||||
@Command(
|
||||
label = "team",
|
||||
usage = {"add <avatarId,...>", "(remove|set) [index|first|last|index-index,...]"},
|
||||
permission = "player.team",
|
||||
permissionTargeted = "player.team.others")
|
||||
label = "team",
|
||||
usage = {"add <avatarId,...>", "(remove|set) [index|first|last|index-index,...]"},
|
||||
permission = "player.team",
|
||||
permissionTargeted = "player.team.others")
|
||||
public final class TeamCommand implements CommandHandler {
|
||||
private static final int BASE_AVATARID = 10000000;
|
||||
|
||||
@@ -45,8 +44,11 @@ public final class TeamCommand implements CommandHandler {
|
||||
return;
|
||||
}
|
||||
|
||||
targetPlayer.getTeamManager().updateTeamEntities(
|
||||
new PacketChangeMpTeamAvatarRsp(targetPlayer, targetPlayer.getTeamManager().getCurrentTeamInfo()));
|
||||
targetPlayer
|
||||
.getTeamManager()
|
||||
.updateTeamEntities(
|
||||
new PacketChangeMpTeamAvatarRsp(
|
||||
targetPlayer, targetPlayer.getTeamManager().getCurrentTeamInfo()));
|
||||
}
|
||||
|
||||
private boolean addCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
@@ -71,14 +73,16 @@ public final class TeamCommand implements CommandHandler {
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
|
||||
if (currentTeamAvatars.size() + avatarIds.length > GAME_OPTIONS.avatarLimits.singlePlayerTeam) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.add_too_much", GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.team.add_too_much", GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var avatarId : avatarIds) {
|
||||
int id = Integer.parseInt(avatarId);
|
||||
if (!addAvatar(sender, targetPlayer, id, index))
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_add_avatar", avatarId);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.team.failed_to_add_avatar", avatarId);
|
||||
if (index > 0) ++index;
|
||||
}
|
||||
return true;
|
||||
@@ -101,7 +105,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
// step 1: parse metaIndex to indexes
|
||||
var subIndexes = transformToIndexes(metaIndex, avatarCount);
|
||||
if (subIndexes == null) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", metaIndex);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.team.failed_to_parse_index", metaIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -146,7 +151,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
index = Integer.parseInt(args.get(1)) - 1;
|
||||
if (index < 0) index = 0;
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", args.get(1));
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.team.failed_to_parse_index", args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -159,7 +165,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
try {
|
||||
avatarId = Integer.parseInt(args.get(2));
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_parse_avatar_id", args.get(2));
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.team.failed_parse_avatar_id", args.get(2));
|
||||
return false;
|
||||
}
|
||||
if (avatarId < BASE_AVATARID) {
|
||||
@@ -167,7 +174,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -186,7 +194,8 @@ public final class TeamCommand implements CommandHandler {
|
||||
}
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
if (!targetPlayer.getAvatars().hasAvatar(avatarId)) {
|
||||
@@ -218,17 +227,19 @@ public final class TeamCommand implements CommandHandler {
|
||||
|
||||
int min, max;
|
||||
try {
|
||||
min = switch (range[0]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[0]);
|
||||
};
|
||||
min =
|
||||
switch (range[0]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[0]);
|
||||
};
|
||||
|
||||
max = switch (range[1]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[1]);
|
||||
};
|
||||
max =
|
||||
switch (range[1]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[1]);
|
||||
};
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
@@ -254,5 +265,4 @@ public final class TeamCommand implements CommandHandler {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "teleportAll", aliases = {"tpall"}, permission = "player.tpall", permissionTargeted = "player.tpall.others")
|
||||
@Command(
|
||||
label = "teleportAll",
|
||||
aliases = {"tpall"},
|
||||
permission = "player.tpall",
|
||||
permissionTargeted = "player.tpall.others")
|
||||
public final class TeleportAllCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -20,10 +23,12 @@ public final class TeleportAllCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
for (Player player : targetPlayer.getWorld().getPlayers()) {
|
||||
if (player.equals(targetPlayer))
|
||||
continue;
|
||||
if (player.equals(targetPlayer)) continue;
|
||||
|
||||
player.getWorld().transferPlayerToScene(player, targetPlayer.getSceneId(), TeleportType.COMMAND, targetPlayer.getPosition());
|
||||
player
|
||||
.getWorld()
|
||||
.transferPlayerToScene(
|
||||
player, targetPlayer.getSceneId(), TeleportType.COMMAND, targetPlayer.getPosition());
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.teleportAll.success"));
|
||||
|
||||
@@ -1,24 +1,29 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.event.player.PlayerTeleportEvent.TeleportType;
|
||||
import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "teleport", aliases = {"tp"}, usage = {"<x> <y> <z> [sceneId]"}, permission = "player.teleport", permissionTargeted = "player.teleport.others")
|
||||
@Command(
|
||||
label = "teleport",
|
||||
aliases = {"tp"},
|
||||
usage = {"<x> <y> <z> [sceneId]"},
|
||||
permission = "player.teleport",
|
||||
permissionTargeted = "player.teleport.others")
|
||||
public final class TeleportCommand implements CommandHandler {
|
||||
|
||||
private float parseRelative(String input, Float current) { // TODO: Maybe this will be useful elsewhere later
|
||||
if (input.contains("~")) { // Relative
|
||||
if (!input.equals("~")) { // Relative with offset
|
||||
private float parseRelative(
|
||||
String input, Float current) { // TODO: Maybe this will be useful elsewhere later
|
||||
if (input.contains("~")) { // Relative
|
||||
if (!input.equals("~")) { // Relative with offset
|
||||
current += Float.parseFloat(input.replace("~", ""));
|
||||
} // Else no offset, no modification
|
||||
} else { // Absolute
|
||||
} // Else no offset, no modification
|
||||
} else { // Absolute
|
||||
current = Float.parseFloat(input);
|
||||
}
|
||||
return current;
|
||||
@@ -37,15 +42,17 @@ public final class TeleportCommand implements CommandHandler {
|
||||
try {
|
||||
sceneId = Integer.parseInt(args.get(3));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
case 3:
|
||||
try {
|
||||
x = this.parseRelative(args.get(0), x);
|
||||
y = this.parseRelative(args.get(1), y);
|
||||
z = this.parseRelative(args.get(2), z);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.invalid_position"));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.teleport.invalid_position"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
@@ -54,15 +61,18 @@ public final class TeleportCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
Position target_pos = new Position(x, y, z);
|
||||
boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, TeleportType.COMMAND, target_pos);
|
||||
boolean result =
|
||||
targetPlayer
|
||||
.getWorld()
|
||||
.transferPlayerToScene(targetPlayer, sceneId, TeleportType.COMMAND, target_pos);
|
||||
|
||||
if (!result) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.exists_error"));
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.success",
|
||||
targetPlayer.getNickname(), x, y, z, sceneId)
|
||||
);
|
||||
CommandHandler.sendMessage(
|
||||
sender,
|
||||
translate(
|
||||
sender, "commands.teleport.success", targetPlayer.getNickname(), x, y, z, sceneId));
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,12 @@ import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(
|
||||
label = "unban",
|
||||
permission = "server.ban",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER
|
||||
)
|
||||
label = "unban",
|
||||
permission = "server.ban",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER)
|
||||
public final class UnBanCommand implements CommandHandler {
|
||||
|
||||
private boolean unBanAccount(Player targetPlayer) {
|
||||
|
||||
@@ -1,19 +1,22 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.player.PlayerProgressManager;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "unlockall", usage = {""}, permission = "player.unlockall", permissionTargeted = "player.unlockall.others")
|
||||
@Command(
|
||||
label = "unlockall",
|
||||
usage = {""},
|
||||
permission = "player.unlockall",
|
||||
permissionTargeted = "player.unlockall.others")
|
||||
public final class UnlockAllCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -34,6 +37,7 @@ public final class UnlockAllCommand implements CommandHandler {
|
||||
|
||||
targetPlayer.sendPacket(new PacketOpenStateChangeNotify(changed));
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.unlockall.success", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(
|
||||
sender, translate(sender, "commands.unlockall.success", targetPlayer.getNickname()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,20 +4,28 @@ import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ClimateType;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(label = "weather", aliases = {"w"}, usage = {"weather [<weatherId>] [<climateType>]"}, permission = "player.weather", permissionTargeted = "player.weather.others")
|
||||
@Command(
|
||||
label = "weather",
|
||||
aliases = {"w"},
|
||||
usage = {"weather [<weatherId>] [<climateType>]"},
|
||||
permission = "player.weather",
|
||||
permissionTargeted = "player.weather.others")
|
||||
public final class WeatherCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
int weatherId = targetPlayer.getWeatherId();
|
||||
ClimateType climate = ClimateType.CLIMATE_NONE; // Sending ClimateType.CLIMATE_NONE to Scene.setWeather will use the default climate for that weather
|
||||
ClimateType climate =
|
||||
ClimateType
|
||||
.CLIMATE_NONE; // Sending ClimateType.CLIMATE_NONE to Scene.setWeather will use the
|
||||
// default climate for that weather
|
||||
|
||||
if (args.isEmpty()) {
|
||||
climate = targetPlayer.getClimate();
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.weather.status", weatherId, climate.getShortName());
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.weather.status", weatherId, climate.getShortName());
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -37,7 +45,8 @@ public final class WeatherCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
targetPlayer.setWeather(weatherId, climate);
|
||||
climate = targetPlayer.getClimate(); // Might be different to what we set
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.weather.success", weatherId, climate.getShortName());
|
||||
climate = targetPlayer.getClimate(); // Might be different to what we set
|
||||
CommandHandler.sendTranslatedMessage(
|
||||
sender, "commands.weather.success", weatherId, climate.getShortName());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,18 +1,15 @@
|
||||
package emu.grasscutter.config;
|
||||
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
|
||||
import static emu.grasscutter.Grasscutter.config;
|
||||
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import java.nio.file.Path;
|
||||
import java.util.Locale;
|
||||
|
||||
/**
|
||||
* A data container for the server's configuration.
|
||||
* <p>
|
||||
* Use `import static emu.grasscutter.Configuration.*;`
|
||||
* to import all configuration constants.
|
||||
*
|
||||
* <p>Use `import static emu.grasscutter.Configuration.*;` to import all configuration constants.
|
||||
*/
|
||||
public final class Configuration extends ConfigContainer {
|
||||
|
||||
@@ -37,7 +34,8 @@ public final class Configuration extends ConfigContainer {
|
||||
public static final Policies HTTP_POLICIES = config.server.http.policies;
|
||||
public static final Files HTTP_STATIC_FILES = config.server.http.files;
|
||||
public static final GameOptions GAME_OPTIONS = config.server.game.gameOptions;
|
||||
public static final GameOptions.InventoryLimits INVENTORY_LIMITS = config.server.game.gameOptions.inventoryLimits;
|
||||
public static final GameOptions.InventoryLimits INVENTORY_LIMITS =
|
||||
config.server.game.gameOptions.inventoryLimits;
|
||||
private static final String DATA_FOLDER = config.folderStructure.data;
|
||||
private static final String PLUGINS_FOLDER = config.folderStructure.plugins;
|
||||
private static final String SCRIPTS_FOLDER = config.folderStructure.scripts;
|
||||
@@ -88,7 +86,7 @@ public final class Configuration extends ConfigContainer {
|
||||
/**
|
||||
* Fallback method.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is undefined.
|
||||
* @return Left or right.
|
||||
*/
|
||||
@@ -99,7 +97,7 @@ public final class Configuration extends ConfigContainer {
|
||||
/**
|
||||
* {@link Configuration#lr(Object, Object)} for {@link String}s.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is empty.
|
||||
* @return Left or right.
|
||||
*/
|
||||
@@ -110,7 +108,7 @@ public final class Configuration extends ConfigContainer {
|
||||
/**
|
||||
* {@link Configuration#lr(Object, Object)} for {@link Integer}s.
|
||||
*
|
||||
* @param left Attempt to use.
|
||||
* @param left Attempt to use.
|
||||
* @param right Use if left is 0.
|
||||
* @return Left or right.
|
||||
*/
|
||||
|
||||
@@ -6,8 +6,6 @@ import emu.grasscutter.tools.Tools;
|
||||
import emu.grasscutter.utils.FileUtils;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
import emu.grasscutter.utils.TsvUtils;
|
||||
import lombok.val;
|
||||
|
||||
import java.io.FileNotFoundException;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
@@ -16,11 +14,13 @@ import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.val;
|
||||
|
||||
public class DataLoader {
|
||||
|
||||
/**
|
||||
* Load a data file by its name. If the file isn't found within the /data directory then it will fallback to the default within the jar resources
|
||||
* Load a data file by its name. If the file isn't found within the /data directory then it will
|
||||
* fallback to the default within the jar resources
|
||||
*
|
||||
* @param resourcePath The path to the data file to be loaded.
|
||||
* @return InputStream of the data file.
|
||||
@@ -32,7 +32,8 @@ public class DataLoader {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an input stream reader for a data file. If the file isn't found within the /data directory then it will fallback to the default within the jar resources
|
||||
* Creates an input stream reader for a data file. If the file isn't found within the /data
|
||||
* directory then it will fallback to the default within the jar resources
|
||||
*
|
||||
* @param resourcePath The path to the data file to be loaded.
|
||||
* @return InputStreamReader of the data file.
|
||||
@@ -40,7 +41,8 @@ public class DataLoader {
|
||||
* @throws FileNotFoundException
|
||||
* @see #load(String, boolean)
|
||||
*/
|
||||
public static InputStreamReader loadReader(String resourcePath) throws IOException, FileNotFoundException {
|
||||
public static InputStreamReader loadReader(String resourcePath)
|
||||
throws IOException, FileNotFoundException {
|
||||
try {
|
||||
InputStream is = load(resourcePath, true);
|
||||
return new InputStreamReader(is);
|
||||
@@ -53,20 +55,22 @@ public class DataLoader {
|
||||
* Load a data file by its name.
|
||||
*
|
||||
* @param resourcePath The path to the data file to be loaded.
|
||||
* @param useFallback If the file does not exist in the /data directory, should it use the default file in the jar?
|
||||
* @param useFallback If the file does not exist in the /data directory, should it use the default
|
||||
* file in the jar?
|
||||
* @return InputStream of the data file.
|
||||
* @throws FileNotFoundException
|
||||
*/
|
||||
public static InputStream load(String resourcePath, boolean useFallback) throws FileNotFoundException {
|
||||
Path path = useFallback
|
||||
? FileUtils.getDataPath(resourcePath)
|
||||
: FileUtils.getDataUserPath(resourcePath);
|
||||
public static InputStream load(String resourcePath, boolean useFallback)
|
||||
throws FileNotFoundException {
|
||||
Path path =
|
||||
useFallback ? FileUtils.getDataPath(resourcePath) : FileUtils.getDataUserPath(resourcePath);
|
||||
if (Files.exists(path)) {
|
||||
// Data is in the resource directory
|
||||
try {
|
||||
return Files.newInputStream(path);
|
||||
} catch (IOException e) {
|
||||
throw new FileNotFoundException(e.getMessage()); // This is evil but so is changing the function signature at this point
|
||||
throw new FileNotFoundException(
|
||||
e.getMessage()); // This is evil but so is changing the function signature at this point
|
||||
}
|
||||
}
|
||||
return null;
|
||||
@@ -84,13 +88,15 @@ public class DataLoader {
|
||||
}
|
||||
}
|
||||
|
||||
public static <T1, T2> Map<T1, T2> loadMap(String resourcePath, Class<T1> keyType, Class<T2> valueType) throws IOException {
|
||||
public static <T1, T2> Map<T1, T2> loadMap(
|
||||
String resourcePath, Class<T1> keyType, Class<T2> valueType) throws IOException {
|
||||
try (InputStreamReader reader = loadReader(resourcePath)) {
|
||||
return JsonUtils.loadToMap(reader, keyType, valueType);
|
||||
}
|
||||
}
|
||||
|
||||
public static <T> List<T> loadTableToList(String resourcePath, Class<T> classType) throws IOException {
|
||||
public static <T> List<T> loadTableToList(String resourcePath, Class<T> classType)
|
||||
throws IOException {
|
||||
val path = FileUtils.getDataPathTsjJsonTsv(resourcePath);
|
||||
Grasscutter.getLogger().debug("Loading data table from: " + path);
|
||||
return switch (FileUtils.getFileExtension(path)) {
|
||||
@@ -107,7 +113,7 @@ public class DataLoader {
|
||||
|
||||
if (filenames == null) {
|
||||
Grasscutter.getLogger().error("We were unable to locate your default data files.");
|
||||
} //else for (Path file : filenames) {
|
||||
} // else for (Path file : filenames) {
|
||||
// String relativePath = String.valueOf(file).split("defaults[\\\\\\/]data[\\\\\\/]")[1];
|
||||
|
||||
// checkAndCopyData(relativePath);
|
||||
|
||||
@@ -6,30 +6,33 @@ import emu.grasscutter.data.excels.*;
|
||||
import emu.grasscutter.game.quest.QuestEncryptionKey;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.*;
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.Tolerate;
|
||||
|
||||
import java.lang.reflect.Field;
|
||||
import java.util.*;
|
||||
|
||||
public class GameData {
|
||||
protected static final Map<String, AbilityData> abilityDataMap = new HashMap<>();
|
||||
protected static final Int2ObjectMap<ScenePointEntry> scenePointEntryMap = new Int2ObjectOpenHashMap<>();
|
||||
protected static final Int2ObjectMap<ScenePointEntry> scenePointEntryMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
// BinOutputs
|
||||
@Getter
|
||||
private static final Int2ObjectMap<HomeworldDefaultSaveData> homeworldDefaultSaveData = new Int2ObjectOpenHashMap<>();
|
||||
@Getter
|
||||
private static final Int2ObjectMap<String> abilityHashes = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<HomeworldDefaultSaveData> homeworldDefaultSaveData =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static final Int2ObjectMap<String> abilityHashes = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@Getter
|
||||
private static final Map<String, AbilityModifierEntry> abilityModifiers = new HashMap<>();
|
||||
@Getter
|
||||
private static final Map<String, ConfigGadget> gadgetConfigData = new HashMap<>();
|
||||
@Getter
|
||||
private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
|
||||
|
||||
@Getter private static final Map<String, ConfigGadget> gadgetConfigData = new HashMap<>();
|
||||
@Getter private static final Map<String, OpenConfigEntry> openConfigEntries = new HashMap<>();
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
@Getter
|
||||
private static final Map<String, ScenePointEntry> scenePointEntries = new HashMap<>();
|
||||
|
||||
private static final Int2ObjectMap<MainQuestData> mainQuestData = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<QuestEncryptionKey> questsKeys = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<SceneNpcBornData> npcBornData = new Int2ObjectOpenHashMap<>();
|
||||
@@ -38,164 +41,286 @@ public class GameData {
|
||||
// ExcelConfigs
|
||||
@Getter
|
||||
private static final ArrayList<CodexReliquaryData> codexReliquaryArrayList = new ArrayList<>();
|
||||
private static final Int2ObjectMap<AchievementData> achievementDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private static final Int2ObjectMap<AchievementData> achievementDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AchievementGoalData> achievementGoalDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AchievementGoalData> achievementGoalDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ActivityData> activityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ActivityShopData> activityShopDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ActivityShopData> activityShopDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ActivityWatcherData> activityWatcherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ActivityWatcherData> activityWatcherDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataItemIdMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataItemIdMap =
|
||||
new Int2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarCostumeData> avatarCostumeDataMap =
|
||||
new Int2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarCurveData> avatarCurveDataMap =
|
||||
new Int2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarData> avatarDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarFetterLevelData> avatarFetterLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarFetterLevelData> avatarFetterLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarFlycloakData> avatarFlycloakDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarFlycloakData> avatarFlycloakDataMap =
|
||||
new Int2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarLevelData> avatarLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarLevelData> avatarLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarSkillData> avatarSkillDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarSkillDepotData> avatarSkillDepotDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarTalentData> avatarTalentDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<BattlePassMissionData> battlePassMissionDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<BattlePassRewardData> battlePassRewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<BattlePassRewardData> battlePassRewardDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<BlossomRefreshExcelConfigData> blossomRefreshExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter
|
||||
private static final Int2ObjectMap<BuffData> buffDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<BlossomRefreshExcelConfigData>
|
||||
blossomRefreshExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static final Int2ObjectMap<BuffData> buffDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ChapterData> chapterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CityData> cityDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexAnimalData> codexAnimalDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CodexAnimalData> codexAnimalDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexMaterialData> codexMaterialDataIdMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CodexMaterialData> codexMaterialDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexQuestData> codexQuestDataIdMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CodexQuestData> codexQuestDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexReliquaryData> codexReliquaryDataIdMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CodexReliquaryData> codexReliquaryDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CodexWeaponData> codexWeaponDataIdMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexWeaponData> codexWeaponDataIdMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CombineData> combineDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CookBonusData> cookBonusDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CookBonusData> cookBonusDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CookRecipeData> cookRecipeDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CookRecipeData> cookRecipeDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<CompoundData> compoundDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<DailyDungeonData> dailyDungeonDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<DungeonEntryData> dungeonEntryDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<EnvAnimalGatherConfigData> envAnimalGatherConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<EnvAnimalGatherConfigData> envAnimalGatherConfigDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<EquipAffixData> equipAffixDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<EquipAffixData> equipAffixDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ForgeData> forgeDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<FurnitureMakeConfigData> furnitureMakeConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<FurnitureMakeConfigData> furnitureMakeConfigDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<GadgetData> gadgetDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<GatherData> gatherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<HomeWorldBgmData> homeWorldBgmDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<HomeWorldBgmData> homeWorldBgmDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<HomeWorldLevelData> homeWorldLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<InvestigationMonsterData> investigationMonsterDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static final Int2ObjectMap<ItemData> itemDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ItemData> itemDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter
|
||||
private static final Int2ObjectMap<MonsterCurveData> monsterCurveDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<MonsterCurveData> monsterCurveDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<MonsterData> monsterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<MonsterDescribeData> monsterDescribeDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<MonsterDescribeData> monsterDescribeDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<MusicGameBasicData> musicGameBasicDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<MusicGameBasicData> musicGameBasicDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter private static final Int2ObjectMap<NpcData> npcDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<NpcData> npcDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<OpenStateData> openStateDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<OpenStateData> openStateDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<PersonalLineData> personalLineDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<PersonalLineData> personalLineDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<PlayerLevelData> playerLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<PlayerLevelData> playerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ProudSkillData> proudSkillDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ProudSkillData> proudSkillDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<QuestData> questDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ReliquaryAffixData> reliquaryAffixDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ReliquaryAffixData> reliquaryAffixDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ReliquaryMainPropData> reliquaryMainPropDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ReliquaryMainPropData> reliquaryMainPropDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<ReliquarySetData> reliquarySetDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ReliquarySetData> reliquarySetDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<RewardPreviewData> rewardPreviewDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<RewardPreviewData> rewardPreviewDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<SceneData> sceneDataMap = new Int2ObjectLinkedOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<TowerFloorData> towerFloorDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<TowerLevelData> towerLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<TowerScheduleData> towerScheduleDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<TowerScheduleData> towerScheduleDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<TriggerExcelConfigData> triggerExcelConfigDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<TriggerExcelConfigData> triggerExcelConfigDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<WeaponCurveData> weaponCurveDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WeaponCurveData> weaponCurveDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<WeaponLevelData> weaponLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WeaponLevelData> weaponLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<WeaponPromoteData> weaponPromoteDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WeaponPromoteData> weaponPromoteDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<WeatherData> weatherDataMap = new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<WorldAreaData> worldAreaDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WorldAreaData> worldAreaDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter
|
||||
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
private static final Int2ObjectMap<AvatarPromoteData> avatarPromoteDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<FetterData> fetterDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ReliquaryLevelData> reliquaryLevelDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ReliquaryLevelData> reliquaryLevelDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
// The following are accessed via getMapByResourceDef, and will show as unused
|
||||
private static final Int2ObjectMap<CodexMaterialData> codexMaterialDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexQuestData> codexQuestDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexReliquaryData> codexReliquaryDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexWeaponData> codexWeaponDataMap = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexMaterialData> codexMaterialDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexQuestData> codexQuestDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexReliquaryData> codexReliquaryDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<CodexWeaponData> codexWeaponDataMap =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
// Cache
|
||||
@Getter
|
||||
private static final IntList scenePointIdList = new IntArrayList();
|
||||
@Getter
|
||||
private static final List<OpenStateData> openStateList = new ArrayList<>();
|
||||
@Getter
|
||||
private static final Map<Integer, List<Integer>> scenePointsPerScene = new HashMap<>();
|
||||
@Getter
|
||||
private static final Map<String, ScriptSceneData> scriptSceneDataMap = new HashMap<>();
|
||||
@Getter private static final IntList scenePointIdList = new IntArrayList();
|
||||
@Getter private static final List<OpenStateData> openStateList = new ArrayList<>();
|
||||
@Getter private static final Map<Integer, List<Integer>> scenePointsPerScene = new HashMap<>();
|
||||
@Getter private static final Map<String, ScriptSceneData> scriptSceneDataMap = new HashMap<>();
|
||||
protected static Int2ObjectMap<IntSet> proudSkillGroupLevels = new Int2ObjectOpenHashMap<>();
|
||||
protected static Int2IntMap proudSkillGroupMaxLevels = new Int2IntOpenHashMap();
|
||||
protected static Int2ObjectMap<IntSet> avatarSkillLevels = new Int2ObjectOpenHashMap<>();
|
||||
@@ -236,7 +361,8 @@ public class GameData {
|
||||
return abilityEmbryos;
|
||||
}
|
||||
|
||||
// Getters that get values rather than containers. If Lombok ever gets syntactic sugar for this, we should adopt that.
|
||||
// Getters that get values rather than containers. If Lombok ever gets syntactic sugar for this,
|
||||
// we should adopt that.
|
||||
public static AbilityData getAbilityData(String abilityName) {
|
||||
return abilityDataMap.get(abilityName);
|
||||
}
|
||||
@@ -283,25 +409,26 @@ public class GameData {
|
||||
return Optional.ofNullable(getRelicLevelData(rankLevel, level)).map(d -> d.getExp()).orElse(0);
|
||||
}
|
||||
|
||||
|
||||
// Generic getter
|
||||
public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
|
||||
Int2ObjectMap<?> map = null;
|
||||
|
||||
try {
|
||||
Field field = GameData.class.getDeclaredField(Utils.lowerCaseFirstChar(resourceDefinition.getSimpleName()) + "Map");
|
||||
Field field =
|
||||
GameData.class.getDeclaredField(
|
||||
Utils.lowerCaseFirstChar(resourceDefinition.getSimpleName()) + "Map");
|
||||
|
||||
field.setAccessible(true);
|
||||
map = (Int2ObjectMap<?>) field.get(null);
|
||||
field.setAccessible(false);
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Error fetching resource map for " + resourceDefinition.getSimpleName(), e);
|
||||
Grasscutter.getLogger()
|
||||
.error("Error fetching resource map for " + resourceDefinition.getSimpleName(), e);
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
|
||||
public static int getWeaponExpRequired(int rankLevel, int level) {
|
||||
WeaponLevelData levelData = weaponLevelDataMap.get(level);
|
||||
if (levelData == null) {
|
||||
@@ -316,12 +443,13 @@ public class GameData {
|
||||
|
||||
public static Map<Integer, List<Integer>> getFetterDataEntries() {
|
||||
if (fetters.isEmpty()) {
|
||||
fetterDataMap.forEach((k, v) -> {
|
||||
if (!fetters.containsKey(v.getAvatarId())) {
|
||||
fetters.put(v.getAvatarId(), new ArrayList<>());
|
||||
}
|
||||
fetters.get(v.getAvatarId()).add(k);
|
||||
});
|
||||
fetterDataMap.forEach(
|
||||
(k, v) -> {
|
||||
if (!fetters.containsKey(v.getAvatarId())) {
|
||||
fetters.put(v.getAvatarId(), new ArrayList<>());
|
||||
}
|
||||
fetters.get(v.getAvatarId()).add(k);
|
||||
});
|
||||
}
|
||||
|
||||
return fetters;
|
||||
@@ -329,11 +457,12 @@ public class GameData {
|
||||
|
||||
public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() {
|
||||
if (shopGoods.isEmpty()) {
|
||||
shopGoodsDataMap.forEach((k, v) -> {
|
||||
if (!shopGoods.containsKey(v.getShopType()))
|
||||
shopGoods.put(v.getShopType(), new ArrayList<>());
|
||||
shopGoods.get(v.getShopType()).add(v);
|
||||
});
|
||||
shopGoodsDataMap.forEach(
|
||||
(k, v) -> {
|
||||
if (!shopGoods.containsKey(v.getShopType()))
|
||||
shopGoods.put(v.getShopType(), new ArrayList<>());
|
||||
shopGoods.get(v.getShopType()).add(v);
|
||||
});
|
||||
}
|
||||
|
||||
return shopGoods;
|
||||
|
||||
@@ -9,50 +9,57 @@ import emu.grasscutter.game.world.SpawnDataEntry;
|
||||
import emu.grasscutter.utils.WeightedList;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class GameDepot {
|
||||
public static final int[] BLOCK_SIZE = new int[]{50, 500};//Scales
|
||||
public static final int[] BLOCK_SIZE = new int[] {50, 500}; // Scales
|
||||
|
||||
private static final Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot = new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
|
||||
new Int2ObjectOpenHashMap<>();
|
||||
|
||||
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
|
||||
@Getter
|
||||
private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists = new HashMap<>();
|
||||
@Getter
|
||||
@Setter
|
||||
private static BlossomConfig blossomConfig;
|
||||
private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
|
||||
new HashMap<>();
|
||||
|
||||
@Getter @Setter private static BlossomConfig blossomConfig;
|
||||
|
||||
public static void load() {
|
||||
for (ReliquaryMainPropData data : GameData.getReliquaryMainPropDataMap().values()) {
|
||||
if (data.getWeight() <= 0 || data.getPropDepotId() <= 0) {
|
||||
continue;
|
||||
}
|
||||
List<ReliquaryMainPropData> list = relicMainPropDepot.computeIfAbsent(data.getPropDepotId(), k -> new ArrayList<>());
|
||||
List<ReliquaryMainPropData> list =
|
||||
relicMainPropDepot.computeIfAbsent(data.getPropDepotId(), k -> new ArrayList<>());
|
||||
list.add(data);
|
||||
WeightedList<ReliquaryMainPropData> weightedList = relicRandomMainPropDepot.computeIfAbsent(data.getPropDepotId(), k -> new WeightedList<>());
|
||||
WeightedList<ReliquaryMainPropData> weightedList =
|
||||
relicRandomMainPropDepot.computeIfAbsent(
|
||||
data.getPropDepotId(), k -> new WeightedList<>());
|
||||
weightedList.add(data.getWeight(), data);
|
||||
}
|
||||
for (ReliquaryAffixData data : GameData.getReliquaryAffixDataMap().values()) {
|
||||
if (data.getWeight() <= 0 || data.getDepotId() <= 0) {
|
||||
continue;
|
||||
}
|
||||
List<ReliquaryAffixData> list = relicAffixDepot.computeIfAbsent(data.getDepotId(), k -> new ArrayList<>());
|
||||
List<ReliquaryAffixData> list =
|
||||
relicAffixDepot.computeIfAbsent(data.getDepotId(), k -> new ArrayList<>());
|
||||
list.add(data);
|
||||
}
|
||||
// Let the server owner know if theyre missing weights
|
||||
if (relicMainPropDepot.size() == 0 || relicAffixDepot.size() == 0) {
|
||||
Grasscutter.getLogger().error("Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder.");
|
||||
Grasscutter.getLogger()
|
||||
.error(
|
||||
"Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder.");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -72,7 +79,8 @@ public class GameDepot {
|
||||
return relicAffixDepot.get(depot);
|
||||
}
|
||||
|
||||
public static void addSpawnListById(HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> data) {
|
||||
public static void addSpawnListById(
|
||||
HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> data) {
|
||||
spawnLists.putAll(data);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,5 @@ public abstract class GameResource {
|
||||
return 0;
|
||||
}
|
||||
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
public void onLoad() {}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
package emu.grasscutter.data;
|
||||
|
||||
import static emu.grasscutter.utils.FileUtils.getDataPath;
|
||||
import static emu.grasscutter.utils.FileUtils.getResourcePath;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.binout.*;
|
||||
@@ -18,9 +22,6 @@ import it.unimi.dsi.fastutil.Pair;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntArraySet;
|
||||
import lombok.val;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.nio.file.Files;
|
||||
@@ -30,10 +31,8 @@ import java.util.concurrent.ConcurrentLinkedQueue;
|
||||
import java.util.concurrent.CopyOnWriteArraySet;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
import static emu.grasscutter.utils.FileUtils.getDataPath;
|
||||
import static emu.grasscutter.utils.FileUtils.getResourcePath;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
import lombok.val;
|
||||
import org.reflections.Reflections;
|
||||
|
||||
public class ResourceLoader {
|
||||
|
||||
@@ -46,14 +45,18 @@ public class ResourceLoader {
|
||||
Set<?> classes = reflections.getSubTypesOf(GameResource.class);
|
||||
|
||||
List<Class<?>> classList = new ArrayList<>(classes.size());
|
||||
classes.forEach(o -> {
|
||||
Class<?> c = (Class<?>) o;
|
||||
if (c.getAnnotation(ResourceType.class) != null) {
|
||||
classList.add(c);
|
||||
}
|
||||
});
|
||||
classes.forEach(
|
||||
o -> {
|
||||
Class<?> c = (Class<?>) o;
|
||||
if (c.getAnnotation(ResourceType.class) != null) {
|
||||
classList.add(c);
|
||||
}
|
||||
});
|
||||
|
||||
classList.sort((a, b) -> b.getAnnotation(ResourceType.class).loadPriority().value() - a.getAnnotation(ResourceType.class).loadPriority().value());
|
||||
classList.sort(
|
||||
(a, b) ->
|
||||
b.getAnnotation(ResourceType.class).loadPriority().value()
|
||||
- a.getAnnotation(ResourceType.class).loadPriority().value());
|
||||
|
||||
return classList;
|
||||
}
|
||||
@@ -67,13 +70,14 @@ public class ResourceLoader {
|
||||
val map = new LinkedHashMap<ResourceType.LoadPriority, Set<Class<?>>>(priorities.size());
|
||||
priorities.forEach(p -> map.put(p, new HashSet<>()));
|
||||
|
||||
classes.forEach(c -> {
|
||||
// val c = (Class<?>) o;
|
||||
val annotation = c.getAnnotation(ResourceType.class);
|
||||
if (annotation != null) {
|
||||
map.get(annotation.loadPriority()).add(c);
|
||||
}
|
||||
});
|
||||
classes.forEach(
|
||||
c -> {
|
||||
// val c = (Class<?>) o;
|
||||
val annotation = c.getAnnotation(ResourceType.class);
|
||||
if (annotation != null) {
|
||||
map.get(annotation.loadPriority()).add(c);
|
||||
}
|
||||
});
|
||||
return List.copyOf(map.values());
|
||||
}
|
||||
|
||||
@@ -112,33 +116,43 @@ public class ResourceLoader {
|
||||
|
||||
public static void loadResources(boolean doReload) {
|
||||
long startTime = System.nanoTime();
|
||||
val errors = new ConcurrentLinkedQueue<Pair<String, Exception>>(); // Logger in a parallel stream will deadlock
|
||||
val errors =
|
||||
new ConcurrentLinkedQueue<
|
||||
Pair<String, Exception>>(); // Logger in a parallel stream will deadlock
|
||||
|
||||
getResourceDefClassesPrioritySets().forEach(classes -> {
|
||||
classes.stream()
|
||||
.parallel().unordered()
|
||||
.forEach(c -> {
|
||||
val type = c.getAnnotation(ResourceType.class);
|
||||
if (type == null) return;
|
||||
getResourceDefClassesPrioritySets()
|
||||
.forEach(
|
||||
classes -> {
|
||||
classes.stream()
|
||||
.parallel()
|
||||
.unordered()
|
||||
.forEach(
|
||||
c -> {
|
||||
val type = c.getAnnotation(ResourceType.class);
|
||||
if (type == null) return;
|
||||
|
||||
val map = GameData.getMapByResourceDef(c);
|
||||
if (map == null) return;
|
||||
val map = GameData.getMapByResourceDef(c);
|
||||
if (map == null) return;
|
||||
|
||||
try {
|
||||
loadFromResource(c, type, map, doReload);
|
||||
} catch (Exception e) {
|
||||
errors.add(Pair.of(Arrays.toString(type.name()), e));
|
||||
}
|
||||
});
|
||||
});
|
||||
errors.forEach(pair -> Grasscutter.getLogger().error("Error loading resource file: " + pair.left(), pair.right()));
|
||||
try {
|
||||
loadFromResource(c, type, map, doReload);
|
||||
} catch (Exception e) {
|
||||
errors.add(Pair.of(Arrays.toString(type.name()), e));
|
||||
}
|
||||
});
|
||||
});
|
||||
errors.forEach(
|
||||
pair ->
|
||||
Grasscutter.getLogger()
|
||||
.error("Error loading resource file: " + pair.left(), pair.right()));
|
||||
long endTime = System.nanoTime();
|
||||
long ns = (endTime - startTime); //divide by 1000000 to get milliseconds.
|
||||
long ns = (endTime - startTime); // divide by 1000000 to get milliseconds.
|
||||
Grasscutter.getLogger().debug("Loading resources took " + ns + "ns == " + ns / 1000000 + "ms");
|
||||
}
|
||||
|
||||
@SuppressWarnings("rawtypes")
|
||||
protected static void loadFromResource(Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception {
|
||||
protected static void loadFromResource(
|
||||
Class<?> c, ResourceType type, Int2ObjectMap map, boolean doReload) throws Exception {
|
||||
val simpleName = c.getSimpleName();
|
||||
if (doReload || !loadedResources.contains(simpleName)) {
|
||||
for (String name : type.name()) {
|
||||
@@ -149,79 +163,95 @@ public class ResourceLoader {
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
protected static <T> void loadFromResource(Class<T> c, Path filename, Int2ObjectMap map) throws Exception {
|
||||
val results = switch (FileUtils.getFileExtension(filename)) {
|
||||
case "json" -> JsonUtils.loadToList(filename, c);
|
||||
case "tsj" -> TsvUtils.loadTsjToListSetField(filename, c);
|
||||
case "tsv" -> TsvUtils.loadTsvToListSetField(filename, c);
|
||||
default -> null;
|
||||
};
|
||||
protected static <T> void loadFromResource(Class<T> c, Path filename, Int2ObjectMap map)
|
||||
throws Exception {
|
||||
val results =
|
||||
switch (FileUtils.getFileExtension(filename)) {
|
||||
case "json" -> JsonUtils.loadToList(filename, c);
|
||||
case "tsj" -> TsvUtils.loadTsjToListSetField(filename, c);
|
||||
case "tsv" -> TsvUtils.loadTsvToListSetField(filename, c);
|
||||
default -> null;
|
||||
};
|
||||
if (results == null) return;
|
||||
results.forEach(o -> {
|
||||
GameResource res = (GameResource) o;
|
||||
res.onLoad();
|
||||
map.put(res.getId(), res);
|
||||
});
|
||||
results.forEach(
|
||||
o -> {
|
||||
GameResource res = (GameResource) o;
|
||||
res.onLoad();
|
||||
map.put(res.getId(), res);
|
||||
});
|
||||
}
|
||||
|
||||
@SuppressWarnings({"rawtypes", "unchecked"})
|
||||
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map) throws Exception {
|
||||
JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c).forEach(o -> {
|
||||
GameResource res = (GameResource) o;
|
||||
res.onLoad();
|
||||
map.put(res.getId(), res);
|
||||
});
|
||||
protected static <T> void loadFromResource(Class<T> c, String fileName, Int2ObjectMap map)
|
||||
throws Exception {
|
||||
JsonUtils.loadToList(getResourcePath("ExcelBinOutput/" + fileName), c)
|
||||
.forEach(
|
||||
o -> {
|
||||
GameResource res = (GameResource) o;
|
||||
res.onLoad();
|
||||
map.put(res.getId(), res);
|
||||
});
|
||||
}
|
||||
|
||||
private static void loadScenePoints() {
|
||||
val pattern = Pattern.compile("scene([0-9]+)_point\\.json");
|
||||
try {
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/Point"), "scene*_point.json").forEach(path -> {
|
||||
val matcher = pattern.matcher(path.getFileName().toString());
|
||||
if (!matcher.find()) return;
|
||||
int sceneId = Integer.parseInt(matcher.group(1));
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/Point"), "scene*_point.json")
|
||||
.forEach(
|
||||
path -> {
|
||||
val matcher = pattern.matcher(path.getFileName().toString());
|
||||
if (!matcher.find()) return;
|
||||
int sceneId = Integer.parseInt(matcher.group(1));
|
||||
|
||||
ScenePointConfig config;
|
||||
try {
|
||||
config = JsonUtils.loadToClass(path, ScenePointConfig.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
ScenePointConfig config;
|
||||
try {
|
||||
config = JsonUtils.loadToClass(path, ScenePointConfig.class);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.points == null) return;
|
||||
if (config.points == null) return;
|
||||
|
||||
val scenePoints = new IntArrayList();
|
||||
config.points.forEach((pointId, pointData) -> {
|
||||
val scenePoint = new ScenePointEntry(sceneId, pointData);
|
||||
scenePoints.add(pointId);
|
||||
pointData.setId(pointId);
|
||||
val scenePoints = new IntArrayList();
|
||||
config.points.forEach(
|
||||
(pointId, pointData) -> {
|
||||
val scenePoint = new ScenePointEntry(sceneId, pointData);
|
||||
scenePoints.add(pointId);
|
||||
pointData.setId(pointId);
|
||||
|
||||
GameData.getScenePointIdList().add(pointId);
|
||||
GameData.getScenePointEntries().put(scenePoint.getName(), scenePoint);
|
||||
GameData.scenePointEntryMap.put((sceneId << 16) + pointId, scenePoint);
|
||||
GameData.getScenePointIdList().add(pointId);
|
||||
GameData.getScenePointEntries().put(scenePoint.getName(), scenePoint);
|
||||
GameData.scenePointEntryMap.put((sceneId << 16) + pointId, scenePoint);
|
||||
|
||||
pointData.updateDailyDungeon();
|
||||
});
|
||||
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
|
||||
});
|
||||
pointData.updateDailyDungeon();
|
||||
});
|
||||
GameData.getScenePointsPerScene().put(sceneId, scenePoints);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
||||
Grasscutter.getLogger()
|
||||
.error("Scene point files cannot be found, you cannot use teleport waypoints!");
|
||||
}
|
||||
}
|
||||
|
||||
private static void cacheTalentLevelSets() {
|
||||
// All known levels, keyed by proudSkillGroupId
|
||||
GameData.getProudSkillDataMap().forEach((id, data) ->
|
||||
GameData.proudSkillGroupLevels
|
||||
.computeIfAbsent(data.getProudSkillGroupId(), i -> new IntArraySet())
|
||||
.add(data.getLevel()));
|
||||
GameData.getProudSkillDataMap()
|
||||
.forEach(
|
||||
(id, data) ->
|
||||
GameData.proudSkillGroupLevels
|
||||
.computeIfAbsent(data.getProudSkillGroupId(), i -> new IntArraySet())
|
||||
.add(data.getLevel()));
|
||||
// All known levels, keyed by avatarSkillId
|
||||
GameData.getAvatarSkillDataMap().forEach((id, data) ->
|
||||
GameData.avatarSkillLevels.put((int) id, GameData.proudSkillGroupLevels.get(data.getProudSkillGroupId())));
|
||||
GameData.getAvatarSkillDataMap()
|
||||
.forEach(
|
||||
(id, data) ->
|
||||
GameData.avatarSkillLevels.put(
|
||||
(int) id, GameData.proudSkillGroupLevels.get(data.getProudSkillGroupId())));
|
||||
// Maximum known levels, keyed by proudSkillGroupId
|
||||
GameData.proudSkillGroupLevels.forEach((id, set) ->
|
||||
GameData.proudSkillGroupMaxLevels.put((int) id, set.intStream().max().getAsInt()));
|
||||
GameData.proudSkillGroupLevels.forEach(
|
||||
(id, set) ->
|
||||
GameData.proudSkillGroupMaxLevels.put((int) id, set.intStream().max().getAsInt()));
|
||||
}
|
||||
|
||||
private static void loadAbilityEmbryos() {
|
||||
@@ -229,7 +259,8 @@ public class ResourceLoader {
|
||||
|
||||
// Read from cached file if exists
|
||||
try {
|
||||
embryoList = JsonUtils.loadToList(getDataPath("AbilityEmbryos.json"), AbilityEmbryoEntry.class);
|
||||
embryoList =
|
||||
JsonUtils.loadToList(getDataPath("AbilityEmbryos.json"), AbilityEmbryoEntry.class);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
|
||||
@@ -239,25 +270,32 @@ public class ResourceLoader {
|
||||
|
||||
val l = new ArrayList<AbilityEmbryoEntry>();
|
||||
try {
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Avatar/"), "ConfigAvatar_*.json").forEach(path -> {
|
||||
val matcher = pattern.matcher(path.getFileName().toString());
|
||||
if (!matcher.find()) return;
|
||||
String avatarName = matcher.group(1);
|
||||
AvatarConfig config;
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Avatar/"), "ConfigAvatar_*.json")
|
||||
.forEach(
|
||||
path -> {
|
||||
val matcher = pattern.matcher(path.getFileName().toString());
|
||||
if (!matcher.find()) return;
|
||||
String avatarName = matcher.group(1);
|
||||
AvatarConfig config;
|
||||
|
||||
try {
|
||||
config = JsonUtils.loadToClass(path, AvatarConfig.class);
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Error loading player ability embryos:", e);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
config = JsonUtils.loadToClass(path, AvatarConfig.class);
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("Error loading player ability embryos:", e);
|
||||
return;
|
||||
}
|
||||
|
||||
if (config.abilities == null) return;
|
||||
if (config.abilities == null) return;
|
||||
|
||||
int s = config.abilities.size();
|
||||
AbilityEmbryoEntry al = new AbilityEmbryoEntry(avatarName, config.abilities.stream().map(Object::toString).toArray(size -> new String[s]));
|
||||
l.add(al);
|
||||
});
|
||||
int s = config.abilities.size();
|
||||
AbilityEmbryoEntry al =
|
||||
new AbilityEmbryoEntry(
|
||||
avatarName,
|
||||
config.abilities.stream()
|
||||
.map(Object::toString)
|
||||
.toArray(size -> new String[s]));
|
||||
l.add(al);
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Error loading ability embryos: no files found");
|
||||
return;
|
||||
@@ -266,7 +304,12 @@ public class ResourceLoader {
|
||||
embryoList = l;
|
||||
|
||||
try {
|
||||
GameDepot.setPlayerAbilities(JsonUtils.loadToMap(getResourcePath("BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json"), String.class, AvatarConfig.class));
|
||||
GameDepot.setPlayerAbilities(
|
||||
JsonUtils.loadToMap(
|
||||
getResourcePath(
|
||||
"BinOutput/AbilityGroup/AbilityGroup_Other_PlayerElementAbility.json"),
|
||||
String.class,
|
||||
AvatarConfig.class));
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Error loading player abilities:", e);
|
||||
}
|
||||
@@ -285,7 +328,10 @@ public class ResourceLoader {
|
||||
private static void loadAbilityModifiers() {
|
||||
// Load from BinOutput
|
||||
try (Stream<Path> paths = Files.walk(getResourcePath("BinOutput/Ability/Temp/"))) {
|
||||
paths.filter(Files::isRegularFile).filter(path -> path.toString().endsWith(".json")).forEach(ResourceLoader::loadAbilityModifiers);
|
||||
paths
|
||||
.filter(Files::isRegularFile)
|
||||
.filter(path -> path.toString().endsWith(".json"))
|
||||
.forEach(ResourceLoader::loadAbilityModifiers);
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Error loading ability modifiers: ", e);
|
||||
}
|
||||
@@ -296,9 +342,11 @@ public class ResourceLoader {
|
||||
|
||||
private static void loadAbilityModifiers(Path path) {
|
||||
try {
|
||||
JsonUtils.loadToList(path, AbilityConfigData.class).forEach(data -> loadAbilityData(data.Default));
|
||||
JsonUtils.loadToList(path, AbilityConfigData.class)
|
||||
.forEach(data -> loadAbilityData(data.Default));
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Error loading ability modifiers from path " + path.toString() + ": ", e);
|
||||
Grasscutter.getLogger()
|
||||
.error("Error loading ability modifiers from path " + path.toString() + ": ", e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -310,20 +358,24 @@ public class ResourceLoader {
|
||||
|
||||
String name = data.abilityName;
|
||||
AbilityModifierEntry modifierEntry = new AbilityModifierEntry(name);
|
||||
modifiers.forEach((key, modifier) -> {
|
||||
Stream.ofNullable(modifier.onAdded).flatMap(Stream::of)
|
||||
// .map(action -> {modifierActionTypes.add(action.$type); return action;})
|
||||
.filter(action -> action.type == AbilityModifierAction.Type.HealHP)
|
||||
.forEach(action -> modifierEntry.getOnAdded().add(action));
|
||||
Stream.ofNullable(modifier.onThinkInterval).flatMap(Stream::of)
|
||||
// .map(action -> {modifierActionTypes.add(action.$type); return action;})
|
||||
.filter(action -> action.type == AbilityModifierAction.Type.HealHP)
|
||||
.forEach(action -> modifierEntry.getOnThinkInterval().add(action));
|
||||
Stream.ofNullable(modifier.onRemoved).flatMap(Stream::of)
|
||||
// .map(action -> {modifierActionTypes.add(action.$type); return action;})
|
||||
.filter(action -> action.type == AbilityModifierAction.Type.HealHP)
|
||||
.forEach(action -> modifierEntry.getOnRemoved().add(action));
|
||||
});
|
||||
modifiers.forEach(
|
||||
(key, modifier) -> {
|
||||
Stream.ofNullable(modifier.onAdded)
|
||||
.flatMap(Stream::of)
|
||||
// .map(action -> {modifierActionTypes.add(action.$type); return action;})
|
||||
.filter(action -> action.type == AbilityModifierAction.Type.HealHP)
|
||||
.forEach(action -> modifierEntry.getOnAdded().add(action));
|
||||
Stream.ofNullable(modifier.onThinkInterval)
|
||||
.flatMap(Stream::of)
|
||||
// .map(action -> {modifierActionTypes.add(action.$type); return action;})
|
||||
.filter(action -> action.type == AbilityModifierAction.Type.HealHP)
|
||||
.forEach(action -> modifierEntry.getOnThinkInterval().add(action));
|
||||
Stream.ofNullable(modifier.onRemoved)
|
||||
.flatMap(Stream::of)
|
||||
// .map(action -> {modifierActionTypes.add(action.$type); return action;})
|
||||
.filter(action -> action.type == AbilityModifierAction.Type.HealHP)
|
||||
.forEach(action -> modifierEntry.getOnRemoved().add(action));
|
||||
});
|
||||
|
||||
GameData.getAbilityModifiers().put(name, modifierEntry);
|
||||
}
|
||||
@@ -347,18 +399,19 @@ public class ResourceLoader {
|
||||
}
|
||||
|
||||
HashMap<GridBlockId, ArrayList<SpawnDataEntry>> areaSort = new HashMap<>();
|
||||
//key = sceneId,x,z , value = ArrayList<SpawnDataEntry>
|
||||
// key = sceneId,x,z , value = ArrayList<SpawnDataEntry>
|
||||
for (SpawnGroupEntry entry : spawnEntryMap) {
|
||||
entry.getSpawns().forEach(
|
||||
s -> {
|
||||
s.setGroup(entry);
|
||||
GridBlockId point = s.getBlockId();
|
||||
if (!areaSort.containsKey(point)) {
|
||||
areaSort.put(point, new ArrayList<>());
|
||||
}
|
||||
areaSort.get(point).add(s);
|
||||
}
|
||||
);
|
||||
entry
|
||||
.getSpawns()
|
||||
.forEach(
|
||||
s -> {
|
||||
s.setGroup(entry);
|
||||
GridBlockId point = s.getBlockId();
|
||||
if (!areaSort.containsKey(point)) {
|
||||
areaSort.put(point, new ArrayList<>());
|
||||
}
|
||||
areaSort.get(point).add(s);
|
||||
});
|
||||
}
|
||||
GameDepot.addSpawnListById(areaSort);
|
||||
}
|
||||
@@ -378,16 +431,19 @@ public class ResourceLoader {
|
||||
|
||||
for (String folderName : folderNames) {
|
||||
try {
|
||||
Files.newDirectoryStream(getResourcePath(folderName), "*.json").forEach(path -> {
|
||||
try {
|
||||
JsonUtils.loadToMap(path, String.class, OpenConfigData[].class)
|
||||
.forEach((name, data) -> map.put(name, new OpenConfigEntry(name, data)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
Files.newDirectoryStream(getResourcePath(folderName), "*.json")
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
JsonUtils.loadToMap(path, String.class, OpenConfigData[].class)
|
||||
.forEach((name, data) -> map.put(name, new OpenConfigEntry(name, data)));
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Error loading open config: no files found in " + folderName);
|
||||
Grasscutter.getLogger()
|
||||
.error("Error loading open config: no files found in " + folderName);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -407,14 +463,16 @@ public class ResourceLoader {
|
||||
|
||||
private static void loadQuests() {
|
||||
try {
|
||||
Files.list(getResourcePath("BinOutput/Quest/")).forEach(path -> {
|
||||
try {
|
||||
val mainQuest = JsonUtils.loadToClass(path, MainQuestData.class);
|
||||
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
|
||||
} catch (IOException e) {
|
||||
Files.list(getResourcePath("BinOutput/Quest/"))
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
val mainQuest = JsonUtils.loadToClass(path, MainQuestData.class);
|
||||
GameData.getMainQuestDataMap().put(mainQuest.getId(), mainQuest);
|
||||
} catch (IOException e) {
|
||||
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Quest data missing");
|
||||
return;
|
||||
@@ -424,11 +482,13 @@ public class ResourceLoader {
|
||||
val questEncryptionMap = GameData.getMainQuestEncryptionMap();
|
||||
String path = "QuestEncryptionKeys.json";
|
||||
try {
|
||||
JsonUtils.loadToList(getResourcePath(path), QuestEncryptionKey.class).forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
||||
JsonUtils.loadToList(getResourcePath(path), QuestEncryptionKey.class)
|
||||
.forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
||||
} catch (IOException | NullPointerException ignored) {
|
||||
}
|
||||
try {
|
||||
DataLoader.loadList(path, QuestEncryptionKey.class).forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
||||
DataLoader.loadList(path, QuestEncryptionKey.class)
|
||||
.forEach(key -> questEncryptionMap.put(key.getMainQuestId(), key));
|
||||
} catch (IOException | NullPointerException ignored) {
|
||||
}
|
||||
Grasscutter.getLogger().debug("Loaded {} quest keys.", questEncryptionMap.size());
|
||||
@@ -436,19 +496,26 @@ public class ResourceLoader {
|
||||
Grasscutter.getLogger().error("Unable to load quest keys.", e);
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
||||
Grasscutter.getLogger()
|
||||
.debug("Loaded " + GameData.getMainQuestDataMap().size() + " MainQuestDatas.");
|
||||
}
|
||||
|
||||
public static void loadScriptSceneData() {
|
||||
try {
|
||||
Files.list(getResourcePath("ScriptSceneData/")).forEach(path -> {
|
||||
try {
|
||||
GameData.getScriptSceneDataMap().put(path.getFileName().toString(), JsonUtils.loadToClass(path, ScriptSceneData.class));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
Grasscutter.getLogger().debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas.");
|
||||
Files.list(getResourcePath("ScriptSceneData/"))
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
GameData.getScriptSceneDataMap()
|
||||
.put(
|
||||
path.getFileName().toString(),
|
||||
JsonUtils.loadToClass(path, ScriptSceneData.class));
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
});
|
||||
Grasscutter.getLogger()
|
||||
.debug("Loaded " + GameData.getScriptSceneDataMap().size() + " ScriptSceneDatas.");
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().debug("ScriptSceneData folder missing or empty.");
|
||||
}
|
||||
@@ -457,18 +524,25 @@ public class ResourceLoader {
|
||||
private static void loadHomeworldDefaultSaveData() {
|
||||
val pattern = Pattern.compile("scene([0-9]+)_home_config\\.json");
|
||||
try {
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/HomeworldDefaultSave"), "scene*_home_config.json").forEach(path -> {
|
||||
val matcher = pattern.matcher(path.getFileName().toString());
|
||||
if (!matcher.find()) return;
|
||||
Files.newDirectoryStream(
|
||||
getResourcePath("BinOutput/HomeworldDefaultSave"), "scene*_home_config.json")
|
||||
.forEach(
|
||||
path -> {
|
||||
val matcher = pattern.matcher(path.getFileName().toString());
|
||||
if (!matcher.find()) return;
|
||||
|
||||
try {
|
||||
val sceneId = Integer.parseInt(matcher.group(1));
|
||||
val data = JsonUtils.loadToClass(path, HomeworldDefaultSaveData.class);
|
||||
GameData.getHomeworldDefaultSaveData().put(sceneId, data);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
});
|
||||
Grasscutter.getLogger().debug("Loaded " + GameData.getHomeworldDefaultSaveData().size() + " HomeworldDefaultSaveDatas.");
|
||||
try {
|
||||
val sceneId = Integer.parseInt(matcher.group(1));
|
||||
val data = JsonUtils.loadToClass(path, HomeworldDefaultSaveData.class);
|
||||
GameData.getHomeworldDefaultSaveData().put(sceneId, data);
|
||||
} catch (Exception ignored) {
|
||||
}
|
||||
});
|
||||
Grasscutter.getLogger()
|
||||
.debug(
|
||||
"Loaded "
|
||||
+ GameData.getHomeworldDefaultSaveData().size()
|
||||
+ " HomeworldDefaultSaveDatas.");
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Failed to load HomeworldDefaultSave folder.");
|
||||
}
|
||||
@@ -476,19 +550,24 @@ public class ResourceLoader {
|
||||
|
||||
private static void loadNpcBornData() {
|
||||
try {
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/SceneNpcBorn/"), "*.json").forEach(path -> {
|
||||
try {
|
||||
val data = JsonUtils.loadToClass(path, SceneNpcBornData.class);
|
||||
if (data.getBornPosList() == null || data.getBornPosList().size() == 0) {
|
||||
return;
|
||||
}
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Scene/SceneNpcBorn/"), "*.json")
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
val data = JsonUtils.loadToClass(path, SceneNpcBornData.class);
|
||||
if (data.getBornPosList() == null || data.getBornPosList().size() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
data.setIndex(SceneIndexManager.buildIndex(3, data.getBornPosList(), item -> item.getPos().toPoint()));
|
||||
GameData.getSceneNpcBornData().put(data.getSceneId(), data);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
});
|
||||
Grasscutter.getLogger().debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas.");
|
||||
data.setIndex(
|
||||
SceneIndexManager.buildIndex(
|
||||
3, data.getBornPosList(), item -> item.getPos().toPoint()));
|
||||
GameData.getSceneNpcBornData().put(data.getSceneId(), data);
|
||||
} catch (IOException ignored) {
|
||||
}
|
||||
});
|
||||
Grasscutter.getLogger()
|
||||
.debug("Loaded " + GameData.getSceneNpcBornData().size() + " SceneNpcBornDatas.");
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Failed to load SceneNpcBorn folder.");
|
||||
}
|
||||
@@ -496,15 +575,20 @@ public class ResourceLoader {
|
||||
|
||||
private static void loadGadgetConfigData() {
|
||||
try {
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Gadget/"), "*.json").forEach(path -> {
|
||||
try {
|
||||
GameData.getGadgetConfigData().putAll(JsonUtils.loadToMap(path, String.class, ConfigGadget.class));
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error("failed to load ConfigGadget entries for " + path.toString(), e);
|
||||
}
|
||||
});
|
||||
Files.newDirectoryStream(getResourcePath("BinOutput/Gadget/"), "*.json")
|
||||
.forEach(
|
||||
path -> {
|
||||
try {
|
||||
GameData.getGadgetConfigData()
|
||||
.putAll(JsonUtils.loadToMap(path, String.class, ConfigGadget.class));
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger()
|
||||
.error("failed to load ConfigGadget entries for " + path.toString(), e);
|
||||
}
|
||||
});
|
||||
|
||||
Grasscutter.getLogger().debug("Loaded {} ConfigGadget entries.", GameData.getGadgetConfigData().size());
|
||||
Grasscutter.getLogger()
|
||||
.debug("Loaded {} ConfigGadget entries.", GameData.getGadgetConfigData().size());
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().error("Failed to load ConfigGadget folder.");
|
||||
}
|
||||
@@ -525,7 +609,9 @@ public class ResourceLoader {
|
||||
}
|
||||
|
||||
public static class AvatarConfig {
|
||||
@SerializedName(value = "abilities", alternate = {"targetAbilities"})
|
||||
@SerializedName(
|
||||
value = "abilities",
|
||||
alternate = {"targetAbilities"})
|
||||
public ArrayList<AvatarConfigAbility> abilities;
|
||||
}
|
||||
|
||||
@@ -547,17 +633,23 @@ public class ResourceLoader {
|
||||
public String $type;
|
||||
public String abilityName;
|
||||
|
||||
@SerializedName(value = "talentIndex", alternate = {"OJOFFKLNAHN"})
|
||||
@SerializedName(
|
||||
value = "talentIndex",
|
||||
alternate = {"OJOFFKLNAHN"})
|
||||
public int talentIndex;
|
||||
|
||||
@SerializedName(value = "skillID", alternate = {"overtime"})
|
||||
@SerializedName(
|
||||
value = "skillID",
|
||||
alternate = {"overtime"})
|
||||
public int skillID;
|
||||
|
||||
@SerializedName(value = "pointDelta", alternate = {"IGEBKIHPOIF"})
|
||||
@SerializedName(
|
||||
value = "pointDelta",
|
||||
alternate = {"IGEBKIHPOIF"})
|
||||
public int pointDelta;
|
||||
}
|
||||
|
||||
public class ScenePointConfig { // Sadly this doesn't work as a local class in loadScenePoints()
|
||||
public class ScenePointConfig { // Sadly this doesn't work as a local class in loadScenePoints()
|
||||
public Map<Integer, PointData> points;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,9 +8,7 @@ import java.util.stream.Stream;
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
public @interface ResourceType {
|
||||
|
||||
/**
|
||||
* Names of the file that this Resource loads from
|
||||
*/
|
||||
/** Names of the file that this Resource loads from */
|
||||
String[] name();
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,9 +4,7 @@ public class AbilityEmbryoEntry {
|
||||
private String name;
|
||||
private String[] abilities;
|
||||
|
||||
public AbilityEmbryoEntry() {
|
||||
|
||||
}
|
||||
public AbilityEmbryoEntry() {}
|
||||
|
||||
public AbilityEmbryoEntry(String avatarName, String[] array) {
|
||||
this.name = avatarName;
|
||||
|
||||
@@ -2,93 +2,266 @@ package emu.grasscutter.data.binout;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.data.common.DynamicFloat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
public class AbilityModifier implements Serializable {
|
||||
private static final long serialVersionUID = -2001232313615923575L;
|
||||
|
||||
@SerializedName(value = "onAdded", alternate = {"KCICDEJLIJD"})
|
||||
@SerializedName(
|
||||
value = "onAdded",
|
||||
alternate = {"KCICDEJLIJD"})
|
||||
public AbilityModifierAction[] onAdded;
|
||||
@SerializedName(value = "onThinkInterval", alternate = {"PBDDACFFPOE"})
|
||||
|
||||
@SerializedName(
|
||||
value = "onThinkInterval",
|
||||
alternate = {"PBDDACFFPOE"})
|
||||
public AbilityModifierAction[] onThinkInterval;
|
||||
|
||||
public AbilityModifierAction[] onRemoved;
|
||||
public DynamicFloat duration = DynamicFloat.ZERO;
|
||||
|
||||
public static class AbilityModifierAction {
|
||||
@SerializedName("$type")
|
||||
public Type type;
|
||||
|
||||
public String target;
|
||||
|
||||
@SerializedName(value = "amount", alternate = "PDLLIFICICJ")
|
||||
public DynamicFloat amount = DynamicFloat.ZERO;
|
||||
|
||||
public DynamicFloat amountByCasterAttackRatio = DynamicFloat.ZERO;
|
||||
public DynamicFloat amountByCasterCurrentHPRatio = DynamicFloat.ZERO;
|
||||
public DynamicFloat amountByCasterMaxHPRatio = DynamicFloat.ZERO;
|
||||
public DynamicFloat amountByGetDamage = DynamicFloat.ZERO;
|
||||
public DynamicFloat amountByTargetCurrentHPRatio = DynamicFloat.ZERO;
|
||||
public DynamicFloat amountByTargetMaxHPRatio = DynamicFloat.ZERO;
|
||||
|
||||
@SerializedName(value = "ignoreAbilityProperty", alternate = "HHFGADCJJDI")
|
||||
public boolean ignoreAbilityProperty;
|
||||
|
||||
public String modifierName;
|
||||
|
||||
public enum Type {
|
||||
ActCameraRadialBlur, ActCameraShake, AddAvatarSkillInfo, AddChargeBarValue,
|
||||
AddClimateMeter, AddElementDurability, AddGlobalValue, AddGlobalValueToTarget,
|
||||
AddRegionalPlayVarValue, ApplyModifier, AttachAbilityStateResistance, AttachBulletAimPoint,
|
||||
AttachEffect, AttachEffectFirework, AttachElementTypeResistance, AttachModifier,
|
||||
AttachUIEffect, AvatarCameraParam, AvatarEnterCameraShot, AvatarEnterFocus,
|
||||
AvatarEnterViewBias, AvatarExitCameraShot, AvatarExitClimb, AvatarExitFocus,
|
||||
AvatarExitViewBias, AvatarShareCDSkillStart, AvatarSkillStart, BroadcastNeuronStimulate,
|
||||
CalcDvalinS04RebornPoint, CallLuaTask, ChangeEnviroWeather, ChangeFollowDampTime,
|
||||
ChangeGadgetUIInteractHint, ChangePlayMode, ChangeTag, ChangeUGCRayTag,
|
||||
ClearEndura, ClearGlobalPos, ClearGlobalValue, ClearLocalGadgets,
|
||||
ClearLockTarget, ClearPos, ConfigAbilityAction, ControlEmotion,
|
||||
CopyGlobalValue, CreateGadget, CreateMovingPlatform, CreateTile,
|
||||
DamageByAttackValue, DebugLog, DestroyTile, DoBlink,
|
||||
DoTileAction, DoWatcherSystemAction, DoWidgetSystemAction, DropSubfield,
|
||||
DummyAction, DungeonFogEffects, ElementAttachForActivityGacha, EnableAIStealthy,
|
||||
EnableAfterImage, EnableAvatarFlyStateTrail, EnableAvatarMoveOnWater, EnableBulletCollisionPluginTrigger,
|
||||
EnableGadgetIntee, EnableHeadControl, EnableHitBoxByName, EnableMainInterface,
|
||||
EnablePartControl, EnablePositionSynchronization, EnablePushColliderName, EnableRocketJump,
|
||||
EnableSceneTransformByName, EnterCameraLock, EntityDoSkill, EquipAffixStart,
|
||||
ExecuteGadgetLua, FireAISoundEvent, FireChargeBarEffect, FireEffect,
|
||||
FireEffectFirework, FireEffectForStorm, FireFishingEvent, FireHitEffect,
|
||||
FireSubEmitterEffect, FireUIEffect, FixedMonsterRushMove, ForceAirStateFly,
|
||||
ForceEnableShakeOffButton, GenerateElemBall, GetFightProperty, GetInteractIdToGlobalValue,
|
||||
GetPos, HealHP, HideUIBillBoard, IgnoreMoveColToRockCol,
|
||||
KillGadget, KillPlayEntity, KillSelf, KillServerGadget,
|
||||
LoseHP, ModifyAvatarSkillCD, ModifyVehicleSkillCD, PlayEmoSync,
|
||||
Predicated, PushDvalinS01Process, PushInterActionByConfigPath, PushPos,
|
||||
Randomed, ReTriggerAISkillInitialCD, RefreshUICombatBarLayout, RegisterAIActionPoint,
|
||||
ReleaseAIActionPoint, RemoveAvatarSkillInfo, RemoveModifier, RemoveModifierByAbilityStateResistanceID,
|
||||
RemoveServerBuff, RemoveUniqueModifier, RemoveVelocityForce, Repeated,
|
||||
ResetAIAttackTarget, ResetAIResistTauntLevel, ResetAIThreatBroadcastRange, ResetAnimatorTrigger,
|
||||
ReviveDeadAvatar, ReviveElemEnergy, ReviveStamina, SectorCityManeuver,
|
||||
SendEffectTrigger, SendEffectTriggerToLineEffect, SendEvtElectricCoreMoveEnterP1, SendEvtElectricCoreMoveInterrupt,
|
||||
ServerLuaCall, ServerLuaTriggerEvent, ServerMonsterLog, SetAIHitFeeling,
|
||||
SetAISkillCDAvailableNow, SetAISkillCDMultiplier, SetAISkillGCD, SetAnimatorBool,
|
||||
SetAnimatorFloat, SetAnimatorInt, SetAnimatorTrigger, SetAvatarCanShakeOff,
|
||||
SetAvatarHitBuckets, SetCanDieImmediately, SetChargeBarValue, SetDvalinS01FlyState,
|
||||
SetEmissionScaler, SetEntityScale, SetExtraAbilityEnable, SetExtraAbilityState,
|
||||
SetGlobalDir, SetGlobalPos, SetGlobalValue, SetGlobalValueByTargetDistance,
|
||||
SetGlobalValueToOverrideMap, SetKeepInAirVelocityForce, SetMaterialParamFloatByTransform, SetNeuronEnable,
|
||||
SetOverrideMapValue, SetPartControlTarget, SetPoseBool, SetPoseFloat,
|
||||
SetPoseInt, SetRandomOverrideMapValue, SetRegionalPlayVarValue, SetSelfAttackTarget,
|
||||
SetSkillAnchor, SetSpecialCamera, SetSurroundAnchor, SetSystemValueToOverrideMap,
|
||||
SetTargetNumToGlobalValue, SetUICombatBarAsh, SetUICombatBarSpark, SetVelocityIgnoreAirGY,
|
||||
SetWeaponAttachPointRealName, SetWeaponBindState, ShowExtraAbility, ShowProgressBarAction,
|
||||
ShowReminder, ShowScreenEffect, ShowTextMap, ShowUICombatBar,
|
||||
StartDither, SumTargetWeightToSelfGlobalValue, Summon, SyncToStageScript,
|
||||
TriggerAbility, TriggerAttackEvent, TriggerAttackTargetMapEvent, TriggerAudio,
|
||||
TriggerAuxWeaponTrans, TriggerBullet, TriggerCreateGadgetToEquipPart, TriggerDropEquipParts,
|
||||
TriggerFaceAnimation, TriggerGadgetInteractive, TriggerHideWeapon, TriggerSetCastShadow,
|
||||
TriggerSetPassThrough, TriggerSetRenderersEnable, TriggerSetShadowRamp, TriggerSetVisible,
|
||||
TriggerTaunt, TriggerThrowEquipPart, TriggerUGCGadgetMove, TryFindBlinkPoint,
|
||||
TryFindBlinkPointByBorn, TryTriggerPlatformStartMove, TurnDirection, TurnDirectionToPos,
|
||||
UpdateReactionDamage, UseSkillEliteSet, WidgetSkillStart
|
||||
ActCameraRadialBlur,
|
||||
ActCameraShake,
|
||||
AddAvatarSkillInfo,
|
||||
AddChargeBarValue,
|
||||
AddClimateMeter,
|
||||
AddElementDurability,
|
||||
AddGlobalValue,
|
||||
AddGlobalValueToTarget,
|
||||
AddRegionalPlayVarValue,
|
||||
ApplyModifier,
|
||||
AttachAbilityStateResistance,
|
||||
AttachBulletAimPoint,
|
||||
AttachEffect,
|
||||
AttachEffectFirework,
|
||||
AttachElementTypeResistance,
|
||||
AttachModifier,
|
||||
AttachUIEffect,
|
||||
AvatarCameraParam,
|
||||
AvatarEnterCameraShot,
|
||||
AvatarEnterFocus,
|
||||
AvatarEnterViewBias,
|
||||
AvatarExitCameraShot,
|
||||
AvatarExitClimb,
|
||||
AvatarExitFocus,
|
||||
AvatarExitViewBias,
|
||||
AvatarShareCDSkillStart,
|
||||
AvatarSkillStart,
|
||||
BroadcastNeuronStimulate,
|
||||
CalcDvalinS04RebornPoint,
|
||||
CallLuaTask,
|
||||
ChangeEnviroWeather,
|
||||
ChangeFollowDampTime,
|
||||
ChangeGadgetUIInteractHint,
|
||||
ChangePlayMode,
|
||||
ChangeTag,
|
||||
ChangeUGCRayTag,
|
||||
ClearEndura,
|
||||
ClearGlobalPos,
|
||||
ClearGlobalValue,
|
||||
ClearLocalGadgets,
|
||||
ClearLockTarget,
|
||||
ClearPos,
|
||||
ConfigAbilityAction,
|
||||
ControlEmotion,
|
||||
CopyGlobalValue,
|
||||
CreateGadget,
|
||||
CreateMovingPlatform,
|
||||
CreateTile,
|
||||
DamageByAttackValue,
|
||||
DebugLog,
|
||||
DestroyTile,
|
||||
DoBlink,
|
||||
DoTileAction,
|
||||
DoWatcherSystemAction,
|
||||
DoWidgetSystemAction,
|
||||
DropSubfield,
|
||||
DummyAction,
|
||||
DungeonFogEffects,
|
||||
ElementAttachForActivityGacha,
|
||||
EnableAIStealthy,
|
||||
EnableAfterImage,
|
||||
EnableAvatarFlyStateTrail,
|
||||
EnableAvatarMoveOnWater,
|
||||
EnableBulletCollisionPluginTrigger,
|
||||
EnableGadgetIntee,
|
||||
EnableHeadControl,
|
||||
EnableHitBoxByName,
|
||||
EnableMainInterface,
|
||||
EnablePartControl,
|
||||
EnablePositionSynchronization,
|
||||
EnablePushColliderName,
|
||||
EnableRocketJump,
|
||||
EnableSceneTransformByName,
|
||||
EnterCameraLock,
|
||||
EntityDoSkill,
|
||||
EquipAffixStart,
|
||||
ExecuteGadgetLua,
|
||||
FireAISoundEvent,
|
||||
FireChargeBarEffect,
|
||||
FireEffect,
|
||||
FireEffectFirework,
|
||||
FireEffectForStorm,
|
||||
FireFishingEvent,
|
||||
FireHitEffect,
|
||||
FireSubEmitterEffect,
|
||||
FireUIEffect,
|
||||
FixedMonsterRushMove,
|
||||
ForceAirStateFly,
|
||||
ForceEnableShakeOffButton,
|
||||
GenerateElemBall,
|
||||
GetFightProperty,
|
||||
GetInteractIdToGlobalValue,
|
||||
GetPos,
|
||||
HealHP,
|
||||
HideUIBillBoard,
|
||||
IgnoreMoveColToRockCol,
|
||||
KillGadget,
|
||||
KillPlayEntity,
|
||||
KillSelf,
|
||||
KillServerGadget,
|
||||
LoseHP,
|
||||
ModifyAvatarSkillCD,
|
||||
ModifyVehicleSkillCD,
|
||||
PlayEmoSync,
|
||||
Predicated,
|
||||
PushDvalinS01Process,
|
||||
PushInterActionByConfigPath,
|
||||
PushPos,
|
||||
Randomed,
|
||||
ReTriggerAISkillInitialCD,
|
||||
RefreshUICombatBarLayout,
|
||||
RegisterAIActionPoint,
|
||||
ReleaseAIActionPoint,
|
||||
RemoveAvatarSkillInfo,
|
||||
RemoveModifier,
|
||||
RemoveModifierByAbilityStateResistanceID,
|
||||
RemoveServerBuff,
|
||||
RemoveUniqueModifier,
|
||||
RemoveVelocityForce,
|
||||
Repeated,
|
||||
ResetAIAttackTarget,
|
||||
ResetAIResistTauntLevel,
|
||||
ResetAIThreatBroadcastRange,
|
||||
ResetAnimatorTrigger,
|
||||
ReviveDeadAvatar,
|
||||
ReviveElemEnergy,
|
||||
ReviveStamina,
|
||||
SectorCityManeuver,
|
||||
SendEffectTrigger,
|
||||
SendEffectTriggerToLineEffect,
|
||||
SendEvtElectricCoreMoveEnterP1,
|
||||
SendEvtElectricCoreMoveInterrupt,
|
||||
ServerLuaCall,
|
||||
ServerLuaTriggerEvent,
|
||||
ServerMonsterLog,
|
||||
SetAIHitFeeling,
|
||||
SetAISkillCDAvailableNow,
|
||||
SetAISkillCDMultiplier,
|
||||
SetAISkillGCD,
|
||||
SetAnimatorBool,
|
||||
SetAnimatorFloat,
|
||||
SetAnimatorInt,
|
||||
SetAnimatorTrigger,
|
||||
SetAvatarCanShakeOff,
|
||||
SetAvatarHitBuckets,
|
||||
SetCanDieImmediately,
|
||||
SetChargeBarValue,
|
||||
SetDvalinS01FlyState,
|
||||
SetEmissionScaler,
|
||||
SetEntityScale,
|
||||
SetExtraAbilityEnable,
|
||||
SetExtraAbilityState,
|
||||
SetGlobalDir,
|
||||
SetGlobalPos,
|
||||
SetGlobalValue,
|
||||
SetGlobalValueByTargetDistance,
|
||||
SetGlobalValueToOverrideMap,
|
||||
SetKeepInAirVelocityForce,
|
||||
SetMaterialParamFloatByTransform,
|
||||
SetNeuronEnable,
|
||||
SetOverrideMapValue,
|
||||
SetPartControlTarget,
|
||||
SetPoseBool,
|
||||
SetPoseFloat,
|
||||
SetPoseInt,
|
||||
SetRandomOverrideMapValue,
|
||||
SetRegionalPlayVarValue,
|
||||
SetSelfAttackTarget,
|
||||
SetSkillAnchor,
|
||||
SetSpecialCamera,
|
||||
SetSurroundAnchor,
|
||||
SetSystemValueToOverrideMap,
|
||||
SetTargetNumToGlobalValue,
|
||||
SetUICombatBarAsh,
|
||||
SetUICombatBarSpark,
|
||||
SetVelocityIgnoreAirGY,
|
||||
SetWeaponAttachPointRealName,
|
||||
SetWeaponBindState,
|
||||
ShowExtraAbility,
|
||||
ShowProgressBarAction,
|
||||
ShowReminder,
|
||||
ShowScreenEffect,
|
||||
ShowTextMap,
|
||||
ShowUICombatBar,
|
||||
StartDither,
|
||||
SumTargetWeightToSelfGlobalValue,
|
||||
Summon,
|
||||
SyncToStageScript,
|
||||
TriggerAbility,
|
||||
TriggerAttackEvent,
|
||||
TriggerAttackTargetMapEvent,
|
||||
TriggerAudio,
|
||||
TriggerAuxWeaponTrans,
|
||||
TriggerBullet,
|
||||
TriggerCreateGadgetToEquipPart,
|
||||
TriggerDropEquipParts,
|
||||
TriggerFaceAnimation,
|
||||
TriggerGadgetInteractive,
|
||||
TriggerHideWeapon,
|
||||
TriggerSetCastShadow,
|
||||
TriggerSetPassThrough,
|
||||
TriggerSetRenderersEnable,
|
||||
TriggerSetShadowRamp,
|
||||
TriggerSetVisible,
|
||||
TriggerTaunt,
|
||||
TriggerThrowEquipPart,
|
||||
TriggerUGCGadgetMove,
|
||||
TryFindBlinkPoint,
|
||||
TryFindBlinkPointByBorn,
|
||||
TryTriggerPlatformStartMove,
|
||||
TurnDirection,
|
||||
TurnDirectionToPos,
|
||||
UpdateReactionDamage,
|
||||
UseSkillEliteSet,
|
||||
WidgetSkillStart
|
||||
}
|
||||
}
|
||||
|
||||
//The following should be implemented into DynamicFloat if older resource formats need to be supported
|
||||
// The following should be implemented into DynamicFloat if older resource formats need to be
|
||||
// supported
|
||||
// public static class AbilityModifierValue {
|
||||
// public boolean isFormula;
|
||||
// public boolean isDynamic;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package emu.grasscutter.data.binout;
|
||||
|
||||
import emu.grasscutter.data.binout.AbilityModifier.AbilityModifierAction;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
@@ -33,5 +32,4 @@ public class AbilityModifierEntry {
|
||||
public List<AbilityModifierAction> getOnRemoved() {
|
||||
return onRemoved;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -1,15 +1,13 @@
|
||||
package emu.grasscutter.data.binout;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ConfigGadget {
|
||||
// There are more values that can be added that might be useful in the json
|
||||
@Nullable
|
||||
ConfigGadgetCombat combat;
|
||||
@Nullable ConfigGadgetCombat combat;
|
||||
}
|
||||
|
||||
@@ -2,29 +2,33 @@ package emu.grasscutter.data.binout;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class HomeworldDefaultSaveData {
|
||||
|
||||
@SerializedName(value = "KFHBFNPDJBE", alternate = "PKACPHDGGEI")
|
||||
List<HomeBlock> homeBlockLists;
|
||||
|
||||
@SerializedName(value = "IJNPADKGNKE", alternate = "MINCKHBNING")
|
||||
Position bornPos;
|
||||
|
||||
@SerializedName("IPIIGEMFLHK")
|
||||
Position bornRot;
|
||||
|
||||
@SerializedName("HHOLBNPIHEM")
|
||||
Position djinPos;
|
||||
|
||||
@SerializedName("KNHCJKHCOAN")
|
||||
HomeFurniture mainhouse;
|
||||
|
||||
@SerializedName("NIHOJFEKFPG")
|
||||
List<HomeFurniture> doorLists;
|
||||
|
||||
@SerializedName("EPGELGEFJFK")
|
||||
List<HomeFurniture> stairLists;
|
||||
|
||||
@@ -48,9 +52,10 @@ public class HomeworldDefaultSaveData {
|
||||
|
||||
@SerializedName(value = "ENHNGKJBJAB", alternate = "KMAAJJHPNBA")
|
||||
int id;
|
||||
|
||||
@SerializedName(value = "NGIEEIOLPPO", alternate = "JFKAHNCPDME")
|
||||
Position pos;
|
||||
//@SerializedName(value = "HEOCEHKEBFM", alternate = "LKCKOOGFDBM")
|
||||
// @SerializedName(value = "HEOCEHKEBFM", alternate = "LKCKOOGFDBM")
|
||||
Position rot;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,10 +2,9 @@ package emu.grasscutter.data.binout;
|
||||
|
||||
import dev.morphia.annotations.Entity;
|
||||
import emu.grasscutter.game.quest.enums.QuestType;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.Data;
|
||||
|
||||
public class MainQuestData {
|
||||
private int id;
|
||||
@@ -63,15 +62,13 @@ public class MainQuestData {
|
||||
private int order;
|
||||
}
|
||||
|
||||
|
||||
@Data
|
||||
@Entity
|
||||
public static class TalkData {
|
||||
private int id;
|
||||
private String heroTalk;
|
||||
|
||||
public TalkData() {
|
||||
}
|
||||
public TalkData() {}
|
||||
|
||||
public TalkData(int id, String heroTalk) {
|
||||
this.id = id;
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
package emu.grasscutter.data.binout;
|
||||
|
||||
import emu.grasscutter.data.ResourceLoader.OpenConfigData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
|
||||
|
||||
@@ -3,13 +3,12 @@ package emu.grasscutter.data.binout;
|
||||
import com.github.davidmoten.rtreemulti.RTree;
|
||||
import com.github.davidmoten.rtreemulti.geometry.Geometry;
|
||||
import emu.grasscutter.scripts.data.SceneGroup;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
@@ -17,13 +16,9 @@ public class SceneNpcBornData {
|
||||
int sceneId;
|
||||
List<SceneNpcBornEntry> bornPosList;
|
||||
|
||||
/**
|
||||
* Spatial Index For NPC
|
||||
*/
|
||||
/** Spatial Index For NPC */
|
||||
transient RTree<SceneNpcBornEntry, Geometry> index;
|
||||
|
||||
/**
|
||||
* npc groups
|
||||
*/
|
||||
/** npc groups */
|
||||
transient Map<Integer, SceneGroup> groups = new ConcurrentHashMap<>();
|
||||
}
|
||||
|
||||
@@ -2,30 +2,41 @@ package emu.grasscutter.data.binout;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Data;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Data
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class SceneNpcBornEntry {
|
||||
@SerializedName(value = "id", alternate = {"_id", "ID"})
|
||||
@SerializedName(
|
||||
value = "id",
|
||||
alternate = {"_id", "ID"})
|
||||
int id;
|
||||
|
||||
@SerializedName(value = "configId", alternate = {"_configId"})
|
||||
@SerializedName(
|
||||
value = "configId",
|
||||
alternate = {"_configId"})
|
||||
int configId;
|
||||
|
||||
@SerializedName(value = "pos", alternate = {"_pos"})
|
||||
@SerializedName(
|
||||
value = "pos",
|
||||
alternate = {"_pos"})
|
||||
Position pos;
|
||||
|
||||
@SerializedName(value = "rot", alternate = {"_rot"})
|
||||
@SerializedName(
|
||||
value = "rot",
|
||||
alternate = {"_rot"})
|
||||
Position rot;
|
||||
|
||||
@SerializedName(value = "groupId", alternate = {"_groupId"})
|
||||
@SerializedName(
|
||||
value = "groupId",
|
||||
alternate = {"_groupId"})
|
||||
int groupId;
|
||||
|
||||
@SerializedName(value = "suiteIdList", alternate = {"_suiteIdList"})
|
||||
@SerializedName(
|
||||
value = "suiteIdList",
|
||||
alternate = {"_suiteIdList"})
|
||||
List<Integer> suiteIdList;
|
||||
}
|
||||
|
||||
@@ -4,10 +4,8 @@ import emu.grasscutter.data.common.PointData;
|
||||
import lombok.Getter;
|
||||
|
||||
public class ScenePointEntry {
|
||||
@Getter
|
||||
final private int sceneId;
|
||||
@Getter
|
||||
final private PointData pointData;
|
||||
@Getter private final int sceneId;
|
||||
@Getter private final PointData pointData;
|
||||
|
||||
@Deprecated(forRemoval = true)
|
||||
public ScenePointEntry(String name, PointData pointData) {
|
||||
|
||||
@@ -1,10 +1,9 @@
|
||||
package emu.grasscutter.data.binout;
|
||||
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
import lombok.Data;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ScriptSceneData {
|
||||
@@ -12,10 +11,8 @@ public class ScriptSceneData {
|
||||
|
||||
@Data
|
||||
public static class ScriptObject {
|
||||
//private SceneGroup groups;
|
||||
// private SceneGroup groups;
|
||||
@SerializedName("dummy_points")
|
||||
private Map<String, List<Float>> dummyPoints;
|
||||
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,16 +3,16 @@ package emu.grasscutter.data.common;
|
||||
import it.unimi.dsi.fastutil.floats.FloatArrayList;
|
||||
import it.unimi.dsi.fastutil.objects.Object2FloatArrayMap;
|
||||
import it.unimi.dsi.fastutil.objects.Object2FloatMap;
|
||||
import lombok.val;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import lombok.val;
|
||||
|
||||
public class DynamicFloat {
|
||||
public static DynamicFloat ZERO = new DynamicFloat(0f);
|
||||
private List<StackOp> ops;
|
||||
private boolean dynamic = false;
|
||||
private float constant = 0f;
|
||||
|
||||
public DynamicFloat(float constant) {
|
||||
this.constant = constant;
|
||||
}
|
||||
@@ -43,8 +43,7 @@ public class DynamicFloat {
|
||||
}
|
||||
|
||||
public float get(Object2FloatMap<String> props) {
|
||||
if (!dynamic)
|
||||
return constant;
|
||||
if (!dynamic) return constant;
|
||||
|
||||
val fl = new FloatArrayList();
|
||||
for (var op : this.ops) {
|
||||
@@ -52,15 +51,15 @@ public class DynamicFloat {
|
||||
case CONSTANT -> fl.push(op.fValue);
|
||||
case KEY -> fl.push(props.getOrDefault(op.sValue, 0f));
|
||||
case ADD -> fl.push(fl.popFloat() + fl.popFloat());
|
||||
case SUB ->
|
||||
fl.push(-fl.popFloat() + fl.popFloat()); // [f0, f1, f2] -> [f0, f1-f2] (opposite of RPN order)
|
||||
case SUB -> fl.push(
|
||||
-fl.popFloat() + fl.popFloat()); // [f0, f1, f2] -> [f0, f1-f2] (opposite of RPN order)
|
||||
case MUL -> fl.push(fl.popFloat() * fl.popFloat());
|
||||
case DIV -> fl.push((1f / fl.popFloat()) * fl.popFloat()); // [f0, f1, f2] -> [f0, f1/f2]
|
||||
case DIV -> fl.push((1f / fl.popFloat()) * fl.popFloat()); // [f0, f1, f2] -> [f0, f1/f2]
|
||||
case NEXBOOLEAN -> fl.push(props.getOrDefault(Optional.of(op.bValue), 0f));
|
||||
}
|
||||
}
|
||||
|
||||
return fl.popFloat(); // well-formed data will always have only one value left at this point
|
||||
return fl.popFloat(); // well-formed data will always have only one value left at this point
|
||||
}
|
||||
|
||||
public static class StackOp {
|
||||
@@ -69,6 +68,7 @@ public class DynamicFloat {
|
||||
public float fValue;
|
||||
public String sValue;
|
||||
public boolean bValue;
|
||||
|
||||
public StackOp(String s) {
|
||||
switch (s.toUpperCase()) {
|
||||
case "ADD" -> this.op = Op.ADD;
|
||||
@@ -92,6 +92,14 @@ public class DynamicFloat {
|
||||
this.fValue = f;
|
||||
}
|
||||
|
||||
enum Op {CONSTANT, KEY, ADD, SUB, MUL, DIV, NEXBOOLEAN}
|
||||
enum Op {
|
||||
CONSTANT,
|
||||
KEY,
|
||||
ADD,
|
||||
SUB,
|
||||
MUL,
|
||||
DIV,
|
||||
NEXBOOLEAN
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,14 +4,17 @@ import com.google.gson.annotations.SerializedName;
|
||||
|
||||
// Used in excels
|
||||
public class ItemParamData {
|
||||
@SerializedName(value = "id", alternate = {"itemId"})
|
||||
@SerializedName(
|
||||
value = "id",
|
||||
alternate = {"itemId"})
|
||||
private int id;
|
||||
|
||||
@SerializedName(value = "count", alternate = {"itemCount"})
|
||||
@SerializedName(
|
||||
value = "count",
|
||||
alternate = {"itemCount"})
|
||||
private int count;
|
||||
|
||||
public ItemParamData() {
|
||||
}
|
||||
public ItemParamData() {}
|
||||
|
||||
public ItemParamData(int id, int count) {
|
||||
this.id = id;
|
||||
|
||||
@@ -4,8 +4,7 @@ public class ItemParamStringData {
|
||||
private int id;
|
||||
private String count;
|
||||
|
||||
public ItemParamStringData() {
|
||||
}
|
||||
public ItemParamStringData() {}
|
||||
|
||||
public int getId() {
|
||||
return id;
|
||||
|
||||
@@ -11,22 +11,25 @@ import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
|
||||
public class PointData {
|
||||
@Getter
|
||||
@Setter
|
||||
private int id;
|
||||
@Getter @Setter private int id;
|
||||
private String $type;
|
||||
@Getter
|
||||
private Position tranPos;
|
||||
@Getter private Position tranPos;
|
||||
|
||||
@SerializedName(value = "dungeonIds", alternate = {"JHHFPGJNMIN"})
|
||||
@SerializedName(
|
||||
value = "dungeonIds",
|
||||
alternate = {"JHHFPGJNMIN"})
|
||||
@Getter
|
||||
private int[] dungeonIds;
|
||||
|
||||
@SerializedName(value = "dungeonRandomList", alternate = {"OIBKFJNBLHO"})
|
||||
@SerializedName(
|
||||
value = "dungeonRandomList",
|
||||
alternate = {"OIBKFJNBLHO"})
|
||||
@Getter
|
||||
private int[] dungeonRandomList;
|
||||
|
||||
@SerializedName(value = "tranSceneId", alternate = {"JHBICGBAPIH"})
|
||||
@SerializedName(
|
||||
value = "tranSceneId",
|
||||
alternate = {"JHBICGBAPIH"})
|
||||
@Getter
|
||||
@Setter
|
||||
private int tranSceneId;
|
||||
|
||||
@@ -11,5 +11,4 @@ public class PropGrowCurve {
|
||||
public String getGrowCurve() {
|
||||
return this.growCurve;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -4,13 +4,12 @@ import com.github.davidmoten.guavamini.Lists;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicBoolean;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Getter;
|
||||
|
||||
@Getter
|
||||
@ResourceType(name = "AchievementExcelConfigData.json")
|
||||
@@ -71,7 +70,9 @@ public class AchievementData extends GameResource {
|
||||
}
|
||||
}
|
||||
|
||||
map.values().stream().filter(a -> !a.hasGroupAchievements() && a.isUsed()).forEach(a -> a.isParent = true);
|
||||
map.values().stream()
|
||||
.filter(a -> !a.hasGroupAchievements() && a.isUsed())
|
||||
.forEach(a -> a.isParent = true);
|
||||
}
|
||||
|
||||
public boolean hasPreStageAchievement() {
|
||||
@@ -91,6 +92,8 @@ public class AchievementData extends GameResource {
|
||||
}
|
||||
|
||||
public Set<Integer> getExcludedGroupAchievementIdList() {
|
||||
return this.groupAchievementIdList.stream().filter(integer -> integer != this.getId()).collect(Collectors.toUnmodifiableSet());
|
||||
return this.groupAchievementIdList.stream()
|
||||
.filter(integer -> integer != this.getId())
|
||||
.collect(Collectors.toUnmodifiableSet());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,14 +3,15 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Objects;
|
||||
|
||||
@ResourceType(name = "NewActivityExcelConfigData.json", loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@ResourceType(
|
||||
name = "NewActivityExcelConfigData.json",
|
||||
loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityData extends GameResource {
|
||||
@@ -27,9 +28,10 @@ public class ActivityData extends GameResource {
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.watcherDataList = watcherId.stream().map(item -> GameData.getActivityWatcherDataMap().get(item.intValue()))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
this.watcherDataList =
|
||||
watcherId.stream()
|
||||
.map(item -> GameData.getActivityWatcherDataMap().get(item.intValue()))
|
||||
.filter(Objects::nonNull)
|
||||
.toList();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,19 +3,14 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.shop.ShopType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "ActivityShopOverallExcelConfigData.json")
|
||||
public class ActivityShopData extends GameResource {
|
||||
@Getter
|
||||
private int scheduleId;
|
||||
@Getter
|
||||
private ShopType shopType;
|
||||
@Getter
|
||||
private List<Integer> sheetList;
|
||||
|
||||
@Getter private int scheduleId;
|
||||
@Getter private ShopType shopType;
|
||||
@Getter private List<Integer> sheetList;
|
||||
|
||||
@Override
|
||||
public int getId() {
|
||||
@@ -23,8 +18,7 @@ public class ActivityShopData extends GameResource {
|
||||
}
|
||||
|
||||
public int getShopTypeId() {
|
||||
if (this.shopType == null)
|
||||
this.shopType = ShopType.SHOP_TYPE_NONE;
|
||||
if (this.shopType == null) this.shopType = ShopType.SHOP_TYPE_NONE;
|
||||
return shopType.shopTypeId;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,25 +3,28 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "NewActivityWatcherConfigData.json", loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
@ResourceType(
|
||||
name = "NewActivityWatcherConfigData.json",
|
||||
loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
@Getter
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ActivityWatcherData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
int id;
|
||||
|
||||
int rewardID;
|
||||
int progress;
|
||||
WatcherTrigger triggerConfig;
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
triggerConfig.paramList = triggerConfig.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
|
||||
triggerConfig.paramList =
|
||||
triggerConfig.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
|
||||
triggerConfig.watcherTriggerType = WatcherTriggerType.getTypeByName(triggerConfig.triggerType);
|
||||
}
|
||||
|
||||
@@ -33,5 +36,4 @@ public class ActivityWatcherData extends GameResource {
|
||||
|
||||
transient WatcherTriggerType watcherTriggerType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ import emu.grasscutter.data.ResourceType;
|
||||
public class AvatarCostumeData extends GameResource {
|
||||
@SerializedName(value = "skinId", alternate = "costumeId")
|
||||
private int skinId;
|
||||
|
||||
private int itemId;
|
||||
private int characterId;
|
||||
private int quality;
|
||||
|
||||
@@ -3,7 +3,6 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.CurveInfo;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Stream;
|
||||
@@ -31,6 +30,7 @@ public class AvatarCurveData extends GameResource {
|
||||
@Override
|
||||
public void onLoad() {
|
||||
this.curveInfoMap = new HashMap<>();
|
||||
Stream.of(this.curveInfos).forEach(info -> this.curveInfoMap.put(info.getType(), info.getValue()));
|
||||
Stream.of(this.curveInfos)
|
||||
.forEach(info -> this.curveInfoMap.put(info.getType(), info.getValue()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,7 +18,5 @@ public class AvatarFlycloakData extends GameResource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
|
||||
}
|
||||
public void onLoad() {}
|
||||
}
|
||||
|
||||
@@ -4,7 +4,6 @@ import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.FightPropData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ResourceType(name = "AvatarPromoteExcelConfigData.json")
|
||||
|
||||
@@ -11,6 +11,7 @@ import lombok.Getter;
|
||||
public class AvatarSkillData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private float cdTime;
|
||||
private int costElemVal;
|
||||
private int maxChargeNum;
|
||||
|
||||
@@ -11,17 +11,17 @@ import emu.grasscutter.game.props.ElementType;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.IntArrayList;
|
||||
import it.unimi.dsi.fastutil.ints.IntList;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.stream.IntStream;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "AvatarSkillDepotExcelConfigData.json", loadPriority = LoadPriority.HIGH)
|
||||
@Getter
|
||||
public class AvatarSkillDepotData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int energySkill;
|
||||
private int attackModeSkill;
|
||||
|
||||
@@ -61,21 +61,24 @@ public class AvatarSkillDepotData extends GameResource {
|
||||
AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup());
|
||||
|
||||
if (config != null) {
|
||||
this.setAbilities(new AbilityEmbryoEntry(getSkillDepotAbilityGroup(), config.abilities.stream().map(Object::toString).toArray(String[]::new)));
|
||||
this.setAbilities(
|
||||
new AbilityEmbryoEntry(
|
||||
getSkillDepotAbilityGroup(),
|
||||
config.abilities.stream().map(Object::toString).toArray(String[]::new)));
|
||||
}
|
||||
}
|
||||
|
||||
// Get constellation item from GameData
|
||||
Optional.ofNullable(this.talents)
|
||||
.map(talents -> talents.get(0))
|
||||
.map(i -> GameData.getAvatarTalentDataMap().get((int) i))
|
||||
.map(talentData -> talentData.getMainCostItemId())
|
||||
.ifPresent(itemId -> this.talentCostItemId = itemId);
|
||||
.map(talents -> talents.get(0))
|
||||
.map(i -> GameData.getAvatarTalentDataMap().get((int) i))
|
||||
.map(talentData -> talentData.getMainCostItemId())
|
||||
.ifPresent(itemId -> this.talentCostItemId = itemId);
|
||||
}
|
||||
|
||||
public IntStream getSkillsAndEnergySkill() {
|
||||
return IntStream.concat(this.skills.stream().mapToInt(i -> i), IntStream.of(this.energySkill))
|
||||
.filter(skillId -> skillId > 0);
|
||||
.filter(skillId -> skillId > 0);
|
||||
}
|
||||
|
||||
@Getter
|
||||
|
||||
@@ -4,7 +4,6 @@ import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.data.common.FightPropData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ResourceType(name = "AvatarTalentExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
|
||||
|
||||
@@ -5,17 +5,17 @@ import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.game.props.BattlePassMissionRefreshType;
|
||||
import emu.grasscutter.game.props.WatcherTriggerType;
|
||||
import emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.MissionStatus;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Set;
|
||||
import java.util.stream.Collectors;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = {"BattlePassMissionExcelConfigData.json"})
|
||||
@Getter
|
||||
public class BattlePassMissionData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int addPoint;
|
||||
private int scheduleId;
|
||||
private int progress;
|
||||
@@ -29,13 +29,16 @@ public class BattlePassMissionData extends GameResource {
|
||||
}
|
||||
|
||||
public boolean isCycleRefresh() {
|
||||
return getRefreshType() == null || getRefreshType() == BattlePassMissionRefreshType.BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE;
|
||||
return getRefreshType() == null
|
||||
|| getRefreshType()
|
||||
== BattlePassMissionRefreshType.BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE;
|
||||
}
|
||||
|
||||
public boolean isValidRefreshType() {
|
||||
return getRefreshType() == null ||
|
||||
getRefreshType() == BattlePassMissionRefreshType.BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE ||
|
||||
getScheduleId() == 2701;
|
||||
return getRefreshType() == null
|
||||
|| getRefreshType()
|
||||
== BattlePassMissionRefreshType.BATTLE_PASS_MISSION_REFRESH_CYCLE_CROSS_SCHEDULE
|
||||
|| getScheduleId() == 2701;
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -43,20 +46,22 @@ public class BattlePassMissionData extends GameResource {
|
||||
if (this.getTriggerConfig() != null) {
|
||||
var params = getTriggerConfig().getParamList()[0];
|
||||
if ((params != null) && !params.isEmpty()) {
|
||||
this.mainParams = Arrays.stream(params.split("[:;,]")).map(Integer::parseInt).collect(Collectors.toSet());
|
||||
this.mainParams =
|
||||
Arrays.stream(params.split("[:;,]")).map(Integer::parseInt).collect(Collectors.toSet());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission toProto() {
|
||||
var protoBuilder = emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.newBuilder();
|
||||
var protoBuilder =
|
||||
emu.grasscutter.net.proto.BattlePassMissionOuterClass.BattlePassMission.newBuilder();
|
||||
|
||||
protoBuilder
|
||||
.setMissionId(getId())
|
||||
.setTotalProgress(this.getProgress())
|
||||
.setRewardBattlePassPoint(this.getAddPoint())
|
||||
.setMissionStatus(MissionStatus.MISSION_STATUS_UNFINISHED)
|
||||
.setMissionType(this.getRefreshType() == null ? 0 : this.getRefreshType().getValue());
|
||||
.setMissionId(getId())
|
||||
.setTotalProgress(this.getProgress())
|
||||
.setRewardBattlePassPoint(this.getAddPoint())
|
||||
.setMissionStatus(MissionStatus.MISSION_STATUS_UNFINISHED)
|
||||
.setMissionType(this.getRefreshType() == null ? 0 : this.getRefreshType().getValue());
|
||||
|
||||
return protoBuilder.build();
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@ package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "BattlePassRewardExcelConfigData.json")
|
||||
@Getter
|
||||
@@ -22,6 +21,5 @@ public class BattlePassRewardData extends GameResource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
}
|
||||
public void onLoad() {}
|
||||
}
|
||||
|
||||
@@ -2,9 +2,8 @@ package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "BlossomRefreshExcelConfigData.json")
|
||||
@Getter
|
||||
@@ -15,16 +14,18 @@ public class BlossomRefreshExcelConfigData extends GameResource {
|
||||
private long nameTextMapHash;
|
||||
private long descTextMapHash;
|
||||
private String icon;
|
||||
private String clientShowType; // BLOSSOM_SHOWTYPE_CHALLENGE, BLOSSOM_SHOWTYPE_NPCTALK
|
||||
private String clientShowType; // BLOSSOM_SHOWTYPE_CHALLENGE, BLOSSOM_SHOWTYPE_NPCTALK
|
||||
|
||||
// Refresh details
|
||||
private String refreshType; // Leyline blossoms, magical ore outcrops
|
||||
private int refreshCount; // Number of entries to spawn at refresh (1 for each leyline type for each city, 4 for magical ore for each city)
|
||||
private String refreshTime; // Server time-of-day to refresh at
|
||||
private RefreshCond[] refreshCondVec; // AR requirements etc.
|
||||
private String refreshType; // Leyline blossoms, magical ore outcrops
|
||||
private int
|
||||
refreshCount; // Number of entries to spawn at refresh (1 for each leyline type for each city,
|
||||
// 4 for magical ore for each city)
|
||||
private String refreshTime; // Server time-of-day to refresh at
|
||||
private RefreshCond[] refreshCondVec; // AR requirements etc.
|
||||
|
||||
private int cityId;
|
||||
private int blossomChestId; // 1 for mora, 2 for exp
|
||||
private int blossomChestId; // 1 for mora, 2 for exp
|
||||
private Drop[] dropVec;
|
||||
|
||||
// Unknown details
|
||||
|
||||
@@ -22,6 +22,7 @@ public class BuffData extends GameResource {
|
||||
}
|
||||
|
||||
public void onLoad() {
|
||||
this.serverBuffType = this.serverBuffType != null ? this.serverBuffType : ServerBuffType.SERVER_BUFF_NONE;
|
||||
this.serverBuffType =
|
||||
this.serverBuffType != null ? this.serverBuffType : ServerBuffType.SERVER_BUFF_NONE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,24 +2,25 @@ package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
@ResourceType(name = "ChapterExcelConfigData.json")
|
||||
@Getter
|
||||
@Setter // TODO: remove on next API break
|
||||
@Setter // TODO: remove on next API break
|
||||
@FieldDefaults(level = AccessLevel.PRIVATE)
|
||||
public class ChapterData extends GameResource {
|
||||
// Why public? TODO: privatise next API break
|
||||
public static final Map<Integer, ChapterData> beginQuestChapterMap = new HashMap<>();
|
||||
public static final Map<Integer, ChapterData> endQuestChapterMap = new HashMap<>();
|
||||
|
||||
@Getter(onMethod_ = @Override)
|
||||
int id;
|
||||
|
||||
int beginQuestId;
|
||||
int endQuestId;
|
||||
int needPlayerLevel;
|
||||
|
||||
@@ -2,13 +2,12 @@ package emu.grasscutter.data.excels;
|
||||
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import java.util.List;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import lombok.experimental.FieldDefaults;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "CityConfigData.json", loadPriority = ResourceType.LoadPriority.HIGH)
|
||||
@Getter
|
||||
@Setter
|
||||
|
||||
@@ -10,10 +10,14 @@ import lombok.Getter;
|
||||
public class CodexAnimalData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int Id;
|
||||
|
||||
private String type;
|
||||
private int describeId;
|
||||
private int sortOrder;
|
||||
@SerializedName(value = "countType", alternate = {"OCCLHPBCDGL"})
|
||||
|
||||
@SerializedName(
|
||||
value = "countType",
|
||||
alternate = {"OCCLHPBCDGL"})
|
||||
private CountType countType;
|
||||
|
||||
public enum CountType {
|
||||
|
||||
@@ -9,24 +9,15 @@ import lombok.Getter;
|
||||
|
||||
@ResourceType(name = {"ReliquaryCodexExcelConfigData.json"})
|
||||
public class CodexReliquaryData extends GameResource {
|
||||
@Getter
|
||||
private int Id;
|
||||
@Getter
|
||||
private int suitId;
|
||||
@Getter
|
||||
private int level;
|
||||
@Getter
|
||||
private int cupId;
|
||||
@Getter
|
||||
private int leatherId;
|
||||
@Getter
|
||||
private int capId;
|
||||
@Getter
|
||||
private int flowerId;
|
||||
@Getter
|
||||
private int sandId;
|
||||
@Getter
|
||||
private int sortOrder;
|
||||
@Getter private int Id;
|
||||
@Getter private int suitId;
|
||||
@Getter private int level;
|
||||
@Getter private int cupId;
|
||||
@Getter private int leatherId;
|
||||
@Getter private int capId;
|
||||
@Getter private int flowerId;
|
||||
@Getter private int sandId;
|
||||
@Getter private int sortOrder;
|
||||
private transient IntCollection ids;
|
||||
|
||||
public boolean containsId(int id) {
|
||||
|
||||
@@ -3,7 +3,6 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
@@ -31,8 +30,10 @@ public class CombineData extends GameResource {
|
||||
public void onLoad() {
|
||||
super.onLoad();
|
||||
// clean data
|
||||
randomItems = randomItems.stream().filter(item -> item.getId() > 0).collect(Collectors.toList());
|
||||
materialItems = materialItems.stream().filter(item -> item.getId() > 0).collect(Collectors.toList());
|
||||
randomItems =
|
||||
randomItems.stream().filter(item -> item.getId() > 0).collect(Collectors.toList());
|
||||
materialItems =
|
||||
materialItems.stream().filter(item -> item.getId() > 0).collect(Collectors.toList());
|
||||
}
|
||||
|
||||
public int getCombineId() {
|
||||
@@ -78,5 +79,4 @@ public class CombineData extends GameResource {
|
||||
public String getRecipeType() {
|
||||
return recipeType;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -3,15 +3,17 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = {"CompoundExcelConfigData.json"}, loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@ResourceType(
|
||||
name = {"CompoundExcelConfigData.json"},
|
||||
loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@Getter
|
||||
public class CompoundData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int groupID;
|
||||
private int rankLevel;
|
||||
private boolean isDefaultUnlocked;
|
||||
|
||||
@@ -4,7 +4,9 @@ import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
|
||||
@ResourceType(name = {"CookBonusExcelConfigData.json"}, loadPriority = LoadPriority.LOW)
|
||||
@ResourceType(
|
||||
name = {"CookBonusExcelConfigData.json"},
|
||||
loadPriority = LoadPriority.LOW)
|
||||
public class CookBonusData extends GameResource {
|
||||
private int avatarId;
|
||||
private int recipeId;
|
||||
@@ -37,6 +39,5 @@ public class CookBonusData extends GameResource {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onLoad() {
|
||||
}
|
||||
public void onLoad() {}
|
||||
}
|
||||
|
||||
@@ -4,11 +4,12 @@ import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.ResourceType.LoadPriority;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import java.util.List;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = {"CookRecipeExcelConfigData.json"}, loadPriority = LoadPriority.LOW)
|
||||
@ResourceType(
|
||||
name = {"CookRecipeExcelConfigData.json"},
|
||||
loadPriority = LoadPriority.LOW)
|
||||
@Getter
|
||||
public class CookRecipeData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
|
||||
@@ -4,16 +4,17 @@ import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
|
||||
import lombok.Getter;
|
||||
|
||||
import java.util.Calendar;
|
||||
import lombok.Getter;
|
||||
|
||||
@ResourceType(name = "DailyDungeonConfigData.json")
|
||||
public class DailyDungeonData extends GameResource {
|
||||
private static final int[] empty = new int[0];
|
||||
private final Int2ObjectMap<int[]> map;
|
||||
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int[] monday;
|
||||
private int[] tuesday;
|
||||
private int[] wednesday;
|
||||
|
||||
@@ -9,19 +9,16 @@ import lombok.Getter;
|
||||
public class DungeonData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
@Getter
|
||||
private int sceneId;
|
||||
@Getter
|
||||
private int showLevel;
|
||||
|
||||
@Getter private int sceneId;
|
||||
@Getter private int showLevel;
|
||||
private int passRewardPreviewID;
|
||||
private String involveType; // TODO enum
|
||||
|
||||
private RewardPreviewData previewData;
|
||||
|
||||
@Getter
|
||||
private int statueCostID;
|
||||
@Getter
|
||||
private int statueCostCount;
|
||||
@Getter private int statueCostID;
|
||||
@Getter private int statueCostCount;
|
||||
|
||||
public RewardPreviewData getRewardPreview() {
|
||||
return previewData;
|
||||
|
||||
@@ -7,10 +7,11 @@ import lombok.Setter;
|
||||
|
||||
@ResourceType(name = "DungeonEntryExcelConfigData.json")
|
||||
@Getter
|
||||
@Setter // TODO: remove this next API break
|
||||
@Setter // TODO: remove this next API break
|
||||
public class DungeonEntryData extends GameResource {
|
||||
@Getter(onMethod_ = @Override)
|
||||
private int id;
|
||||
|
||||
private int dungeonEntryId;
|
||||
private int sceneId;
|
||||
}
|
||||
|
||||
@@ -3,10 +3,11 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@ResourceType(name = "EnvAnimalGatherExcelConfigData.json", loadPriority = ResourceType.LoadPriority.LOW)
|
||||
@ResourceType(
|
||||
name = "EnvAnimalGatherExcelConfigData.json",
|
||||
loadPriority = ResourceType.LoadPriority.LOW)
|
||||
public class EnvAnimalGatherConfigData extends GameResource {
|
||||
private int animalId;
|
||||
private String entityType;
|
||||
|
||||
@@ -3,7 +3,6 @@ package emu.grasscutter.data.excels;
|
||||
import emu.grasscutter.data.GameResource;
|
||||
import emu.grasscutter.data.ResourceType;
|
||||
import emu.grasscutter.data.common.FightPropData;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
@ResourceType(name = "EquipAffixExcelConfigData.json")
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user