Fix player fields not being set

line seps r weird
This commit is contained in:
KingRainbow44 2023-04-10 22:46:19 -04:00
parent 5e56b5e3a8
commit 06cbae31fa
No known key found for this signature in database
GPG Key ID: FC2CB64B00D257BE
453 changed files with 63228 additions and 63071 deletions

View File

@ -1,135 +1,135 @@
// Generated by the protocol buffer compiler. DO NOT EDIT! // Generated by the protocol buffer compiler. DO NOT EDIT!
// source: UgcType.proto // source: UgcType.proto
package emu.grasscutter.net.proto; package emu.grasscutter.net.proto;
public final class UgcTypeOuterClass { public final class UgcTypeOuterClass {
private UgcTypeOuterClass() {} private UgcTypeOuterClass() {}
public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {} public static void registerAllExtensions(com.google.protobuf.ExtensionRegistryLite registry) {}
public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) { public static void registerAllExtensions(com.google.protobuf.ExtensionRegistry registry) {
registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry); registerAllExtensions((com.google.protobuf.ExtensionRegistryLite) registry);
} }
/** /**
* *
* *
* <pre> * <pre>
* 3.2 * 3.2
* </pre> * </pre>
* *
* Protobuf enum {@code UgcType} * Protobuf enum {@code UgcType}
*/ */
public enum UgcType implements com.google.protobuf.ProtocolMessageEnum { public enum UgcType implements com.google.protobuf.ProtocolMessageEnum {
/** <code>UGC_TYPE_NONE = 0;</code> */ /** <code>UGC_TYPE_NONE = 0;</code> */
UGC_TYPE_NONE(0), UGC_TYPE_NONE(0),
/** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */ /** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */
UGC_TYPE_MUSIC_GAME(1), UGC_TYPE_MUSIC_GAME(1),
UNRECOGNIZED(-1), UNRECOGNIZED(-1),
; ;
/** <code>UGC_TYPE_NONE = 0;</code> */ /** <code>UGC_TYPE_NONE = 0;</code> */
public static final int UGC_TYPE_NONE_VALUE = 0; public static final int UGC_TYPE_NONE_VALUE = 0;
/** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */ /** <code>UGC_TYPE_MUSIC_GAME = 1;</code> */
public static final int UGC_TYPE_MUSIC_GAME_VALUE = 1; public static final int UGC_TYPE_MUSIC_GAME_VALUE = 1;
public final int getNumber() { public final int getNumber() {
if (this == UNRECOGNIZED) { if (this == UNRECOGNIZED) {
throw new java.lang.IllegalArgumentException( throw new java.lang.IllegalArgumentException(
"Can't get the number of an unknown enum value."); "Can't get the number of an unknown enum value.");
} }
return value; return value;
} }
/** /**
* @param value The numeric wire value of the corresponding enum entry. * @param value The numeric wire value of the corresponding enum entry.
* @return The enum associated with the given numeric wire value. * @return The enum associated with the given numeric wire value.
* @deprecated Use {@link #forNumber(int)} instead. * @deprecated Use {@link #forNumber(int)} instead.
*/ */
@java.lang.Deprecated @java.lang.Deprecated
public static UgcType valueOf(int value) { public static UgcType valueOf(int value) {
return forNumber(value); return forNumber(value);
} }
/** /**
* @param value The numeric wire value of the corresponding enum entry. * @param value The numeric wire value of the corresponding enum entry.
* @return The enum associated with the given numeric wire value. * @return The enum associated with the given numeric wire value.
*/ */
public static UgcType forNumber(int value) { public static UgcType forNumber(int value) {
switch (value) { switch (value) {
case 0: case 0:
return UGC_TYPE_NONE; return UGC_TYPE_NONE;
case 1: case 1:
return UGC_TYPE_MUSIC_GAME; return UGC_TYPE_MUSIC_GAME;
default: default:
return null; return null;
} }
} }
public static com.google.protobuf.Internal.EnumLiteMap<UgcType> internalGetValueMap() { public static com.google.protobuf.Internal.EnumLiteMap<UgcType> internalGetValueMap() {
return internalValueMap; return internalValueMap;
} }
private static final com.google.protobuf.Internal.EnumLiteMap<UgcType> internalValueMap = private static final com.google.protobuf.Internal.EnumLiteMap<UgcType> internalValueMap =
new com.google.protobuf.Internal.EnumLiteMap<UgcType>() { new com.google.protobuf.Internal.EnumLiteMap<UgcType>() {
public UgcType findValueByNumber(int number) { public UgcType findValueByNumber(int number) {
return UgcType.forNumber(number); return UgcType.forNumber(number);
} }
}; };
public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() { public final com.google.protobuf.Descriptors.EnumValueDescriptor getValueDescriptor() {
if (this == UNRECOGNIZED) { if (this == UNRECOGNIZED) {
throw new java.lang.IllegalStateException( throw new java.lang.IllegalStateException(
"Can't get the descriptor of an unrecognized enum value."); "Can't get the descriptor of an unrecognized enum value.");
} }
return getDescriptor().getValues().get(ordinal()); return getDescriptor().getValues().get(ordinal());
} }
public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() { public final com.google.protobuf.Descriptors.EnumDescriptor getDescriptorForType() {
return getDescriptor(); return getDescriptor();
} }
public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() { public static final com.google.protobuf.Descriptors.EnumDescriptor getDescriptor() {
return emu.grasscutter.net.proto.UgcTypeOuterClass.getDescriptor().getEnumTypes().get(0); return emu.grasscutter.net.proto.UgcTypeOuterClass.getDescriptor().getEnumTypes().get(0);
} }
private static final UgcType[] VALUES = values(); private static final UgcType[] VALUES = values();
public static UgcType valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) { public static UgcType valueOf(com.google.protobuf.Descriptors.EnumValueDescriptor desc) {
if (desc.getType() != getDescriptor()) { if (desc.getType() != getDescriptor()) {
throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type."); throw new java.lang.IllegalArgumentException("EnumValueDescriptor is not for this type.");
} }
if (desc.getIndex() == -1) { if (desc.getIndex() == -1) {
return UNRECOGNIZED; return UNRECOGNIZED;
} }
return VALUES[desc.getIndex()]; return VALUES[desc.getIndex()];
} }
private final int value; private final int value;
private UgcType(int value) { private UgcType(int value) {
this.value = value; this.value = value;
} }
// @@protoc_insertion_point(enum_scope:UgcType) // @@protoc_insertion_point(enum_scope:UgcType)
} }
public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() { public static com.google.protobuf.Descriptors.FileDescriptor getDescriptor() {
return descriptor; return descriptor;
} }
private static com.google.protobuf.Descriptors.FileDescriptor descriptor; private static com.google.protobuf.Descriptors.FileDescriptor descriptor;
static { static {
java.lang.String[] descriptorData = { java.lang.String[] descriptorData = {
"\n\rUgcType.proto*5\n\007UgcType\022\021\n\rUGC_TYPE_N" "\n\rUgcType.proto*5\n\007UgcType\022\021\n\rUGC_TYPE_N"
+ "ONE\020\000\022\027\n\023UGC_TYPE_MUSIC_GAME\020\001B\033\n\031emu.gr" + "ONE\020\000\022\027\n\023UGC_TYPE_MUSIC_GAME\020\001B\033\n\031emu.gr"
+ "asscutter.net.protob\006proto3" + "asscutter.net.protob\006proto3"
}; };
descriptor = descriptor =
com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom( com.google.protobuf.Descriptors.FileDescriptor.internalBuildGeneratedFileFrom(
descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {}); descriptorData, new com.google.protobuf.Descriptors.FileDescriptor[] {});
} }
// @@protoc_insertion_point(outer_class_scope) // @@protoc_insertion_point(outer_class_scope)
} }

View File

@ -1,35 +1,35 @@
package emu.grasscutter; package emu.grasscutter;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import java.util.Arrays; import java.util.Arrays;
public final class GameConstants { public final class GameConstants {
public static final int DEFAULT_TEAMS = 4; public static final int DEFAULT_TEAMS = 4;
public static final int MAX_TEAMS = 10; public static final int MAX_TEAMS = 10;
public static final int MAIN_CHARACTER_MALE = 10000005; public static final int MAIN_CHARACTER_MALE = 10000005;
public static final int MAIN_CHARACTER_FEMALE = 10000007; public static final int MAIN_CHARACTER_FEMALE = 10000007;
public static final Position START_POSITION = new Position(2747, 194, -1719); public static final Position START_POSITION = new Position(2747, 194, -1719);
public static final int MAX_FRIENDS = 60; public static final int MAX_FRIENDS = 60;
public static final int MAX_FRIEND_REQUESTS = 50; public static final int MAX_FRIEND_REQUESTS = 50;
public static final int SERVER_CONSOLE_UID = 99; // The UID of the server console's "player". public static final int SERVER_CONSOLE_UID = 99; // The UID of the server console's "player".
public static final int BATTLE_PASS_MAX_LEVEL = 50; public static final int BATTLE_PASS_MAX_LEVEL = 50;
public static final int BATTLE_PASS_POINT_PER_LEVEL = 1000; public static final int BATTLE_PASS_POINT_PER_LEVEL = 1000;
public static final int BATTLE_PASS_POINT_PER_WEEK = 10000; public static final int BATTLE_PASS_POINT_PER_WEEK = 10000;
public static final int BATTLE_PASS_LEVEL_PRICE = 150; public static final int BATTLE_PASS_LEVEL_PRICE = 150;
public static final int BATTLE_PASS_CURRENT_INDEX = 2; public static final int BATTLE_PASS_CURRENT_INDEX = 2;
// Default entity ability hashes. // Default entity ability hashes.
public static final String[] DEFAULT_ABILITY_STRINGS = { public static final String[] DEFAULT_ABILITY_STRINGS = {
"Avatar_DefaultAbility_VisionReplaceDieInvincible", "Avatar_DefaultAbility_VisionReplaceDieInvincible",
"Avatar_DefaultAbility_AvartarInShaderChange", "Avatar_DefaultAbility_AvartarInShaderChange",
"Avatar_SprintBS_Invincible", "Avatar_SprintBS_Invincible",
"Avatar_Freeze_Duration_Reducer", "Avatar_Freeze_Duration_Reducer",
"Avatar_Attack_ReviveEnergy", "Avatar_Attack_ReviveEnergy",
"Avatar_Component_Initializer", "Avatar_Component_Initializer",
"Avatar_FallAnthem_Achievement_Listener" "Avatar_FallAnthem_Achievement_Listener"
}; };
public static final int[] DEFAULT_ABILITY_HASHES = public static final int[] DEFAULT_ABILITY_HASHES =
Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray(); Arrays.stream(DEFAULT_ABILITY_STRINGS).mapToInt(Utils::abilityHash).toArray();
public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default"); public static final int DEFAULT_ABILITY_NAME = Utils.abilityHash("Default");
public static String VERSION = "3.5.0"; public static String VERSION = "3.5.0";
} }

View File

@ -1,322 +1,322 @@
package emu.grasscutter; package emu.grasscutter;
import static emu.grasscutter.config.Configuration.SERVER; import static emu.grasscutter.config.Configuration.SERVER;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
import ch.qos.logback.classic.Level; import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger; import ch.qos.logback.classic.Logger;
import emu.grasscutter.auth.AuthenticationSystem; import emu.grasscutter.auth.AuthenticationSystem;
import emu.grasscutter.auth.DefaultAuthentication; import emu.grasscutter.auth.DefaultAuthentication;
import emu.grasscutter.command.CommandMap; import emu.grasscutter.command.CommandMap;
import emu.grasscutter.command.DefaultPermissionHandler; import emu.grasscutter.command.DefaultPermissionHandler;
import emu.grasscutter.command.PermissionHandler; import emu.grasscutter.command.PermissionHandler;
import emu.grasscutter.config.ConfigContainer; import emu.grasscutter.config.ConfigContainer;
import emu.grasscutter.data.ResourceLoader; import emu.grasscutter.data.ResourceLoader;
import emu.grasscutter.database.DatabaseManager; import emu.grasscutter.database.DatabaseManager;
import emu.grasscutter.plugin.PluginManager; import emu.grasscutter.plugin.PluginManager;
import emu.grasscutter.plugin.api.ServerHook; import emu.grasscutter.plugin.api.ServerHook;
import emu.grasscutter.scripts.ScriptLoader; import emu.grasscutter.scripts.ScriptLoader;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.http.HttpServer; import emu.grasscutter.server.http.HttpServer;
import emu.grasscutter.server.http.dispatch.DispatchHandler; import emu.grasscutter.server.http.dispatch.DispatchHandler;
import emu.grasscutter.server.http.dispatch.RegionHandler; import emu.grasscutter.server.http.dispatch.RegionHandler;
import emu.grasscutter.server.http.documentation.DocumentationServerHandler; import emu.grasscutter.server.http.documentation.DocumentationServerHandler;
import emu.grasscutter.server.http.handlers.AnnouncementsHandler; import emu.grasscutter.server.http.handlers.AnnouncementsHandler;
import emu.grasscutter.server.http.handlers.GachaHandler; import emu.grasscutter.server.http.handlers.GachaHandler;
import emu.grasscutter.server.http.handlers.GenericHandler; import emu.grasscutter.server.http.handlers.GenericHandler;
import emu.grasscutter.server.http.handlers.LogHandler; import emu.grasscutter.server.http.handlers.LogHandler;
import emu.grasscutter.tools.Tools; import emu.grasscutter.tools.Tools;
import emu.grasscutter.utils.*; import emu.grasscutter.utils.*;
import java.io.File; import java.io.File;
import java.io.FileWriter; import java.io.FileWriter;
import java.io.IOError; import java.io.IOError;
import java.io.IOException; import java.io.IOException;
import java.util.Calendar; import java.util.Calendar;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
import org.jline.reader.EndOfFileException; import org.jline.reader.EndOfFileException;
import org.jline.reader.LineReader; import org.jline.reader.LineReader;
import org.jline.reader.LineReaderBuilder; import org.jline.reader.LineReaderBuilder;
import org.jline.reader.UserInterruptException; import org.jline.reader.UserInterruptException;
import org.jline.terminal.Terminal; import org.jline.terminal.Terminal;
import org.jline.terminal.TerminalBuilder; import org.jline.terminal.TerminalBuilder;
import org.reflections.Reflections; import org.reflections.Reflections;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
public final class Grasscutter { public final class Grasscutter {
public static final File configFile = new File("./config.json"); public static final File configFile = new File("./config.json");
public static final Reflections reflector = new Reflections("emu.grasscutter"); 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; @Getter public static ConfigContainer config;
@Getter @Setter private static Language language; @Getter @Setter private static Language language;
@Getter @Setter private static String preferredLanguage; @Getter @Setter private static String preferredLanguage;
@Getter private static int currentDayOfWeek; @Getter private static int currentDayOfWeek;
@Setter private static ServerRunMode runModeOverride = null; // Config override for run mode @Setter private static ServerRunMode runModeOverride = null; // Config override for run mode
@Getter private static HttpServer httpServer; @Getter private static HttpServer httpServer;
@Getter private static GameServer gameServer; @Getter private static GameServer gameServer;
@Getter private static PluginManager pluginManager; @Getter private static PluginManager pluginManager;
@Getter private static CommandMap commandMap; @Getter private static CommandMap commandMap;
@Getter @Setter private static AuthenticationSystem authenticationSystem; @Getter @Setter private static AuthenticationSystem authenticationSystem;
@Getter @Setter private static PermissionHandler permissionHandler; @Getter @Setter private static PermissionHandler permissionHandler;
private static LineReader consoleLineReader = null; private static LineReader consoleLineReader = null;
static { static {
// Declare logback configuration. // Declare logback configuration.
System.setProperty("logback.configurationFile", "src/main/resources/logback.xml"); System.setProperty("logback.configurationFile", "src/main/resources/logback.xml");
// Disable the MongoDB logger. // Disable the MongoDB logger.
var mongoLogger = (Logger) LoggerFactory.getLogger("org.mongodb.driver"); var mongoLogger = (Logger) LoggerFactory.getLogger("org.mongodb.driver");
mongoLogger.setLevel(Level.OFF); mongoLogger.setLevel(Level.OFF);
// Load server configuration. // Load server configuration.
Grasscutter.loadConfig(); Grasscutter.loadConfig();
// Attempt to update configuration. // Attempt to update configuration.
ConfigContainer.updateConfig(); ConfigContainer.updateConfig();
// Load translation files. // Load translation files.
Grasscutter.loadLanguage(); Grasscutter.loadLanguage();
// Check server structure. // Check server structure.
Utils.startupCheck(); Utils.startupCheck();
} }
public static void main(String[] args) throws Exception { public static void main(String[] args) throws Exception {
Crypto.loadKeys(); // Load keys from buffers. Crypto.loadKeys(); // Load keys from buffers.
// Parse start-up arguments. // Parse start-up arguments.
if (StartupArguments.parse(args)) { if (StartupArguments.parse(args)) {
System.exit(0); // Exit early. System.exit(0); // Exit early.
} }
// Create command map. // Create command map.
commandMap = new CommandMap(true); commandMap = new CommandMap(true);
// Initialize server. // Initialize server.
logger.info(translate("messages.status.starting")); logger.info(translate("messages.status.starting"));
logger.info(translate("messages.status.game_version", GameConstants.VERSION)); logger.info(translate("messages.status.game_version", GameConstants.VERSION));
logger.info(translate("messages.status.version", BuildConfig.VERSION, BuildConfig.GIT_HASH)); logger.info(translate("messages.status.version", BuildConfig.VERSION, BuildConfig.GIT_HASH));
// Load all resources. // Load all resources.
Grasscutter.updateDayOfWeek(); Grasscutter.updateDayOfWeek();
ResourceLoader.loadAll(); ResourceLoader.loadAll();
ScriptLoader.init(); ScriptLoader.init();
// Generate handbooks. // Generate handbooks.
Tools.createGmHandbooks(false); Tools.createGmHandbooks(false);
// Initialize database. // Initialize database.
DatabaseManager.initialize(); DatabaseManager.initialize();
// Initialize the default systems. // Initialize the default systems.
authenticationSystem = new DefaultAuthentication(); authenticationSystem = new DefaultAuthentication();
permissionHandler = new DefaultPermissionHandler(); permissionHandler = new DefaultPermissionHandler();
// Create server instances. // Create server instances.
httpServer = new HttpServer(); httpServer = new HttpServer();
gameServer = new GameServer(); gameServer = new GameServer();
// Create a server hook instance with both servers. // Create a server hook instance with both servers.
new ServerHook(gameServer, httpServer); new ServerHook(gameServer, httpServer);
// Create plugin manager instance. // Create plugin manager instance.
pluginManager = new PluginManager(); pluginManager = new PluginManager();
// Add HTTP routes after loading plugins. // Add HTTP routes after loading plugins.
httpServer.addRouter(HttpServer.UnhandledRequestRouter.class); httpServer.addRouter(HttpServer.UnhandledRequestRouter.class);
httpServer.addRouter(HttpServer.DefaultRequestRouter.class); httpServer.addRouter(HttpServer.DefaultRequestRouter.class);
httpServer.addRouter(RegionHandler.class); httpServer.addRouter(RegionHandler.class);
httpServer.addRouter(LogHandler.class); httpServer.addRouter(LogHandler.class);
httpServer.addRouter(GenericHandler.class); httpServer.addRouter(GenericHandler.class);
httpServer.addRouter(AnnouncementsHandler.class); httpServer.addRouter(AnnouncementsHandler.class);
httpServer.addRouter(DispatchHandler.class); httpServer.addRouter(DispatchHandler.class);
httpServer.addRouter(GachaHandler.class); httpServer.addRouter(GachaHandler.class);
httpServer.addRouter(DocumentationServerHandler.class); httpServer.addRouter(DocumentationServerHandler.class);
// Start servers. // Start servers.
var runMode = Grasscutter.getRunMode(); var runMode = Grasscutter.getRunMode();
if (runMode == ServerRunMode.HYBRID) { if (runMode == ServerRunMode.HYBRID) {
httpServer.start(); httpServer.start();
gameServer.start(); gameServer.start();
} else if (runMode == ServerRunMode.DISPATCH_ONLY) { } else if (runMode == ServerRunMode.DISPATCH_ONLY) {
httpServer.start(); httpServer.start();
} else if (runMode == ServerRunMode.GAME_ONLY) { } else if (runMode == ServerRunMode.GAME_ONLY) {
gameServer.start(); gameServer.start();
} else { } else {
logger.error(translate("messages.status.run_mode_error", runMode)); logger.error(translate("messages.status.run_mode_error", runMode));
logger.error(translate("messages.status.run_mode_help")); logger.error(translate("messages.status.run_mode_help"));
logger.error(translate("messages.status.shutdown")); logger.error(translate("messages.status.shutdown"));
System.exit(1); System.exit(1);
} }
// Enable all plugins. // Enable all plugins.
pluginManager.enablePlugins(); pluginManager.enablePlugins();
// Hook into shutdown event. // Hook into shutdown event.
Runtime.getRuntime().addShutdownHook(new Thread(Grasscutter::onShutdown)); Runtime.getRuntime().addShutdownHook(new Thread(Grasscutter::onShutdown));
// Open console. // Open console.
Grasscutter.startConsole(); Grasscutter.startConsole();
} }
/** Server shutdown event. */ /** Server shutdown event. */
private static void onShutdown() { private static void onShutdown() {
// Disable all plugins. // Disable all plugins.
if (pluginManager != null) pluginManager.disablePlugins(); if (pluginManager != null) pluginManager.disablePlugins();
} }
/* /*
* Methods for the language system component. * Methods for the language system component.
*/ */
public static void loadLanguage() { public static void loadLanguage() {
var locale = config.language.language; var locale = config.language.language;
language = Language.getLanguage(Utils.getLanguageCode(locale)); language = Language.getLanguage(Utils.getLanguageCode(locale));
} }
/* /*
* Methods for the configuration system component. * 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() { public static void loadConfig() {
// Check if config.json exists. If not, we generate a new config. // Check if config.json exists. If not, we generate a new config.
if (!configFile.exists()) { if (!configFile.exists()) {
getLogger().info("config.json could not be found. Generating a default configuration ..."); getLogger().info("config.json could not be found. Generating a default configuration ...");
config = new ConfigContainer(); config = new ConfigContainer();
Grasscutter.saveConfig(config); Grasscutter.saveConfig(config);
return; return;
} }
// If the file already exists, we attempt to load it. // If the file already exists, we attempt to load it.
try { try {
config = JsonUtils.loadToClass(configFile.toPath(), ConfigContainer.class); config = JsonUtils.loadToClass(configFile.toPath(), ConfigContainer.class);
} catch (Exception exception) { } catch (Exception exception) {
getLogger() getLogger()
.error( .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."); "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); System.exit(1);
} }
} }
/** /**
* Saves the provided server configuration. * Saves the provided server configuration.
* *
* @param config The configuration to save, or null for a new one. * @param config The configuration to save, or null for a new one.
*/ */
public static void saveConfig(@Nullable ConfigContainer config) { public static void saveConfig(@Nullable ConfigContainer config) {
if (config == null) config = new ConfigContainer(); if (config == null) config = new ConfigContainer();
try (FileWriter file = new FileWriter(configFile)) { try (FileWriter file = new FileWriter(configFile)) {
file.write(JsonUtils.encode(config)); file.write(JsonUtils.encode(config));
} catch (IOException ignored) { } catch (IOException ignored) {
logger.error("Unable to write to config file."); logger.error("Unable to write to config file.");
} catch (Exception e) { } catch (Exception e) {
logger.error("Unable to save config file.", e); logger.error("Unable to save config file.", e);
} }
} }
/* /*
* Getters for the various server components. * Getters for the various server components.
*/ */
public static Language getLanguage(String langCode) { public static Language getLanguage(String langCode) {
return Language.getLanguage(langCode); return Language.getLanguage(langCode);
} }
public static ServerRunMode getRunMode() { public static ServerRunMode getRunMode() {
return Grasscutter.runModeOverride != null ? Grasscutter.runModeOverride : SERVER.runMode; return Grasscutter.runModeOverride != null ? Grasscutter.runModeOverride : SERVER.runMode;
} }
public static LineReader getConsole() { public static LineReader getConsole() {
if (consoleLineReader == null) { if (consoleLineReader == null) {
Terminal terminal = null; Terminal terminal = null;
try { try {
terminal = TerminalBuilder.builder().jna(true).build(); terminal = TerminalBuilder.builder().jna(true).build();
} catch (Exception e) { } catch (Exception e) {
try { try {
// Fallback to a dumb jline terminal. // Fallback to a dumb jline terminal.
terminal = TerminalBuilder.builder().dumb(true).build(); terminal = TerminalBuilder.builder().dumb(true).build();
} catch (Exception ignored) { } catch (Exception ignored) {
// When dumb is true, build() never throws. // When dumb is true, build() never throws.
} }
} }
consoleLineReader = LineReaderBuilder.builder().terminal(terminal).build(); consoleLineReader = LineReaderBuilder.builder().terminal(terminal).build();
} }
return consoleLineReader; return consoleLineReader;
} }
/* /*
* Utility methods. * Utility methods.
*/ */
public static void updateDayOfWeek() { public static void updateDayOfWeek() {
Calendar calendar = Calendar.getInstance(); Calendar calendar = Calendar.getInstance();
Grasscutter.currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK); Grasscutter.currentDayOfWeek = calendar.get(Calendar.DAY_OF_WEEK);
logger.debug("Set day of week to " + currentDayOfWeek); logger.debug("Set day of week to " + currentDayOfWeek);
} }
public static void startConsole() { public static void startConsole() {
// Console should not start in dispatch only mode. // Console should not start in dispatch only mode.
if (SERVER.runMode == ServerRunMode.DISPATCH_ONLY) { if (SERVER.runMode == ServerRunMode.DISPATCH_ONLY) {
logger.info(translate("messages.dispatch.no_commands_error")); logger.info(translate("messages.dispatch.no_commands_error"));
return; return;
} else { } else {
logger.info(translate("messages.status.done")); logger.info(translate("messages.status.done"));
} }
String input = null; String input = null;
var isLastInterrupted = false; var isLastInterrupted = false;
while (config.server.game.enableConsole) { while (config.server.game.enableConsole) {
try { try {
input = consoleLineReader.readLine("> "); input = consoleLineReader.readLine("> ");
} catch (UserInterruptException e) { } catch (UserInterruptException e) {
if (!isLastInterrupted) { if (!isLastInterrupted) {
isLastInterrupted = true; isLastInterrupted = true;
logger.info("Press Ctrl-C again to shutdown."); logger.info("Press Ctrl-C again to shutdown.");
continue; continue;
} else { } else {
Runtime.getRuntime().exit(0); Runtime.getRuntime().exit(0);
} }
} catch (EndOfFileException e) { } catch (EndOfFileException e) {
logger.info("EOF detected."); logger.info("EOF detected.");
continue; continue;
} catch (IOError e) { } catch (IOError e) {
logger.error("An IO error occurred while trying to read from console.", e); logger.error("An IO error occurred while trying to read from console.", e);
return; return;
} }
isLastInterrupted = false; isLastInterrupted = false;
try { try {
commandMap.invoke(null, null, input); commandMap.invoke(null, null, input);
} catch (Exception e) { } catch (Exception e) {
logger.error(translate("messages.game.command_error"), e); logger.error(translate("messages.game.command_error"), e);
} }
} }
} }
/* /*
* Enums for the configuration. * Enums for the configuration.
*/ */
public enum ServerRunMode { public enum ServerRunMode {
HYBRID, HYBRID,
DISPATCH_ONLY, DISPATCH_ONLY,
GAME_ONLY GAME_ONLY
} }
public enum ServerDebugMode { public enum ServerDebugMode {
ALL, ALL,
MISSING, MISSING,
WHITELIST, WHITELIST,
BLACKLIST, BLACKLIST,
NONE NONE
} }
} }

