mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-26 21:10:23 +00:00
Create initial handbook data dumpers
these can be accessed by using `-dump=commands,en-us` or `-dump=avatars/items,EN` (all languages supported)
This commit is contained in:
parent
ac7b4d1238
commit
7c4186f5df
@ -1,16 +1,215 @@
|
||||
package emu.grasscutter.tools;
|
||||
|
||||
import emu.grasscutter.net.proto.GetGachaInfoRspOuterClass.GetGachaInfoRsp;
|
||||
import emu.grasscutter.net.proto.GetShopRspOuterClass.GetShopRsp;
|
||||
|
||||
public final class Dumpers {
|
||||
public static void extractBanner(byte[] data) throws Exception {
|
||||
GetGachaInfoRsp proto = GetGachaInfoRsp.parseFrom(data);
|
||||
System.out.println(proto);
|
||||
}
|
||||
|
||||
public static void extractShop(byte[] data) throws Exception {
|
||||
GetShopRsp proto = GetShopRsp.parseFrom(data);
|
||||
System.out.println(proto);
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.tools;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.Command.TargetRequirement;
|
||||
import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.ResourceLoader;
|
||||
import emu.grasscutter.game.inventory.ItemType;
|
||||
import emu.grasscutter.utils.JsonUtils;
|
||||
import emu.grasscutter.utils.Language;
|
||||
import lombok.AllArgsConstructor;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.nio.file.Files;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.stream.Collectors;
|
||||
|
||||
public interface Dumpers {
|
||||
/**
|
||||
* Fetches the description of a command.
|
||||
*
|
||||
* @param locale The locale to use.
|
||||
* @param command The command to get the description of.
|
||||
* @return The description of the command.
|
||||
*/
|
||||
private static String commandDescription(String locale, Command command) {
|
||||
try {
|
||||
// Get the language by the locale.
|
||||
var language = Language.getLanguage(locale);
|
||||
if (language == null) throw new IllegalArgumentException("Invalid language.");
|
||||
|
||||
return language.get("commands." + command.label() + ".description");
|
||||
} catch (IllegalArgumentException ignored) {
|
||||
return command.label();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Encodes the dump into comma separated values.
|
||||
*
|
||||
* @param dump The dump to encode.
|
||||
* @return The encoded dump.
|
||||
*/
|
||||
private static String miniEncode(Map<Integer, ?> dump) {
|
||||
return dump.entrySet().stream()
|
||||
.map(entry -> entry.getKey() + "," + entry.getValue().toString())
|
||||
.collect(Collectors.joining("\n"));
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps all commands to a JSON file.
|
||||
*
|
||||
* @param locale The language to dump the commands in.
|
||||
*/
|
||||
static void dumpCommands(String locale) {
|
||||
// Check that commands are registered.
|
||||
var commandMap = CommandMap.getInstance();
|
||||
if (commandMap == null) commandMap = new CommandMap(true);
|
||||
|
||||
// Convert all registered commands to an info map.
|
||||
var dump = new HashMap<String, CommandInfo>();
|
||||
commandMap.getAnnotationsAsList().forEach(command -> {
|
||||
var description = Dumpers.commandDescription(locale, command);
|
||||
var labels = new ArrayList<String>(){{
|
||||
this.add(command.label());
|
||||
this.addAll(List.of(command.aliases()));
|
||||
}};
|
||||
|
||||
// Add the command info to the list.
|
||||
dump.put(command.label(), new CommandInfo(
|
||||
labels, description, List.of(command.usage()), List.of(
|
||||
command.permission(), command.permissionTargeted()),
|
||||
command.targetRequirement()));
|
||||
});
|
||||
|
||||
try {
|
||||
// Create a file for the dump.
|
||||
var file = new File("commands.json");
|
||||
if (file.exists() && !file.delete())
|
||||
throw new RuntimeException("Failed to delete file.");
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
throw new RuntimeException("Failed to create file.");
|
||||
|
||||
// Write the dump to the file.
|
||||
Files.writeString(file.toPath(), JsonUtils.encode(dump));
|
||||
} catch (IOException ignored) {
|
||||
throw new RuntimeException("Failed to write to file.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps all avatars to a JSON file.
|
||||
*
|
||||
* @param locale The language to dump the avatars in.
|
||||
*/
|
||||
static void dumpAvatars(String locale) {
|
||||
// Reload resources.
|
||||
ResourceLoader.loadAll();
|
||||
Language.loadTextMaps();
|
||||
|
||||
// Convert all known avatars to an avatar map.
|
||||
var dump = new HashMap<Integer, AvatarInfo>();
|
||||
GameData.getAvatarDataMap().forEach((id, avatar) -> {
|
||||
var langHash = avatar.getNameTextMapHash();
|
||||
dump.put(id, new AvatarInfo(
|
||||
langHash == 0 ? avatar.getName() : Language.getTextMapKey(langHash).get(locale),
|
||||
avatar.getQualityType().equals("QUALITY_PURPLE") ? Quality.EPIC : Quality.LEGENDARY,
|
||||
avatar.getId()
|
||||
));
|
||||
});
|
||||
|
||||
try {
|
||||
// Create a file for the dump.
|
||||
var file = new File("avatars.json");
|
||||
if (file.exists() && !file.delete())
|
||||
throw new RuntimeException("Failed to delete file.");
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
throw new RuntimeException("Failed to create file.");
|
||||
|
||||
// Write the dump to the file.
|
||||
Files.writeString(file.toPath(), JsonUtils.encode(dump));
|
||||
} catch (IOException ignored) {
|
||||
throw new RuntimeException("Failed to write to file.");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps all items to a JSON file.
|
||||
*
|
||||
* @param locale The language to dump the items in.
|
||||
*/
|
||||
static void dumpItems(String locale) {
|
||||
// Reload resources.
|
||||
ResourceLoader.loadAll();
|
||||
Language.loadTextMaps();
|
||||
|
||||
// Convert all known items to an item map.
|
||||
var dump = new HashMap<Integer, ItemData>();
|
||||
GameData.getItemDataMap().forEach((id, item) -> dump.put(id, new ItemData(
|
||||
item.getId(), Language.getTextMapKey(item.getNameTextMapHash()).get(locale),
|
||||
Quality.from(item.getRankLevel()), item.getItemType()
|
||||
)));
|
||||
|
||||
try {
|
||||
// Create a file for the dump.
|
||||
var file = new File("items.csv");
|
||||
if (file.exists() && !file.delete())
|
||||
throw new RuntimeException("Failed to delete file.");
|
||||
if (!file.exists() && !file.createNewFile())
|
||||
throw new RuntimeException("Failed to create file.");
|
||||
|
||||
// Write the dump to the file.
|
||||
Files.writeString(file.toPath(), Dumpers.miniEncode(dump));
|
||||
} catch (IOException ignored) {
|
||||
throw new RuntimeException("Failed to write to file.");
|
||||
}
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
class CommandInfo {
|
||||
public List<String> name;
|
||||
public String description;
|
||||
public List<String> usage;
|
||||
public List<String> permission;
|
||||
public TargetRequirement target;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
class AvatarInfo {
|
||||
public String name;
|
||||
public Quality quality;
|
||||
public int id;
|
||||
}
|
||||
|
||||
@AllArgsConstructor
|
||||
class ItemData {
|
||||
public int id;
|
||||
public String name;
|
||||
public Quality quality;
|
||||
public ItemType type;
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return this.id + ","
|
||||
+ this.name + ","
|
||||
+ this.quality + ","
|
||||
+ this.type;
|
||||
}
|
||||
}
|
||||
|
||||
enum Quality {
|
||||
LEGENDARY, EPIC, RARE, UNCOMMON, COMMON, UNKNOWN;
|
||||
|
||||
/**
|
||||
* Convert a rank level to a quality.
|
||||
*
|
||||
* @param rankLevel The rank level to convert.
|
||||
* @return The quality.
|
||||
*/
|
||||
static Quality from(int rankLevel) {
|
||||
return switch (rankLevel) {
|
||||
case 0 -> UNKNOWN;
|
||||
case 1 -> COMMON;
|
||||
case 2 -> UNCOMMON;
|
||||
case 3 -> RARE;
|
||||
case 4 -> EPIC;
|
||||
default -> LEGENDARY;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,129 +1,164 @@
|
||||
package emu.grasscutter.utils;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.*;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import emu.grasscutter.BuildConfig;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerRunMode;
|
||||
import emu.grasscutter.net.packet.PacketOpcodesUtils;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** A parser for start-up arguments. */
|
||||
public final class StartupArguments {
|
||||
/* A map of parameter -> argument handler. */
|
||||
private static final Map<String, Function<String, Boolean>> argumentHandlers =
|
||||
Map.of(
|
||||
"-dumppacketids",
|
||||
parameter -> {
|
||||
PacketOpcodesUtils.dumpPacketIds();
|
||||
return true;
|
||||
},
|
||||
"-version", StartupArguments::printVersion,
|
||||
"-debug", StartupArguments::enableDebug,
|
||||
"-lang",
|
||||
parameter -> {
|
||||
Grasscutter.setPreferredLanguage(parameter);
|
||||
return false;
|
||||
},
|
||||
"-game",
|
||||
parameter -> {
|
||||
Grasscutter.setRunModeOverride(ServerRunMode.GAME_ONLY);
|
||||
return false;
|
||||
},
|
||||
"-dispatch",
|
||||
parameter -> {
|
||||
Grasscutter.setRunModeOverride(ServerRunMode.DISPATCH_ONLY);
|
||||
return false;
|
||||
},
|
||||
"-test",
|
||||
parameter -> {
|
||||
// Disable the console.
|
||||
SERVER.game.enableConsole = false;
|
||||
// Disable HTTP encryption.
|
||||
SERVER.http.encryption.useEncryption = false;
|
||||
return false;
|
||||
},
|
||||
|
||||
// Aliases.
|
||||
"-v", StartupArguments::printVersion,
|
||||
"-debugall",
|
||||
parameter -> {
|
||||
StartupArguments.enableDebug("all");
|
||||
return false;
|
||||
});
|
||||
|
||||
private StartupArguments() {
|
||||
// This class is not meant to be instantiated.
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the provided start-up arguments.
|
||||
*
|
||||
* @param args The application start-up arguments.
|
||||
* @return If the application should exit.
|
||||
*/
|
||||
public static boolean parse(String[] args) {
|
||||
boolean exitEarly = false;
|
||||
|
||||
// Parse the arguments.
|
||||
for (var input : args) {
|
||||
var containsParameter = input.contains("=");
|
||||
|
||||
var argument = containsParameter ? input.split("=")[0] : input;
|
||||
var handler = argumentHandlers.get(argument.toLowerCase());
|
||||
|
||||
if (handler != null) {
|
||||
exitEarly |= handler.apply(containsParameter ? input.split("=")[1] : null);
|
||||
}
|
||||
}
|
||||
|
||||
return exitEarly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the server version.
|
||||
*
|
||||
* @param parameter Additional parameters.
|
||||
* @return True to exit early.
|
||||
*/
|
||||
private static boolean printVersion(String parameter) {
|
||||
System.out.println("Grasscutter version: " + BuildConfig.VERSION + "-" + BuildConfig.GIT_HASH);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debug logging.
|
||||
*
|
||||
* @param parameter Additional parameters.
|
||||
* @return False to continue execution.
|
||||
*/
|
||||
private static boolean enableDebug(String parameter) {
|
||||
if (parameter != null && parameter.equals("all")) {
|
||||
// Override default debug configs
|
||||
GAME_INFO.isShowLoopPackets = DEBUG_MODE_INFO.isShowLoopPackets;
|
||||
GAME_INFO.isShowPacketPayload = DEBUG_MODE_INFO.isShowPacketPayload;
|
||||
GAME_INFO.logPackets = DEBUG_MODE_INFO.logPackets;
|
||||
DISPATCH_INFO.logRequests = DEBUG_MODE_INFO.logRequests;
|
||||
}
|
||||
|
||||
// Set the main logger to debug.
|
||||
Grasscutter.getLogger().setLevel(DEBUG_MODE_INFO.serverLoggerLevel);
|
||||
Grasscutter.getLogger().debug("The logger is now running in debug mode.");
|
||||
|
||||
// Log level to other third-party services
|
||||
Level loggerLevel = DEBUG_MODE_INFO.servicesLoggersLevel;
|
||||
|
||||
// Change loggers to debug.
|
||||
((Logger) LoggerFactory.getLogger("io.javalin")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.quartz")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.reflections")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.eclipse.jetty")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.mongodb.driver")).setLevel(loggerLevel);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.utils;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.*;
|
||||
|
||||
import ch.qos.logback.classic.Level;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import emu.grasscutter.BuildConfig;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerRunMode;
|
||||
import emu.grasscutter.net.packet.PacketOpcodesUtils;
|
||||
import java.util.Map;
|
||||
import java.util.function.Function;
|
||||
|
||||
import emu.grasscutter.tools.Dumpers;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
/** A parser for start-up arguments. */
|
||||
public final class StartupArguments {
|
||||
/* A map of parameter -> argument handler. */
|
||||
private static final Map<String, Function<String, Boolean>> argumentHandlers =
|
||||
Map.of(
|
||||
"-dumppacketids",
|
||||
parameter -> {
|
||||
PacketOpcodesUtils.dumpPacketIds();
|
||||
return true;
|
||||
},
|
||||
"-version", StartupArguments::printVersion,
|
||||
"-debug", StartupArguments::enableDebug,
|
||||
"-lang",
|
||||
parameter -> {
|
||||
Grasscutter.setPreferredLanguage(parameter);
|
||||
return false;
|
||||
},
|
||||
"-game",
|
||||
parameter -> {
|
||||
Grasscutter.setRunModeOverride(ServerRunMode.GAME_ONLY);
|
||||
return false;
|
||||
},
|
||||
"-dispatch",
|
||||
parameter -> {
|
||||
Grasscutter.setRunModeOverride(ServerRunMode.DISPATCH_ONLY);
|
||||
return false;
|
||||
},
|
||||
"-test",
|
||||
parameter -> {
|
||||
// Disable the console.
|
||||
SERVER.game.enableConsole = false;
|
||||
// Disable HTTP encryption.
|
||||
SERVER.http.encryption.useEncryption = false;
|
||||
return false;
|
||||
},
|
||||
"-dump", StartupArguments::dump,
|
||||
|
||||
// Aliases.
|
||||
"-v", StartupArguments::printVersion,
|
||||
"-debugall",
|
||||
parameter -> {
|
||||
StartupArguments.enableDebug("all");
|
||||
return false;
|
||||
});
|
||||
|
||||
private StartupArguments() {
|
||||
// This class is not meant to be instantiated.
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses the provided start-up arguments.
|
||||
*
|
||||
* @param args The application start-up arguments.
|
||||
* @return If the application should exit.
|
||||
*/
|
||||
public static boolean parse(String[] args) {
|
||||
boolean exitEarly = false;
|
||||
|
||||
// Parse the arguments.
|
||||
for (var input : args) {
|
||||
var containsParameter = input.contains("=");
|
||||
|
||||
var argument = containsParameter ? input.split("=")[0] : input;
|
||||
var handler = argumentHandlers.get(argument.toLowerCase());
|
||||
|
||||
if (handler != null) {
|
||||
exitEarly |= handler.apply(containsParameter ? input.split("=")[1] : null);
|
||||
}
|
||||
}
|
||||
|
||||
return exitEarly;
|
||||
}
|
||||
|
||||
/**
|
||||
* Prints the server version.
|
||||
*
|
||||
* @param parameter Additional parameters.
|
||||
* @return True to exit early.
|
||||
*/
|
||||
private static boolean printVersion(String parameter) {
|
||||
System.out.println("Grasscutter version: " + BuildConfig.VERSION + "-" + BuildConfig.GIT_HASH);
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables debug logging.
|
||||
*
|
||||
* @param parameter Additional parameters.
|
||||
* @return False to continue execution.
|
||||
*/
|
||||
private static boolean enableDebug(String parameter) {
|
||||
if (parameter != null && parameter.equals("all")) {
|
||||
// Override default debug configs
|
||||
GAME_INFO.isShowLoopPackets = DEBUG_MODE_INFO.isShowLoopPackets;
|
||||
GAME_INFO.isShowPacketPayload = DEBUG_MODE_INFO.isShowPacketPayload;
|
||||
GAME_INFO.logPackets = DEBUG_MODE_INFO.logPackets;
|
||||
DISPATCH_INFO.logRequests = DEBUG_MODE_INFO.logRequests;
|
||||
}
|
||||
|
||||
// Set the main logger to debug.
|
||||
Grasscutter.getLogger().setLevel(DEBUG_MODE_INFO.serverLoggerLevel);
|
||||
Grasscutter.getLogger().debug("The logger is now running in debug mode.");
|
||||
|
||||
// Log level to other third-party services
|
||||
Level loggerLevel = DEBUG_MODE_INFO.servicesLoggersLevel;
|
||||
|
||||
// Change loggers to debug.
|
||||
((Logger) LoggerFactory.getLogger("io.javalin")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.quartz")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.reflections")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.eclipse.jetty")).setLevel(loggerLevel);
|
||||
((Logger) LoggerFactory.getLogger("org.mongodb.driver")).setLevel(loggerLevel);
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Dumps the specified information.
|
||||
*
|
||||
* @param parameter The parameter to dump.
|
||||
* @return True to exit early.
|
||||
*/
|
||||
private static boolean dump(String parameter) {
|
||||
// Parse the parameter.
|
||||
if (!parameter.contains(",")) {
|
||||
Grasscutter.getLogger().error("Dumper usage: -dump=<content>,<language>");
|
||||
return true;
|
||||
}
|
||||
|
||||
var split = parameter.split(",");
|
||||
var content = split[0];
|
||||
var language = split[1];
|
||||
|
||||
try {
|
||||
switch (content.toLowerCase()) {
|
||||
case "commands" -> Dumpers.dumpCommands(language);
|
||||
case "avatars" -> Dumpers.dumpAvatars(language);
|
||||
case "items" -> Dumpers.dumpItems(language);
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().info("Finished dumping.");
|
||||
} catch (Exception exception) {
|
||||
Grasscutter.getLogger().error("Unable to complete dump.", exception);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user