View File

@ -1,158 +1,158 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.achievement.AchievementData; import emu.grasscutter.data.excels.achievement.AchievementData;
import emu.grasscutter.game.achievement.AchievementControlReturns; import emu.grasscutter.game.achievement.AchievementControlReturns;
import emu.grasscutter.game.achievement.Achievements; import emu.grasscutter.game.achievement.Achievements;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger; import java.util.concurrent.atomic.AtomicInteger;
@Command( @Command(
label = "achievement", label = "achievement",
usage = { usage = {
"(grant|revoke) <achievementId>", "(grant|revoke) <achievementId>",
"progress <achievementId> <progress>", "progress <achievementId> <progress>",
"grantall", "grantall",
"revokeall" "revokeall"
}, },
aliases = {"am"}, aliases = {"am"},
permission = "player.achievement", permission = "player.achievement",
permissionTargeted = "player.achievement.others", permissionTargeted = "player.achievement.others",
targetRequirement = Command.TargetRequirement.PLAYER, targetRequirement = Command.TargetRequirement.PLAYER,
threading = true) threading = true)
public final class AchievementCommand implements CommandHandler { public final class AchievementCommand implements CommandHandler {
private static void sendSuccessMessage(Player sender, String cmd, Object... args) { private static void sendSuccessMessage(Player sender, String cmd, Object... args) {
CommandHandler.sendTranslatedMessage( CommandHandler.sendTranslatedMessage(
sender, AchievementControlReturns.Return.SUCCESS.getKey() + cmd, args); sender, AchievementControlReturns.Return.SUCCESS.getKey() + cmd, args);
} }
private static Optional<Integer> parseInt(String s) { private static Optional<Integer> parseInt(String s) {
try { try {
return Optional.of(Integer.parseInt(s)); return Optional.of(Integer.parseInt(s));
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
return Optional.empty(); return Optional.empty();
} }
} }
private static void grantAll(Player sender, Player targetPlayer, Achievements achievements) { private static void grantAll(Player sender, Player targetPlayer, Achievements achievements) {
var counter = new AtomicInteger(); var counter = new AtomicInteger();
GameData.getAchievementDataMap().values().stream() GameData.getAchievementDataMap().values().stream()
.filter(AchievementData::isUsed) .filter(AchievementData::isUsed)
.filter(AchievementData::isParent) .filter(AchievementData::isParent)
.forEach( .forEach(
data -> { data -> {
var success = achievements.grant(data.getId()); var success = achievements.grant(data.getId());
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) { if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
counter.addAndGet(success.getChangedAchievementStatusNum()); counter.addAndGet(success.getChangedAchievementStatusNum());
} }
}); });
sendSuccessMessage(sender, "grantall", counter.intValue(), targetPlayer.getNickname()); sendSuccessMessage(sender, "grantall", counter.intValue(), targetPlayer.getNickname());
} }
private static void revokeAll(Player sender, Player targetPlayer, Achievements achievements) { private static void revokeAll(Player sender, Player targetPlayer, Achievements achievements) {
var counter = new AtomicInteger(); var counter = new AtomicInteger();
GameData.getAchievementDataMap().values().stream() GameData.getAchievementDataMap().values().stream()
.filter(AchievementData::isUsed) .filter(AchievementData::isUsed)
.filter(AchievementData::isParent) .filter(AchievementData::isParent)
.forEach( .forEach(
data -> { data -> {
var success = achievements.revoke(data.getId()); var success = achievements.revoke(data.getId());
if (success.getRet() == AchievementControlReturns.Return.SUCCESS) { if (success.getRet() == AchievementControlReturns.Return.SUCCESS) {
counter.addAndGet(success.getChangedAchievementStatusNum()); counter.addAndGet(success.getChangedAchievementStatusNum());
} }
}); });
sendSuccessMessage(sender, "revokeall", counter.intValue(), targetPlayer.getNickname()); sendSuccessMessage(sender, "revokeall", counter.intValue(), targetPlayer.getNickname());
} }
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { if (args.size() < 1) {
this.sendUsageMessage(sender); this.sendUsageMessage(sender);
return; return;
} }
var command = args.remove(0).toLowerCase(); var command = args.remove(0).toLowerCase();
var achievements = Achievements.getByPlayer(targetPlayer); var achievements = Achievements.getByPlayer(targetPlayer);
switch (command) { switch (command) {
case "grant" -> this.grant(sender, targetPlayer, achievements, args); case "grant" -> this.grant(sender, targetPlayer, achievements, args);
case "revoke" -> this.revoke(sender, targetPlayer, achievements, args); case "revoke" -> this.revoke(sender, targetPlayer, achievements, args);
case "progress" -> this.progress(sender, targetPlayer, achievements, args); case "progress" -> this.progress(sender, targetPlayer, achievements, args);
case "grantall" -> grantAll(sender, targetPlayer, achievements); case "grantall" -> grantAll(sender, targetPlayer, achievements);
case "revokeall" -> revokeAll(sender, targetPlayer, achievements); case "revokeall" -> revokeAll(sender, targetPlayer, achievements);
default -> this.sendUsageMessage(sender); default -> this.sendUsageMessage(sender);
} }
} }
private void grant( private void grant(
Player sender, Player targetPlayer, Achievements achievements, List<String> args) { Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
if (args.size() < 1) { if (args.size() < 1) {
this.sendUsageMessage(sender); this.sendUsageMessage(sender);
} }
parseInt(args.remove(0)) parseInt(args.remove(0))
.ifPresentOrElse( .ifPresentOrElse(
integer -> { integer -> {
var ret = achievements.grant(integer); var ret = achievements.grant(integer);
switch (ret.getRet()) { switch (ret.getRet()) {
case SUCCESS -> sendSuccessMessage(sender, "grant", targetPlayer.getNickname()); case SUCCESS -> sendSuccessMessage(sender, "grant", targetPlayer.getNickname());
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage( case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
sender, ret.getRet().getKey()); sender, ret.getRet().getKey());
case ALREADY_ACHIEVED -> CommandHandler.sendTranslatedMessage( case ALREADY_ACHIEVED -> CommandHandler.sendTranslatedMessage(
sender, ret.getRet().getKey(), targetPlayer.getNickname()); sender, ret.getRet().getKey(), targetPlayer.getNickname());
} }
}, },
() -> this.sendUsageMessage(sender)); () -> this.sendUsageMessage(sender));
} }
private void revoke( private void revoke(
Player sender, Player targetPlayer, Achievements achievements, List<String> args) { Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
if (args.size() < 1) { if (args.size() < 1) {
this.sendUsageMessage(sender); this.sendUsageMessage(sender);
} }
parseInt(args.remove(0)) parseInt(args.remove(0))
.ifPresentOrElse( .ifPresentOrElse(
integer -> { integer -> {
var ret = achievements.revoke(integer); var ret = achievements.revoke(integer);
switch (ret.getRet()) { switch (ret.getRet()) {
case SUCCESS -> sendSuccessMessage(sender, "revoke", targetPlayer.getNickname()); case SUCCESS -> sendSuccessMessage(sender, "revoke", targetPlayer.getNickname());
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage( case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
sender, ret.getRet().getKey()); sender, ret.getRet().getKey());
case NOT_YET_ACHIEVED -> CommandHandler.sendTranslatedMessage( case NOT_YET_ACHIEVED -> CommandHandler.sendTranslatedMessage(
sender, ret.getRet().getKey(), targetPlayer.getNickname()); sender, ret.getRet().getKey(), targetPlayer.getNickname());
} }
}, },
() -> this.sendUsageMessage(sender)); () -> this.sendUsageMessage(sender));
} }
private void progress( private void progress(
Player sender, Player targetPlayer, Achievements achievements, List<String> args) { Player sender, Player targetPlayer, Achievements achievements, List<String> args) {
if (args.size() < 2) { if (args.size() < 2) {
this.sendUsageMessage(sender); this.sendUsageMessage(sender);
} }
parseInt(args.remove(0)) parseInt(args.remove(0))
.ifPresentOrElse( .ifPresentOrElse(
integer -> { integer -> {
parseInt(args.remove(0)) parseInt(args.remove(0))
.ifPresentOrElse( .ifPresentOrElse(
progress -> { progress -> {
var ret = achievements.progress(integer, progress); var ret = achievements.progress(integer, progress);
switch (ret.getRet()) { switch (ret.getRet()) {
case SUCCESS -> sendSuccessMessage( case SUCCESS -> sendSuccessMessage(
sender, "progress", targetPlayer.getNickname(), integer, progress); sender, "progress", targetPlayer.getNickname(), integer, progress);
case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage( case ACHIEVEMENT_NOT_FOUND -> CommandHandler.sendTranslatedMessage(
sender, ret.getRet().getKey()); sender, ret.getRet().getKey());
} }
}, },
() -> this.sendUsageMessage(sender)); () -> this.sendUsageMessage(sender));
}, },
() -> this.sendUsageMessage(sender)); () -> this.sendUsageMessage(sender));
} }
} }

View File

@ -1,139 +1,139 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.command.CommandHelpers.*; import static emu.grasscutter.command.CommandHelpers.*;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.entity.*; import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.Scene;
import emu.grasscutter.server.event.entity.EntityDamageEvent; import emu.grasscutter.server.event.entity.EntityDamageEvent;
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify; import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import lombok.Setter; import lombok.Setter;
@Command( @Command(
label = "entity", label = "entity",
usage = { usage = {
"<configId gadget> [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]", "<configId gadget> [state<state>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]",
"<configId monster> [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]" "<configId monster> [ai<aiId>] [maxhp<maxhp>] [hp<hp>(0 for infinite)] [atk<atk>] [def<def>]"
}, },
permission = "server.entity") permission = "server.entity")
public final class EntityCommand implements CommandHandler { public final class EntityCommand implements CommandHandler {
private static final Map<Pattern, BiConsumer<EntityParameters, Integer>> intCommandHandlers = private static final Map<Pattern, BiConsumer<EntityParameters, Integer>> intCommandHandlers =
Map.ofEntries( Map.ofEntries(
Map.entry(stateRegex, EntityParameters::setState), Map.entry(stateRegex, EntityParameters::setState),
Map.entry(maxHPRegex, EntityParameters::setMaxHP), Map.entry(maxHPRegex, EntityParameters::setMaxHP),
Map.entry(hpRegex, EntityParameters::setHp), Map.entry(hpRegex, EntityParameters::setHp),
Map.entry(defRegex, EntityParameters::setDef), Map.entry(defRegex, EntityParameters::setDef),
Map.entry(atkRegex, EntityParameters::setAtk), Map.entry(atkRegex, EntityParameters::setAtk),
Map.entry(aiRegex, EntityParameters::setAi)); Map.entry(aiRegex, EntityParameters::setAi));
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
EntityParameters param = new EntityParameters(); EntityParameters param = new EntityParameters();
parseIntParameters(args, param, intCommandHandlers); parseIntParameters(args, param, intCommandHandlers);
// At this point, first remaining argument MUST be the id and the rest the pos // At this point, first remaining argument MUST be the id and the rest the pos
if (args.size() != 1) { 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(); throw new IllegalArgumentException();
} }
try { try {
param.configId = Integer.parseInt(args.get(0)); param.configId = Integer.parseInt(args.get(0));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.cfgId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.cfgId"));
} }
param.scene = targetPlayer.getScene(); param.scene = targetPlayer.getScene();
var entity = param.scene.getEntityByConfigId(param.configId); var entity = param.scene.getEntityByConfigId(param.configId);
if (entity == null) { if (entity == null) {
CommandHandler.sendMessage(sender, translate(sender, "commands.entity.not_found_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.entity.not_found_error"));
return; return;
} }
applyFightProps(entity, param); applyFightProps(entity, param);
applyGadgetParams(entity, param); applyGadgetParams(entity, param);
applyMonsterParams(entity, param); applyMonsterParams(entity, param);
CommandHandler.sendMessage(sender, translate(sender, "commands.status.success")); CommandHandler.sendMessage(sender, translate(sender, "commands.status.success"));
} }
private void applyGadgetParams(GameEntity entity, EntityParameters param) { private void applyGadgetParams(GameEntity entity, EntityParameters param) {
if (!(entity instanceof EntityGadget)) { if (!(entity instanceof EntityGadget)) {
return; return;
} }
if (param.state != -1) { if (param.state != -1) {
((EntityGadget) entity).updateState(param.state); ((EntityGadget) entity).updateState(param.state);
} }
} }
private void applyMonsterParams(GameEntity entity, EntityParameters param) { private void applyMonsterParams(GameEntity entity, EntityParameters param) {
if (!(entity instanceof EntityMonster)) { if (!(entity instanceof EntityMonster)) {
return; return;
} }
if (param.ai != -1) { if (param.ai != -1) {
((EntityMonster) entity).setAiId(param.ai); ((EntityMonster) entity).setAiId(param.ai);
// TODO notify // TODO notify
} }
} }
private void applyFightProps(GameEntity entity, EntityParameters param) { private void applyFightProps(GameEntity entity, EntityParameters param) {
var changedFields = new ArrayList<FightProperty>(); var changedFields = new ArrayList<FightProperty>();
if (param.maxHP != -1) { if (param.maxHP != -1) {
setFightProperty(entity, FightProperty.FIGHT_PROP_MAX_HP, param.maxHP, changedFields); setFightProperty(entity, FightProperty.FIGHT_PROP_MAX_HP, param.maxHP, changedFields);
} }
if (param.hp != -1) { if (param.hp != -1) {
float targetHp = param.hp == 0 ? Float.MAX_VALUE : param.hp; float targetHp = param.hp == 0 ? Float.MAX_VALUE : param.hp;
float oldHp = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP); float oldHp = entity.getFightProperty(FightProperty.FIGHT_PROP_CUR_HP);
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_HP, targetHp, changedFields); setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_HP, targetHp, changedFields);
EntityDamageEvent event = EntityDamageEvent event =
new EntityDamageEvent(entity, oldHp - targetHp, ElementType.None, null); new EntityDamageEvent(entity, oldHp - targetHp, ElementType.None, null);
callHPEvents(entity, event); callHPEvents(entity, event);
} }
if (param.atk != -1) { if (param.atk != -1) {
setFightProperty(entity, FightProperty.FIGHT_PROP_ATTACK, param.atk, changedFields); setFightProperty(entity, FightProperty.FIGHT_PROP_ATTACK, param.atk, changedFields);
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk, changedFields); setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk, changedFields);
} }
if (param.def != -1) { if (param.def != -1) {
setFightProperty(entity, FightProperty.FIGHT_PROP_DEFENSE, param.def, changedFields); setFightProperty(entity, FightProperty.FIGHT_PROP_DEFENSE, param.def, changedFields);
setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def, changedFields); setFightProperty(entity, FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def, changedFields);
} }
if (!changedFields.isEmpty()) { if (!changedFields.isEmpty()) {
entity entity
.getScene() .getScene()
.broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, changedFields)); .broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, changedFields));
} }
} }
private void callHPEvents(GameEntity entity, EntityDamageEvent event) { private void callHPEvents(GameEntity entity, EntityDamageEvent event) {
entity.runLuaCallbacks(event); entity.runLuaCallbacks(event);
} }
private void setFightProperty( private void setFightProperty(
GameEntity entity, FightProperty property, float value, List<FightProperty> modifiedProps) { GameEntity entity, FightProperty property, float value, List<FightProperty> modifiedProps) {
entity.setFightProperty(property, value); entity.setFightProperty(property, value);
modifiedProps.add(property); modifiedProps.add(property);
} }
private static class EntityParameters { private static class EntityParameters {
@Setter public int configId = -1; @Setter public int configId = -1;
@Setter public int state = -1; @Setter public int state = -1;
@Setter public int hp = -1; @Setter public int hp = -1;
@Setter public int maxHP = -1; @Setter public int maxHP = -1;
@Setter public int atk = -1; @Setter public int atk = -1;
@Setter public int def = -1; @Setter public int def = -1;
@Setter public int ai = -1; @Setter public int ai = -1;
public Scene scene = null; public Scene scene = null;
} }
} }

View File

@ -1,72 +1,72 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.world.SceneGroupInstance; import emu.grasscutter.game.world.SceneGroupInstance;
import java.util.List; import java.util.List;
@Command( @Command(
label = "group", label = "group",
aliases = {"g"}, aliases = {"g"},
usage = {"(refresh) [<groupId>] [<suiteId>]"}, usage = {"(refresh) [<groupId>] [<suiteId>]"},
permission = "player.group", permission = "player.group",
permissionTargeted = "player.group.others") permissionTargeted = "player.group.others")
public final class GroupCommand implements CommandHandler { public final class GroupCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.isEmpty()) { if (args.isEmpty()) {
return; return;
} }
String cmd = args.remove(0).toLowerCase(); String cmd = args.remove(0).toLowerCase();
int groupId = 0; int groupId = 0;
int suiteId = 0; int suiteId = 0;
switch (args.size()) { switch (args.size()) {
case 2: case 2:
try { try {
suiteId = Integer.parseInt(args.get(1)); suiteId = Integer.parseInt(args.get(1));
} catch (Exception e) { } catch (Exception e) {
CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_suiteid")); CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_suiteid"));
return; return;
} // Fallthrough } // Fallthrough
case 1: case 1:
try { try {
groupId = Integer.parseInt(args.get(0)); groupId = Integer.parseInt(args.get(0));
} catch (Exception e) { } catch (Exception e) {
CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_groupid")); CommandHandler.sendMessage(sender, translate(sender, "commands.group.invalid_groupid"));
return; return;
} }
break; break;
default: default:
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
switch (cmd) { switch (cmd) {
case "refresh" -> { case "refresh" -> {
SceneGroupInstance groupInstance = SceneGroupInstance groupInstance =
targetPlayer.getScene().getScriptManager().getGroupInstanceById(groupId); targetPlayer.getScene().getScriptManager().getGroupInstanceById(groupId);
if (groupInstance == null) { if (groupInstance == null) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.group.group_not_found", groupId)); sender, translate(sender, "commands.group.group_not_found", groupId));
return; return;
} }
if (args.size() >= 2) { if (args.size() >= 2) {
targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance, suiteId, false); targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance, suiteId, false);
} else { } else {
targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance); targetPlayer.getScene().getScriptManager().refreshGroup(groupInstance);
} }
CommandHandler.sendMessage(sender, translate(sender, "commands.group.refreshed", groupId)); CommandHandler.sendMessage(sender, translate(sender, "commands.group.refreshed", groupId));
} }
default -> { default -> {
sendUsageMessage(sender); sendUsageMessage(sender);
} }
} }
} }
} }

View File

@ -1,279 +1,279 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.PlayerProperty; import emu.grasscutter.game.props.PlayerProperty;
import emu.grasscutter.game.tower.TowerLevelRecord; import emu.grasscutter.game.tower.TowerLevelRecord;
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify; import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
import emu.grasscutter.server.packet.send.PacketSceneAreaUnlockNotify; import emu.grasscutter.server.packet.send.PacketSceneAreaUnlockNotify;
import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify; import emu.grasscutter.server.packet.send.PacketScenePointUnlockNotify;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
@Command( @Command(
label = "setProp", label = "setProp",
aliases = {"prop"}, aliases = {"prop"},
usage = {"<prop> <value>"}, usage = {"<prop> <value>"},
permission = "player.setprop", permission = "player.setprop",
permissionTargeted = "player.setprop.others") permissionTargeted = "player.setprop.others")
public final class SetPropCommand implements CommandHandler { public final class SetPropCommand implements CommandHandler {
// List of map areas. Unfortunately, there is no readily available source for them in excels or // List of map areas. Unfortunately, there is no readily available source for them in excels or
// bins. // bins.
private static final List<Integer> sceneAreas = private static final List<Integer> sceneAreas =
List.of( 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, 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); 28, 29, 32, 100, 101, 102, 103, 200, 210, 300, 400, 401, 402, 403);
Map<String, Prop> props; Map<String, Prop> props;
public SetPropCommand() { public SetPropCommand() {
this.props = new HashMap<>(); this.props = new HashMap<>();
// Full PlayerProperty enum that won't be advertised but can be used by devs // Full PlayerProperty enum that won't be advertised but can be used by devs
for (PlayerProperty prop : PlayerProperty.values()) { for (PlayerProperty prop : PlayerProperty.values()) {
String name = prop.toString().substring(5); // PROP_EXP -> EXP String name = prop.toString().substring(5); // PROP_EXP -> EXP
String key = name.toLowerCase(); // EXP -> exp String key = name.toLowerCase(); // EXP -> exp
this.props.put(key, new Prop(name, prop)); this.props.put(key, new Prop(name, prop));
} }
// Add special props // Add special props
Prop worldlevel = Prop worldlevel =
new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL); new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL);
this.props.put("worldlevel", worldlevel); this.props.put("worldlevel", worldlevel);
this.props.put("wl", worldlevel); this.props.put("wl", worldlevel);
Prop abyss = new Prop("Tower Level", PseudoProp.TOWER_LEVEL); Prop abyss = new Prop("Tower Level", PseudoProp.TOWER_LEVEL);
this.props.put("abyss", abyss); this.props.put("abyss", abyss);
this.props.put("abyssfloor", abyss); this.props.put("abyssfloor", abyss);
this.props.put("ut", abyss); this.props.put("ut", abyss);
this.props.put("tower", abyss); this.props.put("tower", abyss);
this.props.put("towerlevel", abyss); this.props.put("towerlevel", abyss);
this.props.put("unlocktower", abyss); this.props.put("unlocktower", abyss);
Prop bplevel = new Prop("BP Level", PseudoProp.BP_LEVEL); Prop bplevel = new Prop("BP Level", PseudoProp.BP_LEVEL);
this.props.put("bplevel", bplevel); this.props.put("bplevel", bplevel);
this.props.put("bp", bplevel); this.props.put("bp", bplevel);
this.props.put("battlepass", bplevel); this.props.put("battlepass", bplevel);
Prop godmode = new Prop("GodMode", PseudoProp.GOD_MODE); Prop godmode = new Prop("GodMode", PseudoProp.GOD_MODE);
this.props.put("godmode", godmode); this.props.put("godmode", godmode);
this.props.put("god", godmode); this.props.put("god", godmode);
Prop nostamina = new Prop("UnlimitedStamina", PseudoProp.UNLIMITED_STAMINA); Prop nostamina = new Prop("UnlimitedStamina", PseudoProp.UNLIMITED_STAMINA);
this.props.put("unlimitedstamina", nostamina); this.props.put("unlimitedstamina", nostamina);
this.props.put("us", nostamina); this.props.put("us", nostamina);
this.props.put("nostamina", nostamina); this.props.put("nostamina", nostamina);
this.props.put("nostam", nostamina); this.props.put("nostam", nostamina);
this.props.put("ns", nostamina); this.props.put("ns", nostamina);
Prop unlimitedenergy = new Prop("UnlimitedEnergy", PseudoProp.UNLIMITED_ENERGY); Prop unlimitedenergy = new Prop("UnlimitedEnergy", PseudoProp.UNLIMITED_ENERGY);
this.props.put("unlimitedenergy", unlimitedenergy); this.props.put("unlimitedenergy", unlimitedenergy);
this.props.put("ue", unlimitedenergy); this.props.put("ue", unlimitedenergy);
Prop setopenstate = new Prop("SetOpenstate", PseudoProp.SET_OPENSTATE); Prop setopenstate = new Prop("SetOpenstate", PseudoProp.SET_OPENSTATE);
this.props.put("setopenstate", setopenstate); this.props.put("setopenstate", setopenstate);
this.props.put("so", setopenstate); this.props.put("so", setopenstate);
Prop unsetopenstate = new Prop("UnsetOpenstate", PseudoProp.UNSET_OPENSTATE); Prop unsetopenstate = new Prop("UnsetOpenstate", PseudoProp.UNSET_OPENSTATE);
this.props.put("unsetopenstate", unsetopenstate); this.props.put("unsetopenstate", unsetopenstate);
this.props.put("uo", unsetopenstate); this.props.put("uo", unsetopenstate);
Prop unlockmap = new Prop("UnlockMap", PseudoProp.UNLOCK_MAP); Prop unlockmap = new Prop("UnlockMap", PseudoProp.UNLOCK_MAP);
this.props.put("unlockmap", unlockmap); this.props.put("unlockmap", unlockmap);
this.props.put("um", unlockmap); this.props.put("um", unlockmap);
} }
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() != 2) { if (args.size() != 2) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
String propStr = args.get(0).toLowerCase(); String propStr = args.get(0).toLowerCase();
String valueStr = args.get(1).toLowerCase(); String valueStr = args.get(1).toLowerCase();
int value; int value;
if (!props.containsKey(propStr)) { if (!props.containsKey(propStr)) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
try { try {
value = value =
switch (valueStr.toLowerCase()) { switch (valueStr.toLowerCase()) {
case "on", "true" -> 1; case "on", "true" -> 1;
case "off", "false" -> 0; case "off", "false" -> 0;
case "toggle" -> -1; case "toggle" -> -1;
default -> Integer.parseInt(valueStr); default -> Integer.parseInt(valueStr);
}; };
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error"); CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
return; return;
} }
boolean success = false; boolean success = false;
Prop prop = props.get(propStr); Prop prop = props.get(propStr);
success = success =
switch (prop.pseudoProp) { switch (prop.pseudoProp) {
case WORLD_LEVEL -> targetPlayer.setWorldLevel(value); case WORLD_LEVEL -> targetPlayer.setWorldLevel(value);
case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value); case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value);
case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value); case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value);
case GOD_MODE, UNLIMITED_STAMINA, UNLIMITED_ENERGY -> this.setBool( case GOD_MODE, UNLIMITED_STAMINA, UNLIMITED_ENERGY -> this.setBool(
sender, targetPlayer, prop.pseudoProp, value); sender, targetPlayer, prop.pseudoProp, value);
case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1); case SET_OPENSTATE -> this.setOpenState(targetPlayer, value, 1);
case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0); case UNSET_OPENSTATE -> this.setOpenState(targetPlayer, value, 0);
case UNLOCK_MAP -> unlockMap(targetPlayer); case UNLOCK_MAP -> unlockMap(targetPlayer);
default -> targetPlayer.setProperty(prop.prop, value); default -> targetPlayer.setProperty(prop.prop, value);
}; };
if (success) { if (success) {
if (targetPlayer == sender) { if (targetPlayer == sender) {
CommandHandler.sendTranslatedMessage( CommandHandler.sendTranslatedMessage(
sender, "commands.generic.set_to", prop.name, valueStr); sender, "commands.generic.set_to", prop.name, valueStr);
} else { } else {
String uidStr = targetPlayer.getAccount().getId(); String uidStr = targetPlayer.getAccount().getId();
CommandHandler.sendTranslatedMessage( CommandHandler.sendTranslatedMessage(
sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr); sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr);
} }
} else { } else {
if (prop.prop if (prop.prop
!= PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages != PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages
int min = targetPlayer.getPropertyMin(prop.prop); int min = targetPlayer.getPropertyMin(prop.prop);
int max = targetPlayer.getPropertyMax(prop.prop); int max = targetPlayer.getPropertyMax(prop.prop);
CommandHandler.sendTranslatedMessage( CommandHandler.sendTranslatedMessage(
sender, "commands.generic.invalid.value_between", prop.name, min, max); sender, "commands.generic.invalid.value_between", prop.name, min, max);
} }
} }
} }
private boolean setTowerLevel(Player sender, Player targetPlayer, int topFloor) { private boolean setTowerLevel(Player sender, Player targetPlayer, int topFloor) {
List<Integer> floorIds = targetPlayer.getServer().getTowerSystem().getAllFloors(); List<Integer> floorIds = targetPlayer.getServer().getTowerSystem().getAllFloors();
if (topFloor < 0 || topFloor > floorIds.size()) { if (topFloor < 0 || topFloor > floorIds.size()) {
CommandHandler.sendTranslatedMessage( CommandHandler.sendTranslatedMessage(
sender, "commands.generic.invalid.value_between", "Tower Level", 0, floorIds.size()); sender, "commands.generic.invalid.value_between", "Tower Level", 0, floorIds.size());
return false; return false;
} }
Map<Integer, TowerLevelRecord> recordMap = targetPlayer.getTowerManager().getRecordMap(); Map<Integer, TowerLevelRecord> recordMap = targetPlayer.getTowerManager().getRecordMap();
// Add records for each unlocked floor // Add records for each unlocked floor
for (int floor : floorIds.subList(0, topFloor)) { for (int floor : floorIds.subList(0, topFloor)) {
if (!recordMap.containsKey(floor)) { if (!recordMap.containsKey(floor)) {
recordMap.put(floor, new TowerLevelRecord(floor)); recordMap.put(floor, new TowerLevelRecord(floor));
} }
} }
// Remove records for each floor past our target // Remove records for each floor past our target
for (int floor : floorIds.subList(topFloor, floorIds.size())) { for (int floor : floorIds.subList(topFloor, floorIds.size())) {
recordMap.remove(floor); recordMap.remove(floor);
} }
// Six stars required on Floor 8 to unlock Floor 9+ // Six stars required on Floor 8 to unlock Floor 9+
if (topFloor > 8) { if (topFloor > 8) {
recordMap recordMap
.get(floorIds.get(7)) .get(floorIds.get(7))
.setLevelStars( .setLevelStars(
0, 0,
6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at 6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at
// all // all
} }
return true; return true;
} }
private boolean setBool(Player sender, Player targetPlayer, PseudoProp pseudoProp, int value) { private boolean setBool(Player sender, Player targetPlayer, PseudoProp pseudoProp, int value) {
boolean enabled = boolean enabled =
switch (pseudoProp) { switch (pseudoProp) {
case GOD_MODE -> targetPlayer.isInGodMode(); case GOD_MODE -> targetPlayer.isInGodMode();
case UNLIMITED_STAMINA -> targetPlayer.isUnlimitedStamina(); case UNLIMITED_STAMINA -> targetPlayer.isUnlimitedStamina();
case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().isEnergyUsage(); case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().isEnergyUsage();
default -> false; default -> false;
}; };
enabled = enabled =
switch (value) { switch (value) {
case -1 -> !enabled; case -1 -> !enabled;
case 0 -> false; case 0 -> false;
default -> true; default -> true;
}; };
switch (pseudoProp) { switch (pseudoProp) {
case GOD_MODE: case GOD_MODE:
targetPlayer.setInGodMode(enabled); targetPlayer.setInGodMode(enabled);
break; break;
case UNLIMITED_STAMINA: case UNLIMITED_STAMINA:
targetPlayer.setUnlimitedStamina(enabled); targetPlayer.setUnlimitedStamina(enabled);
break; break;
case UNLIMITED_ENERGY: case UNLIMITED_ENERGY:
targetPlayer.getEnergyManager().setEnergyUsage(!enabled); targetPlayer.getEnergyManager().setEnergyUsage(!enabled);
break; break;
default: default:
return false; return false;
} }
return true; return true;
} }
private boolean setOpenState(Player targetPlayer, int state, int value) { private boolean setOpenState(Player targetPlayer, int state, int value) {
targetPlayer.sendPacket(new PacketOpenStateChangeNotify(state, value)); targetPlayer.sendPacket(new PacketOpenStateChangeNotify(state, value));
return true; return true;
} }
private boolean unlockMap(Player targetPlayer) { private boolean unlockMap(Player targetPlayer) {
// Unlock. // Unlock.
GameData.getScenePointsPerScene() GameData.getScenePointsPerScene()
.forEach( .forEach(
(sceneId, scenePoints) -> { (sceneId, scenePoints) -> {
// Unlock trans points. // Unlock trans points.
targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints); targetPlayer.getUnlockedScenePoints(sceneId).addAll(scenePoints);
// Unlock map areas. // Unlock map areas.
targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas); targetPlayer.getUnlockedSceneAreas(sceneId).addAll(sceneAreas);
}); });
// Send notify. // Send notify.
int playerScene = targetPlayer.getSceneId(); int playerScene = targetPlayer.getSceneId();
targetPlayer.sendPacket( targetPlayer.sendPacket(
new PacketScenePointUnlockNotify( new PacketScenePointUnlockNotify(
playerScene, targetPlayer.getUnlockedScenePoints(playerScene))); playerScene, targetPlayer.getUnlockedScenePoints(playerScene)));
targetPlayer.sendPacket( targetPlayer.sendPacket(
new PacketSceneAreaUnlockNotify( new PacketSceneAreaUnlockNotify(
playerScene, targetPlayer.getUnlockedSceneAreas(playerScene))); playerScene, targetPlayer.getUnlockedSceneAreas(playerScene)));
return true; return true;
} }
enum PseudoProp { enum PseudoProp {
NONE, NONE,
WORLD_LEVEL, WORLD_LEVEL,
TOWER_LEVEL, TOWER_LEVEL,
BP_LEVEL, BP_LEVEL,
GOD_MODE, GOD_MODE,
UNLIMITED_STAMINA, UNLIMITED_STAMINA,
UNLIMITED_ENERGY, UNLIMITED_ENERGY,
SET_OPENSTATE, SET_OPENSTATE,
UNSET_OPENSTATE, UNSET_OPENSTATE,
UNLOCK_MAP UNLOCK_MAP
} }
static class Prop { static class Prop {
String name; String name;
PlayerProperty prop; PlayerProperty prop;
PseudoProp pseudoProp; PseudoProp pseudoProp;
public Prop(PlayerProperty prop) { public Prop(PlayerProperty prop) {
this(prop.toString(), prop, PseudoProp.NONE); this(prop.toString(), prop, PseudoProp.NONE);
} }
public Prop(String name) { public Prop(String name) {
this(name, PlayerProperty.PROP_NONE, PseudoProp.NONE); this(name, PlayerProperty.PROP_NONE, PseudoProp.NONE);
} }
public Prop(String name, PseudoProp pseudoProp) { public Prop(String name, PseudoProp pseudoProp) {
this(name, PlayerProperty.PROP_NONE, pseudoProp); this(name, PlayerProperty.PROP_NONE, pseudoProp);
} }
public Prop(String name, PlayerProperty prop) { public Prop(String name, PlayerProperty prop) {
this(name, prop, PseudoProp.NONE); this(name, prop, PseudoProp.NONE);
} }
public Prop(String name, PlayerProperty prop, PseudoProp pseudoProp) { public Prop(String name, PlayerProperty prop, PseudoProp pseudoProp) {
this.name = name; this.name = name;
this.prop = prop; this.prop = prop;
this.pseudoProp = pseudoProp; this.pseudoProp = pseudoProp;
} }
} }
} }

View File

@ -1,217 +1,217 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.command.CommandHelpers.*; import static emu.grasscutter.command.CommandHelpers.*;
import static emu.grasscutter.config.Configuration.GAME_OPTIONS; import static emu.grasscutter.config.Configuration.GAME_OPTIONS;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.GadgetData; import emu.grasscutter.data.excels.GadgetData;
import emu.grasscutter.data.excels.ItemData; import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.data.excels.monster.MonsterData; import emu.grasscutter.data.excels.monster.MonsterData;
import emu.grasscutter.game.entity.*; import emu.grasscutter.game.entity.*;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.EntityType; import emu.grasscutter.game.props.EntityType;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.world.Scene; import emu.grasscutter.game.world.Scene;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import lombok.Setter; import lombok.Setter;
@Command( @Command(
label = "spawn", label = "spawn",
aliases = {"drop", "s"}, aliases = {"drop", "s"},
usage = { usage = {
"<itemId> [x<amount>] [blk<blockId>] [grp<groupId>] [cfg<configId>] <x> <y> <z>", "<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>", "<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>" "<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", permission = "server.spawn",
permissionTargeted = "server.spawn.others") permissionTargeted = "server.spawn.others")
public final class SpawnCommand implements CommandHandler { public final class SpawnCommand implements CommandHandler {
private static final Map<Pattern, BiConsumer<SpawnParameters, Integer>> intCommandHandlers = private static final Map<Pattern, BiConsumer<SpawnParameters, Integer>> intCommandHandlers =
Map.ofEntries( Map.ofEntries(
Map.entry(lvlRegex, SpawnParameters::setLvl), Map.entry(lvlRegex, SpawnParameters::setLvl),
Map.entry(amountRegex, SpawnParameters::setAmount), Map.entry(amountRegex, SpawnParameters::setAmount),
Map.entry(stateRegex, SpawnParameters::setState), Map.entry(stateRegex, SpawnParameters::setState),
Map.entry(blockRegex, SpawnParameters::setBlockId), Map.entry(blockRegex, SpawnParameters::setBlockId),
Map.entry(groupRegex, SpawnParameters::setGroupId), Map.entry(groupRegex, SpawnParameters::setGroupId),
Map.entry(configRegex, SpawnParameters::setConfigId), Map.entry(configRegex, SpawnParameters::setConfigId),
Map.entry(maxHPRegex, SpawnParameters::setMaxHP), Map.entry(maxHPRegex, SpawnParameters::setMaxHP),
Map.entry(hpRegex, SpawnParameters::setHp), Map.entry(hpRegex, SpawnParameters::setHp),
Map.entry(defRegex, SpawnParameters::setDef), Map.entry(defRegex, SpawnParameters::setDef),
Map.entry(atkRegex, SpawnParameters::setAtk), Map.entry(atkRegex, SpawnParameters::setAtk),
Map.entry(aiRegex, SpawnParameters::setAi)); Map.entry(aiRegex, SpawnParameters::setAi));
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
SpawnParameters param = new SpawnParameters(); SpawnParameters param = new SpawnParameters();
parseIntParameters(args, param, intCommandHandlers); parseIntParameters(args, param, intCommandHandlers);
// At this point, first remaining argument MUST be the id and the rest the pos // At this point, first remaining argument MUST be the id and the rest the pos
if (args.size() < 1) { 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(); throw new IllegalArgumentException();
} }
switch (args.size()) { switch (args.size()) {
case 4: case 4:
try { try {
float x, y, z; float x, y, z;
x = Float.parseFloat(args.get(1)); x = Float.parseFloat(args.get(1));
y = Float.parseFloat(args.get(2)); y = Float.parseFloat(args.get(2));
z = Float.parseFloat(args.get(3)); z = Float.parseFloat(args.get(3));
param.pos = new Position(x, y, z); param.pos = new Position(x, y, z);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.execution.argument_error")); sender, translate(sender, "commands.execution.argument_error"));
} // Fallthrough } // Fallthrough
case 1: case 1:
try { try {
param.id = Integer.parseInt(args.get(0)); param.id = Integer.parseInt(args.get(0));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.generic.invalid.entityId")); sender, translate(sender, "commands.generic.invalid.entityId"));
} }
break; break;
default: default:
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
MonsterData monsterData = GameData.getMonsterDataMap().get(param.id); MonsterData monsterData = GameData.getMonsterDataMap().get(param.id);
GadgetData gadgetData = GameData.getGadgetDataMap().get(param.id); GadgetData gadgetData = GameData.getGadgetDataMap().get(param.id);
ItemData itemData = GameData.getItemDataMap().get(param.id); ItemData itemData = GameData.getItemDataMap().get(param.id);
if (monsterData == null && gadgetData == null && itemData == null) { if (monsterData == null && gadgetData == null && itemData == null) {
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId"));
return; return;
} }
param.scene = targetPlayer.getScene(); param.scene = targetPlayer.getScene();
if (param.scene.getEntities().size() + param.amount > GAME_OPTIONS.sceneEntityLimit) { if (param.scene.getEntities().size() + param.amount > GAME_OPTIONS.sceneEntityLimit) {
param.amount = param.amount =
Math.max( Math.max(
Math.min( Math.min(
GAME_OPTIONS.sceneEntityLimit - param.scene.getEntities().size(), param.amount), GAME_OPTIONS.sceneEntityLimit - param.scene.getEntities().size(), param.amount),
0); 0);
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.spawn.limit_reached", param.amount)); sender, translate(sender, "commands.spawn.limit_reached", param.amount));
if (param.amount <= 0) { if (param.amount <= 0) {
return; return;
} }
} }
double maxRadius = Math.sqrt(param.amount * 0.2 / Math.PI); double maxRadius = Math.sqrt(param.amount * 0.2 / Math.PI);
if (param.pos == null) { if (param.pos == null) {
param.pos = targetPlayer.getPosition(); param.pos = targetPlayer.getPosition();
} }
for (int i = 0; i < param.amount; i++) { for (int i = 0; i < param.amount; i++) {
Position pos = GetRandomPositionInCircle(param.pos, maxRadius).addY(3); Position pos = GetRandomPositionInCircle(param.pos, maxRadius).addY(3);
GameEntity entity = null; GameEntity entity = null;
if (itemData != null) { if (itemData != null) {
entity = createItem(itemData, param, pos); entity = createItem(itemData, param, pos);
} }
if (gadgetData != null) { if (gadgetData != null) {
pos.addY(-3); pos.addY(-3);
entity = createGadget(gadgetData, param, pos, targetPlayer); entity = createGadget(gadgetData, param, pos, targetPlayer);
} }
if (monsterData != null) { if (monsterData != null) {
entity = createMonster(monsterData, param, pos); entity = createMonster(monsterData, param, pos);
} }
applyCommonParameters(entity, param); applyCommonParameters(entity, param);
param.scene.addEntity(entity); param.scene.addEntity(entity);
} }
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.spawn.success", param.amount, param.id)); sender, translate(sender, "commands.spawn.success", param.amount, param.id));
} }
private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) { private EntityItem createItem(ItemData itemData, SpawnParameters param, Position pos) {
return new EntityItem(param.scene, null, itemData, pos, 1, true); return new EntityItem(param.scene, null, itemData, pos, 1, true);
} }
private EntityMonster createMonster( private EntityMonster createMonster(
MonsterData monsterData, SpawnParameters param, Position pos) { MonsterData monsterData, SpawnParameters param, Position pos) {
var entity = new EntityMonster(param.scene, monsterData, pos, param.lvl); var entity = new EntityMonster(param.scene, monsterData, pos, param.lvl);
if (param.ai != -1) { if (param.ai != -1) {
entity.setAiId(param.ai); entity.setAiId(param.ai);
} }
return entity; return entity;
} }
private EntityBaseGadget createGadget( private EntityBaseGadget createGadget(
GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) { GadgetData gadgetData, SpawnParameters param, Position pos, Player targetPlayer) {
EntityBaseGadget entity; EntityBaseGadget entity;
if (gadgetData.getType() == EntityType.Vehicle) { if (gadgetData.getType() == EntityType.Vehicle) {
entity = entity =
new EntityVehicle( new EntityVehicle(
param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation()); param.scene, targetPlayer, param.id, 0, pos, targetPlayer.getRotation());
} else { } else {
entity = new EntityGadget(param.scene, param.id, pos, targetPlayer.getRotation()); entity = new EntityGadget(param.scene, param.id, pos, targetPlayer.getRotation());
if (param.state != -1) { if (param.state != -1) {
((EntityGadget) entity).setState(param.state); ((EntityGadget) entity).setState(param.state);
} }
} }
return entity; return entity;
} }
private void applyCommonParameters(GameEntity entity, SpawnParameters param) { private void applyCommonParameters(GameEntity entity, SpawnParameters param) {
if (param.blockId != -1) { if (param.blockId != -1) {
entity.setBlockId(param.blockId); entity.setBlockId(param.blockId);
} }
if (param.groupId != -1) { if (param.groupId != -1) {
entity.setGroupId(param.groupId); entity.setGroupId(param.groupId);
} }
if (param.configId != -1) { if (param.configId != -1) {
entity.setConfigId(param.configId); entity.setConfigId(param.configId);
} }
if (param.maxHP != -1) { if (param.maxHP != -1) {
entity.setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, param.maxHP); entity.setFightProperty(FightProperty.FIGHT_PROP_MAX_HP, param.maxHP);
entity.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, param.maxHP); entity.setFightProperty(FightProperty.FIGHT_PROP_BASE_HP, param.maxHP);
} }
if (param.hp != -1) { if (param.hp != -1) {
entity.setFightProperty( entity.setFightProperty(
FightProperty.FIGHT_PROP_CUR_HP, param.hp == 0 ? Float.MAX_VALUE : param.hp); FightProperty.FIGHT_PROP_CUR_HP, param.hp == 0 ? Float.MAX_VALUE : param.hp);
} }
if (param.atk != -1) { if (param.atk != -1) {
entity.setFightProperty(FightProperty.FIGHT_PROP_ATTACK, param.atk); entity.setFightProperty(FightProperty.FIGHT_PROP_ATTACK, param.atk);
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk); entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, param.atk);
} }
if (param.def != -1) { if (param.def != -1) {
entity.setFightProperty(FightProperty.FIGHT_PROP_DEFENSE, param.def); entity.setFightProperty(FightProperty.FIGHT_PROP_DEFENSE, param.def);
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def); entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, param.def);
} }
} }
private Position GetRandomPositionInCircle(Position origin, double radius) { private Position GetRandomPositionInCircle(Position origin, double radius) {
Position target = origin.clone(); Position target = origin.clone();
double angle = Math.random() * 360; double angle = Math.random() * 360;
double r = Math.sqrt(Math.random() * radius * radius); double r = Math.sqrt(Math.random() * radius * radius);
target.addX((float) (r * Math.cos(angle))).addZ((float) (r * Math.sin(angle))); target.addX((float) (r * Math.cos(angle))).addZ((float) (r * Math.sin(angle)));
return target; return target;
} }
private static class SpawnParameters { private static class SpawnParameters {
@Setter public int id; @Setter public int id;
@Setter public int lvl = 1; @Setter public int lvl = 1;
@Setter public int amount = 1; @Setter public int amount = 1;
@Setter public int blockId = -1; @Setter public int blockId = -1;
@Setter public int groupId = -1; @Setter public int groupId = -1;
@Setter public int configId = -1; @Setter public int configId = -1;
@Setter public int state = -1; @Setter public int state = -1;
@Setter public int hp = -1; @Setter public int hp = -1;
@Setter public int maxHP = -1; @Setter public int maxHP = -1;
@Setter public int atk = -1; @Setter public int atk = -1;
@Setter public int def = -1; @Setter public int def = -1;
@Setter public int ai = -1; @Setter public int ai = -1;
@Setter public Position pos = null; @Setter public Position pos = null;
public Scene scene = null; public Scene scene = null;
} }
} }

View File

@ -1,129 +1,129 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData; import emu.grasscutter.data.excels.avatar.AvatarSkillDepotData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.utils.Language; import emu.grasscutter.utils.Language;
import java.util.List; import java.util.List;
@Command( @Command(
label = "talent", label = "talent",
usage = {"set <talentId> <level>", "(n|e|q|all) <level>", "getid"}, usage = {"set <talentId> <level>", "(n|e|q|all) <level>", "getid"},
permission = "player.settalent", permission = "player.settalent",
permissionTargeted = "player.settalent.others") permissionTargeted = "player.settalent.others")
public final class TalentCommand implements CommandHandler { public final class TalentCommand implements CommandHandler {
private void setTalentLevel(Player sender, Avatar avatar, int skillId, int newLevel) { private void setTalentLevel(Player sender, Avatar avatar, int skillId, int newLevel) {
if (avatar.setSkillLevel(skillId, newLevel)) { if (avatar.setSkillLevel(skillId, newLevel)) {
long nameHash = GameData.getAvatarSkillDataMap().get(skillId).getNameTextMapHash(); long nameHash = GameData.getAvatarSkillDataMap().get(skillId).getNameTextMapHash();
var name = Language.getTextMapKey(nameHash); var name = Language.getTextMapKey(nameHash);
CommandHandler.sendTranslatedMessage( CommandHandler.sendTranslatedMessage(
sender, "commands.talent.set_id", skillId, name, newLevel); sender, "commands.talent.set_id", skillId, name, newLevel);
} else { } else {
CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range"); CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range");
} }
} }
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { if (args.size() < 1) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
Avatar avatar = targetPlayer.getTeamManager().getCurrentAvatarEntity().getAvatar(); Avatar avatar = targetPlayer.getTeamManager().getCurrentAvatarEntity().getAvatar();
AvatarSkillDepotData skillDepot = avatar.getSkillDepot(); AvatarSkillDepotData skillDepot = avatar.getSkillDepot();
if (skillDepot if (skillDepot
== null) { // Avatars without skill depots aren't a suitable target even with manual skillId == null) { // Avatars without skill depots aren't a suitable target even with manual skillId
// specified // specified
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id"); CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id");
return; return;
} }
int skillId = 0; int skillId = 0;
int newLevel = -1; int newLevel = -1;
String cmdSwitch = args.get(0).toLowerCase(); String cmdSwitch = args.get(0).toLowerCase();
switch (cmdSwitch) { switch (cmdSwitch) {
default -> { default -> {
sendUsageMessage(sender); sendUsageMessage(sender);
} }
case "set" -> { case "set" -> {
if (args.size() < 3) { if (args.size() < 3) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
try { try {
skillId = Integer.parseInt(args.get(1)); skillId = Integer.parseInt(args.get(1));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id"); CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_skill_id");
return; return;
} }
try { try {
newLevel = Integer.parseInt(args.get(2)); newLevel = Integer.parseInt(args.get(2));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level"); CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
return; return;
} }
setTalentLevel(sender, avatar, skillId, newLevel); setTalentLevel(sender, avatar, skillId, newLevel);
} }
case "n", "e", "q" -> { case "n", "e", "q" -> {
if (args.size() < 2) { if (args.size() < 2) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
try { try {
newLevel = Integer.parseInt(args.get(1)); newLevel = Integer.parseInt(args.get(1));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level"); CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
return; return;
} }
skillId = skillId =
switch (cmdSwitch) { switch (cmdSwitch) {
default -> skillDepot.getSkills().get(0); default -> skillDepot.getSkills().get(0);
case "e" -> skillDepot.getSkills().get(1); case "e" -> skillDepot.getSkills().get(1);
case "q" -> skillDepot.getEnergySkill(); case "q" -> skillDepot.getEnergySkill();
}; };
setTalentLevel(sender, avatar, skillId, newLevel); setTalentLevel(sender, avatar, skillId, newLevel);
} }
case "all" -> { case "all" -> {
if (args.size() < 2) { if (args.size() < 2) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
try { try {
newLevel = Integer.parseInt(args.get(1)); newLevel = Integer.parseInt(args.get(1));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level"); CommandHandler.sendTranslatedMessage(sender, "commands.talent.invalid_level");
return; return;
} }
// This stops setTalentLevel from outputting 3 "levels out of range" messages // This stops setTalentLevel from outputting 3 "levels out of range" messages
if (newLevel < 1 || newLevel > 15) { if (newLevel < 1 || newLevel > 15) {
CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range"); CommandHandler.sendTranslatedMessage(sender, "commands.talent.out_of_range");
return; return;
} }
int finalNewLevel = newLevel; int finalNewLevel = newLevel;
skillDepot skillDepot
.getSkillsAndEnergySkill() .getSkillsAndEnergySkill()
.forEach(id -> setTalentLevel(sender, avatar, id, finalNewLevel)); .forEach(id -> setTalentLevel(sender, avatar, id, finalNewLevel));
} }
case "getid" -> { case "getid" -> {
var map = GameData.getAvatarSkillDataMap(); var map = GameData.getAvatarSkillDataMap();
skillDepot skillDepot
.getSkillsAndEnergySkill() .getSkillsAndEnergySkill()
.forEach( .forEach(
id -> { id -> {
var talent = map.get(id); var talent = map.get(id);
if (talent == null) return; if (talent == null) return;
var talentName = Language.getTextMapKey(talent.getNameTextMapHash()); var talentName = Language.getTextMapKey(talent.getNameTextMapHash());
var talentDesc = Language.getTextMapKey(talent.getDescTextMapHash()); var talentDesc = Language.getTextMapKey(talent.getDescTextMapHash());
CommandHandler.sendTranslatedMessage( CommandHandler.sendTranslatedMessage(
sender, "commands.talent.id_desc", id, talentName, talentDesc); sender, "commands.talent.id_desc", id, talentName, talentDesc);
}); });
} }
} }
} }
} }

View File

@ -1,156 +1,156 @@
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.activity.trialavatar.TrialAvatarActivityHandler; import emu.grasscutter.game.activity.trialavatar.TrialAvatarActivityHandler;
import emu.grasscutter.game.activity.trialavatar.TrialAvatarPlayerData; import emu.grasscutter.game.activity.trialavatar.TrialAvatarPlayerData;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActivityType; import emu.grasscutter.game.props.ActivityType;
import emu.grasscutter.server.packet.send.PacketActivityInfoNotify; import emu.grasscutter.server.packet.send.PacketActivityInfoNotify;
import emu.grasscutter.utils.JsonUtils; import emu.grasscutter.utils.JsonUtils;
import java.util.List; import java.util.List;
@Command( @Command(
label = "trialAvatarActivity", label = "trialAvatarActivity",
aliases = {"taa"}, aliases = {"taa"},
usage = { usage = {
"change <scheduleId>", "change <scheduleId>",
"toggleDungeon <index(start from 1)|all>", "toggleDungeon <index(start from 1)|all>",
"toggleReward <index(start from 1)|all>" "toggleReward <index(start from 1)|all>"
}, },
permission = "player.trialavataractivity", permission = "player.trialavataractivity",
permissionTargeted = "player.trialavataractivity.others") permissionTargeted = "player.trialavataractivity.others")
public final class TrialAvatarActivityCommand implements CommandHandler { public final class TrialAvatarActivityCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 2) { if (args.size() < 2) {
sendUsageMessage(sender); sendUsageMessage(sender);
return; return;
} }
var action = args.get(0).toLowerCase(); var action = args.get(0).toLowerCase();
var param = args.get(1); var param = args.get(1);
var playerDataOption = var playerDataOption =
targetPlayer targetPlayer
.getActivityManager() .getActivityManager()
.getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR); .getPlayerActivityDataByActivityType(ActivityType.NEW_ACTIVITY_TRIAL_AVATAR);
if (playerDataOption.isEmpty()) { if (playerDataOption.isEmpty()) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.not_found")); sender, translate(sender, "commands.trialAvatarActivity.not_found"));
return; return;
} }
var playerData = playerDataOption.get(); var playerData = playerDataOption.get();
var handler = (TrialAvatarActivityHandler) playerData.getActivityHandler(); var handler = (TrialAvatarActivityHandler) playerData.getActivityHandler();
if (handler == null) { if (handler == null) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.not_found")); sender, translate(sender, "commands.trialAvatarActivity.not_found"));
return; return;
} }
var trialAvatarPlayerData = var trialAvatarPlayerData =
JsonUtils.decode(playerData.getDetail(), TrialAvatarPlayerData.class); JsonUtils.decode(playerData.getDetail(), TrialAvatarPlayerData.class);
if (trialAvatarPlayerData == null) { if (trialAvatarPlayerData == null) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.not_found")); sender, translate(sender, "commands.trialAvatarActivity.not_found"));
return; return;
} }
switch (action) { switch (action) {
default -> this.sendUsageMessage(sender); default -> this.sendUsageMessage(sender);
case "change" -> { case "change" -> {
if (!param.chars().allMatch(Character::isDigit)) { // if its not number if (!param.chars().allMatch(Character::isDigit)) { // if its not number
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.invalid_param")); sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
return; return;
} }
if (TrialAvatarPlayerData.getAvatarIdList(Integer.parseInt(param)).isEmpty()) { if (TrialAvatarPlayerData.getAvatarIdList(Integer.parseInt(param)).isEmpty()) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, sender,
translate( translate(
sender, sender,
"commands.trialAvatarActivity.schedule_not_found", "commands.trialAvatarActivity.schedule_not_found",
Integer.parseInt(param))); Integer.parseInt(param)));
return; return;
} }
playerData.setDetail(TrialAvatarPlayerData.create(Integer.parseInt(param))); playerData.setDetail(TrialAvatarPlayerData.create(Integer.parseInt(param)));
playerData.save(); playerData.save();
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, sender,
translate( translate(
sender, "commands.trialAvatarActivity.success_schedule", Integer.parseInt(param))); sender, "commands.trialAvatarActivity.success_schedule", Integer.parseInt(param)));
} }
case "toggledungeon" -> { case "toggledungeon" -> {
if (param.chars().allMatch(Character::isDigit)) { // if its number if (param.chars().allMatch(Character::isDigit)) { // if its number
if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size() if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size()
|| Integer.parseInt(param) - 1 <= 0) { || Integer.parseInt(param) - 1 <= 0) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.invalid_param")); sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
return; return;
} }
TrialAvatarPlayerData.RewardInfoItem rewardInfo = TrialAvatarPlayerData.RewardInfoItem rewardInfo =
trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1); trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1);
rewardInfo.setPassedDungeon(!rewardInfo.isPassedDungeon()); rewardInfo.setPassedDungeon(!rewardInfo.isPassedDungeon());
playerData.setDetail(trialAvatarPlayerData); playerData.setDetail(trialAvatarPlayerData);
playerData.save(); playerData.save();
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, sender,
translate( translate(
sender, "commands.trialAvatarActivity.success_dungeon", Integer.parseInt(param))); sender, "commands.trialAvatarActivity.success_dungeon", Integer.parseInt(param)));
} else { } else {
if (!param.equals("all")) { if (!param.equals("all")) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.invalid_param")); sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
return; return;
} }
trialAvatarPlayerData trialAvatarPlayerData
.getRewardInfoList() .getRewardInfoList()
.forEach(r -> r.setPassedDungeon(!r.isPassedDungeon())); .forEach(r -> r.setPassedDungeon(!r.isPassedDungeon()));
playerData.setDetail(trialAvatarPlayerData); playerData.setDetail(trialAvatarPlayerData);
playerData.save(); playerData.save();
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.success_dungeon_all")); sender, translate(sender, "commands.trialAvatarActivity.success_dungeon_all"));
} }
} }
case "togglereward" -> { case "togglereward" -> {
if (param.chars().allMatch(Character::isDigit)) { // if its number if (param.chars().allMatch(Character::isDigit)) { // if its number
if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size() if (Integer.parseInt(param) - 1 >= trialAvatarPlayerData.getRewardInfoList().size()
|| Integer.parseInt(param) - 1 <= 0) { || Integer.parseInt(param) - 1 <= 0) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.invalid_param")); sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
return; return;
} }
TrialAvatarPlayerData.RewardInfoItem rewardInfo = TrialAvatarPlayerData.RewardInfoItem rewardInfo =
trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1); trialAvatarPlayerData.getRewardInfoList().get(Integer.parseInt(param) - 1);
rewardInfo.setReceivedReward(!rewardInfo.isReceivedReward()); rewardInfo.setReceivedReward(!rewardInfo.isReceivedReward());
playerData.setDetail(trialAvatarPlayerData); playerData.setDetail(trialAvatarPlayerData);
playerData.save(); playerData.save();
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, sender,
translate( translate(
sender, "commands.trialAvatarActivity.success_reward", Integer.parseInt(param))); sender, "commands.trialAvatarActivity.success_reward", Integer.parseInt(param)));
} else { } else {
if (!param.toLowerCase().equals("all")) { if (!param.toLowerCase().equals("all")) {
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.invalid_param")); sender, translate(sender, "commands.trialAvatarActivity.invalid_param"));
return; return;
} }
trialAvatarPlayerData trialAvatarPlayerData
.getRewardInfoList() .getRewardInfoList()
.forEach(r -> r.setReceivedReward(!r.isReceivedReward())); .forEach(r -> r.setReceivedReward(!r.isReceivedReward()));
playerData.setDetail(trialAvatarPlayerData); playerData.setDetail(trialAvatarPlayerData);
playerData.save(); playerData.save();
CommandHandler.sendMessage( CommandHandler.sendMessage(
sender, translate(sender, "commands.trialAvatarActivity.success_reward_all")); sender, translate(sender, "commands.trialAvatarActivity.success_reward_all"));
} }
} }
} }
targetPlayer.sendPacket( targetPlayer.sendPacket(
new PacketActivityInfoNotify( new PacketActivityInfoNotify(
handler.toProto(playerData, targetPlayer.getActivityManager().getConditionExecutor()))); handler.toProto(playerData, targetPlayer.getActivityManager().getConditionExecutor())));
} }
} }

View File

@ -1,118 +1,118 @@
package emu.grasscutter.config; package emu.grasscutter.config;
import static emu.grasscutter.Grasscutter.config; import static emu.grasscutter.Grasscutter.config;
import emu.grasscutter.utils.FileUtils; import emu.grasscutter.utils.FileUtils;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.Locale; import java.util.Locale;
/** /**
* A data container for the server's configuration. * 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 { public final class Configuration extends ConfigContainer {
/* /*
* Constants * Constants
*/ */
// 'c' is short for 'config' and makes code look 'cleaner'. // 'c' is short for 'config' and makes code look 'cleaner'.
public static final ConfigContainer c = config; public static final ConfigContainer c = config;
public static final Locale LANGUAGE = config.language.language; public static final Locale LANGUAGE = config.language.language;
public static final Locale FALLBACK_LANGUAGE = config.language.fallback; public static final Locale FALLBACK_LANGUAGE = config.language.fallback;
public static final String DOCUMENT_LANGUAGE = config.language.document; public static final String DOCUMENT_LANGUAGE = config.language.document;
public static final Server SERVER = config.server; public static final Server SERVER = config.server;
public static final Database DATABASE = config.databaseInfo; public static final Database DATABASE = config.databaseInfo;
public static final Account ACCOUNT = config.account; public static final Account ACCOUNT = config.account;
public static final HTTP HTTP_INFO = config.server.http; public static final HTTP HTTP_INFO = config.server.http;
public static final Game GAME_INFO = config.server.game; public static final Game GAME_INFO = config.server.game;
public static final Dispatch DISPATCH_INFO = config.server.dispatch; public static final Dispatch DISPATCH_INFO = config.server.dispatch;
public static final DebugMode DEBUG_MODE_INFO = config.server.debugMode; public static final DebugMode DEBUG_MODE_INFO = config.server.debugMode;
public static final Encryption HTTP_ENCRYPTION = config.server.http.encryption; public static final Encryption HTTP_ENCRYPTION = config.server.http.encryption;
public static final Policies HTTP_POLICIES = config.server.http.policies; public static final Policies HTTP_POLICIES = config.server.http.policies;
public static final Files HTTP_STATIC_FILES = config.server.http.files; 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 GAME_OPTIONS = config.server.game.gameOptions;
public static final GameOptions.InventoryLimits INVENTORY_LIMITS = public static final GameOptions.InventoryLimits INVENTORY_LIMITS =
config.server.game.gameOptions.inventoryLimits; config.server.game.gameOptions.inventoryLimits;
private static final String DATA_FOLDER = config.folderStructure.data; private static final String DATA_FOLDER = config.folderStructure.data;
private static final String PLUGINS_FOLDER = config.folderStructure.plugins; private static final String PLUGINS_FOLDER = config.folderStructure.plugins;
private static final String SCRIPTS_FOLDER = config.folderStructure.scripts; private static final String SCRIPTS_FOLDER = config.folderStructure.scripts;
private static final String PACKETS_FOLDER = config.folderStructure.packets; private static final String PACKETS_FOLDER = config.folderStructure.packets;
/* /*
* Utilities * Utilities
*/ */
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static String DATA() { public static String DATA() {
return DATA_FOLDER; return DATA_FOLDER;
} }
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static String DATA(String path) { public static String DATA(String path) {
return Path.of(DATA_FOLDER, path).toString(); return Path.of(DATA_FOLDER, path).toString();
} }
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static Path getResourcePath(String path) { public static Path getResourcePath(String path) {
return FileUtils.getResourcePath(path); return FileUtils.getResourcePath(path);
} }
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static String RESOURCE(String path) { public static String RESOURCE(String path) {
return FileUtils.getResourcePath(path).toString(); return FileUtils.getResourcePath(path).toString();
} }
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static String PLUGIN() { public static String PLUGIN() {
return PLUGINS_FOLDER; return PLUGINS_FOLDER;
} }
public static String PLUGIN(String path) { public static String PLUGIN(String path) {
return Path.of(PLUGINS_FOLDER, path).toString(); return Path.of(PLUGINS_FOLDER, path).toString();
} }
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static String SCRIPT(String path) { public static String SCRIPT(String path) {
return Path.of(SCRIPTS_FOLDER, path).toString(); return Path.of(SCRIPTS_FOLDER, path).toString();
} }
@Deprecated(forRemoval = true) @Deprecated(forRemoval = true)
public static String PACKET(String path) { public static String PACKET(String path) {
return Path.of(PACKETS_FOLDER, path).toString(); return Path.of(PACKETS_FOLDER, path).toString();
} }
/** /**
* Fallback method. * Fallback method.
* *
* @param left Attempt to use. * @param left Attempt to use.
* @param right Use if left is undefined. * @param right Use if left is undefined.
* @return Left or right. * @return Left or right.
*/ */
public static <T> T lr(T left, T right) { public static <T> T lr(T left, T right) {
return left == null ? right : left; return left == null ? right : left;
} }
/** /**
* {@link Configuration#lr(Object, Object)} for {@link String}s. * {@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. * @param right Use if left is empty.
* @return Left or right. * @return Left or right.
*/ */
public static String lr(String left, String right) { public static String lr(String left, String right) {
return left.isEmpty() ? right : left; return left.isEmpty() ? right : left;
} }
/** /**
* {@link Configuration#lr(Object, Object)} for {@link Integer}s. * {@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. * @param right Use if left is 0.
* @return Left or right. * @return Left or right.
*/ */
public static int lr(int left, int right) { public static int lr(int left, int right) {
return left == 0 ? right : left; return left == 0 ? right : left;
} }
} }

View File

@ -1,86 +1,86 @@
package emu.grasscutter.data; package emu.grasscutter.data;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.ResourceLoader.AvatarConfig; import emu.grasscutter.data.ResourceLoader.AvatarConfig;
import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData; import emu.grasscutter.data.excels.reliquary.ReliquaryAffixData;
import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData; import emu.grasscutter.data.excels.reliquary.ReliquaryMainPropData;
import emu.grasscutter.game.managers.blossom.BlossomConfig; import emu.grasscutter.game.managers.blossom.BlossomConfig;
import emu.grasscutter.game.world.SpawnDataEntry; import emu.grasscutter.game.world.SpawnDataEntry;
import emu.grasscutter.utils.WeightedList; import emu.grasscutter.utils.WeightedList;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap; import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2ObjectOpenHashMap;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
import java.util.Map; import java.util.Map;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
public class GameDepot { 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 = private static final Int2ObjectMap<WeightedList<ReliquaryMainPropData>> relicRandomMainPropDepot =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot = private static final Int2ObjectMap<List<ReliquaryMainPropData>> relicMainPropDepot =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot = private static final Int2ObjectMap<List<ReliquaryAffixData>> relicAffixDepot =
new Int2ObjectOpenHashMap<>(); new Int2ObjectOpenHashMap<>();
@Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>(); @Getter @Setter private static Map<String, AvatarConfig> playerAbilities = new HashMap<>();
@Getter @Getter
private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists = private static final HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> spawnLists =
new HashMap<>(); new HashMap<>();
@Getter @Setter private static BlossomConfig blossomConfig; @Getter @Setter private static BlossomConfig blossomConfig;
public static void load() { public static void load() {
for (ReliquaryMainPropData data : GameData.getReliquaryMainPropDataMap().values()) { for (ReliquaryMainPropData data : GameData.getReliquaryMainPropDataMap().values()) {
if (data.getWeight() <= 0 || data.getPropDepotId() <= 0) { if (data.getWeight() <= 0 || data.getPropDepotId() <= 0) {
continue; continue;
} }
List<ReliquaryMainPropData> list = List<ReliquaryMainPropData> list =
relicMainPropDepot.computeIfAbsent(data.getPropDepotId(), k -> new ArrayList<>()); relicMainPropDepot.computeIfAbsent(data.getPropDepotId(), k -> new ArrayList<>());
list.add(data); list.add(data);
WeightedList<ReliquaryMainPropData> weightedList = WeightedList<ReliquaryMainPropData> weightedList =
relicRandomMainPropDepot.computeIfAbsent( relicRandomMainPropDepot.computeIfAbsent(
data.getPropDepotId(), k -> new WeightedList<>()); data.getPropDepotId(), k -> new WeightedList<>());
weightedList.add(data.getWeight(), data); weightedList.add(data.getWeight(), data);
} }
for (ReliquaryAffixData data : GameData.getReliquaryAffixDataMap().values()) { for (ReliquaryAffixData data : GameData.getReliquaryAffixDataMap().values()) {
if (data.getWeight() <= 0 || data.getDepotId() <= 0) { if (data.getWeight() <= 0 || data.getDepotId() <= 0) {
continue; continue;
} }
List<ReliquaryAffixData> list = List<ReliquaryAffixData> list =
relicAffixDepot.computeIfAbsent(data.getDepotId(), k -> new ArrayList<>()); relicAffixDepot.computeIfAbsent(data.getDepotId(), k -> new ArrayList<>());
list.add(data); list.add(data);
} }
// Let the server owner know if theyre missing weights // Let the server owner know if theyre missing weights
if (relicMainPropDepot.size() == 0 || relicAffixDepot.size() == 0) { if (relicMainPropDepot.size() == 0 || relicAffixDepot.size() == 0) {
Grasscutter.getLogger() Grasscutter.getLogger()
.error( .error(
"Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder."); "Relic properties are missing weights! Please check your ReliquaryMainPropExcelConfigData or ReliquaryAffixExcelConfigData files in your ExcelBinOutput folder.");
} }
} }
public static ReliquaryMainPropData getRandomRelicMainProp(int depot) { public static ReliquaryMainPropData getRandomRelicMainProp(int depot) {
WeightedList<ReliquaryMainPropData> depotList = relicRandomMainPropDepot.get(depot); WeightedList<ReliquaryMainPropData> depotList = relicRandomMainPropDepot.get(depot);
if (depotList == null) { if (depotList == null) {
return null; return null;
} }
return depotList.next(); return depotList.next();
} }
public static List<ReliquaryMainPropData> getRelicMainPropList(int depot) { public static List<ReliquaryMainPropData> getRelicMainPropList(int depot) {
return relicMainPropDepot.get(depot); return relicMainPropDepot.get(depot);
} }
public static List<ReliquaryAffixData> getRelicAffixList(int depot) { public static List<ReliquaryAffixData> getRelicAffixList(int depot) {
return relicAffixDepot.get(depot); return relicAffixDepot.get(depot);
} }
public static void addSpawnListById( public static void addSpawnListById(
HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> data) { HashMap<SpawnDataEntry.GridBlockId, ArrayList<SpawnDataEntry>> data) {
spawnLists.putAll(data); spawnLists.putAll(data);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,3 +1,3 @@
package emu.grasscutter.data.binout.config; package emu.grasscutter.data.binout.config;
public class ConfigEntityAvatar extends ConfigEntityBase {} public class ConfigEntityAvatar extends ConfigEntityBase {}

View File

@ -1,17 +1,17 @@
package emu.grasscutter.data.binout.config; package emu.grasscutter.data.binout.config;
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData; import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
import emu.grasscutter.data.binout.config.fields.ConfigCombat; import emu.grasscutter.data.binout.config.fields.ConfigCombat;
import emu.grasscutter.data.binout.config.fields.ConfigCommon; import emu.grasscutter.data.binout.config.fields.ConfigCommon;
import emu.grasscutter.data.binout.config.fields.ConfigGlobalValue; import emu.grasscutter.data.binout.config.fields.ConfigGlobalValue;
import java.util.Collection; import java.util.Collection;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import lombok.Data; import lombok.Data;
@Data @Data
public class ConfigEntityBase { public class ConfigEntityBase {
@Nullable ConfigCommon configCommon; @Nullable ConfigCommon configCommon;
@Nullable ConfigCombat combat; @Nullable ConfigCombat combat;
Collection<ConfigAbilityData> abilities; Collection<ConfigAbilityData> abilities;
ConfigGlobalValue globalValue; // used for SGV in monsters and Gadgets ConfigGlobalValue globalValue; // used for SGV in monsters and Gadgets
} }

View File

@ -1,11 +1,11 @@
package emu.grasscutter.data.binout.config; package emu.grasscutter.data.binout.config;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigEntityGadget extends ConfigEntityBase { public class ConfigEntityGadget extends ConfigEntityBase {
// There are more values that can be added that might be useful in the json // There are more values that can be added that might be useful in the json
} }

View File

@ -1,6 +1,6 @@
package emu.grasscutter.data.binout.config; package emu.grasscutter.data.binout.config;
import lombok.Data; import lombok.Data;
@Data @Data
public class ConfigEntityMonster extends ConfigEntityBase {} public class ConfigEntityMonster extends ConfigEntityBase {}

View File

@ -1,13 +1,13 @@
package emu.grasscutter.data.binout.config; package emu.grasscutter.data.binout.config;
import emu.grasscutter.data.binout.config.fields.ConfigAbilityData; import emu.grasscutter.data.binout.config.fields.ConfigAbilityData;
import java.util.List; import java.util.List;
import lombok.Getter; import lombok.Getter;
public class ConfigLevelEntity { public class ConfigLevelEntity {
@Getter private List<ConfigAbilityData> abilities; // monster abilities @Getter private List<ConfigAbilityData> abilities; // monster abilities
@Getter private List<ConfigAbilityData> avatarAbilities; @Getter private List<ConfigAbilityData> avatarAbilities;
@Getter private List<ConfigAbilityData> teamAbilities; @Getter private List<ConfigAbilityData> teamAbilities;
@Getter private List<Integer> preloadMonsterEntityIDs; @Getter private List<Integer> preloadMonsterEntityIDs;
} }

View File

@ -1,10 +1,10 @@
package emu.grasscutter.data.binout.config.fields; package emu.grasscutter.data.binout.config.fields;
import lombok.Data; import lombok.Data;
@Data @Data
public class ConfigAbilityData { public class ConfigAbilityData {
public String abilityID; public String abilityID;
public String abilityName; public String abilityName;
public String abilityOverride; public String abilityOverride;
} }

View File

@ -1,8 +1,8 @@
package emu.grasscutter.data.binout.config.fields; package emu.grasscutter.data.binout.config.fields;
import lombok.Data; import lombok.Data;
@Data @Data
public class ConfigAiBeta { public class ConfigAiBeta {
boolean enable; boolean enable;
} }

View File

@ -1,12 +1,12 @@
package emu.grasscutter.data.binout.config.fields; package emu.grasscutter.data.binout.config.fields;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigCombat { public class ConfigCombat {
// There are more values that can be added that might be useful in the json // There are more values that can be added that might be useful in the json
ConfigCombatProperty property; ConfigCombatProperty property;
} }

View File

@ -1,18 +1,18 @@
package emu.grasscutter.data.binout.config.fields; package emu.grasscutter.data.binout.config.fields;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigCombatDie { public class ConfigCombatDie {
@SerializedName( @SerializedName(
value = "dieEndTime", value = "dieEndTime",
alternate = {"HGGPMFGGBNC"}) alternate = {"HGGPMFGGBNC"})
double dieEndTime; double dieEndTime;
double dieForceDisappearTime; double dieForceDisappearTime;
boolean hasAnimatorDie; boolean hasAnimatorDie;
} }

View File

@ -1,18 +1,18 @@
package emu.grasscutter.data.binout.config.fields; package emu.grasscutter.data.binout.config.fields;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ConfigCombatProperty { public class ConfigCombatProperty {
float HP; float HP;
boolean isLockHP; boolean isLockHP;
boolean isInvincible; boolean isInvincible;
boolean isGhostToAllied; boolean isGhostToAllied;
float attack; float attack;
float defence; float defence;
float weight; float weight;
boolean useCreatorProperty; boolean useCreatorProperty;
} }

View File

@ -1,6 +1,6 @@
package emu.grasscutter.data.binout.config.fields; package emu.grasscutter.data.binout.config.fields;
import lombok.Data; import lombok.Data;
@Data @Data
public class ConfigCommon {} public class ConfigCommon {}

View File

@ -1,12 +1,12 @@
package emu.grasscutter.data.binout.config.fields; package emu.grasscutter.data.binout.config.fields;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
import lombok.Data; import lombok.Data;
/** Contains information about the entities SGVs */ /** Contains information about the entities SGVs */
@Data @Data
public class ConfigGlobalValue { public class ConfigGlobalValue {
Set<String> serverGlobalValues; Set<String> serverGlobalValues;
Map<String, Float> initServerGlobalValues; Map<String, Float> initServerGlobalValues;
} }

View File

@ -1,22 +1,22 @@
package emu.grasscutter.data.binout.routes; package emu.grasscutter.data.binout.routes;
// import emu.grasscutter.scripts.constants.IntValueEnum; // import emu.grasscutter.scripts.constants.IntValueEnum;
import lombok.Getter; import lombok.Getter;
public enum RotAngleType /*implements IntValueEnum */ { public enum RotAngleType /*implements IntValueEnum */ {
ROT_NONE(-1), ROT_NONE(-1),
ROT_ANGLE_X(0), ROT_ANGLE_X(0),
ROT_ANGLE_Y(1), ROT_ANGLE_Y(1),
ROT_ANGLE_Z(2); ROT_ANGLE_Z(2);
@Getter private final int id; @Getter private final int id;
RotAngleType(int id) { RotAngleType(int id) {
this.id = id; this.id = id;
} }
// @Override // @Override
public int getValue() { public int getValue() {
return id; return id;
} }
} }

View File

@ -1,7 +1,7 @@
package emu.grasscutter.data.binout.routes; package emu.grasscutter.data.binout.routes;
public enum RotType { public enum RotType {
ROT_NONE, ROT_NONE,
ROT_ANGLE, ROT_ANGLE,
ROT_ROUND ROT_ROUND
} }

View File

@ -1,29 +1,29 @@
package emu.grasscutter.data.binout.routes; package emu.grasscutter.data.binout.routes;
import emu.grasscutter.net.proto.RouteOuterClass; import emu.grasscutter.net.proto.RouteOuterClass;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.val; import lombok.val;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class Route { public class Route {
private int localId; private int localId;
private String name; private String name;
private RouteType type = RouteType.Unknown; private RouteType type = RouteType.Unknown;
private RoutePoint[] points; private RoutePoint[] points;
private float arriveRange; // optional private float arriveRange; // optional
private RotType rotType; // optional private RotType rotType; // optional
private RotAngleType rotAngleType; // optional private RotAngleType rotAngleType; // optional
public RouteOuterClass.Route toProto() { public RouteOuterClass.Route toProto() {
val builder = RouteOuterClass.Route.newBuilder().setRouteType(type.getValue()); val builder = RouteOuterClass.Route.newBuilder().setRouteType(type.getValue());
if (points != null) { if (points != null) {
for (var routePoint : points) { for (var routePoint : points) {
builder.addRoutePoints(routePoint.toProto().setArriveRange(arriveRange)); builder.addRoutePoints(routePoint.toProto().setArriveRange(arriveRange));
} }
} }
return builder.build(); return builder.build();
} }
} }

View File

@ -1,31 +1,31 @@
package emu.grasscutter.data.binout.routes; package emu.grasscutter.data.binout.routes;
import emu.grasscutter.net.proto.RoutePointOuterClass; import emu.grasscutter.net.proto.RoutePointOuterClass;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
import lombok.val; import lombok.val;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class RoutePoint { public class RoutePoint {
private Position pos; private Position pos;
private int speedLevel; // optional private int speedLevel; // optional
private float waitTime; // optional private float waitTime; // optional
private float targetVelocity; // optional private float targetVelocity; // optional
private boolean hasReachEvent; // optional private boolean hasReachEvent; // optional
// rotRoundReachDir //optional Pos with optional values // rotRoundReachDir //optional Pos with optional values
// rotRoundLeaveDir //optional Pos with optional values // rotRoundLeaveDir //optional Pos with optional values
public RoutePointOuterClass.RoutePoint.Builder toProto() { public RoutePointOuterClass.RoutePoint.Builder toProto() {
val builder = RoutePointOuterClass.RoutePoint.newBuilder().setPosition(pos.toProto()); val builder = RoutePointOuterClass.RoutePoint.newBuilder().setPosition(pos.toProto());
if (waitTime != 0) { if (waitTime != 0) {
builder.setTime(waitTime); builder.setTime(waitTime);
} else if (targetVelocity != 0) { } else if (targetVelocity != 0) {
builder.setVelocity(targetVelocity); builder.setVelocity(targetVelocity);
} }
return builder; return builder;
} }
} }

View File

@ -1,22 +1,22 @@
package emu.grasscutter.data.binout.routes; package emu.grasscutter.data.binout.routes;
// import emu.grasscutter.scripts.constants.IntValueEnum; // import emu.grasscutter.scripts.constants.IntValueEnum;
import lombok.Getter; import lombok.Getter;
public enum RouteType /*implements IntValueEnum*/ { public enum RouteType /*implements IntValueEnum*/ {
Unknown(-1), Unknown(-1),
OneWay(0), OneWay(0),
Reciprocate(1), Reciprocate(1),
Loop(2); Loop(2);
@Getter private final int id; @Getter private final int id;
RouteType(int id) { RouteType(int id) {
this.id = id; this.id = id;
} }
// @Override // @Override
public int getValue() { public int getValue() {
return id; return id;
} }
} }

View File

@ -1,13 +1,13 @@
package emu.grasscutter.data.binout.routes; package emu.grasscutter.data.binout.routes;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Data; import lombok.Data;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class SceneRoutes { public class SceneRoutes {
private int sceneId; private int sceneId;
@Nullable private Route[] routes; @Nullable private Route[] routes;
} }

View File

@ -1,9 +1,9 @@
package emu.grasscutter.data.common; package emu.grasscutter.data.common;
import java.util.List; import java.util.List;
public interface BaseTrialActivityData { public interface BaseTrialActivityData {
List<Integer> getAvatarIndexIdList(); List<Integer> getAvatarIndexIdList();
List<Integer> getRewardIdList(); List<Integer> getRewardIdList();
} }

View File

@ -1,70 +1,70 @@
package emu.grasscutter.data.common; package emu.grasscutter.data.common;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.excels.dungeon.DailyDungeonData; import emu.grasscutter.data.excels.dungeon.DailyDungeonData;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter; import lombok.Getter;
import lombok.Setter; import lombok.Setter;
public final class PointData { public final class PointData {
@Getter @Setter private int id; @Getter @Setter private int id;
private String $type; private String $type;
@Getter private Position tranPos; @Getter private Position tranPos;
@Getter private Position pos; @Getter private Position pos;
@Getter private Position rot; @Getter private Position rot;
@Getter private Position size; @Getter private Position size;
@SerializedName( @SerializedName(
value = "dungeonIds", value = "dungeonIds",
alternate = {"JHHFPGJNMIN"}) alternate = {"JHHFPGJNMIN"})
@Getter @Getter
private int[] dungeonIds; private int[] dungeonIds;
@SerializedName( @SerializedName(
value = "dungeonRandomList", value = "dungeonRandomList",
alternate = {"OIBKFJNBLHO"}) alternate = {"OIBKFJNBLHO"})
@Getter @Getter
private int[] dungeonRandomList; private int[] dungeonRandomList;
@SerializedName( @SerializedName(
value = "groupIDs", value = "groupIDs",
alternate = {"HFOBOOHKBGF"}) alternate = {"HFOBOOHKBGF"})
@Getter @Getter
private int[] groupIDs; private int[] groupIDs;
@SerializedName( @SerializedName(
value = "tranSceneId", value = "tranSceneId",
alternate = {"JHBICGBAPIH"}) alternate = {"JHBICGBAPIH"})
@Getter @Getter
@Setter @Setter
private int tranSceneId; private int tranSceneId;
public String getType() { public String getType() {
return $type; return $type;
} }
public void updateDailyDungeon() { public void updateDailyDungeon() {
if (this.dungeonRandomList == null || this.dungeonRandomList.length == 0) { if (this.dungeonRandomList == null || this.dungeonRandomList.length == 0) {
return; return;
} }
IntList newDungeons = new IntArrayList(); IntList newDungeons = new IntArrayList();
int day = Grasscutter.getCurrentDayOfWeek(); int day = Grasscutter.getCurrentDayOfWeek();
for (int randomId : this.dungeonRandomList) { for (int randomId : this.dungeonRandomList) {
DailyDungeonData data = GameData.getDailyDungeonDataMap().get(randomId); DailyDungeonData data = GameData.getDailyDungeonDataMap().get(randomId);
if (data != null) { if (data != null) {
for (int d : data.getDungeonsByDay(day)) { for (int d : data.getDungeonsByDay(day)) {
newDungeons.add(d); newDungeons.add(d);
} }
} }
} }
this.dungeonIds = newDungeons.toIntArray(); this.dungeonIds = newDungeons.toIntArray();
} }
} }

View File

@ -1,17 +1,17 @@
package emu.grasscutter.data.custom; package emu.grasscutter.data.custom;
import emu.grasscutter.data.common.BaseTrialActivityData; import emu.grasscutter.data.common.BaseTrialActivityData;
import java.util.List; import java.util.List;
import lombok.*; import lombok.*;
@Data @Data
public class TrialAvatarActivityCustomData implements BaseTrialActivityData { public class TrialAvatarActivityCustomData implements BaseTrialActivityData {
private int ScheduleId; private int ScheduleId;
private List<Integer> AvatarIndexIdList; private List<Integer> AvatarIndexIdList;
private List<Integer> RewardIdList; private List<Integer> RewardIdList;
public void onLoad() { public void onLoad() {
this.AvatarIndexIdList = AvatarIndexIdList.stream().filter(x -> x > 0).toList(); this.AvatarIndexIdList = AvatarIndexIdList.stream().filter(x -> x > 0).toList();
this.RewardIdList = RewardIdList.stream().filter(x -> x > 0).toList(); this.RewardIdList = RewardIdList.stream().filter(x -> x > 0).toList();
} }
} }

View File

@ -1,16 +1,16 @@
package emu.grasscutter.data.custom; package emu.grasscutter.data.custom;
import java.util.List; import java.util.List;
import lombok.*; import lombok.*;
@Data @Data
public class TrialAvatarCustomData { public class TrialAvatarCustomData {
private int trialAvatarId; private int trialAvatarId;
private List<String> trialAvatarParamList; private List<String> trialAvatarParamList;
private int coreProudSkillLevel; private int coreProudSkillLevel;
private int skillDepotId; private int skillDepotId;
public void onLoad() { public void onLoad() {
this.trialAvatarParamList = trialAvatarParamList.stream().filter(x -> !x.isBlank()).toList(); this.trialAvatarParamList = trialAvatarParamList.stream().filter(x -> !x.isBlank()).toList();
} }
} }

View File

@ -1,22 +1,22 @@
package emu.grasscutter.data.excels; package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.EntityType; import emu.grasscutter.game.props.EntityType;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = "GadgetExcelConfigData.json") @ResourceType(name = "GadgetExcelConfigData.json")
@Getter @Getter
public final class GadgetData extends GameResource { public final class GadgetData extends GameResource {
@Getter(onMethod_ = @Override) @Getter(onMethod_ = @Override)
private int id; private int id;
private EntityType type; private EntityType type;
private String jsonName; private String jsonName;
private boolean isInteractive; private boolean isInteractive;
private String[] tags; private String[] tags;
private String itemJsonName; private String itemJsonName;
private long nameTextMapHash; private long nameTextMapHash;
private int campId; private int campId;
private String visionLevel; private String visionLevel;
} }

View File

@ -1,27 +1,27 @@
package emu.grasscutter.data.excels; package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@Data @Data
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
@ResourceType(name = "GuideTriggerExcelConfigData.json") @ResourceType(name = "GuideTriggerExcelConfigData.json")
public class GuideTriggerData extends GameResource { public class GuideTriggerData extends GameResource {
// more like open state guide than quest guide // more like open state guide than quest guide
private int id; // dont use, just to prevent resource loader from not functioning private int id; // dont use, just to prevent resource loader from not functioning
private String guideName; private String guideName;
private String type; private String type;
private String openState; private String openState;
@Override @Override
public int getId() { public int getId() {
return this.id; return this.id;
} }
public void onLoad() { public void onLoad() {
GameData.getGuideTriggerDataStringMap().put(getGuideName(), this); GameData.getGuideTriggerDataStringMap().put(getGuideName(), this);
} }
} }

View File

@ -1,154 +1,154 @@
package emu.grasscutter.data.excels; package emu.grasscutter.data.excels;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.common.ItemUseData; import emu.grasscutter.data.common.ItemUseData;
import emu.grasscutter.game.inventory.EquipType; import emu.grasscutter.game.inventory.EquipType;
import emu.grasscutter.game.inventory.ItemType; import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.inventory.MaterialType; import emu.grasscutter.game.inventory.MaterialType;
import emu.grasscutter.game.props.FightProperty; import emu.grasscutter.game.props.FightProperty;
import emu.grasscutter.game.props.ItemUseAction.ItemUseAction; import emu.grasscutter.game.props.ItemUseAction.ItemUseAction;
import emu.grasscutter.game.props.ItemUseOp; import emu.grasscutter.game.props.ItemUseOp;
import emu.grasscutter.game.props.ItemUseTarget; import emu.grasscutter.game.props.ItemUseTarget;
import it.unimi.dsi.fastutil.ints.IntOpenHashSet; import it.unimi.dsi.fastutil.ints.IntOpenHashSet;
import it.unimi.dsi.fastutil.ints.IntSet; import it.unimi.dsi.fastutil.ints.IntSet;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import lombok.Getter; import lombok.Getter;
@ResourceType( @ResourceType(
name = { name = {
"MaterialExcelConfigData.json", "MaterialExcelConfigData.json",
"WeaponExcelConfigData.json", "WeaponExcelConfigData.json",
"ReliquaryExcelConfigData.json", "ReliquaryExcelConfigData.json",
"HomeWorldFurnitureExcelConfigData.json" "HomeWorldFurnitureExcelConfigData.json"
}) })
@Getter @Getter
public class ItemData extends GameResource { public class ItemData extends GameResource {
// Main // Main
@Getter(onMethod_ = @Override) @Getter(onMethod_ = @Override)
private int id; private int id;
private final int stackLimit = 1; private final int stackLimit = 1;
private int maxUseCount; private int maxUseCount;
private int rankLevel; private int rankLevel;
private String effectName; private String effectName;
private int rank; private int rank;
private int weight; private int weight;
private int gadgetId; private int gadgetId;
private int[] destroyReturnMaterial; private int[] destroyReturnMaterial;
private int[] destroyReturnMaterialCount; private int[] destroyReturnMaterialCount;
// Enums // Enums
private final ItemType itemType = ItemType.ITEM_NONE; private final ItemType itemType = ItemType.ITEM_NONE;
private MaterialType materialType = MaterialType.MATERIAL_NONE; private MaterialType materialType = MaterialType.MATERIAL_NONE;
private EquipType equipType = EquipType.EQUIP_NONE; private EquipType equipType = EquipType.EQUIP_NONE;
private String effectType; private String effectType;
private String destroyRule; private String destroyRule;
// Food // Food
private String foodQuality; private String foodQuality;
private int[] satiationParams; private int[] satiationParams;
// Usable item // Usable item
private final ItemUseTarget useTarget = ItemUseTarget.ITEM_USE_TARGET_NONE; private final ItemUseTarget useTarget = ItemUseTarget.ITEM_USE_TARGET_NONE;
private List<ItemUseData> itemUse; private List<ItemUseData> itemUse;
private List<ItemUseAction> itemUseActions; private List<ItemUseAction> itemUseActions;
private final boolean useOnGain = false; private final boolean useOnGain = false;
// Relic // Relic
private int mainPropDepotId; private int mainPropDepotId;
private int appendPropDepotId; private int appendPropDepotId;
private int appendPropNum; private int appendPropNum;
private int setId; private int setId;
private int[] addPropLevels; private int[] addPropLevels;
private int baseConvExp; private int baseConvExp;
private int maxLevel; private int maxLevel;
// Weapon // Weapon
private int weaponPromoteId; private int weaponPromoteId;
private int weaponBaseExp; private int weaponBaseExp;
private int storyId; private int storyId;
private int avatarPromoteId; private int avatarPromoteId;
private int awakenMaterial; private int awakenMaterial;
private int[] awakenCosts; private int[] awakenCosts;
private int[] skillAffix; private int[] skillAffix;
private WeaponProperty[] weaponProp; private WeaponProperty[] weaponProp;
// Hash // Hash
private long nameTextMapHash; private long nameTextMapHash;
// Furniture // Furniture
private int comfort; private int comfort;
private List<Integer> furnType; private List<Integer> furnType;
private List<Integer> furnitureGadgetID; private List<Integer> furnitureGadgetID;
@SerializedName( @SerializedName(
value = "roomSceneId", value = "roomSceneId",
alternate = {"BMEPAMCNABE", "DANFGGLKLNO", "JFDLJGDFIGL", "OHIANNAEEAK", "MFGACDIOHGF"}) alternate = {"BMEPAMCNABE", "DANFGGLKLNO", "JFDLJGDFIGL", "OHIANNAEEAK", "MFGACDIOHGF"})
private int roomSceneId; private int roomSceneId;
// Custom // Custom
private transient IntSet addPropLevelSet; private transient IntSet addPropLevelSet;
public WeaponProperty[] getWeaponProperties() { public WeaponProperty[] getWeaponProperties() {
return this.weaponProp; return this.weaponProp;
} }
public boolean canAddRelicProp(int level) { public boolean canAddRelicProp(int level) {
return this.addPropLevelSet != null && this.addPropLevelSet.contains(level); return this.addPropLevelSet != null && this.addPropLevelSet.contains(level);
} }
public boolean isEquip() { public boolean isEquip() {
return this.itemType == ItemType.ITEM_RELIQUARY || this.itemType == ItemType.ITEM_WEAPON; return this.itemType == ItemType.ITEM_RELIQUARY || this.itemType == ItemType.ITEM_WEAPON;
} }
@Override @Override
public void onLoad() { public void onLoad() {
if (this.itemType == ItemType.ITEM_RELIQUARY) { if (this.itemType == ItemType.ITEM_RELIQUARY) {
if (this.addPropLevels != null && this.addPropLevels.length > 0) { if (this.addPropLevels != null && this.addPropLevels.length > 0) {
this.addPropLevelSet = new IntOpenHashSet(this.addPropLevels); this.addPropLevelSet = new IntOpenHashSet(this.addPropLevels);
} }
} else if (this.itemType == ItemType.ITEM_WEAPON) { } else if (this.itemType == ItemType.ITEM_WEAPON) {
this.equipType = EquipType.EQUIP_WEAPON; this.equipType = EquipType.EQUIP_WEAPON;
} else { } else {
this.equipType = EquipType.EQUIP_NONE; this.equipType = EquipType.EQUIP_NONE;
} }
if (this.weaponProp != null) { if (this.weaponProp != null) {
this.weaponProp = this.weaponProp =
Arrays.stream(this.weaponProp) Arrays.stream(this.weaponProp)
.filter(prop -> prop.getPropType() != null) .filter(prop -> prop.getPropType() != null)
.toArray(WeaponProperty[]::new); .toArray(WeaponProperty[]::new);
} }
if (this.getFurnType() != null) { if (this.getFurnType() != null) {
this.furnType = this.furnType.stream().filter(x -> x > 0).toList(); this.furnType = this.furnType.stream().filter(x -> x > 0).toList();
} }
if (this.getFurnitureGadgetID() != null) { if (this.getFurnitureGadgetID() != null) {
this.furnitureGadgetID = this.furnitureGadgetID.stream().filter(x -> x > 0).toList(); this.furnitureGadgetID = this.furnitureGadgetID.stream().filter(x -> x > 0).toList();
} }
// Prevent material type from being null // Prevent material type from being null
this.materialType = this.materialType == null ? MaterialType.MATERIAL_NONE : this.materialType; this.materialType = this.materialType == null ? MaterialType.MATERIAL_NONE : this.materialType;
if (this.itemUse != null && !this.itemUse.isEmpty()) { if (this.itemUse != null && !this.itemUse.isEmpty()) {
this.itemUseActions = this.itemUseActions =
this.itemUse.stream() this.itemUse.stream()
.filter(x -> x.getUseOp() != ItemUseOp.ITEM_USE_NONE) .filter(x -> x.getUseOp() != ItemUseOp.ITEM_USE_NONE)
.map(ItemUseAction::fromItemUseData) .map(ItemUseAction::fromItemUseData)
.filter(Objects::nonNull) .filter(Objects::nonNull)
.toList(); .toList();
} }
} }
@Getter @Getter
public static class WeaponProperty { public static class WeaponProperty {
private FightProperty propType; private FightProperty propType;
private float initValue; private float initValue;
private String type; private String type;
} }
} }

View File

@ -1,140 +1,140 @@
package emu.grasscutter.data.excels; package emu.grasscutter.data.excels;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.quest.enums.*; import emu.grasscutter.game.quest.enums.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
import javax.annotation.Nonnull; import javax.annotation.Nonnull;
import javax.annotation.Nullable; import javax.annotation.Nullable;
import lombok.*; import lombok.*;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@ResourceType(name = "QuestExcelConfigData.json") @ResourceType(name = "QuestExcelConfigData.json")
@Getter @Getter
@ToString @ToString
public class QuestData extends GameResource { public class QuestData extends GameResource {
@Getter private int subId; @Getter private int subId;
@Getter private int mainId; @Getter private int mainId;
@Getter private int order; @Getter private int order;
@Getter private long descTextMapHash; @Getter private long descTextMapHash;
@Getter private boolean finishParent; @Getter private boolean finishParent;
@Getter private boolean isRewind; @Getter private boolean isRewind;
@Getter private LogicType acceptCondComb; @Getter private LogicType acceptCondComb;
@Getter private LogicType finishCondComb; @Getter private LogicType finishCondComb;
@Getter private LogicType failCondComb; @Getter private LogicType failCondComb;
@Getter private List<QuestAcceptCondition> acceptCond; @Getter private List<QuestAcceptCondition> acceptCond;
@Getter private List<QuestContentCondition> finishCond; @Getter private List<QuestContentCondition> finishCond;
@Getter private List<QuestContentCondition> failCond; @Getter private List<QuestContentCondition> failCond;
@Getter private List<QuestExecParam> beginExec; @Getter private List<QuestExecParam> beginExec;
@Getter private List<QuestExecParam> finishExec; @Getter private List<QuestExecParam> finishExec;
@Getter private List<QuestExecParam> failExec; @Getter private List<QuestExecParam> failExec;
@Getter private Guide guide; @Getter private Guide guide;
@Getter private List<Integer> trialAvatarList; @Getter private List<Integer> trialAvatarList;
public static String questConditionKey( public static String questConditionKey(
@Nonnull Enum<?> type, int firstParam, @Nullable String paramsStr) { @Nonnull Enum<?> type, int firstParam, @Nullable String paramsStr) {
return type.name() + firstParam + (paramsStr != null ? paramsStr : ""); return type.name() + firstParam + (paramsStr != null ? paramsStr : "");
} }
// ResourceLoader not happy if you remove getId() ~~ // ResourceLoader not happy if you remove getId() ~~
public int getId() { public int getId() {
return subId; return subId;
} }
public void onLoad() { public void onLoad() {
this.acceptCond = acceptCond.stream().filter(p -> p.getType() != null).toList(); this.acceptCond = acceptCond.stream().filter(p -> p.getType() != null).toList();
this.finishCond = finishCond.stream().filter(p -> p.getType() != null).toList(); this.finishCond = finishCond.stream().filter(p -> p.getType() != null).toList();
this.failCond = failCond.stream().filter(p -> p.getType() != null).toList(); this.failCond = failCond.stream().filter(p -> p.getType() != null).toList();
this.beginExec = beginExec.stream().filter(p -> p.type != null).toList(); this.beginExec = beginExec.stream().filter(p -> p.type != null).toList();
this.finishExec = finishExec.stream().filter(p -> p.type != null).toList(); this.finishExec = finishExec.stream().filter(p -> p.type != null).toList();
this.failExec = failExec.stream().filter(p -> p.type != null).toList(); this.failExec = failExec.stream().filter(p -> p.type != null).toList();
if (this.acceptCondComb == null) this.acceptCondComb = LogicType.LOGIC_NONE; if (this.acceptCondComb == null) this.acceptCondComb = LogicType.LOGIC_NONE;
if (this.finishCondComb == null) this.finishCondComb = LogicType.LOGIC_NONE; if (this.finishCondComb == null) this.finishCondComb = LogicType.LOGIC_NONE;
if (this.failCondComb == null) this.failCondComb = LogicType.LOGIC_NONE; if (this.failCondComb == null) this.failCondComb = LogicType.LOGIC_NONE;
addToCache(); addToCache();
} }
private void addToCache() { private void addToCache() {
if (this.acceptCond == null) { if (this.acceptCond == null) {
Grasscutter.getLogger().warn("missing AcceptConditions for quest {}", getSubId()); Grasscutter.getLogger().warn("missing AcceptConditions for quest {}", getSubId());
return; return;
} }
var cacheMap = GameData.getBeginCondQuestMap(); var cacheMap = GameData.getBeginCondQuestMap();
if (getAcceptCond().isEmpty()) { if (getAcceptCond().isEmpty()) {
var list = var list =
cacheMap.computeIfAbsent( cacheMap.computeIfAbsent(
QuestData.questConditionKey(QuestCond.QUEST_COND_NONE, 0, null), QuestData.questConditionKey(QuestCond.QUEST_COND_NONE, 0, null),
e -> new ArrayList<>()); e -> new ArrayList<>());
list.add(this); list.add(this);
} else { } else {
this.getAcceptCond() this.getAcceptCond()
.forEach( .forEach(
questCondition -> { questCondition -> {
if (questCondition.getType() == null) { if (questCondition.getType() == null) {
Grasscutter.getLogger().warn("null accept type for quest {}", getSubId()); Grasscutter.getLogger().warn("null accept type for quest {}", getSubId());
return; return;
} }
var key = questCondition.asKey(); var key = questCondition.asKey();
var list = cacheMap.computeIfAbsent(key, e -> new ArrayList<>()); var list = cacheMap.computeIfAbsent(key, e -> new ArrayList<>());
list.add(this); list.add(this);
}); });
} }
} }
@Data @Data
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public static class QuestExecParam { public static class QuestExecParam {
@SerializedName("_type") @SerializedName("_type")
QuestExec type; QuestExec type;
@SerializedName("_param") @SerializedName("_param")
String[] param; String[] param;
@SerializedName("_count") @SerializedName("_count")
String count; String count;
} }
public static class QuestAcceptCondition extends QuestCondition<QuestCond> {} public static class QuestAcceptCondition extends QuestCondition<QuestCond> {}
public static class QuestContentCondition extends QuestCondition<QuestContent> {} public static class QuestContentCondition extends QuestCondition<QuestContent> {}
@Data @Data
public static class QuestCondition<TYPE extends Enum<?> & QuestTrigger> { public static class QuestCondition<TYPE extends Enum<?> & QuestTrigger> {
@SerializedName("_type") @SerializedName("_type")
private TYPE type; private TYPE type;
@SerializedName("_param") @SerializedName("_param")
private int[] param; private int[] param;
@SerializedName("_param_str") @SerializedName("_param_str")
private String paramStr; private String paramStr;
@SerializedName("_count") @SerializedName("_count")
private int count; private int count;
public String asKey() { public String asKey() {
return questConditionKey(getType(), getParam()[0], getParamStr()); return questConditionKey(getType(), getParam()[0], getParamStr());
} }
} }
@Data @Data
public static class Guide { public static class Guide {
private String type; private String type;
private List<String> param; private List<String> param;
private int guideScene; private int guideScene;
} }
} }

View File

@ -1,85 +1,85 @@
package emu.grasscutter.data.excels; package emu.grasscutter.data.excels;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.RefreshType; import emu.grasscutter.game.props.RefreshType;
import emu.grasscutter.game.world.World; import emu.grasscutter.game.world.World;
import java.util.Arrays; import java.util.Arrays;
import java.util.List; import java.util.List;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = "RefreshPolicyExcelConfigData.json") @ResourceType(name = "RefreshPolicyExcelConfigData.json")
public class RefreshPolicyExcelConfigData extends GameResource { public class RefreshPolicyExcelConfigData extends GameResource {
@Getter private int id; @Getter private int id;
@Getter private RefreshType type; @Getter private RefreshType type;
@Getter private String time; @Getter private String time;
private static int upperBound(List<Integer> list, int low, int high, int value) { private static int upperBound(List<Integer> list, int low, int high, int value) {
while (low < high) { while (low < high) {
int middle = (high + low) / 2; int middle = (high + low) / 2;
if (list.size() >= middle) return low; // Just in case if (list.size() >= middle) return low; // Just in case
if (list.get(middle) > value) { if (list.get(middle) > value) {
high = middle; high = middle;
} else { } else {
low = middle + 1; low = middle + 1;
} }
} }
return low; return low;
} }
public int getIntervalInSeconds(World world) { public int getIntervalInSeconds(World world) {
if (time.isEmpty()) return -1; if (time.isEmpty()) return -1;
var currentTimestamp = world.getTotalGameTimeMinutes(); var currentTimestamp = world.getTotalGameTimeMinutes();
try { try {
List<String> paramsStr = Arrays.asList(time.split(";")); List<String> paramsStr = Arrays.asList(time.split(";"));
List<Integer> params = paramsStr.stream().map(Integer::parseInt).toList(); List<Integer> params = paramsStr.stream().map(Integer::parseInt).toList();
switch (type) { switch (type) {
case REFRESH_NONE: case REFRESH_NONE:
return -1; return -1;
case REFRESH_INTERVAL: case REFRESH_INTERVAL:
if (params.isEmpty()) return -1; if (params.isEmpty()) return -1;
return params.get(0); return params.get(0);
case REFRESH_DAILY: case REFRESH_DAILY:
{ {
var dayTime = (world.getTotalGameTimeMinutes() / (24 * 60)) * 24 * 60 * 60; var dayTime = (world.getTotalGameTimeMinutes() / (24 * 60)) * 24 * 60 * 60;
var temp = currentTimestamp - dayTime; var temp = currentTimestamp - dayTime;
var upper_bound_idx = var upper_bound_idx =
upperBound( upperBound(
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp); params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
var upper_bound = params.get(upper_bound_idx); var upper_bound = params.get(upper_bound_idx);
if (params.get(params.size() - 1) == upper_bound) { if (params.get(params.size() - 1) == upper_bound) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7; return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
} else if (params.get(0) == upper_bound) { } else if (params.get(0) == upper_bound) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7; return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
} }
return (params.get(upper_bound_idx - 1) - params.get(0)); return (params.get(upper_bound_idx - 1) - params.get(0));
} }
case REFRESH_WEEKlY: case REFRESH_WEEKlY:
if (params.size() < 2) return -1; if (params.size() < 2) return -1;
{ {
var weekTime = (world.getTotalGameTimeDays() / 7) * 60 * 60 * 24 * 7; var weekTime = (world.getTotalGameTimeDays() / 7) * 60 * 60 * 24 * 7;
var temp = currentTimestamp - weekTime; var temp = currentTimestamp - weekTime;
var upper_bound_idx = var upper_bound_idx =
upperBound( upperBound(
params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp); params, (int) params.get(0), (int) params.get(params.size() - 1), (int) temp);
var upper_bound = params.get(upper_bound_idx); var upper_bound = params.get(upper_bound_idx);
if (params.get(params.size() - 1) == upper_bound) { if (params.get(params.size() - 1) == upper_bound) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7; return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
} else if (params.get(0) == upper_bound) { } else if (params.get(0) == upper_bound) {
return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7; return (params.get(params.size() - 1) - params.get(0)) + 60 * 60 * 24 * 7;
} }
return (params.get(upper_bound_idx - 1) - params.get(0)); return (params.get(upper_bound_idx - 1) - params.get(0));
} }
case REFRESH_DAYBEGIN_INTERVAL: case REFRESH_DAYBEGIN_INTERVAL:
if (params.size() == 0) return -1; if (params.size() == 0) return -1;
return params.get(0) * 60 * 60 * 24; return params.get(0) * 60 * 60 * 24;
} }
} catch (Exception e) { } catch (Exception e) {
} }
return -1; return -1;
} }
} }

View File

@ -1,22 +1,22 @@
package emu.grasscutter.data.excels; package emu.grasscutter.data.excels;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.SceneType; import emu.grasscutter.game.props.SceneType;
import java.util.List; import java.util.List;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = "SceneExcelConfigData.json") @ResourceType(name = "SceneExcelConfigData.json")
@Getter @Getter
public class SceneData extends GameResource { public class SceneData extends GameResource {
@Getter(onMethod_ = @Override) @Getter(onMethod_ = @Override)
private int id; private int id;
@SerializedName("type") @SerializedName("type")
private SceneType sceneType; private SceneType sceneType;
private String scriptData; private String scriptData;
private String levelEntityConfig; private String levelEntityConfig;
private List<Integer> specifiedAvatarList; private List<Integer> specifiedAvatarList;
} }

View File

@ -1,100 +1,100 @@
package emu.grasscutter.data.excels.achievement; package emu.grasscutter.data.excels.achievement;
import com.github.davidmoten.guavamini.Lists; import com.github.davidmoten.guavamini.Lists;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.excels.BattlePassMissionData; import emu.grasscutter.data.excels.BattlePassMissionData;
import java.util.HashSet; import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
@ResourceType(name = "AchievementExcelConfigData.json") @ResourceType(name = "AchievementExcelConfigData.json")
public class AchievementData extends GameResource { public class AchievementData extends GameResource {
private static final AtomicBoolean isDivided = new AtomicBoolean(); private static final AtomicBoolean isDivided = new AtomicBoolean();
private int goalId; private int goalId;
private int preStageAchievementId; private int preStageAchievementId;
private final Set<Integer> groupAchievementIdList = new HashSet<>(); private final Set<Integer> groupAchievementIdList = new HashSet<>();
private boolean isParent; private boolean isParent;
private long titleTextMapHash; private long titleTextMapHash;
private long descTextMapHash; private long descTextMapHash;
private int finishRewardId; private int finishRewardId;
private boolean isDeleteWatcherAfterFinish; private boolean isDeleteWatcherAfterFinish;
private int id; private int id;
private BattlePassMissionData.TriggerConfig triggerConfig; private BattlePassMissionData.TriggerConfig triggerConfig;
private int progress; private int progress;
private boolean isDisuse; private boolean isDisuse;
public static void divideIntoGroups() { public static void divideIntoGroups() {
if (isDivided.get()) { if (isDivided.get()) {
return; return;
} }
isDivided.set(true); isDivided.set(true);
var map = GameData.getAchievementDataMap(); var map = GameData.getAchievementDataMap();
var achievementDataList = map.values().stream().filter(AchievementData::isUsed).toList(); var achievementDataList = map.values().stream().filter(AchievementData::isUsed).toList();
for (var data : achievementDataList) { for (var data : achievementDataList) {
if (!data.hasPreStageAchievement() || data.hasGroupAchievements()) { if (!data.hasPreStageAchievement() || data.hasGroupAchievements()) {
continue; continue;
} }
List<Integer> ids = Lists.newArrayList(); List<Integer> ids = Lists.newArrayList();
int parentId = data.getId(); int parentId = data.getId();
while (true) { while (true) {
var next = map.get(parentId + 1); var next = map.get(parentId + 1);
if (next == null || parentId != next.getPreStageAchievementId()) { if (next == null || parentId != next.getPreStageAchievementId()) {
break; break;
} }
parentId++; parentId++;
} }
map.get(parentId).isParent = true; map.get(parentId).isParent = true;
while (true) { while (true) {
ids.add(parentId); ids.add(parentId);
var previous = map.get(--parentId); var previous = map.get(--parentId);
if (previous == null) { if (previous == null) {
break; break;
} else if (!previous.hasPreStageAchievement()) { } else if (!previous.hasPreStageAchievement()) {
ids.add(parentId); ids.add(parentId);
break; break;
} }
} }
for (int i : ids) { for (int i : ids) {
map.get(i).groupAchievementIdList.addAll(ids); map.get(i).groupAchievementIdList.addAll(ids);
} }
} }
map.values().stream() map.values().stream()
.filter(a -> !a.hasGroupAchievements() && a.isUsed()) .filter(a -> !a.hasGroupAchievements() && a.isUsed())
.forEach(a -> a.isParent = true); .forEach(a -> a.isParent = true);
} }
public boolean hasPreStageAchievement() { public boolean hasPreStageAchievement() {
return this.preStageAchievementId != 0; return this.preStageAchievementId != 0;
} }
public boolean hasGroupAchievements() { public boolean hasGroupAchievements() {
return !this.groupAchievementIdList.isEmpty(); return !this.groupAchievementIdList.isEmpty();
} }
public boolean isUsed() { public boolean isUsed() {
return !this.isDisuse; return !this.isDisuse;
} }
public Set<Integer> getGroupAchievementIdList() { public Set<Integer> getGroupAchievementIdList() {
return this.groupAchievementIdList.stream().collect(Collectors.toUnmodifiableSet()); return this.groupAchievementIdList.stream().collect(Collectors.toUnmodifiableSet());
} }
public Set<Integer> getExcludedGroupAchievementIdList() { public Set<Integer> getExcludedGroupAchievementIdList() {
return this.groupAchievementIdList.stream() return this.groupAchievementIdList.stream()
.filter(integer -> integer != this.getId()) .filter(integer -> integer != this.getId())
.collect(Collectors.toUnmodifiableSet()); .collect(Collectors.toUnmodifiableSet());
} }
} }

View File

@ -1,13 +1,13 @@
package emu.grasscutter.data.excels.achievement; package emu.grasscutter.data.excels.achievement;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import lombok.Getter; import lombok.Getter;
@Getter @Getter
@ResourceType(name = "AchievementGoalExcelConfigData.json") @ResourceType(name = "AchievementGoalExcelConfigData.json")
public class AchievementGoalData extends GameResource { public class AchievementGoalData extends GameResource {
private int id; private int id;
private long nameTextMapHash; private long nameTextMapHash;
private int finishRewardId; private int finishRewardId;
} }

View File

@ -1,38 +1,38 @@
package emu.grasscutter.data.excels.activity; package emu.grasscutter.data.excels.activity;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.activity.condition.ActivityConditions; import emu.grasscutter.game.activity.condition.ActivityConditions;
import emu.grasscutter.game.quest.enums.LogicType; import emu.grasscutter.game.quest.enums.LogicType;
import java.util.List; import java.util.List;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@ResourceType(name = "NewActivityCondExcelConfigData.json") @ResourceType(name = "NewActivityCondExcelConfigData.json")
@Getter @Getter
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ActivityCondExcelConfigData extends GameResource { public class ActivityCondExcelConfigData extends GameResource {
int condId; int condId;
LogicType condComb; LogicType condComb;
List<ActivityConfigCondition> cond; List<ActivityConfigCondition> cond;
public static class ActivityConfigCondition { public static class ActivityConfigCondition {
@Getter private ActivityConditions type; @Getter private ActivityConditions type;
@Getter private List<Integer> param; @Getter private List<Integer> param;
public int[] paramArray() { public int[] paramArray() {
return param.stream().mapToInt(Integer::intValue).toArray(); return param.stream().mapToInt(Integer::intValue).toArray();
} }
} }
@Override @Override
public int getId() { public int getId() {
return condId; return condId;
} }
@Override @Override
public void onLoad() { public void onLoad() {
cond.removeIf(c -> c.type == null); cond.removeIf(c -> c.type == null);
} }
} }

View File

@ -1,37 +1,37 @@
package emu.grasscutter.data.excels.activity; package emu.grasscutter.data.excels.activity;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@ResourceType( @ResourceType(
name = "NewActivityExcelConfigData.json", name = "NewActivityExcelConfigData.json",
loadPriority = ResourceType.LoadPriority.LOW) loadPriority = ResourceType.LoadPriority.LOW)
@Getter @Getter
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ActivityData extends GameResource { public class ActivityData extends GameResource {
int activityId; int activityId;
String activityType; String activityType;
List<Integer> condGroupId; List<Integer> condGroupId;
List<Integer> watcherId; List<Integer> watcherId;
List<ActivityWatcherData> watcherDataList; List<ActivityWatcherData> watcherDataList;
@Override @Override
public int getId() { public int getId() {
return this.activityId; return this.activityId;
} }
@Override @Override
public void onLoad() { public void onLoad() {
this.watcherDataList = this.watcherDataList =
watcherId.stream() watcherId.stream()
.map(item -> GameData.getActivityWatcherDataMap().get(item.intValue())) .map(item -> GameData.getActivityWatcherDataMap().get(item.intValue()))
.filter(Objects::nonNull) .filter(Objects::nonNull)
.toList(); .toList();
} }
} }

View File

@ -1,24 +1,24 @@
package emu.grasscutter.data.excels.activity; package emu.grasscutter.data.excels.activity;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.shop.ShopType; import emu.grasscutter.game.shop.ShopType;
import java.util.List; import java.util.List;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = "ActivityShopOverallExcelConfigData.json") @ResourceType(name = "ActivityShopOverallExcelConfigData.json")
public class ActivityShopData extends GameResource { public class ActivityShopData extends GameResource {
@Getter private int scheduleId; @Getter private int scheduleId;
@Getter private ShopType shopType; @Getter private ShopType shopType;
@Getter private List<Integer> sheetList; @Getter private List<Integer> sheetList;
@Override @Override
public int getId() { public int getId() {
return getShopTypeId(); return getShopTypeId();
} }
public int getShopTypeId() { 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; return shopType.shopTypeId;
} }
} }

View File

@ -1,45 +1,45 @@
package emu.grasscutter.data.excels.activity; package emu.grasscutter.data.excels.activity;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.WatcherTriggerType; import emu.grasscutter.game.props.WatcherTriggerType;
import java.util.List; import java.util.List;
import lombok.AccessLevel; import lombok.AccessLevel;
import lombok.Getter; import lombok.Getter;
import lombok.experimental.FieldDefaults; import lombok.experimental.FieldDefaults;
@ResourceType( @ResourceType(
name = "NewActivityWatcherConfigData.json", name = "NewActivityWatcherConfigData.json",
loadPriority = ResourceType.LoadPriority.HIGH) loadPriority = ResourceType.LoadPriority.HIGH)
@Getter @Getter
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public class ActivityWatcherData extends GameResource { public class ActivityWatcherData extends GameResource {
@Getter(onMethod_ = @Override) @Getter(onMethod_ = @Override)
int id; int id;
int rewardID; int rewardID;
int progress; int progress;
WatcherTrigger triggerConfig; WatcherTrigger triggerConfig;
@Override @Override
public void onLoad() { public void onLoad() {
this.triggerConfig.paramList = this.triggerConfig.paramList =
this.triggerConfig.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList(); this.triggerConfig.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
this.triggerConfig.watcherTriggerType = this.triggerConfig.watcherTriggerType =
WatcherTriggerType.getTypeByName(this.triggerConfig.triggerType); WatcherTriggerType.getTypeByName(this.triggerConfig.triggerType);
} }
@Getter @Getter
@FieldDefaults(level = AccessLevel.PRIVATE) @FieldDefaults(level = AccessLevel.PRIVATE)
public static class WatcherTrigger { public static class WatcherTrigger {
String triggerType; String triggerType;
List<String> paramList; List<String> paramList;
transient WatcherTriggerType watcherTriggerType; transient WatcherTriggerType watcherTriggerType;
public void onLoad() { public void onLoad() {
this.paramList = this.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList(); this.paramList = this.paramList.stream().filter(x -> (x != null) && !x.isBlank()).toList();
this.watcherTriggerType = WatcherTriggerType.getTypeByName(this.triggerType); this.watcherTriggerType = WatcherTriggerType.getTypeByName(this.triggerType);
} }
} }
} }

View File

@ -1,38 +1,38 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
@ResourceType(name = "AvatarCostumeExcelConfigData.json") @ResourceType(name = "AvatarCostumeExcelConfigData.json")
public class AvatarCostumeData extends GameResource { public class AvatarCostumeData extends GameResource {
@SerializedName(value = "skinId", alternate = "costumeId") @SerializedName(value = "skinId", alternate = "costumeId")
private int skinId; private int skinId;
private int itemId; private int itemId;
private int characterId; private int characterId;
private int quality; private int quality;
@Override @Override
public int getId() { public int getId() {
return this.skinId; return this.skinId;
} }
public int getItemId() { public int getItemId() {
return this.itemId; return this.itemId;
} }
public int getCharacterId() { public int getCharacterId() {
return characterId; return characterId;
} }
public int getQuality() { public int getQuality() {
return quality; return quality;
} }
@Override @Override
public void onLoad() { public void onLoad() {
GameData.getAvatarCostumeDataItemIdMap().put(this.getItemId(), this); GameData.getAvatarCostumeDataItemIdMap().put(this.getItemId(), this);
} }
} }

View File

@ -1,36 +1,36 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.common.CurveInfo; import emu.grasscutter.data.common.CurveInfo;
import java.util.HashMap; import java.util.HashMap;
import java.util.Map; import java.util.Map;
import java.util.stream.Stream; import java.util.stream.Stream;
@ResourceType(name = "AvatarCurveExcelConfigData.json") @ResourceType(name = "AvatarCurveExcelConfigData.json")
public class AvatarCurveData extends GameResource { public class AvatarCurveData extends GameResource {
private int level; private int level;
private CurveInfo[] curveInfos; private CurveInfo[] curveInfos;
private Map<String, Float> curveInfoMap; private Map<String, Float> curveInfoMap;
@Override @Override
public int getId() { public int getId() {
return this.level; return this.level;
} }
public int getLevel() { public int getLevel() {
return level; return level;
} }
public Map<String, Float> getCurveInfos() { public Map<String, Float> getCurveInfos() {
return curveInfoMap; return curveInfoMap;
} }
@Override @Override
public void onLoad() { public void onLoad() {
this.curveInfoMap = new HashMap<>(); this.curveInfoMap = new HashMap<>();
Stream.of(this.curveInfos) Stream.of(this.curveInfos)
.forEach(info -> this.curveInfoMap.put(info.getType(), info.getValue())); .forEach(info -> this.curveInfoMap.put(info.getType(), info.getValue()));
} }
} }

View File

@ -1,23 +1,23 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
@ResourceType(name = "AvatarFettersLevelExcelConfigData.json") @ResourceType(name = "AvatarFettersLevelExcelConfigData.json")
public class AvatarFetterLevelData extends GameResource { public class AvatarFetterLevelData extends GameResource {
private int fetterLevel; private int fetterLevel;
private int needExp; private int needExp;
@Override @Override
public int getId() { public int getId() {
return this.fetterLevel; return this.fetterLevel;
} }
public int getLevel() { public int getLevel() {
return fetterLevel; return fetterLevel;
} }
public int getExp() { public int getExp() {
return needExp; return needExp;
} }
} }

View File

@ -1,22 +1,22 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
@ResourceType(name = "AvatarFlycloakExcelConfigData.json") @ResourceType(name = "AvatarFlycloakExcelConfigData.json")
public class AvatarFlycloakData extends GameResource { public class AvatarFlycloakData extends GameResource {
private int flycloakId; private int flycloakId;
private long nameTextMapHash; private long nameTextMapHash;
@Override @Override
public int getId() { public int getId() {
return this.flycloakId; return this.flycloakId;
} }
public long getNameTextMapHash() { public long getNameTextMapHash() {
return nameTextMapHash; return nameTextMapHash;
} }
@Override @Override
public void onLoad() {} public void onLoad() {}
} }

View File

@ -1,23 +1,23 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
@ResourceType(name = "AvatarLevelExcelConfigData.json") @ResourceType(name = "AvatarLevelExcelConfigData.json")
public class AvatarLevelData extends GameResource { public class AvatarLevelData extends GameResource {
private int level; private int level;
private int exp; private int exp;
@Override @Override
public int getId() { public int getId() {
return this.level; return this.level;
} }
public int getLevel() { public int getLevel() {
return level; return level;
} }
public int getExp() { public int getExp() {
return exp; return exp;
} }
} }

View File

@ -1,74 +1,74 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.common.FightPropData;
import emu.grasscutter.data.common.ItemParamData; import emu.grasscutter.data.common.ItemParamData;
import java.util.ArrayList; import java.util.ArrayList;
@ResourceType(name = "AvatarPromoteExcelConfigData.json") @ResourceType(name = "AvatarPromoteExcelConfigData.json")
public class AvatarPromoteData extends GameResource { public class AvatarPromoteData extends GameResource {
private int avatarPromoteId; private int avatarPromoteId;
private int promoteLevel; private int promoteLevel;
private int scoinCost; private int scoinCost;
private ItemParamData[] costItems; private ItemParamData[] costItems;
private int unlockMaxLevel; private int unlockMaxLevel;
private FightPropData[] addProps; private FightPropData[] addProps;
private int requiredPlayerLevel; private int requiredPlayerLevel;
@Override @Override
public int getId() { public int getId() {
return (avatarPromoteId << 8) + promoteLevel; return (avatarPromoteId << 8) + promoteLevel;
} }
public int getAvatarPromoteId() { public int getAvatarPromoteId() {
return avatarPromoteId; return avatarPromoteId;
} }
public int getPromoteLevel() { public int getPromoteLevel() {
return promoteLevel; return promoteLevel;
} }
public ItemParamData[] getCostItems() { public ItemParamData[] getCostItems() {
return costItems; return costItems;
} }
public int getCoinCost() { public int getCoinCost() {
return scoinCost; return scoinCost;
} }
public FightPropData[] getAddProps() { public FightPropData[] getAddProps() {
return addProps; return addProps;
} }
public int getUnlockMaxLevel() { public int getUnlockMaxLevel() {
return unlockMaxLevel; return unlockMaxLevel;
} }
public int getRequiredPlayerLevel() { public int getRequiredPlayerLevel() {
return requiredPlayerLevel; return requiredPlayerLevel;
} }
@Override @Override
public void onLoad() { public void onLoad() {
// Trim item params // Trim item params
ArrayList<ItemParamData> trim = new ArrayList<>(getAddProps().length); ArrayList<ItemParamData> trim = new ArrayList<>(getAddProps().length);
for (ItemParamData itemParam : getCostItems()) { for (ItemParamData itemParam : getCostItems()) {
if (itemParam.getId() == 0) { if (itemParam.getId() == 0) {
continue; continue;
} }
trim.add(itemParam); trim.add(itemParam);
} }
this.costItems = trim.toArray(new ItemParamData[trim.size()]); this.costItems = trim.toArray(new ItemParamData[trim.size()]);
// Trim fight prop data (just in case) // Trim fight prop data (just in case)
ArrayList<FightPropData> parsed = new ArrayList<>(getAddProps().length); ArrayList<FightPropData> parsed = new ArrayList<>(getAddProps().length);
for (FightPropData prop : getAddProps()) { for (FightPropData prop : getAddProps()) {
if (prop.getPropType() != null && prop.getValue() != 0f) { if (prop.getPropType() != null && prop.getValue() != 0f) {
prop.onLoad(); prop.onLoad();
parsed.add(prop); parsed.add(prop);
} }
} }
this.addProps = parsed.toArray(new FightPropData[parsed.size()]); this.addProps = parsed.toArray(new FightPropData[parsed.size()]);
} }
} }

View File

@ -1,24 +1,24 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import lombok.Data; import lombok.Data;
import lombok.EqualsAndHashCode; import lombok.EqualsAndHashCode;
@Data @Data
@ResourceType(name = "AvatarReplaceCostumeExcelConfigData.json") @ResourceType(name = "AvatarReplaceCostumeExcelConfigData.json")
@EqualsAndHashCode(callSuper = false) @EqualsAndHashCode(callSuper = false)
public class AvatarReplaceCostumeData extends GameResource { public class AvatarReplaceCostumeData extends GameResource {
private int avatarId; private int avatarId;
@SerializedName( @SerializedName(
value = "costumeId", value = "costumeId",
alternate = {"MGLCOPOIJIC", "BDBMOBGKIAP"}) alternate = {"MGLCOPOIJIC", "BDBMOBGKIAP"})
private int costumeId; private int costumeId;
@Override @Override
public int getId() { public int getId() {
return costumeId; return costumeId;
} }
} }

View File

@ -1,25 +1,25 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority; import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.ElementType;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = "AvatarSkillExcelConfigData.json", loadPriority = LoadPriority.HIGHEST) @ResourceType(name = "AvatarSkillExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
@Getter @Getter
public class AvatarSkillData extends GameResource { public class AvatarSkillData extends GameResource {
@Getter(onMethod_ = @Override) @Getter(onMethod_ = @Override)
private int id; private int id;
private float cdTime; private float cdTime;
private int costElemVal; private int costElemVal;
private int maxChargeNum; private int maxChargeNum;
private int triggerID; private int triggerID;
private boolean isAttackCameraLock; private boolean isAttackCameraLock;
private int proudSkillGroupId; private int proudSkillGroupId;
private ElementType costElemType; private ElementType costElemType;
private long nameTextMapHash; private long nameTextMapHash;
private long descTextMapHash; private long descTextMapHash;
private String abilityName; private String abilityName;
} }

View File

@ -1,89 +1,89 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameDepot; import emu.grasscutter.data.GameDepot;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceLoader.AvatarConfig; import emu.grasscutter.data.ResourceLoader.AvatarConfig;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority; import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.binout.AbilityEmbryoEntry; import emu.grasscutter.data.binout.AbilityEmbryoEntry;
import emu.grasscutter.game.props.ElementType; import emu.grasscutter.game.props.ElementType;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import it.unimi.dsi.fastutil.ints.IntArrayList; import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import java.util.List; import java.util.List;
import java.util.Optional; import java.util.Optional;
import java.util.stream.IntStream; import java.util.stream.IntStream;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = "AvatarSkillDepotExcelConfigData.json", loadPriority = LoadPriority.HIGH) @ResourceType(name = "AvatarSkillDepotExcelConfigData.json", loadPriority = LoadPriority.HIGH)
@Getter @Getter
public class AvatarSkillDepotData extends GameResource { public class AvatarSkillDepotData extends GameResource {
@Getter(onMethod_ = @Override) @Getter(onMethod_ = @Override)
private int id; private int id;
private int energySkill; private int energySkill;
private int attackModeSkill; private int attackModeSkill;
private List<Integer> skills; private List<Integer> skills;
private List<Integer> subSkills; private List<Integer> subSkills;
private List<String> extraAbilities; private List<String> extraAbilities;
private List<Integer> talents; private List<Integer> talents;
private List<InherentProudSkillOpens> inherentProudSkillOpens; private List<InherentProudSkillOpens> inherentProudSkillOpens;
private String talentStarName; private String talentStarName;
private String skillDepotAbilityGroup; private String skillDepotAbilityGroup;
// Transient // Transient
private AvatarSkillData energySkillData; private AvatarSkillData energySkillData;
private ElementType elementType; private ElementType elementType;
private IntList abilities; private IntList abilities;
private int talentCostItemId; private int talentCostItemId;
public void setAbilities(AbilityEmbryoEntry info) { public void setAbilities(AbilityEmbryoEntry info) {
this.abilities = new IntArrayList(info.getAbilities().length); this.abilities = new IntArrayList(info.getAbilities().length);
for (String ability : info.getAbilities()) { for (String ability : info.getAbilities()) {
this.abilities.add(Utils.abilityHash(ability)); this.abilities.add(Utils.abilityHash(ability));
} }
} }
@Override @Override
public void onLoad() { public void onLoad() {
// Set energy skill data // Set energy skill data
this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill); this.energySkillData = GameData.getAvatarSkillDataMap().get(this.energySkill);
if (this.energySkillData != null) { if (this.energySkillData != null) {
this.elementType = this.energySkillData.getCostElemType(); this.elementType = this.energySkillData.getCostElemType();
} else { } else {
this.elementType = ElementType.None; this.elementType = ElementType.None;
} }
// Set embryo abilities (if player skill depot) // Set embryo abilities (if player skill depot)
if (getSkillDepotAbilityGroup() != null && getSkillDepotAbilityGroup().length() > 0) { if (getSkillDepotAbilityGroup() != null && getSkillDepotAbilityGroup().length() > 0) {
AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup()); AvatarConfig config = GameDepot.getPlayerAbilities().get(getSkillDepotAbilityGroup());
if (config != null) { if (config != null) {
this.setAbilities( this.setAbilities(
new AbilityEmbryoEntry( new AbilityEmbryoEntry(
getSkillDepotAbilityGroup(), getSkillDepotAbilityGroup(),
config.abilities.stream().map(Object::toString).toArray(String[]::new))); config.abilities.stream().map(Object::toString).toArray(String[]::new)));
} }
} }
// Get constellation item from GameData // Get constellation item from GameData
Optional.ofNullable(this.talents) Optional.ofNullable(this.talents)
.map(talents -> talents.get(0)) .map(talents -> talents.get(0))
.map(i -> GameData.getAvatarTalentDataMap().get((int) i)) .map(i -> GameData.getAvatarTalentDataMap().get((int) i))
.map(talentData -> talentData.getMainCostItemId()) .map(talentData -> talentData.getMainCostItemId())
.ifPresent(itemId -> this.talentCostItemId = itemId); .ifPresent(itemId -> this.talentCostItemId = itemId);
} }
public IntStream getSkillsAndEnergySkill() { public IntStream getSkillsAndEnergySkill() {
return IntStream.concat(this.skills.stream().mapToInt(i -> i), IntStream.of(this.energySkill)) return IntStream.concat(this.skills.stream().mapToInt(i -> i), IntStream.of(this.energySkill))
.filter(skillId -> skillId > 0); .filter(skillId -> skillId > 0);
} }
@Getter @Getter
public static class InherentProudSkillOpens { public static class InherentProudSkillOpens {
private int proudSkillGroupId; private int proudSkillGroupId;
private int needAvatarPromoteLevel; private int needAvatarPromoteLevel;
} }
} }

View File

@ -1,69 +1,69 @@
package emu.grasscutter.data.excels.avatar; package emu.grasscutter.data.excels.avatar;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.data.ResourceType.LoadPriority; import emu.grasscutter.data.ResourceType.LoadPriority;
import emu.grasscutter.data.common.FightPropData; import emu.grasscutter.data.common.FightPropData;
import java.util.ArrayList; import java.util.ArrayList;
@ResourceType(name = "AvatarTalentExcelConfigData.json", loadPriority = LoadPriority.HIGHEST) @ResourceType(name = "AvatarTalentExcelConfigData.json", loadPriority = LoadPriority.HIGHEST)
public class AvatarTalentData extends GameResource { public class AvatarTalentData extends GameResource {
private int talentId; private int talentId;
private int prevTalent; private int prevTalent;
private long nameTextMapHash; private long nameTextMapHash;
private String icon; private String icon;
private int mainCostItemId; private int mainCostItemId;
private int mainCostItemCount; private int mainCostItemCount;
private String openConfig; private String openConfig;
private FightPropData[] addProps; private FightPropData[] addProps;
private float[] paramList; private float[] paramList;
@Override @Override
public int getId() { public int getId() {
return this.talentId; return this.talentId;
} }
public int PrevTalent() { public int PrevTalent() {
return prevTalent; return prevTalent;
} }
public long getNameTextMapHash() { public long getNameTextMapHash() {
return nameTextMapHash; return nameTextMapHash;
} }
public String getIcon() { public String getIcon() {
return icon; return icon;
} }
public int getMainCostItemId() { public int getMainCostItemId() {
return mainCostItemId; return mainCostItemId;
} }
public int getMainCostItemCount() { public int getMainCostItemCount() {
return mainCostItemCount; return mainCostItemCount;
} }
public String getOpenConfig() { public String getOpenConfig() {
return openConfig; return openConfig;
} }
public FightPropData[] getAddProps() { public FightPropData[] getAddProps() {
return addProps; return addProps;
} }
public float[] getParamList() { public float[] getParamList() {
return paramList; return paramList;
} }
@Override @Override
public void onLoad() { public void onLoad() {
ArrayList<FightPropData> parsed = new ArrayList<FightPropData>(getAddProps().length); ArrayList<FightPropData> parsed = new ArrayList<FightPropData>(getAddProps().length);
for (FightPropData prop : getAddProps()) { for (FightPropData prop : getAddProps()) {
if (prop.getPropType() != null || prop.getValue() == 0f) { if (prop.getPropType() != null || prop.getValue() == 0f) {
prop.onLoad(); prop.onLoad();
parsed.add(prop); parsed.add(prop);
} }
} }
this.addProps = parsed.toArray(new FightPropData[parsed.size()]); this.addProps = parsed.toArray(new FightPropData[parsed.size()]);
} }
} }

View File

@ -1,27 +1,27 @@
package emu.grasscutter.data.excels.codex; package emu.grasscutter.data.excels.codex;
import com.google.gson.annotations.SerializedName; import com.google.gson.annotations.SerializedName;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = {"AnimalCodexExcelConfigData.json"}) @ResourceType(name = {"AnimalCodexExcelConfigData.json"})
@Getter @Getter
public class CodexAnimalData extends GameResource { public class CodexAnimalData extends GameResource {
@Getter(onMethod_ = @Override) @Getter(onMethod_ = @Override)
private int Id; private int Id;
private String type; private String type;
private int describeId; private int describeId;
private int sortOrder; private int sortOrder;
@SerializedName( @SerializedName(
value = "countType", value = "countType",
alternate = {"OCCLHPBCDGL"}) alternate = {"OCCLHPBCDGL"})
private CountType countType; private CountType countType;
public enum CountType { public enum CountType {
CODEX_COUNT_TYPE_KILL, CODEX_COUNT_TYPE_KILL,
CODEX_COUNT_TYPE_CAPTURE CODEX_COUNT_TYPE_CAPTURE
} }
} }

View File

@ -1,29 +1,29 @@
package emu.grasscutter.data.excels.codex; package emu.grasscutter.data.excels.codex;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
@ResourceType(name = {"MaterialCodexExcelConfigData.json"}) @ResourceType(name = {"MaterialCodexExcelConfigData.json"})
public class CodexMaterialData extends GameResource { public class CodexMaterialData extends GameResource {
private int Id; private int Id;
private int materialId; private int materialId;
private int sortOrder; private int sortOrder;
public int getSortOrder() { public int getSortOrder() {
return sortOrder; return sortOrder;
} }
public int getMaterialId() { public int getMaterialId() {
return materialId; return materialId;
} }
public int getId() { public int getId() {
return Id; return Id;
} }
@Override @Override
public void onLoad() { public void onLoad() {
GameData.getCodexMaterialDataIdMap().put(this.getMaterialId(), this); GameData.getCodexMaterialDataIdMap().put(this.getMaterialId(), this);
} }
} }

View File

@ -1,41 +1,41 @@
package emu.grasscutter.data.excels.codex; package emu.grasscutter.data.excels.codex;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
@ResourceType(name = {"QuestCodexExcelConfigData.json"}) @ResourceType(name = {"QuestCodexExcelConfigData.json"})
public class CodexQuestData extends GameResource { public class CodexQuestData extends GameResource {
private int Id; private int Id;
private int parentQuestId; private int parentQuestId;
private int chapterId; private int chapterId;
private int sortOrder; private int sortOrder;
private boolean isDisuse; private boolean isDisuse;
public int getParentQuestId() { public int getParentQuestId() {
return parentQuestId; return parentQuestId;
} }
public int getId() { public int getId() {
return Id; return Id;
} }
public int getChapterId() { public int getChapterId() {
return chapterId; return chapterId;
} }
public int getSortOrder() { public int getSortOrder() {
return sortOrder; return sortOrder;
} }
public boolean getIsDisuse() { public boolean getIsDisuse() {
return isDisuse; return isDisuse;
} }
@Override @Override
public void onLoad() { public void onLoad() {
if (!this.getIsDisuse()) { if (!this.getIsDisuse()) {
GameData.getCodexQuestDataIdMap().put(this.getParentQuestId(), this); GameData.getCodexQuestDataIdMap().put(this.getParentQuestId(), this);
} }
} }
} }

View File

@ -1,47 +1,47 @@
package emu.grasscutter.data.excels.codex; package emu.grasscutter.data.excels.codex;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import it.unimi.dsi.fastutil.ints.IntCollection; import it.unimi.dsi.fastutil.ints.IntCollection;
import it.unimi.dsi.fastutil.ints.IntList; import it.unimi.dsi.fastutil.ints.IntList;
import lombok.Getter; import lombok.Getter;
@ResourceType(name = {"ReliquaryCodexExcelConfigData.json"}) @ResourceType(name = {"ReliquaryCodexExcelConfigData.json"})
public class CodexReliquaryData extends GameResource { public class CodexReliquaryData extends GameResource {
@Getter private int Id; @Getter private int Id;
@Getter private int suitId; @Getter private int suitId;
@Getter private int level; @Getter private int level;
@Getter private int cupId; @Getter private int cupId;
@Getter private int leatherId; @Getter private int leatherId;
@Getter private int capId; @Getter private int capId;
@Getter private int flowerId; @Getter private int flowerId;
@Getter private int sandId; @Getter private int sandId;
@Getter private int sortOrder; @Getter private int sortOrder;
private transient IntCollection ids; private transient IntCollection ids;
public boolean containsId(int id) { public boolean containsId(int id) {
return getIds().contains(id); return getIds().contains(id);
} }
public IntCollection getIds() { public IntCollection getIds() {
if (this.ids == null) { if (this.ids == null) {
int[] idsArr = {cupId, leatherId, capId, flowerId, sandId}; int[] idsArr = {cupId, leatherId, capId, flowerId, sandId};
this.ids = IntList.of(idsArr); this.ids = IntList.of(idsArr);
} }
return this.ids; return this.ids;
} }
@Override @Override
public void onLoad() { public void onLoad() {
// Normalize all itemIds to the 0-substat form // Normalize all itemIds to the 0-substat form
cupId = (cupId / 10) * 10; cupId = (cupId / 10) * 10;
leatherId = (leatherId / 10) * 10; leatherId = (leatherId / 10) * 10;
capId = (capId / 10) * 10; capId = (capId / 10) * 10;
flowerId = (flowerId / 10) * 10; flowerId = (flowerId / 10) * 10;
sandId = (sandId / 10) * 10; sandId = (sandId / 10) * 10;
GameData.getCodexReliquaryArrayList().add(this); GameData.getCodexReliquaryArrayList().add(this);
GameData.getCodexReliquaryDataIdMap().put(getSuitId(), this); GameData.getCodexReliquaryDataIdMap().put(getSuitId(), this);
} }
} }

Some files were not shown because too many files have changed in this diff Show More