mirror of
https://github.com/Melledy/Grasscutter.git
synced 2024-11-22 06:31:26 +00:00
Merge development
into localization
This commit is contained in:
commit
0d7f58fc25
2
.gitignore
vendored
2
.gitignore
vendored
@ -67,4 +67,4 @@ mongod.exe
|
||||
/*.sh
|
||||
language/
|
||||
languages/
|
||||
gacha_mappings.js
|
||||
gacha-mapping.js
|
@ -28,7 +28,7 @@ plugins {
|
||||
// Eclipse Support
|
||||
id 'eclipse'
|
||||
|
||||
// Intelij Support
|
||||
// IntelliJ Support
|
||||
id 'idea'
|
||||
|
||||
// Maven
|
||||
|
@ -6,7 +6,6 @@ import emu.grasscutter.Grasscutter.ServerRunMode;
|
||||
import emu.grasscutter.game.mail.Mail;
|
||||
|
||||
public final class Config {
|
||||
|
||||
public String DatabaseUrl = "mongodb://localhost:27017";
|
||||
public String DatabaseCollection = "grasscutter";
|
||||
|
||||
|
@ -4,9 +4,7 @@ import java.io.File;
|
||||
import java.io.FileReader;
|
||||
import java.io.FileWriter;
|
||||
import java.io.IOError;
|
||||
import java.net.InetSocketAddress;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
|
||||
import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.plugin.PluginManager;
|
||||
@ -28,24 +26,25 @@ import com.google.gson.GsonBuilder;
|
||||
import ch.qos.logback.classic.Logger;
|
||||
import emu.grasscutter.data.ResourceLoader;
|
||||
import emu.grasscutter.database.DatabaseManager;
|
||||
import emu.grasscutter.languages.CNLanguage;
|
||||
import emu.grasscutter.languages.Language;
|
||||
import emu.grasscutter.utils.Language;
|
||||
import emu.grasscutter.server.dispatch.DispatchServer;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.tools.Tools;
|
||||
import emu.grasscutter.utils.Crypto;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public final class Grasscutter {
|
||||
private static final Logger log = (Logger) LoggerFactory.getLogger(Grasscutter.class);
|
||||
private static Config config;
|
||||
private static LineReader consoleLineReader = null;
|
||||
|
||||
private static Config config;
|
||||
private static Language language;
|
||||
private static CNLanguage cn_language;
|
||||
|
||||
private static final Gson gson = new GsonBuilder().setPrettyPrinting().create();
|
||||
private static final File configFile = new File("./config.json");
|
||||
|
||||
private static int day; // Current day of week
|
||||
private static int day; // Current day of week.
|
||||
|
||||
private static DispatchServer dispatchServer;
|
||||
private static GameServer gameServer;
|
||||
@ -60,7 +59,7 @@ public final class Grasscutter {
|
||||
// Load server configuration.
|
||||
Grasscutter.loadConfig();
|
||||
|
||||
// Load Language
|
||||
// Load translation files.
|
||||
Grasscutter.loadLanguage();
|
||||
|
||||
// Check server structure.
|
||||
@ -68,21 +67,18 @@ public final class Grasscutter {
|
||||
}
|
||||
|
||||
public static void main(String[] args) throws Exception {
|
||||
Crypto.loadKeys();
|
||||
Crypto.loadKeys(); // Load keys from buffers.
|
||||
|
||||
// Parse arguments.
|
||||
for (String arg : args) {
|
||||
switch (arg.toLowerCase()) {
|
||||
case "-handbook" -> {
|
||||
Tools.createGmHandbook(); return;
|
||||
}
|
||||
case "-gachamap" -> {
|
||||
Tools.createGachaMapping("./gacha_mappings.js"); return;
|
||||
}
|
||||
case "-handbook" -> Tools.createGmHandbook();
|
||||
case "-gachamap" -> Tools.createGachaMapping("./gacha-mapping.js");
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize server.
|
||||
Grasscutter.getLogger().info(language.Starting_Grasscutter);
|
||||
Grasscutter.getLogger().info(translate("messages.status.starting"));
|
||||
|
||||
// Load all resources.
|
||||
Grasscutter.updateDayOfWeek();
|
||||
@ -97,7 +93,7 @@ public final class Grasscutter {
|
||||
|
||||
// Create server instances.
|
||||
dispatchServer = new DispatchServer();
|
||||
gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port));
|
||||
gameServer = new GameServer();
|
||||
// Create a server hook instance with both servers.
|
||||
new ServerHook(gameServer, dispatchServer);
|
||||
|
||||
@ -110,9 +106,9 @@ public final class Grasscutter {
|
||||
} else if (getConfig().RunMode == ServerRunMode.GAME_ONLY) {
|
||||
gameServer.start();
|
||||
} else {
|
||||
getLogger().error(language.Invalid_server_run_mode + " " + getConfig().RunMode);
|
||||
getLogger().error(language.Server_run_mode);
|
||||
getLogger().error(language.Shutting_down);
|
||||
getLogger().error(translate("messages.status.run_mode_error", getConfig().RunMode));
|
||||
getLogger().error(translate("messages.status.run_mode_help"));
|
||||
getLogger().error(translate("messages.status.shutdown"));
|
||||
System.exit(1);
|
||||
}
|
||||
|
||||
@ -145,41 +141,8 @@ public final class Grasscutter {
|
||||
}
|
||||
|
||||
public static void loadLanguage() {
|
||||
try (FileReader file = new FileReader(String.format("%s%s.json", getConfig().LANGUAGE_FOLDER, Grasscutter.config.LocaleLanguage))) {
|
||||
language = gson.fromJson(file, Language.class);
|
||||
} catch (Exception e) {
|
||||
Grasscutter.language = new Language();
|
||||
Grasscutter.cn_language = new CNLanguage();
|
||||
Grasscutter.config.LocaleLanguage = Locale.getDefault();
|
||||
saveConfig();
|
||||
|
||||
try {
|
||||
File folder = new File("./languages");
|
||||
if (!folder.exists() && !folder.isDirectory()) {
|
||||
//noinspection ResultOfMethodCallIgnored
|
||||
folder.mkdirs();
|
||||
}
|
||||
} catch (Exception ee) {
|
||||
Grasscutter.getLogger().error("Unable to create language folder.");
|
||||
}
|
||||
try (FileWriter file = new FileWriter("./languages/" + Locale.US + ".json")) {
|
||||
file.write(gson.toJson(language));
|
||||
} catch (Exception ee) {
|
||||
Grasscutter.getLogger().error("Unable to create language file.");
|
||||
}
|
||||
try (FileWriter file = new FileWriter("./languages/" + Locale.SIMPLIFIED_CHINESE + ".json")) {
|
||||
file.write(gson.toJson(cn_language));
|
||||
} catch (Exception ee) {
|
||||
Grasscutter.getLogger().error("无法创建简体中文语言文件。");
|
||||
}
|
||||
|
||||
// try again
|
||||
try (FileReader file = new FileReader(String.format("%s%s.json", getConfig().LANGUAGE_FOLDER, Grasscutter.config.LocaleLanguage))) {
|
||||
language = gson.fromJson(file, Language.class);
|
||||
} catch (Exception ee) {
|
||||
Grasscutter.getLogger().error("Unable to load " + Grasscutter.config.LocaleLanguage + ".json");
|
||||
}
|
||||
}
|
||||
var locale = config.LocaleLanguage;
|
||||
language = Language.getLanguage(locale.toLanguageTag());
|
||||
}
|
||||
|
||||
public static void saveConfig() {
|
||||
@ -193,11 +156,11 @@ public final class Grasscutter {
|
||||
public static void startConsole() {
|
||||
// Console should not start in dispatch only mode.
|
||||
if (getConfig().RunMode == ServerRunMode.DISPATCH_ONLY) {
|
||||
getLogger().info(language.Dispatch_mode_not_support_command);
|
||||
getLogger().info(translate("messages.dispatch.no_commands_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
getLogger().info(language.Start_done);
|
||||
getLogger().info(translate("messages.status.done"));
|
||||
String input = null;
|
||||
boolean isLastInterrupted = false;
|
||||
while (true) {
|
||||
@ -223,7 +186,7 @@ public final class Grasscutter {
|
||||
try {
|
||||
CommandMap.getInstance().invoke(null, null, input);
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error(language.Command_error, e);
|
||||
Grasscutter.getLogger().error(translate("messages.game.command_error"), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import org.reflections.Reflections;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@SuppressWarnings({"UnusedReturnValue", "unused"})
|
||||
public final class CommandMap {
|
||||
private final Map<String, CommandHandler> commands = new HashMap<>();
|
||||
@ -109,7 +111,7 @@ public final class CommandMap {
|
||||
public void invoke(Player player, Player targetPlayer, String rawMessage) {
|
||||
rawMessage = rawMessage.trim();
|
||||
if (rawMessage.length() == 0) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().No_command_specified);
|
||||
CommandHandler.sendMessage(player, translate("commands.generic.not_specified"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -118,11 +120,12 @@ public final class CommandMap {
|
||||
List<String> args = new LinkedList<>(Arrays.asList(split));
|
||||
String label = args.remove(0);
|
||||
String playerId = (player == null) ? consoleId : player.getAccount().getId();
|
||||
// Check for special cases - currently only target command
|
||||
|
||||
// Check for special cases - currently only target command.
|
||||
String targetUidStr = null;
|
||||
if (label.startsWith("@")) { // @[UID]
|
||||
if (label.startsWith("@")) { // @[UID]
|
||||
targetUidStr = label.substring(1);
|
||||
} else if (label.equalsIgnoreCase("target")) { // target [[@]UID]
|
||||
} else if (label.equalsIgnoreCase("target")) { // target [[@]UID]
|
||||
if (args.size() > 0) {
|
||||
targetUidStr = args.get(0);
|
||||
if (targetUidStr.startsWith("@")) {
|
||||
@ -133,68 +136,64 @@ public final class CommandMap {
|
||||
}
|
||||
}
|
||||
if (targetUidStr != null) {
|
||||
if (targetUidStr.equals("")) { // Clears default targetPlayer
|
||||
if (targetUidStr.equals("")) { // Clears the default targetPlayer.
|
||||
targetPlayerIds.remove(playerId);
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Target_cleared);
|
||||
return;
|
||||
} else { // Sets default targetPlayer to the UID given
|
||||
CommandHandler.sendMessage(player, translate("commands.execution.clear_target"));
|
||||
} else { // Sets default targetPlayer to the UID provided.
|
||||
try {
|
||||
int uid = Integer.parseInt(targetUidStr);
|
||||
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(uid);
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Player_not_found_or_offline);
|
||||
CommandHandler.sendMessage(player, translate("commands.generic.execution.player_exist_offline_error"));
|
||||
} else {
|
||||
targetPlayerIds.put(playerId, uid);
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Target_set.replace("{uid}", targetUidStr));
|
||||
CommandHandler.sendMessage(player, translate("commands.execution.set_target", targetUidStr));
|
||||
}
|
||||
} catch (NumberFormatException e) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Invalid_UID);
|
||||
CommandHandler.sendMessage(player, translate("commands.execution.uid_error"));
|
||||
}
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
// Get command handler.
|
||||
CommandHandler handler = this.commands.get(label);
|
||||
if (handler == null) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Unknown_command + label);
|
||||
CommandHandler.sendMessage(player, translate("commands.generic.unknown_command", label));
|
||||
return;
|
||||
}
|
||||
|
||||
// If any @UID argument is present, override targetPlayer with it
|
||||
// If any @UID argument is present, override targetPlayer with it.
|
||||
for (int i = 0; i < args.size(); i++) {
|
||||
String arg = args.get(i);
|
||||
if (!arg.startsWith("@")) {
|
||||
continue;
|
||||
} else {
|
||||
if (arg.startsWith("@")) {
|
||||
arg = args.remove(i).substring(1);
|
||||
try {
|
||||
int uid = Integer.parseInt(arg);
|
||||
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(uid);
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Player_not_found_or_offline);
|
||||
CommandHandler.sendMessage(player, translate("commands.generic.execution.player_exist_offline_error"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
} catch (NumberFormatException e) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Invalid_UID);
|
||||
CommandHandler.sendMessage(player, translate("commands.execution.uid_error"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If there's still no targetPlayer at this point, use previously-set target
|
||||
if (targetPlayer == null) {
|
||||
if (targetPlayerIds.containsKey(playerId)) {
|
||||
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(targetPlayerIds.get(playerId)); // We check every time in case the target goes offline after being targeted
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Player_not_found_or_offline);
|
||||
CommandHandler.sendMessage(player, translate("commands.generic.execution.player_exist_offline_error"));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
// If there's still no targetPlayer at this point, use local player
|
||||
if (targetPlayer == null) {
|
||||
targetPlayer = player;
|
||||
}
|
||||
// If there's still no targetPlayer at this point, use executor.
|
||||
targetPlayer = player;
|
||||
}
|
||||
}
|
||||
|
||||
@ -205,12 +204,12 @@ public final class CommandMap {
|
||||
Account account = player.getAccount();
|
||||
if (player != targetPlayer) { // Additional permission required for targeting another player
|
||||
if (!permissionNodeTargeted.isEmpty() && !account.hasPermission(permissionNodeTargeted)) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().You_not_permission_run_command);
|
||||
CommandHandler.sendMessage(player, translate("commands.generic.permission_error"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().You_not_permission_run_command);
|
||||
CommandHandler.sendMessage(player, translate("commands.generic.permission_error"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -220,10 +219,8 @@ public final class CommandMap {
|
||||
final Player targetPlayerF = targetPlayer; // Is there a better way to do this?
|
||||
Runnable runnable = () -> handler.execute(player, targetPlayerF, args);
|
||||
if(threading) {
|
||||
Thread command = new Thread(runnable);
|
||||
command.start();
|
||||
}
|
||||
else {
|
||||
new Thread(runnable).start();
|
||||
} else {
|
||||
runnable.run();
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
@ -8,18 +7,20 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "account", usage = "account <create|delete> <username> [uid]", description = "Modify user accounts")
|
||||
public final class AccountCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (sender != null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().This_command_can_only_run_from_console);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.console_execute_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Account_command_usage);
|
||||
CommandHandler.sendMessage(null, translate("commands.account.command_usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -28,7 +29,7 @@ public final class AccountCommand implements CommandHandler {
|
||||
|
||||
switch (action) {
|
||||
default:
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Account_command_usage);
|
||||
CommandHandler.sendMessage(null, translate("commands.account.command_usage"));
|
||||
return;
|
||||
case "create":
|
||||
int uid = 0;
|
||||
@ -36,27 +37,27 @@ public final class AccountCommand implements CommandHandler {
|
||||
try {
|
||||
uid = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Invalid_UID);
|
||||
CommandHandler.sendMessage(null, translate("commands.account.invalid"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
emu.grasscutter.game.Account account = DatabaseHelper.createAccountWithId(username, uid);
|
||||
if (account == null) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Account_exists);
|
||||
CommandHandler.sendMessage(null, translate("commands.account.exists"));
|
||||
return;
|
||||
} else {
|
||||
account.addPermission("*");
|
||||
account.save(); // Save account to database.
|
||||
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Account_create_UID.replace("{uid}", Integer.toString(account.getPlayerUid())));
|
||||
CommandHandler.sendMessage(null, translate("commands.account.create", Integer.toString(account.getPlayerUid())));
|
||||
}
|
||||
return;
|
||||
case "delete":
|
||||
if (DatabaseHelper.deleteAccount(username)) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Account_delete);
|
||||
CommandHandler.sendMessage(null, translate("commands.account.delete"));
|
||||
} else {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Account_not_find);
|
||||
CommandHandler.sendMessage(null, translate("commands.account.no_account"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "broadcast", usage = "broadcast <message>",
|
||||
description = "Sends a message to all the players", aliases = {"b"}, permission = "server.broadcast")
|
||||
public final class BroadcastCommand implements CommandHandler {
|
||||
@ -14,7 +16,7 @@ public final class BroadcastCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Broadcast_command_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.broadcast.command_usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -24,6 +26,6 @@ public final class BroadcastCommand implements CommandHandler {
|
||||
CommandHandler.sendMessage(p, message);
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Broadcast_message_sent);
|
||||
CommandHandler.sendMessage(sender, translate("commands.broadcast.message_sent"));
|
||||
}
|
||||
}
|
||||
|
@ -1,43 +1,43 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "changescene", usage = "changescene <scene id>",
|
||||
description = "Changes your scene", aliases = {"scene"}, permission = "player.changescene")
|
||||
public final class ChangeSceneCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() != 1) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Change_screen_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.changescene.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int sceneId = Integer.parseInt(args.get(0));
|
||||
|
||||
if (sceneId == targetPlayer.getSceneId()) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Change_screen_you_in_that_screen);
|
||||
CommandHandler.sendMessage(sender, translate("commands.changescene.already_in_scene"));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, targetPlayer.getPos());
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Change_screen + sceneId);
|
||||
CommandHandler.sendMessage(sender, translate("commands.changescene.result", Integer.toString(sceneId)));
|
||||
|
||||
if (!result) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Change_screen_not_exist);
|
||||
CommandHandler.sendMessage(sender, translate("commands.changescene.exists_error"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_arguments);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.argument_error"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "clear", usage = "clear <all|wp|art|mat>", //Merged /clearartifacts and /clearweapons to /clear <args> [uid]
|
||||
description = "Deletes unequipped unlocked items, including yellow rarity ones from your inventory",
|
||||
aliases = {"clear"}, permission = "player.clearinv")
|
||||
@ -19,11 +21,11 @@ public final class ClearCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.command_usage"));
|
||||
return;
|
||||
}
|
||||
Inventory playerInventory = targetPlayer.getInventory();
|
||||
@ -35,7 +37,7 @@ public final class ClearCommand implements CommandHandler {
|
||||
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
|
||||
.filter(item -> !item.isLocked() && !item.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_weapons.replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.weapons", targetPlayer.getNickname()));
|
||||
}
|
||||
case "art" -> {
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
@ -43,7 +45,7 @@ public final class ClearCommand implements CommandHandler {
|
||||
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
|
||||
.filter(item -> !item.isLocked() && !item.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_artifacts.replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.artifacts", targetPlayer.getNickname()));
|
||||
}
|
||||
case "mat" -> {
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
@ -51,7 +53,7 @@ public final class ClearCommand implements CommandHandler {
|
||||
.filter(item -> item.getLevel() == 1 && item.getExp() == 0)
|
||||
.filter(item -> !item.isLocked() && !item.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_artifacts.replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.materials", targetPlayer.getNickname()));
|
||||
}
|
||||
case "all" -> {
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
@ -59,34 +61,44 @@ public final class ClearCommand implements CommandHandler {
|
||||
.filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0)
|
||||
.filter(item1 -> !item1.isLocked() && !item1.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_artifacts.replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.artifacts", targetPlayer.getNickname()));
|
||||
playerInventory.removeItems(toDelete);
|
||||
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
.filter(item2 -> item2.getItemType() == ItemType.ITEM_MATERIAL)
|
||||
.filter(item2 -> !item2.isLocked() && !item2.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_artifacts.replace("{name}", targetPlayer.getNickname()));
|
||||
playerInventory.removeItems(toDelete);
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.materials", targetPlayer.getNickname()));
|
||||
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
.filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON)
|
||||
.filter(item3 -> item3.getLevel() == 1 && item3.getExp() == 0)
|
||||
.filter(item3 -> !item3.isLocked() && !item3.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_artifacts.replace("{name}", targetPlayer.getNickname()));
|
||||
playerInventory.removeItems(toDelete);
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.weapons", targetPlayer.getNickname()));
|
||||
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
.filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE)
|
||||
.filter(item4 -> !item4.isLocked() && !item4.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_furniture.replace("{name}", targetPlayer.getNickname()));
|
||||
playerInventory.removeItems(toDelete);
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.furniture", targetPlayer.getNickname()));
|
||||
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
.filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY)
|
||||
.filter(item5 -> !item5.isLocked() && !item5.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_displays.replace("{name}", targetPlayer.getNickname()));
|
||||
playerInventory.removeItems(toDelete);
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.displays", targetPlayer.getNickname()));
|
||||
|
||||
toDelete = playerInventory.getItems().values().stream()
|
||||
.filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL)
|
||||
.filter(item6 -> !item6.isLocked() && !item6.isEquipped())
|
||||
.toList();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_virtuals.replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Clear_everything.replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.virtuals", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.clear.everything", targetPlayer.getNickname()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,39 +7,40 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "coop", usage = "coop [host UID]",
|
||||
description = "Forces someone to join the world of others", permission = "server.coop")
|
||||
public final class CoopCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
Player host = sender;
|
||||
switch (args.size()) {
|
||||
case 0: // Summon target to self
|
||||
if (sender == null) { // Console doesn't have a self to summon to
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Coop_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.coop.usage"));
|
||||
if (sender == null) // Console doesn't have a self to summon to
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case 1: // Summon target to argument
|
||||
try {
|
||||
int hostId = Integer.parseInt(args.get(0));
|
||||
host = Grasscutter.getGameServer().getPlayerByUid(hostId);
|
||||
if (host == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Player_is_offline);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.player_offline_error"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_playerId);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.uid_error"));
|
||||
return;
|
||||
}
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Coop_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.coop.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -49,6 +50,6 @@ public final class CoopCommand implements CommandHandler {
|
||||
}
|
||||
host.getServer().getMultiplayerManager().applyEnterMp(targetPlayer, host.getUid());
|
||||
targetPlayer.getServer().getMultiplayerManager().applyEnterMpReply(host, targetPlayer.getUid(), true);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Coop_success.replace("{host}", host.getNickname()).replace("{target}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.coop.success", targetPlayer.getNickname(), host.getNickname()));
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,8 @@ import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "drop", usage = "drop <itemId|itemName> [amount]",
|
||||
description = "Drops an item near you", aliases = {"d", "dropitem"}, permission = "server.drop")
|
||||
public final class DropCommand implements CommandHandler {
|
||||
@ -18,7 +20,7 @@ public final class DropCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(null, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -30,25 +32,25 @@ public final class DropCommand implements CommandHandler {
|
||||
try {
|
||||
amount = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_amount);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.amount"));
|
||||
return;
|
||||
} // Slightly cheeky here: no break so it falls through to initialize the first argument too
|
||||
} // Slightly cheeky here: no break, so it falls through to initialize the first argument too
|
||||
case 1:
|
||||
try {
|
||||
item = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Drop_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.drop.command_usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
ItemData itemData = GameData.getItemDataMap().get(item);
|
||||
if (itemData == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId"));
|
||||
return;
|
||||
}
|
||||
if (itemData.isEquip()) {
|
||||
@ -62,6 +64,6 @@ public final class DropCommand implements CommandHandler {
|
||||
EntityItem entity = new EntityItem(targetPlayer.getScene(), targetPlayer, itemData, targetPlayer.getPos().clone().addY(3f), amount);
|
||||
targetPlayer.getScene().addEntity(entity);
|
||||
}
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Drop_dropped_of.replace("{amount}", Integer.toString(amount)).replace("{item}", Integer.toString(item)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.drop.success", Integer.toString(amount), Integer.toString(item)));
|
||||
}
|
||||
}
|
@ -1,43 +1,43 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "enterdungeon", usage = "enterdungeon <dungeon id>",
|
||||
description = "Enter a dungeon", aliases = {"dungeon"}, permission = "player.enterdungeon")
|
||||
public final class EnterDungeonCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(null, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().EnterDungeon_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int dungeonId = Integer.parseInt(args.get(0));
|
||||
|
||||
if (dungeonId == targetPlayer.getSceneId()) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().EnterDungeon_you_in_that_dungeon);
|
||||
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.in_dungeon_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = targetPlayer.getServer().getDungeonManager().enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().EnterDungeon_changed_to_dungeon + dungeonId);
|
||||
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.changed", dungeonId));
|
||||
|
||||
if (!result) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().EnterDungeon_dungeon_not_found);
|
||||
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.not_found_error"));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().EnterDungeon_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.usage"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -13,6 +13,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "giveall", usage = "giveall [amount]",
|
||||
description = "Gives all items", aliases = {"givea"}, permission = "player.giveall", threading = true)
|
||||
public final class GiveAllCommand implements CommandHandler {
|
||||
@ -20,7 +22,7 @@ public final class GiveAllCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
int amount = 99999;
|
||||
@ -32,21 +34,21 @@ public final class GiveAllCommand implements CommandHandler {
|
||||
try {
|
||||
amount = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_amount);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.amount"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default: // invalid
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().GiveAll_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.giveAll.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
this.giveAllItems(targetPlayer, amount);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().GiveAll_done);
|
||||
CommandHandler.sendMessage(sender, translate("commands.giveAll.success", targetPlayer.getNickname()));
|
||||
}
|
||||
|
||||
public void giveAllItems(Player player, int amount) {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().GiveAll_item);
|
||||
CommandHandler.sendMessage(player, translate("commands.giveAll.started"));
|
||||
|
||||
for (AvatarData avatarData: GameData.getAvatarDataMap().values()) {
|
||||
//Exclude test avatar
|
||||
|
@ -14,17 +14,19 @@ import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "giveart", usage = "giveart <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]", description = "Gives the player a specified artifact", aliases = {"gart"}, permission = "player.giveart")
|
||||
public final class GiveArtifactCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().GiveArtifact_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -32,12 +34,12 @@ public final class GiveArtifactCommand implements CommandHandler {
|
||||
try {
|
||||
itemId = Integer.parseInt(args.remove(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_artifact_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.id_error"));
|
||||
return;
|
||||
}
|
||||
ItemData itemData = GameData.getItemDataMap().get(itemId);
|
||||
if (itemData.getItemType() != ItemType.ITEM_RELIQUARY) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_artifact_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.id_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -45,7 +47,7 @@ public final class GiveArtifactCommand implements CommandHandler {
|
||||
try {
|
||||
mainPropId = Integer.parseInt(args.remove(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_arguments);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.execution.argument_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -59,7 +61,7 @@ public final class GiveArtifactCommand implements CommandHandler {
|
||||
} catch (NumberFormatException ignored) { // Could be a stat,times string so no need to panic
|
||||
}
|
||||
|
||||
ArrayList<Integer> appendPropIdList = new ArrayList<>();
|
||||
List<Integer> appendPropIdList = new ArrayList<>();
|
||||
try {
|
||||
args.forEach(it -> {
|
||||
String[] arr;
|
||||
@ -74,7 +76,7 @@ public final class GiveArtifactCommand implements CommandHandler {
|
||||
appendPropIdList.addAll(Collections.nCopies(n, Integer.parseInt(it)));
|
||||
});
|
||||
} catch (Exception ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_arguments);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.argument_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -85,7 +87,7 @@ public final class GiveArtifactCommand implements CommandHandler {
|
||||
item.getAppendPropIdList().addAll(appendPropIdList);
|
||||
targetPlayer.getInventory().addItem(item, ActionReason.SubfieldDrop);
|
||||
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().GiveArtifact_given.replace("{itemId}", Integer.toString(itemId)).replace("target", Integer.toString(targetPlayer.getUid())));
|
||||
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.success", Integer.toString(itemId), Integer.toString(targetPlayer.getUid())));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,6 +10,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "givechar", usage = "givechar <avatarId> [level]",
|
||||
description = "Gives the player a specified character", aliases = {"givec"}, permission = "player.givechar")
|
||||
public final class GiveCharCommand implements CommandHandler {
|
||||
@ -17,7 +19,7 @@ public final class GiveCharCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -30,7 +32,7 @@ public final class GiveCharCommand implements CommandHandler {
|
||||
level = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// TODO: Parse from avatar name using GM Handbook.
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_avatar_level);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarLevel"));
|
||||
return;
|
||||
} // Cheeky fall-through to parse first argument too
|
||||
case 1:
|
||||
@ -38,24 +40,24 @@ public final class GiveCharCommand implements CommandHandler {
|
||||
avatarId = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// TODO: Parse from avatar name using GM Handbook.
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_avatar_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarId"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().GiveChar_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.giveChar.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
AvatarData avatarData = GameData.getAvatarDataMap().get(avatarId);
|
||||
if (avatarData == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_avatar_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarId"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Check level.
|
||||
if (level > 90) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_avatar_level);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarLevel"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -75,6 +77,6 @@ public final class GiveCharCommand implements CommandHandler {
|
||||
avatar.recalcStats();
|
||||
|
||||
targetPlayer.addAvatar(avatar);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().GiveChar_given.replace("{avatarId}", Integer.toString(avatarId)).replace("{level}", Integer.toString(level)).replace("{target}", Integer.toString(targetPlayer.getUid())));
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.giveChar.given", Integer.toString(avatarId), Integer.toString(level), Integer.toString(targetPlayer.getUid())));
|
||||
}
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ import java.util.List;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.regex.Matcher;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "give", usage = "give <itemId|itemName> [amount] [level]", description = "Gives an item to you or the specified player", aliases = {
|
||||
"g", "item", "giveitem"}, permission = "player.give")
|
||||
public final class GiveCommand implements CommandHandler {
|
||||
@ -33,7 +35,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
int item;
|
||||
@ -67,21 +69,21 @@ public final class GiveCommand implements CommandHandler {
|
||||
try {
|
||||
refinement = Integer.parseInt(args.get(3));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_refinement);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemRefinement"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 3: // <itemId|itemName> [amount] [level]
|
||||
try {
|
||||
lvl = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_level);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemLevel"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 2: // <itemId|itemName> [amount]
|
||||
try {
|
||||
amount = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_amount);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.amount"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 1: // <itemId|itemName>
|
||||
@ -89,30 +91,28 @@ public final class GiveCommand implements CommandHandler {
|
||||
item = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// TODO: Parse from item name using GM Handbook.
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default: // *No args*
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Give_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.give.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
|
||||
ItemData itemData = GameData.getItemDataMap().get(item);
|
||||
if (itemData == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId"));
|
||||
return;
|
||||
}
|
||||
if (refinement != 0) {
|
||||
if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
|
||||
if (refinement < 1 || refinement > 5) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Give_refinement_must_between_1_and_5);
|
||||
CommandHandler.sendMessage(sender, translate("commands.give.refinement_must_between_1_and_5"));
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Give_refinement_only_applicable_weapons);
|
||||
CommandHandler.sendMessage(sender, translate("commands.give.refinement_only_applicable_weapons"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -120,11 +120,11 @@ public final class GiveCommand implements CommandHandler {
|
||||
this.item(targetPlayer, itemData, amount, lvl, refinement);
|
||||
|
||||
if (!itemData.isEquip()) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Give_given.replace("{amount}", Integer.toString(amount)).replace("{item}", Integer.toString(item)).replace("{target}", Integer.toString(targetPlayer.getUid())));
|
||||
CommandHandler.sendMessage(sender, translate("commands.give.given", Integer.toString(amount), Integer.toString(item), Integer.toString(targetPlayer.getUid())));
|
||||
} else if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Give_given_with_level_and_refinement.replace("{item}", Integer.toString(item)).replace("{lvl}", Integer.toString(lvl)).replace("{refinement}", Integer.toString(refinement)).replace("{amount}", Integer.toString(amount)).replace("{target}", Integer.toString(targetPlayer.getUid())));
|
||||
CommandHandler.sendMessage(sender, translate("commands.give.given_with_level_and_refinement", Integer.toString(item), Integer.toString(lvl), Integer.toString(refinement), Integer.toString(amount), Integer.toString(targetPlayer.getUid())));
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender,Grasscutter.getLanguage().Give_given_level.replace("{item}", Integer.toString(item)).replace("{lvl}", Integer.toString(lvl)).replace("{amount}", Integer.toString(amount)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.give.given_level", Integer.toString(item), Integer.toString(lvl), Integer.toString(amount)));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,6 +7,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "godmode", usage = "godmode [on|off|toggle]",
|
||||
description = "Prevents you from taking damage. Defaults to toggle.", permission = "player.godmode")
|
||||
public final class GodModeCommand implements CommandHandler {
|
||||
@ -14,7 +16,7 @@ public final class GodModeCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -30,11 +32,11 @@ public final class GodModeCommand implements CommandHandler {
|
||||
case "toggle":
|
||||
break; // Already toggled
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Godmode_status);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
targetPlayer.setGodmode(enabled);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Godmode_status.replace("{status}", (enabled ? Grasscutter.getLanguage().Enabled : Grasscutter.getLanguage().Disabled)).replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.godmode.success", (enabled ? translate("commands.status.enabled") : translate("commands.status.disabled")), targetPlayer.getNickname()));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
@ -10,13 +9,15 @@ import emu.grasscutter.server.packet.send.PacketAvatarLifeStateChangeNotify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "heal", usage = "heal|h", aliases = {"h"},
|
||||
description = "Heal all characters in your current team.", permission = "player.heal")
|
||||
public final class HealCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -31,6 +32,6 @@ public final class HealCommand implements CommandHandler {
|
||||
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
|
||||
}
|
||||
});
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Heal_message);
|
||||
CommandHandler.sendMessage(sender, translate("commands.heal.success"));
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "help", usage = "help [command]",
|
||||
description = "Sends the help message or shows information about a specified command")
|
||||
public final class HelpCommand implements CommandHandler {
|
||||
@ -31,16 +33,16 @@ public final class HelpCommand implements CommandHandler {
|
||||
} else {
|
||||
String command = args.get(0);
|
||||
CommandHandler handler = CommandMap.getInstance().getHandler(command);
|
||||
StringBuilder builder = new StringBuilder(player == null ? "\n" + Grasscutter.getLanguage().Help + " - " : Grasscutter.getLanguage().Help + " - ").append(command).append(": \n");
|
||||
StringBuilder builder = new StringBuilder(player == null ? "\n" + translate("commands.status.help") + " - " : translate("commands.status.help") + " - ").append(command).append(": \n");
|
||||
if (handler == null) {
|
||||
builder.append(Grasscutter.getLanguage().No_command_found);
|
||||
builder.append(translate("commands.generic.command_exist_error"));
|
||||
} else {
|
||||
Command annotation = handler.getClass().getAnnotation(Command.class);
|
||||
|
||||
builder.append(" ").append(annotation.description()).append("\n");
|
||||
builder.append(Grasscutter.getLanguage().Help_usage).append(annotation.usage());
|
||||
builder.append(translate("commands.help.usage")).append(annotation.usage());
|
||||
if (annotation.aliases().length >= 1) {
|
||||
builder.append("\n").append(Grasscutter.getLanguage().Help_aliases);
|
||||
builder.append("\n").append(translate("commands.help.aliases"));
|
||||
for (String alias : annotation.aliases()) {
|
||||
builder.append(alias).append(" ");
|
||||
}
|
||||
@ -56,13 +58,13 @@ public final class HelpCommand implements CommandHandler {
|
||||
|
||||
void SendAllHelpMessage(Player player, List<Command> annotations) {
|
||||
if (player == null) {
|
||||
StringBuilder builder = new StringBuilder("\n" + Grasscutter.getLanguage().Help_available_command + "\n");
|
||||
StringBuilder builder = new StringBuilder("\n" + translate("commands.help.available_commands") + "\n");
|
||||
annotations.forEach(annotation -> {
|
||||
builder.append(annotation.label()).append("\n");
|
||||
builder.append(" ").append(annotation.description()).append("\n");
|
||||
builder.append(Grasscutter.getLanguage().Help_usage).append(annotation.usage());
|
||||
builder.append(translate("commands.help.usage")).append(annotation.usage());
|
||||
if (annotation.aliases().length >= 1) {
|
||||
builder.append("\n").append(Grasscutter.getLanguage().Help_aliases);
|
||||
builder.append("\n").append(translate("commands.help.aliases"));
|
||||
for (String alias : annotation.aliases()) {
|
||||
builder.append(alias).append(" ");
|
||||
}
|
||||
@ -73,13 +75,13 @@ public final class HelpCommand implements CommandHandler {
|
||||
|
||||
CommandHandler.sendMessage(null, builder.toString());
|
||||
} else {
|
||||
CommandHandler.sendMessage(player, Grasscutter.getLanguage().Help_available_command);
|
||||
CommandHandler.sendMessage(player, translate("commands.help.available_commands"));
|
||||
annotations.forEach(annotation -> {
|
||||
StringBuilder builder = new StringBuilder(annotation.label()).append("\n");
|
||||
builder.append(" ").append(annotation.description()).append("\n");
|
||||
builder.append(Grasscutter.getLanguage().Help_usage).append(annotation.usage());
|
||||
builder.append(translate("commands.help.usage")).append(annotation.usage());
|
||||
if (annotation.aliases().length >= 1) {
|
||||
builder.append("\n").append(Grasscutter.getLanguage().Help_aliases);
|
||||
builder.append("\n").append(translate("commands.help.aliases"));
|
||||
for (String alias : annotation.aliases()) {
|
||||
builder.append(alias).append(" ");
|
||||
}
|
||||
|
@ -1,12 +1,13 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "kick", usage = "kick",
|
||||
description = "Kicks the specified player from the server (WIP)", permission = "server.kick")
|
||||
public final class KickCommand implements CommandHandler {
|
||||
@ -14,14 +15,16 @@ public final class KickCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (sender != null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Kick_player_kick_player.replace("{sendUid}", Integer.toString(sender.getAccount().getPlayerUid())).replace("{sendName}", sender.getAccount().getUsername()).replace("kickUid", Integer.toString(targetPlayer.getUid())).replace("{kickName}", targetPlayer.getAccount().getUsername()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.kick.player_kick_player",
|
||||
Integer.toString(sender.getAccount().getPlayerUid()), sender.getAccount().getUsername(),
|
||||
Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Kick_server_player.replace("{kickUid}", Integer.toString(targetPlayer.getUid())).replace("{kickName}", targetPlayer.getAccount().getUsername()));
|
||||
CommandHandler.sendMessage(null, translate("commands.kick.server_kick_player", Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
||||
}
|
||||
|
||||
targetPlayer.getSession().close();
|
||||
|
@ -10,6 +10,8 @@ import emu.grasscutter.game.world.Scene;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "killall", usage = "killall [sceneId]",
|
||||
description = "Kill all entities", permission = "server.killall")
|
||||
public final class KillAllCommand implements CommandHandler {
|
||||
@ -17,7 +19,7 @@ public final class KillAllCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -30,14 +32,14 @@ public final class KillAllCommand implements CommandHandler {
|
||||
scene = targetPlayer.getWorld().getSceneById(Integer.parseInt(args.get(0)));
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Kill_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.kill.usage"));
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_arguments);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.argument_error"));
|
||||
}
|
||||
if (scene == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Kill_scene_not_found_in_player_world);
|
||||
CommandHandler.sendMessage(sender, translate("commands.kill.scene_not_found_in_player_world"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -46,7 +48,7 @@ public final class KillAllCommand implements CommandHandler {
|
||||
List<GameEntity> toKill = sceneF.getEntities().values().stream()
|
||||
.filter(entity -> entity instanceof EntityMonster)
|
||||
.toList();
|
||||
toKill.stream().forEach(entity -> sceneF.killEntity(entity, 0));
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Kill_kill_monsters_in_scene.replace("{size}", Integer.toString(toKill.size())).replace("{id}", Integer.toString(scene.getId())));
|
||||
toKill.forEach(entity -> sceneF.killEntity(entity, 0));
|
||||
CommandHandler.sendMessage(sender, translate("commands.kill.kill_monsters_in_scene", Integer.toString(toKill.size()), Integer.toString(scene.getId())));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
@ -12,6 +11,8 @@ import emu.grasscutter.server.packet.send.PacketLifeStateChangeNotify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "killcharacter", usage = "killcharacter", aliases = {"suicide", "kill"},
|
||||
description = "Kills the players current character", permission = "player.killcharacter")
|
||||
public final class KillCharacterCommand implements CommandHandler {
|
||||
@ -19,7 +20,7 @@ public final class KillCharacterCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -32,6 +33,6 @@ public final class KillCharacterCommand implements CommandHandler {
|
||||
targetPlayer.getScene().removeEntity(entity);
|
||||
entity.onDeath(0);
|
||||
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().KillCharacter_kill_current_character.replace("{name}", targetPlayer.getNickname()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.killCharacter.success", targetPlayer.getNickname()));
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import emu.grasscutter.game.player.Player;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "list", usage = "list [uid]",
|
||||
description = "List online players", aliases = {"players"})
|
||||
public final class ListCommand implements CommandHandler {
|
||||
@ -21,7 +23,7 @@ public final class ListCommand implements CommandHandler {
|
||||
needUID = args.get(0).equals("uid");
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().List_message.replace("{size}", Integer.toString(playersMap.size())));
|
||||
CommandHandler.sendMessage(sender, translate("commands.list.success", Integer.toString(playersMap.size())));
|
||||
|
||||
if (playersMap.size() != 0) {
|
||||
StringBuilder playerSet = new StringBuilder();
|
||||
|
@ -8,6 +8,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "permission", usage = "permission <add|remove> <permission>",
|
||||
description = "Grants or removes a permission for a user", permission = "*")
|
||||
public final class PermissionCommand implements CommandHandler {
|
||||
@ -15,12 +17,12 @@ public final class PermissionCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() != 2) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Permission_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.permission.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -29,23 +31,23 @@ public final class PermissionCommand implements CommandHandler {
|
||||
|
||||
Account account = targetPlayer.getAccount();
|
||||
if (account == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Account_not_find);
|
||||
CommandHandler.sendMessage(sender, translate("commands.permission.account_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (action) {
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Permission_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.permission.usage"));
|
||||
break;
|
||||
case "add":
|
||||
if (account.addPermission(permission)) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Permission_add);
|
||||
} else CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Permission_have_permission);
|
||||
CommandHandler.sendMessage(sender, translate("commands.permission.add"));
|
||||
} else CommandHandler.sendMessage(sender, translate("commands.permission.has_error"));
|
||||
break;
|
||||
case "remove":
|
||||
if (account.removePermission(permission)) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Permission_remove);
|
||||
} else CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Permission_not_have_permission);
|
||||
CommandHandler.sendMessage(sender, translate("commands.permission.remove"));
|
||||
} else CommandHandler.sendMessage(sender, translate("commands.permission.not_have_error"));
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
@ -8,6 +7,8 @@ import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "position", usage = "position", aliases = {"pos"},
|
||||
description = "Get coordinates.")
|
||||
public final class PositionCommand implements CommandHandler {
|
||||
@ -15,11 +16,13 @@ public final class PositionCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
Position pos = targetPlayer.getPos();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Position_message.replace("{x}", Float.toString(pos.getX())).replace("{y}", Float.toString(pos.getY())).replace("{z}", Float.toString(pos.getZ())).replace("{id}", Integer.toString(targetPlayer.getSceneId())));
|
||||
CommandHandler.sendMessage(sender, translate("commands.position.success",
|
||||
Float.toString(pos.getX()), Float.toString(pos.getY()), Float.toString(pos.getZ()),
|
||||
Integer.toString(targetPlayer.getSceneId())));
|
||||
}
|
||||
}
|
||||
|
@ -7,19 +7,23 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "reload", usage = "reload",
|
||||
description = "Reload server config", permission = "server.reload")
|
||||
public final class ReloadCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Reload_reload_start);
|
||||
CommandHandler.sendMessage(sender, translate("commands.reload.reload_start"));
|
||||
|
||||
Grasscutter.loadConfig();
|
||||
Grasscutter.loadLanguage();
|
||||
Grasscutter.getGameServer().getGachaManager().load();
|
||||
Grasscutter.getGameServer().getDropManager().load();
|
||||
Grasscutter.getGameServer().getShopManager().load();
|
||||
Grasscutter.getDispatchServer().loadQueries();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Reload_reload_done);
|
||||
|
||||
CommandHandler.sendMessage(sender, translate("commands.reload.reload_done"));
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,5 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
@ -9,6 +8,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "resetconst", usage = "resetconst [all]",
|
||||
description = "Resets the constellation level on your current active character, will need to relog after using the command to see any changes.",
|
||||
aliases = {"resetconstellation"}, permission = "player.resetconstellation")
|
||||
@ -17,13 +18,13 @@ public final class ResetConstCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() > 0 && args.get(0).equalsIgnoreCase("all")) {
|
||||
targetPlayer.getAvatars().forEach(this::resetConstellation);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().ResetConst_reset_all);
|
||||
CommandHandler.sendMessage(sender, translate("commands.resetConst.reset_all"));
|
||||
} else {
|
||||
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
if (entity == null) {
|
||||
@ -33,7 +34,7 @@ public final class ResetConstCommand implements CommandHandler {
|
||||
Avatar avatar = entity.getAvatar();
|
||||
this.resetConstellation(avatar);
|
||||
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().ResetConst_reset_all_done.replace("{name}", avatar.getAvatarData().getName()));
|
||||
CommandHandler.sendMessage(sender, translate("commands.resetConst.success", avatar.getAvatarData().getName()));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -7,18 +7,20 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "resetshop", usage = "resetshop",
|
||||
description = "Reset target player's shop refresh time.", permission = "server.resetshop")
|
||||
public final class ResetShopLimitCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
targetPlayer.getShopLimit().forEach(x -> x.setNextRefreshTime(0));
|
||||
targetPlayer.save();
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Success);
|
||||
CommandHandler.sendMessage(sender, translate("commands.status.success"));
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,9 @@ import emu.grasscutter.game.player.Player;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Command(label = "sendmail", usage = "sendmail <userId|all|help> [templateId]",
|
||||
description = "Sends mail to the specified user. The usage of this command changes based on it's composition state.", permission = "server.sendmail")
|
||||
public final class SendMailCommand implements CommandHandler {
|
||||
@ -45,16 +48,16 @@ public final class SendMailCommand implements CommandHandler {
|
||||
if (DatabaseHelper.getPlayerById(Integer.parseInt(args.get(0))) != null) {
|
||||
mailBuilder = new MailBuilder(Integer.parseInt(args.get(0)), new Mail());
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_user_not_exist.replace("{id}", args.get(0)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.user_not_exist", args.get(0)));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
mailBeingConstructed.put(senderId, mailBuilder);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_start_composition);
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.start_composition"));
|
||||
}
|
||||
case 2 -> CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_templates);
|
||||
default -> CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_invalid_arguments);
|
||||
case 2 -> CommandHandler.sendMessage(sender, translate("commands.sendMail.templates"));
|
||||
default -> CommandHandler.sendMessage(sender, translate("commands.sendMail.invalid_arguments"));
|
||||
}
|
||||
} else {
|
||||
MailBuilder mailBuilder = mailBeingConstructed.get(senderId);
|
||||
@ -63,28 +66,28 @@ public final class SendMailCommand implements CommandHandler {
|
||||
switch (args.get(0).toLowerCase()) {
|
||||
case "stop" -> {
|
||||
mailBeingConstructed.remove(senderId);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_send_cancel);
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.sendCancel"));
|
||||
return;
|
||||
}
|
||||
case "finish" -> {
|
||||
if (mailBuilder.constructionStage == 3) {
|
||||
if (!mailBuilder.sendToAll) {
|
||||
Grasscutter.getGameServer().getPlayerByUid(mailBuilder.recipient, true).sendMail(mailBuilder.mail);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_send_done.replace("{name}", Integer.toString(mailBuilder.recipient)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.send_done", Integer.toString(mailBuilder.recipient)));
|
||||
} else {
|
||||
for (Player player : DatabaseHelper.getAllPlayers()) {
|
||||
Grasscutter.getGameServer().getPlayerByUid(player.getUid(), true).sendMail(mailBuilder.mail);
|
||||
}
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_send_all_done);
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.send_all_done"));
|
||||
}
|
||||
mailBeingConstructed.remove(senderId);
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_not_composition_end.replace("{args}", getConstructionArgs(mailBuilder.constructionStage)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.not_composition_end", getConstructionArgs(mailBuilder.constructionStage)));
|
||||
}
|
||||
return;
|
||||
}
|
||||
case "help" -> {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_please_use.replace("{args}", getConstructionArgs(mailBuilder.constructionStage)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.please_use", getConstructionArgs(mailBuilder.constructionStage)));
|
||||
return;
|
||||
}
|
||||
default -> {
|
||||
@ -92,19 +95,19 @@ public final class SendMailCommand implements CommandHandler {
|
||||
case 0 -> {
|
||||
String title = String.join(" ", args.subList(0, args.size()));
|
||||
mailBuilder.mail.mailContent.title = title;
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_set_title.replace("{title}", title));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.set_title", title));
|
||||
mailBuilder.constructionStage++;
|
||||
}
|
||||
case 1 -> {
|
||||
String contents = String.join(" ", args.subList(0, args.size()));
|
||||
mailBuilder.mail.mailContent.content = contents;
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_set_contents.replace("{contents}", contents));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.set_contents", contents));
|
||||
mailBuilder.constructionStage++;
|
||||
}
|
||||
case 2 -> {
|
||||
String msgSender = String.join(" ", args.subList(0, args.size()));
|
||||
mailBuilder.mail.mailContent.sender = msgSender;
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_set_message_sender.replace("{send}", msgSender));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.set_message_sender", msgSender));
|
||||
mailBuilder.constructionStage++;
|
||||
}
|
||||
case 3 -> {
|
||||
@ -117,21 +120,21 @@ public final class SendMailCommand implements CommandHandler {
|
||||
try {
|
||||
refinement = Integer.parseInt(args.get(3));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_refinement);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemRefinement"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 3: // <itemId|itemName> [amount] [level]
|
||||
try {
|
||||
lvl = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_level);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemLevel"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 2: // <itemId|itemName> [amount]
|
||||
try {
|
||||
amount = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_amount);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.amount"));
|
||||
return;
|
||||
} // Fallthrough
|
||||
case 1: // <itemId|itemName>
|
||||
@ -139,46 +142,34 @@ public final class SendMailCommand implements CommandHandler {
|
||||
item = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
// TODO: Parse from item name using GM Handbook.
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_item_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
default: // *No args*
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Give_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.give.usage"));
|
||||
return;
|
||||
}
|
||||
mailBuilder.mail.itemList.add(new Mail.MailItem(item, amount, lvl));
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_send.replace("{amount}", Integer.toString(amount)).replace("{item}", Integer.toString(item)).replace("{lvl}", Integer.toString(lvl)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.send", Integer.toString(amount), Integer.toString(item), Integer.toString(lvl)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SendMail_invalid_arguments_please_use.replace("{args}", getConstructionArgs(mailBuilder.constructionStage)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMail.invalid_arguments_please_use", getConstructionArgs(mailBuilder.constructionStage)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getConstructionArgs(int stage) {
|
||||
switch (stage) {
|
||||
case 0 -> {
|
||||
return Grasscutter.getLanguage().SendMail_title;
|
||||
}
|
||||
case 1 -> {
|
||||
return Grasscutter.getLanguage().SendMail_message;
|
||||
}
|
||||
case 2 -> {
|
||||
return Grasscutter.getLanguage().SendMail_sender;
|
||||
|
||||
}
|
||||
case 3 -> {
|
||||
return Grasscutter.getLanguage().SendMail_arguments;
|
||||
}
|
||||
default -> {
|
||||
Thread.dumpStack();
|
||||
return Grasscutter.getLanguage().SendMail_error.replace("{stage}", Integer.toString(stage));
|
||||
}
|
||||
}
|
||||
return switch(stage) {
|
||||
case 0 -> translate("commands.sendMail.title");
|
||||
case 1 -> translate("commands.sendMail.message");
|
||||
case 2 -> translate("commands.sendMail.sender");
|
||||
case 3 -> translate("commands.sendMail.arguments");
|
||||
default -> translate("commands.sendMail.error", Integer.toString(stage));
|
||||
};
|
||||
}
|
||||
|
||||
public static class MailBuilder {
|
||||
|
@ -1,12 +1,13 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "say", usage = "say <message>", description = "Sends a message to a player as the server",
|
||||
aliases = {"sendservmsg", "sendservermessage", "sendmessage"}, permission = "server.sendmessage")
|
||||
public final class SendMessageCommand implements CommandHandler {
|
||||
@ -14,16 +15,16 @@ public final class SendMessageCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
if (args.size() == 0) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().SendMessage_usage);
|
||||
CommandHandler.sendMessage(null, translate("commands.sendMessage.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
String message = String.join(" ", args);
|
||||
CommandHandler.sendMessage(targetPlayer, message);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SenaMessage_message_sent);
|
||||
CommandHandler.sendMessage(sender, translate("commands.sendMessage.success"));
|
||||
}
|
||||
}
|
@ -2,7 +2,6 @@ package emu.grasscutter.command.commands;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
@ -10,6 +9,8 @@ import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "setfetterlevel", usage = "setfetterlevel <level>",
|
||||
description = "Sets your fetter level for your current active character",
|
||||
aliases = {"setfetterlvl", "setfriendship"}, permission = "player.setfetterlevel")
|
||||
@ -18,19 +19,19 @@ public final class SetFetterLevelCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() != 1) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SetFetterLevel_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.setFetterLevel.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int fetterLevel = Integer.parseInt(args.get(0));
|
||||
if (fetterLevel < 0 || fetterLevel > 10) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SetFetterLevel_fetter_level_must_between_0_and_10);
|
||||
CommandHandler.sendMessage(sender, translate("commands.setFetterLevel.range_error"));
|
||||
return;
|
||||
}
|
||||
Avatar avatar = targetPlayer.getTeamManager().getCurrentAvatarEntity().getAvatar();
|
||||
@ -42,9 +43,9 @@ public final class SetFetterLevelCommand implements CommandHandler {
|
||||
avatar.save();
|
||||
|
||||
targetPlayer.sendPacket(new PacketAvatarFetterDataNotify(avatar));
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SetFetterLevel_fetter_set_level.replace("{level}", Integer.toString(fetterLevel)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.setFetterLevel.success", fetterLevel));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SetFetterLevel_invalid_fetter_level);
|
||||
CommandHandler.sendMessage(sender, translate("commands.setFetterLevel.level_error"));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -10,13 +10,15 @@ import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.entity.EntityAvatar;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.languages.Language;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
import emu.grasscutter.utils.Language;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "setstats", usage = "setstats|stats <stat> <value>",
|
||||
description = "Set fight property for your current active character", aliases = {"stats"}, permission = "player.setstats")
|
||||
public final class SetStatsCommand implements CommandHandler {
|
||||
class Stat {
|
||||
static class Stat {
|
||||
String name;
|
||||
FightProperty prop;
|
||||
boolean percent;
|
||||
@ -27,44 +29,43 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
this.percent = percent;
|
||||
}
|
||||
}
|
||||
Map<String, Stat> stats;
|
||||
|
||||
Map<String, Stat> stats = new HashMap<>();
|
||||
|
||||
public SetStatsCommand() {
|
||||
Language lang = Grasscutter.getLanguage();
|
||||
stats = new HashMap<String, Stat>();
|
||||
// Default stats
|
||||
stats.put("maxhp", new Stat(lang.Stats_FIGHT_PROP_MAX_HP, FightProperty.FIGHT_PROP_MAX_HP, false));
|
||||
stats.put("hp", new Stat(lang.Stats_FIGHT_PROP_CUR_HP, FightProperty.FIGHT_PROP_CUR_HP, false));
|
||||
stats.put("atk", new Stat(lang.Stats_FIGHT_PROP_CUR_ATTACK, FightProperty.FIGHT_PROP_CUR_ATTACK, false));
|
||||
stats.put("atkb", new Stat(lang.Stats_FIGHT_PROP_BASE_ATTACK, FightProperty.FIGHT_PROP_BASE_ATTACK, false)); // This doesn't seem to get used to recalculate ATK, so it's only useful for stuff like Bennett's buff.
|
||||
stats.put("def", new Stat(lang.Stats_FIGHT_PROP_DEFENSE, FightProperty.FIGHT_PROP_DEFENSE, false));
|
||||
stats.put("em", new Stat(lang.Stats_FIGHT_PROP_ELEMENT_MASTERY, FightProperty.FIGHT_PROP_ELEMENT_MASTERY, false));
|
||||
stats.put("er", new Stat(lang.Stats_FIGHT_PROP_CHARGE_EFFICIENCY, FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, true));
|
||||
stats.put("crate", new Stat(lang.Stats_FIGHT_PROP_CRITICAL, FightProperty.FIGHT_PROP_CRITICAL, true));
|
||||
stats.put("cdmg", new Stat(lang.Stats_FIGHT_PROP_CRITICAL_HURT, FightProperty.FIGHT_PROP_CRITICAL_HURT, true));
|
||||
stats.put("dmg", new Stat(lang.Stats_FIGHT_PROP_ADD_HURT, FightProperty.FIGHT_PROP_ADD_HURT, true)); // This seems to get reset after attacks
|
||||
stats.put("eanemo", new Stat(lang.Stats_FIGHT_PROP_WIND_ADD_HURT, FightProperty.FIGHT_PROP_WIND_ADD_HURT, true));
|
||||
stats.put("ecryo", new Stat(lang.Stats_FIGHT_PROP_ICE_ADD_HURT, FightProperty.FIGHT_PROP_ICE_ADD_HURT, true));
|
||||
stats.put("edendro", new Stat(lang.Stats_FIGHT_PROP_GRASS_ADD_HURT, FightProperty.FIGHT_PROP_GRASS_ADD_HURT, true));
|
||||
stats.put("eelectro", new Stat(lang.Stats_FIGHT_PROP_ELEC_ADD_HURT, FightProperty.FIGHT_PROP_ELEC_ADD_HURT, true));
|
||||
stats.put("egeo", new Stat(lang.Stats_FIGHT_PROP_ROCK_ADD_HURT, FightProperty.FIGHT_PROP_ROCK_ADD_HURT, true));
|
||||
stats.put("ehydro", new Stat(lang.Stats_FIGHT_PROP_WATER_ADD_HURT, FightProperty.FIGHT_PROP_WATER_ADD_HURT, true));
|
||||
stats.put("epyro", new Stat(lang.Stats_FIGHT_PROP_FIRE_ADD_HURT, FightProperty.FIGHT_PROP_FIRE_ADD_HURT, true));
|
||||
stats.put("ephys", new Stat(lang.Stats_FIGHT_PROP_PHYSICAL_ADD_HURT, FightProperty.FIGHT_PROP_PHYSICAL_ADD_HURT, true));
|
||||
stats.put("resall", new Stat(lang.Stats_FIGHT_PROP_SUB_HURT, FightProperty.FIGHT_PROP_SUB_HURT, true)); // This seems to get reset after attacks
|
||||
stats.put("resanemo", new Stat(lang.Stats_FIGHT_PROP_WIND_SUB_HURT, FightProperty.FIGHT_PROP_WIND_SUB_HURT, true));
|
||||
stats.put("rescryo", new Stat(lang.Stats_FIGHT_PROP_ICE_SUB_HURT, FightProperty.FIGHT_PROP_ICE_SUB_HURT, true));
|
||||
stats.put("resdendro", new Stat(lang.Stats_FIGHT_PROP_GRASS_SUB_HURT, FightProperty.FIGHT_PROP_GRASS_SUB_HURT, true));
|
||||
stats.put("reselectro", new Stat(lang.Stats_FIGHT_PROP_ELEC_SUB_HURT, FightProperty.FIGHT_PROP_ELEC_SUB_HURT, true));
|
||||
stats.put("resgeo", new Stat(lang.Stats_FIGHT_PROP_ROCK_SUB_HURT, FightProperty.FIGHT_PROP_ROCK_SUB_HURT, true));
|
||||
stats.put("reshydro", new Stat(lang.Stats_FIGHT_PROP_WATER_SUB_HURT, FightProperty.FIGHT_PROP_WATER_SUB_HURT, true));
|
||||
stats.put("respyro", new Stat(lang.Stats_FIGHT_PROP_FIRE_SUB_HURT, FightProperty.FIGHT_PROP_FIRE_SUB_HURT, true));
|
||||
stats.put("resphys", new Stat(lang.Stats_FIGHT_PROP_PHYSICAL_SUB_HURT, FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, true));
|
||||
stats.put("cdr", new Stat(lang.Stats_FIGHT_PROP_SKILL_CD_MINUS_RATIO, FightProperty.FIGHT_PROP_SKILL_CD_MINUS_RATIO, true));
|
||||
stats.put("heal", new Stat(lang.Stats_FIGHT_PROP_HEAL_ADD, FightProperty.FIGHT_PROP_HEAL_ADD, true));
|
||||
stats.put("heali", new Stat(lang.Stats_FIGHT_PROP_HEALED_ADD, FightProperty.FIGHT_PROP_HEALED_ADD, true));
|
||||
stats.put("shield", new Stat(lang.Stats_FIGHT_PROP_SHIELD_COST_MINUS_RATIO, FightProperty.FIGHT_PROP_SHIELD_COST_MINUS_RATIO, true));
|
||||
stats.put("defi", new Stat(lang.Stats_FIGHT_PROP_DEFENCE_IGNORE_RATIO, FightProperty.FIGHT_PROP_DEFENCE_IGNORE_RATIO, true));
|
||||
stats.put("maxhp", new Stat(FightProperty.FIGHT_PROP_MAX_HP.toString(), FightProperty.FIGHT_PROP_MAX_HP, false));
|
||||
stats.put("hp", new Stat(FightProperty.FIGHT_PROP_CUR_HP.toString(), FightProperty.FIGHT_PROP_CUR_HP, false));
|
||||
stats.put("atk", new Stat(FightProperty.FIGHT_PROP_CUR_ATTACK.toString(), FightProperty.FIGHT_PROP_CUR_ATTACK, false));
|
||||
stats.put("atkb", new Stat(FightProperty.FIGHT_PROP_BASE_ATTACK.toString(), FightProperty.FIGHT_PROP_BASE_ATTACK, false)); // This doesn't seem to get used to recalculate ATK, so it's only useful for stuff like Bennett's buff.
|
||||
stats.put("def", new Stat(FightProperty.FIGHT_PROP_DEFENSE.toString(), FightProperty.FIGHT_PROP_DEFENSE, false));
|
||||
stats.put("em", new Stat(FightProperty.FIGHT_PROP_ELEMENT_MASTERY.toString(), FightProperty.FIGHT_PROP_ELEMENT_MASTERY, false));
|
||||
stats.put("er", new Stat(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY.toString(), FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, true));
|
||||
stats.put("crate", new Stat(FightProperty.FIGHT_PROP_CRITICAL.toString(), FightProperty.FIGHT_PROP_CRITICAL, true));
|
||||
stats.put("cdmg", new Stat(FightProperty.FIGHT_PROP_CRITICAL_HURT.toString(), FightProperty.FIGHT_PROP_CRITICAL_HURT, true));
|
||||
stats.put("dmg", new Stat(FightProperty.FIGHT_PROP_ADD_HURT.toString(), FightProperty.FIGHT_PROP_ADD_HURT, true)); // This seems to get reset after attacks
|
||||
stats.put("eanemo", new Stat(FightProperty.FIGHT_PROP_WIND_ADD_HURT.toString(), FightProperty.FIGHT_PROP_WIND_ADD_HURT, true));
|
||||
stats.put("ecryo", new Stat(FightProperty.FIGHT_PROP_ICE_ADD_HURT.toString(), FightProperty.FIGHT_PROP_ICE_ADD_HURT, true));
|
||||
stats.put("edendro", new Stat(FightProperty.FIGHT_PROP_GRASS_ADD_HURT.toString(), FightProperty.FIGHT_PROP_GRASS_ADD_HURT, true));
|
||||
stats.put("eelectro", new Stat(FightProperty.FIGHT_PROP_ELEC_ADD_HURT.toString(), FightProperty.FIGHT_PROP_ELEC_ADD_HURT, true));
|
||||
stats.put("egeo", new Stat(FightProperty.FIGHT_PROP_ROCK_ADD_HURT.toString(), FightProperty.FIGHT_PROP_ROCK_ADD_HURT, true));
|
||||
stats.put("ehydro", new Stat(FightProperty.FIGHT_PROP_WATER_ADD_HURT.toString(), FightProperty.FIGHT_PROP_WATER_ADD_HURT, true));
|
||||
stats.put("epyro", new Stat(FightProperty.FIGHT_PROP_FIRE_ADD_HURT.toString(), FightProperty.FIGHT_PROP_FIRE_ADD_HURT, true));
|
||||
stats.put("ephys", new Stat(FightProperty.FIGHT_PROP_PHYSICAL_ADD_HURT.toString(), FightProperty.FIGHT_PROP_PHYSICAL_ADD_HURT, true));
|
||||
stats.put("resall", new Stat(FightProperty.FIGHT_PROP_SUB_HURT.toString(), FightProperty.FIGHT_PROP_SUB_HURT, true)); // This seems to get reset after attacks
|
||||
stats.put("resanemo", new Stat(FightProperty.FIGHT_PROP_WIND_SUB_HURT.toString(), FightProperty.FIGHT_PROP_WIND_SUB_HURT, true));
|
||||
stats.put("rescryo", new Stat(FightProperty.FIGHT_PROP_ICE_SUB_HURT.toString(), FightProperty.FIGHT_PROP_ICE_SUB_HURT, true));
|
||||
stats.put("resdendro", new Stat(FightProperty.FIGHT_PROP_GRASS_SUB_HURT.toString(), FightProperty.FIGHT_PROP_GRASS_SUB_HURT, true));
|
||||
stats.put("reselectro", new Stat(FightProperty.FIGHT_PROP_ELEC_SUB_HURT.toString(), FightProperty.FIGHT_PROP_ELEC_SUB_HURT, true));
|
||||
stats.put("resgeo", new Stat(FightProperty.FIGHT_PROP_ROCK_SUB_HURT.toString(), FightProperty.FIGHT_PROP_ROCK_SUB_HURT, true));
|
||||
stats.put("reshydro", new Stat(FightProperty.FIGHT_PROP_WATER_SUB_HURT.toString(), FightProperty.FIGHT_PROP_WATER_SUB_HURT, true));
|
||||
stats.put("respyro", new Stat(FightProperty.FIGHT_PROP_FIRE_SUB_HURT.toString(), FightProperty.FIGHT_PROP_FIRE_SUB_HURT, true));
|
||||
stats.put("resphys", new Stat(FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT.toString(), FightProperty.FIGHT_PROP_PHYSICAL_SUB_HURT, true));
|
||||
stats.put("cdr", new Stat(FightProperty.FIGHT_PROP_SKILL_CD_MINUS_RATIO.toString(), FightProperty.FIGHT_PROP_SKILL_CD_MINUS_RATIO, true));
|
||||
stats.put("heal", new Stat(FightProperty.FIGHT_PROP_HEAL_ADD.toString(), FightProperty.FIGHT_PROP_HEAL_ADD, true));
|
||||
stats.put("heali", new Stat(FightProperty.FIGHT_PROP_HEALED_ADD.toString(), FightProperty.FIGHT_PROP_HEALED_ADD, true));
|
||||
stats.put("shield", new Stat(FightProperty.FIGHT_PROP_SHIELD_COST_MINUS_RATIO.toString(), FightProperty.FIGHT_PROP_SHIELD_COST_MINUS_RATIO, true));
|
||||
stats.put("defi", new Stat(FightProperty.FIGHT_PROP_DEFENCE_IGNORE_RATIO.toString(), FightProperty.FIGHT_PROP_DEFENCE_IGNORE_RATIO, true));
|
||||
// Compatibility aliases
|
||||
stats.put("mhp", stats.get("maxhp"));
|
||||
stats.put("cr", stats.get("crate"));
|
||||
@ -175,26 +176,23 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
Language lang = Grasscutter.getLanguage();
|
||||
String syntax = sender == null ? lang.SetStats_usage_console : lang.SetStats_usage_console;
|
||||
String usage = syntax + lang.SetStats_help_message;
|
||||
String syntax = sender == null ? translate("commands.setStats.usage_console") : translate("commands.setStats.ingame");
|
||||
String usage = syntax + translate("commands.setStats.help_message");
|
||||
String statStr;
|
||||
String valueStr;
|
||||
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, lang.Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args.size()) {
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, usage);
|
||||
return;
|
||||
case 2:
|
||||
statStr = args.get(0).toLowerCase();
|
||||
valueStr = args.get(1);
|
||||
break;
|
||||
};
|
||||
if (args.size() == 2) {
|
||||
statStr = args.get(0).toLowerCase();
|
||||
valueStr = args.get(1);
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, usage);
|
||||
return;
|
||||
}
|
||||
|
||||
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
|
||||
@ -206,7 +204,7 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
value = Float.parseFloat(valueStr);
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, lang.SetStats_value_error);
|
||||
CommandHandler.sendMessage(sender, translate("commands.setStats.value_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -220,15 +218,14 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
valueStr = String.format("%.0f", value);
|
||||
}
|
||||
if (targetPlayer == sender) {
|
||||
CommandHandler.sendMessage(sender, lang.SetStats_set_self.replace("{name}", stat.name).replace("{value}", valueStr));
|
||||
CommandHandler.sendMessage(sender, translate("commands.setStats.set_self", stat.name, valueStr));
|
||||
} else {
|
||||
String uidStr = targetPlayer.getAccount().getId();
|
||||
CommandHandler.sendMessage(sender, lang.SetStats_set_for_uid.replace("{name}", stat.name).replace("{uid}", uidStr).replace("{value}", valueStr));
|
||||
CommandHandler.sendMessage(sender, translate("commands.setStats.set_self", stat.name, uidStr, valueStr));
|
||||
}
|
||||
return;
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, usage);
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -7,6 +7,8 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "setworldlevel", usage = "setworldlevel <level>",
|
||||
description = "Sets your world level (Relog to see proper effects)",
|
||||
aliases = {"setworldlvl"}, permission = "player.setworldlevel")
|
||||
@ -15,19 +17,19 @@ public final class SetWorldLevelCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SetWorldLevel_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.setWorldLevel.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int level = Integer.parseInt(args.get(0));
|
||||
if (level > 8 || level < 0) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SetWorldLevel_world_level_must_between_0_and_8);
|
||||
CommandHandler.sendMessage(sender, translate("commands.setWorldLevel.value_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -35,9 +37,9 @@ public final class SetWorldLevelCommand implements CommandHandler {
|
||||
targetPlayer.getWorld().setWorldLevel(level);
|
||||
targetPlayer.setWorldLevel(level);
|
||||
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().SetWorldLevel_set_world_level.replace("{level}", Integer.toString(level)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.setWorldLevel.success", Integer.toString(level)));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().SetWorldLevel_invalid_world_level);
|
||||
CommandHandler.sendMessage(null, translate("commands.setWorldLevel.invalid_world_level"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -20,6 +20,8 @@ import javax.swing.text.html.parser.Entity;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "spawn", usage = "spawn <entityId> [amount] [level(monster only)]",
|
||||
description = "Spawns an entity near you", permission = "server.spawn")
|
||||
public final class SpawnCommand implements CommandHandler {
|
||||
@ -27,7 +29,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -39,23 +41,23 @@ public final class SpawnCommand implements CommandHandler {
|
||||
try {
|
||||
level = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_arguments);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
case 2:
|
||||
try {
|
||||
amount = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_amount);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.error.amount"));
|
||||
} // Fallthrough
|
||||
case 1:
|
||||
try {
|
||||
id = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_entity_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.error.entityId"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Spawn_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.spawn.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -63,7 +65,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
GadgetData gadgetData = GameData.getGadgetDataMap().get(id);
|
||||
ItemData itemData = GameData.getItemDataMap().get(id);
|
||||
if (monsterData == null && gadgetData == null && itemData == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_entity_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.generic.error.entityId"));
|
||||
return;
|
||||
}
|
||||
Scene scene = targetPlayer.getScene();
|
||||
@ -99,7 +101,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
|
||||
scene.addEntity(entity);
|
||||
}
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Spawn_message.replace("{amount}", Integer.toString(amount)).replace("{id}", Integer.toString(id)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.spawn.success", Integer.toString(amount), Integer.toString(id)));
|
||||
}
|
||||
|
||||
private Position GetRandomPositionInCircle(Position origin, double radius){
|
||||
|
@ -7,17 +7,19 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "stop", usage = "stop",
|
||||
description = "Stops the server", permission = "server.stop")
|
||||
public final class StopCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
CommandHandler.sendMessage(null, Grasscutter.getLanguage().Stop_message);
|
||||
CommandHandler.sendMessage(null, translate("commands.stop.success"));
|
||||
for (Player p : Grasscutter.getGameServer().getPlayers().values()) {
|
||||
CommandHandler.sendMessage(p, Grasscutter.getLanguage().Stop_message);
|
||||
CommandHandler.sendMessage(p, translate("commands.stop.success"));
|
||||
}
|
||||
|
||||
System.exit(1);
|
||||
System.exit(1000);
|
||||
}
|
||||
}
|
||||
|
@ -12,13 +12,15 @@ import emu.grasscutter.server.packet.send.PacketAvatarSkillUpgradeRsp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "talent", usage = "talent <talentID> <value>",
|
||||
description = "Set talent level for your current active character", permission = "player.settalent")
|
||||
public final class TalentCommand implements CommandHandler {
|
||||
private void setTalentLevel(Player sender, Player player, Avatar avatar, int talentId, int talentLevel) {
|
||||
int oldLevel = avatar.getSkillLevelMap().get(talentId);
|
||||
if (talentLevel < 0 || talentLevel > 15) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_lower_16);
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.lower_16"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -30,29 +32,29 @@ public final class TalentCommand implements CommandHandler {
|
||||
player.sendPacket(new PacketAvatarSkillChangeNotify(avatar, talentId, oldLevel, talentLevel));
|
||||
player.sendPacket(new PacketAvatarSkillUpgradeRsp(avatar, talentId, oldLevel, talentLevel));
|
||||
|
||||
String successMessage = Grasscutter.getLanguage().Talent_set_id.replace("{id}", Integer.toString(talentId));
|
||||
String successMessage = "commands.talent.set_id";
|
||||
AvatarSkillDepotData depot = avatar.getData().getSkillDepot();
|
||||
if (talentId == depot.getSkills().get(0)) {
|
||||
successMessage = Grasscutter.getLanguage().Talent_set_atk;
|
||||
successMessage = "commands.talent.set_atk";
|
||||
} else if (talentId == depot.getSkills().get(1)) {
|
||||
successMessage = Grasscutter.getLanguage().Talent_set_e;
|
||||
successMessage = "commands.talent.set_e";
|
||||
} else if (talentId == depot.getEnergySkill()) {
|
||||
successMessage = Grasscutter.getLanguage().Talent_set_q;
|
||||
successMessage = "commands.talent.set_q";
|
||||
}
|
||||
CommandHandler.sendMessage(sender, successMessage.replace("{level}", Integer.toString(talentLevel)));
|
||||
CommandHandler.sendMessage(sender, translate(successMessage, talentLevel));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() < 1){
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_1);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_2);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_3);
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_1"));
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_2"));
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_3"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -60,66 +62,54 @@ public final class TalentCommand implements CommandHandler {
|
||||
Avatar avatar = entity.getAvatar();
|
||||
String cmdSwitch = args.get(0);
|
||||
switch (cmdSwitch) {
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_1);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_2);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_3);
|
||||
return;
|
||||
case "set":
|
||||
if (args.size() < 3){
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_1);
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_3);
|
||||
default -> {
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_1"));
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_2"));
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_3"));
|
||||
return;
|
||||
}
|
||||
case "set" -> {
|
||||
if (args.size() < 3) {
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_1"));
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_3"));
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int skillId = Integer.parseInt(args.get(1));
|
||||
int newLevel = Integer.parseInt(args.get(2));
|
||||
setTalentLevel(sender, targetPlayer, avatar, skillId, newLevel);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_invalid_skill_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.invalid_skill_id"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "n":
|
||||
case "e":
|
||||
case "q":
|
||||
if (args.size() < 2){
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_usage_2);
|
||||
}
|
||||
case "n", "e", "q" -> {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.usage_2"));
|
||||
return;
|
||||
}
|
||||
|
||||
AvatarSkillDepotData SkillDepot = avatar.getData().getSkillDepot();
|
||||
int skillId;
|
||||
switch (cmdSwitch) {
|
||||
default:
|
||||
skillId = SkillDepot.getSkills().get(0);
|
||||
break;
|
||||
case "e":
|
||||
skillId = SkillDepot.getSkills().get(1);
|
||||
break;
|
||||
case "q":
|
||||
skillId = SkillDepot.getEnergySkill();
|
||||
break;
|
||||
}
|
||||
|
||||
int skillId = switch (cmdSwitch) {
|
||||
default -> SkillDepot.getSkills().get(0);
|
||||
case "e" -> SkillDepot.getSkills().get(1);
|
||||
case "q" -> SkillDepot.getEnergySkill();
|
||||
};
|
||||
try {
|
||||
int newLevel = Integer.parseInt(args.get(1));
|
||||
setTalentLevel(sender, targetPlayer, avatar, skillId, newLevel);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_invalid_talent_level);
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.invalid_level"));
|
||||
return;
|
||||
}
|
||||
break;
|
||||
case "getid":
|
||||
}
|
||||
case "getid" -> {
|
||||
int skillIdNorAtk = avatar.getData().getSkillDepot().getSkills().get(0);
|
||||
int skillIdE = avatar.getData().getSkillDepot().getSkills().get(1);
|
||||
int skillIdQ = avatar.getData().getSkillDepot().getEnergySkill();
|
||||
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_normal_attack_id.replace("{id}", Integer.toString(skillIdNorAtk)));
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_e_skill_id.replace("{id}", Integer.toString(skillIdE)));
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Talent_q_skill_id.replace("{id}", Integer.toString(skillIdQ)));
|
||||
break;
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.normal_attack_id", Integer.toString(skillIdNorAtk)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.e_skill_id", Integer.toString(skillIdE)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.talent.q_skill_id", Integer.toString(skillIdQ)));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -8,18 +8,20 @@ import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "tpall", usage = "tpall",
|
||||
description = "Teleports all players in your world to your position", permission = "player.tpall")
|
||||
public final class TeleportAllCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
if (!targetPlayer.getWorld().isMultiplayer()) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().TeleportAll_message);
|
||||
CommandHandler.sendMessage(sender, translate("commands.teleportAll.error"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -30,5 +32,7 @@ public final class TeleportAllCommand implements CommandHandler {
|
||||
|
||||
player.getWorld().transferPlayerToScene(player, targetPlayer.getSceneId(), pos);
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(sender, translate("commands.teleportAll.success"));
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,8 @@ import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "teleport", usage = "teleport <x> <y> <z> [scene id]", aliases = {"tp"},
|
||||
description = "Change the player's position.", permission = "player.teleport")
|
||||
public final class TeleportCommand implements CommandHandler {
|
||||
@ -26,7 +28,7 @@ public final class TeleportCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -41,7 +43,7 @@ public final class TeleportCommand implements CommandHandler {
|
||||
try {
|
||||
sceneId = Integer.parseInt(args.get(3));
|
||||
}catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Invalid_arguments);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.argument_error"));
|
||||
} // Fallthrough
|
||||
case 3:
|
||||
try {
|
||||
@ -49,20 +51,23 @@ public final class TeleportCommand implements CommandHandler {
|
||||
y = parseRelative(args.get(1), y);
|
||||
z = parseRelative(args.get(2), z);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Teleport_invalid_position);
|
||||
CommandHandler.sendMessage(sender, translate("commands.teleport.invalid_position"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Teleport_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.teleport.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
Position target_pos = new Position(x, y, z);
|
||||
boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, target_pos);
|
||||
if (!result) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Teleport_invalid_position);
|
||||
CommandHandler.sendMessage(sender, translate("commands.teleport.invalid_position"));
|
||||
} else {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Teleport_message.replace("{name}", targetPlayer.getNickname()).replace("{x}", Float.toString(x)).replace("{y}", Float.toString(y)).replace("{z}", Float.toString(z)).replace("{id}", Integer.toString(sceneId)));
|
||||
CommandHandler.sendMessage(sender, translate("commands.teleport.success",
|
||||
targetPlayer.getNickname(), Float.toString(x), Float.toString(y),
|
||||
Float.toString(z), Integer.toString(sceneId))
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
|
@ -9,6 +9,8 @@ import emu.grasscutter.server.packet.send.PacketSceneAreaWeatherNotify;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "weather", usage = "weather <weatherId> [climateId]",
|
||||
description = "Changes the weather.", aliases = {"w"}, permission = "player.weather")
|
||||
public final class WeatherCommand implements CommandHandler {
|
||||
@ -16,7 +18,7 @@ public final class WeatherCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (targetPlayer == null) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Target_needed);
|
||||
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -27,17 +29,17 @@ public final class WeatherCommand implements CommandHandler {
|
||||
try {
|
||||
climateId = Integer.parseInt(args.get(1));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Weather_invalid_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.weather.invalid_id"));
|
||||
}
|
||||
case 1:
|
||||
try {
|
||||
weatherId = Integer.parseInt(args.get(0));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Weather_invalid_id);
|
||||
CommandHandler.sendMessage(sender, translate("commands.weather.invalid_id"));
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Weather_usage);
|
||||
CommandHandler.sendMessage(sender, translate("commands.weather.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -46,7 +48,6 @@ public final class WeatherCommand implements CommandHandler {
|
||||
targetPlayer.getScene().setWeather(weatherId);
|
||||
targetPlayer.getScene().setClimate(climate);
|
||||
targetPlayer.getScene().broadcastPacket(new PacketSceneAreaWeatherNotify(targetPlayer));
|
||||
CommandHandler.sendMessage(sender, Grasscutter.getLanguage().Weather_message.replace("{weatherId}", Integer.toString(weatherId)).replace("{climateId}", Integer.toString(climateId)));
|
||||
|
||||
CommandHandler.sendMessage(sender, translate("commands.weather.success", Integer.toString(weatherId), Integer.toString(climateId)));
|
||||
}
|
||||
}
|
||||
|
@ -4,13 +4,7 @@ import com.google.gson.reflect.TypeToken;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.common.ItemParamData;
|
||||
import emu.grasscutter.data.def.ItemData;
|
||||
import emu.grasscutter.data.def.ShopGoodsData;
|
||||
import emu.grasscutter.game.inventory.GameItem;
|
||||
import emu.grasscutter.game.managers.InventoryManager;
|
||||
import emu.grasscutter.game.props.ActionReason;
|
||||
import emu.grasscutter.net.proto.ItemParamOuterClass;
|
||||
import emu.grasscutter.net.proto.ShopGoodsOuterClass;
|
||||
import emu.grasscutter.server.game.GameServer;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
|
||||
@ -54,9 +48,9 @@ public class ShopManager {
|
||||
|
||||
public static int getShopNextRefreshTime(ShopInfo shopInfo) {
|
||||
return switch (shopInfo.getShopRefreshType()) {
|
||||
case SHOP_REFRESH_DAILY -> Utils.GetNextTimestampOfThisHour(REFRESH_HOUR, TIME_ZONE, shopInfo.getShopRefreshParam());
|
||||
case SHOP_REFRESH_WEEKLY -> Utils.GetNextTimestampOfThisHourInNextWeek(REFRESH_HOUR, TIME_ZONE, shopInfo.getShopRefreshParam());
|
||||
case SHOP_REFRESH_MONTHLY -> Utils.GetNextTimestampOfThisHourInNextMonth(REFRESH_HOUR, TIME_ZONE, shopInfo.getShopRefreshParam());
|
||||
case SHOP_REFRESH_DAILY -> Utils.getNextTimestampOfThisHour(REFRESH_HOUR, TIME_ZONE, shopInfo.getShopRefreshParam());
|
||||
case SHOP_REFRESH_WEEKLY -> Utils.getNextTimestampOfThisHourInNextWeek(REFRESH_HOUR, TIME_ZONE, shopInfo.getShopRefreshParam());
|
||||
case SHOP_REFRESH_MONTHLY -> Utils.getNextTimestampOfThisHourInNextMonth(REFRESH_HOUR, TIME_ZONE, shopInfo.getShopRefreshParam());
|
||||
default -> 0;
|
||||
};
|
||||
}
|
||||
|
@ -1,289 +0,0 @@
|
||||
package emu.grasscutter.languages;
|
||||
|
||||
public final class CNLanguage {
|
||||
public String An_error_occurred_during_game_update = "游戏更新时发生了错误.";
|
||||
public String Starting_Grasscutter = "正在开启Grasscutter...";
|
||||
public String Invalid_server_run_mode = "无效的服务器运行模式. ";
|
||||
public String Server_run_mode = "服务器运行模式必须为以下几种之一: 'HYBRID'(混合模式), 'DISPATCH_ONLY'(仅dispatch模式), 或 'GAME_ONLY'(仅游戏模式). 无法启动Grasscutter...";
|
||||
public String Shutting_down = "正在停止....";
|
||||
public String Start_done = "加载完成!需要指令帮助请输入 \"help\"";
|
||||
public String Dispatch_mode_not_support_command = "仅dispatch模式无法使用指令。";
|
||||
public String Command_error = "命令错误:";
|
||||
public String Error = "出现错误.";
|
||||
public String Grasscutter_is_free = "Grasscutter是免费软件,如果你是花钱买到的,你大概被骗了。主页: https://github.com/Grasscutters/Grasscutter";
|
||||
public String Game_start_port = "游戏服务器已在端口 {port} 上开启。";
|
||||
public String Client_connect = "来自 {address} 的客户端已连接。";
|
||||
public String Client_disconnect = "来自 {address} 的客户端已断开。";
|
||||
public String Client_request = "[Dispatch] 客户端 {ip} 请求: {method} {url}";
|
||||
public String Not_load_keystore = "[Dispatch] 无法加载证书,正在尝试默认密码...";
|
||||
public String Use_default_keystore = "[Dispatch] 成功使用默认密码加载证书. 请考虑将config.json中的KeystorePassword项改为123456.";
|
||||
public String Load_keystore_error = "[Dispatch] 加载证书时出现错误!";
|
||||
public String Not_find_ssl_cert = "[Dispatch] 未找到SSL证书,正在回滚至HTTP模式。";
|
||||
public String Welcome = "欢迎使用Grasscutter";
|
||||
public String Potential_unhandled_request = "[Dispatch] 潜在的未处理请求: {method} {url}";
|
||||
public String Client_login_token = "[Dispatch] 客户端 {ip} 正在尝试使用token登录...";
|
||||
public String Client_token_login_failed = "[Dispatch] 客户端 {ip} 使用token登录失败。";
|
||||
public String Client_login_in_token = "[Dispatch] 客户端 {ip} 使用token以 {uid} 的身份登录。";
|
||||
public String Game_account_cache_error = "游戏账户缓存出现错误。";
|
||||
public String Wrong_session_key = "会话密钥错误。";
|
||||
public String Client_exchange_combo_token = "[Dispatch] 客户端 {ip} 成功交换token。";
|
||||
public String Client_failed_exchange_combo_token = "[Dispatch] 客户端 {ip} 交换token失败。";
|
||||
public String Dispatch_start_server_port = "[Dispatch] Dispatch服务器已在端口 {port} 上开启。";
|
||||
public String Client_failed_login_account_create = "[Dispatch] 客户端 {ip} 登录失败: 已创建UID为 {uid} 的账户。";
|
||||
public String Client_failed_login_account_create_failed = "[Dispatch] 客户端 {ip} 登录失败: 创建账户失败。";
|
||||
public String Client_failed_login_account_no_found = "[Dispatch] 客户端 {ip} 登录失败: 未找到帐户。";
|
||||
public String Client_login = "[Dispatch] 客户端 {ip} 以 {uid} 的身份登录。";
|
||||
public String Username_not_found = "未找到此用户名.";
|
||||
public String Username_not_found_create_failed = "未找到此用户名, 创建失败。.";
|
||||
|
||||
// Command
|
||||
public String No_command_specified = "未指定命令.";
|
||||
public String Unknown_command = "未知命令: ";
|
||||
public String You_not_permission_run_command = "你没有权限运行此命令.";
|
||||
public String This_command_can_only_run_from_console = "此命令只能在控制台运行.";
|
||||
public String Run_this_command_in_game = "请在游戏内运行此命令.";
|
||||
public String Invalid_playerId = "无效的玩家ID.";
|
||||
public String Player_not_found = "未找到此玩家.";
|
||||
public String Player_is_offline = "此玩家已离线.";
|
||||
public String Invalid_amount = "无效的数量.";
|
||||
public String Invalid_arguments = "无效的命令参数.";
|
||||
public String Invalid_artifact_id = "无效的圣遗物ID.";
|
||||
public String Invalid_avatar_id = "无效的角色ID.";
|
||||
public String Invalid_avatar_level = "无效的角色等级.";
|
||||
public String Invalid_entity_id = "无效的物品ID.";
|
||||
public String Invalid_item_id = "无效的物品ID.";
|
||||
public String Invalid_item_level = "无效的物品等级.";
|
||||
public String Invalid_item_refinement = "无效的精炼等级.";
|
||||
public String Invalid_UID = "无效的UID.";
|
||||
public String Enabled = "启用";
|
||||
public String Disabled = "禁用";
|
||||
public String No_command_found = "未找到命令.";
|
||||
public String Help = "帮助";
|
||||
public String Player_not_found_or_offline = "此玩家不存在或已离线.";
|
||||
public String Success = "成功";
|
||||
public String Target_cleared = "已清除选择目标";
|
||||
public String Target_set = "接下来的命令将默认以 @{uid} 为目标。输入命令时不必继续携带UID参数。";
|
||||
public String Target_needed = "此命令需要指定一个目标用户. 输入命令时携带 <@UID> 参数或使用 /target @UID 来指定一个默认目标用户.";
|
||||
|
||||
// Help
|
||||
public String Help_usage = " 用法: ";
|
||||
public String Help_aliases = " 别名: ";
|
||||
public String Help_available_command = " 可用命令:";
|
||||
|
||||
// Account
|
||||
public String Modify_user_account = "修改用户帐户";
|
||||
public String Account_exists = "账户已存在.";
|
||||
public String Account_create_UID = "UID为 {uid} 的账户已创建.";
|
||||
public String Account_delete = "已删除账户.";
|
||||
public String Account_not_find = "账户不存在.";
|
||||
public String Account_command_usage = "用法: account <create(创建)|delete(删除)> <用户名> [uid]";
|
||||
|
||||
// Broadcast
|
||||
public String Broadcast_command_usage = "用法: broadcast <消息>";
|
||||
public String Broadcast_message_sent = "消息已发送.";
|
||||
|
||||
// ChangeScene
|
||||
public String Change_screen_usage = "用法: changescene <场景id>";
|
||||
public String Change_screen_you_in_that_screen = "你已经在此场景中了";
|
||||
public String Change_screen = "切换到场景 ";
|
||||
public String Change_screen_not_exist = "此场景不存在。";
|
||||
|
||||
// Cleart_or_playerId
|
||||
public String Clear_weapons = "已清除 {name} 的武器.";
|
||||
public String Clear_artifacts = "已清除 {name} 的圣遗物 .";
|
||||
public String Clear_materials = "已清除 {name} 的材料.";
|
||||
public String Clear_furniture = "已清除 {name} 的摆设.";
|
||||
public String Clear_displays = "已清除 {name} 的displays.";
|
||||
public String Clear_virtuals = "已清除 {name} 的virtuals.";
|
||||
public String Clear_everything = "已清除 {name} 的所有物品.";
|
||||
|
||||
// Coop
|
||||
public String Coop_usage = "用法: coop <房主的UID>";
|
||||
public String Coop_success = "已将{target}拉进{host}的世界.";
|
||||
|
||||
// Drop
|
||||
public String Drop_usage = "用法: drop <物品ID|物品名> [数量]";
|
||||
public String Drop_dropped_of = "已在地上丢弃 {amount} 个 {item}.";
|
||||
|
||||
// EnterDungeon
|
||||
public String EnterDungeon_usage = "用法: enterdungeon <副本 id>";
|
||||
public String EnterDungeon_changed_to_dungeon = "已进入副本 ";
|
||||
public String EnterDungeon_dungeon_not_found = "副本不存在";
|
||||
public String EnterDungeon_you_in_that_dungeon = "你已经在此副本中了。";
|
||||
|
||||
// GiveAll
|
||||
public String GiveAll_usage = "用法: giveall [数量]";
|
||||
public String GiveAll_item = "正在给予所有物品...";
|
||||
public String GiveAll_done = "完成。";
|
||||
|
||||
// GiveArtifact
|
||||
public String GiveArtifact_usage = "用法: giveart|gart [玩家] <圣遗物Id> <主词条Id> [<副词条Id>[,<被强化次数>]]... [等级]";
|
||||
public String GiveArtifact_given = "已将 {itemId} 给予 {target}.";
|
||||
|
||||
// GiveChar
|
||||
public String GiveChar_usage = "用法: givechar <p玩家> <角色Id|角色名> [等级]";
|
||||
public String GiveChar_given = "将等级为 {level} 的 {avatarId} 给予 {target}.";
|
||||
|
||||
// Give
|
||||
public String Give_usage = "用法: give [玩家名] <物品ID|物品名> [数量] [等级] ";
|
||||
public String Give_refinement_only_applicable_weapons = "精炼只对武器有效。";
|
||||
public String Give_refinement_must_between_1_and_5 = "精炼等级必须在1和5之间。";
|
||||
public String Give_given = "已将 {amount} 个 {item} 给与 {target}.";
|
||||
public String Give_given_with_level_and_refinement = "已将 {amount} 个等级为 {lvl}, 精炼 {refinement} 的 {item} 给予 {target}.";
|
||||
public String Give_given_level = "已将 {amount} 个等级为 {lvl} 的 {item} 给与 {target}.";
|
||||
|
||||
// GodMode
|
||||
public String Godmode_usage = "用法: godmode [on|off|toggle]";
|
||||
public String Godmode_status = "设置 {name} 的无敌模式为: {status} ";
|
||||
|
||||
// Heal
|
||||
public String Heal_message = "所有角色已被治疗。";
|
||||
|
||||
// Kick
|
||||
public String Kick_player_kick_player = "玩家 [{sendUid}:{sendName}] 已踢出 [{kickUid}:{kickName}]";
|
||||
public String Kick_server_player = "正在踢出玩家 [{kickUid}:{kickName}]";
|
||||
|
||||
// Kill
|
||||
public String Kill_usage = "用法: killall [玩家UID] [场景ID]";
|
||||
public String Kill_scene_not_found_in_player_world = "未在玩家世界中找到此场景";
|
||||
public String Kill_kill_monsters_in_scene = "已杀死场景 {id} 中的 {size} 只怪物。 ";
|
||||
|
||||
// KillCharacter
|
||||
public String KillCharacter_usage = "用法: /killcharacter [玩家Id]";
|
||||
public String KillCharacter_kill_current_character = "已干掉 {name} 当前的场上角色.";
|
||||
|
||||
// List
|
||||
public String List_message = "现有 {size} 名玩家在线:";
|
||||
|
||||
// Permission
|
||||
public String Permission_usage = "用法: permission <add|remove> <权限名>";
|
||||
public String Permission_add = "权限已添加。";
|
||||
public String Permission_have_permission = "此玩家已拥有此权限!";
|
||||
public String Permission_remove = "权限已移除。";
|
||||
public String Permission_not_have_permission = "此玩家未拥有此权限!";
|
||||
|
||||
// Position
|
||||
public String Position_message = "坐标: {x},{y},{z}\n场景: {id}";
|
||||
|
||||
// Reload
|
||||
public String Reload_reload_start = "正在重新加载配置.";
|
||||
public String Reload_reload_done = "完成.";
|
||||
|
||||
// ResetConst
|
||||
public String ResetConst_reset_all = "重置你所有角色的命座。";
|
||||
public String ResetConst_reset_all_done = "{name} 的命座已被重置。请重新登录。";
|
||||
|
||||
// ResetShopLimit
|
||||
public String ResetShopLimit_usage = "用法: /resetshop <玩家id>";
|
||||
|
||||
// SendMail
|
||||
public String SendMail_usage = "用法: give [player] <itemId|itemName> [amount]";
|
||||
public String SendMail_user_not_exist = "不存在id为 '{id}' 的用户。";
|
||||
public String SendMail_start_composition = "开始编辑邮件的组成部分.\n请使用 `/sendmail <标题>` 以继续.\n你可以在任何时候使用`/sendmail stop` 来停止编辑.";
|
||||
public String SendMail_templates = "很快就会有邮件模板了.......";
|
||||
public String SendMail_invalid_arguments = "无效的参数.\n用法: `/sendmail <用户Id|all|help> [模板Id]``";
|
||||
public String SendMail_send_cancel = "已取消发送邮件。";
|
||||
public String SendMail_send_done = "已向 {name} 发送邮件!";
|
||||
public String SendMail_send_all_done = "已向所有玩家发送邮件!";
|
||||
public String SendMail_not_composition_end = "邮件组成部分编辑尚未结束.\n请使用 `/sendmail {args}` 或 `/sendmail stop` 来停止编辑";
|
||||
public String SendMail_Please_use = "请使用 `/sendmail {args}`";
|
||||
public String SendMail_set_title = "邮件标题已设为 '{title}'.\n使用 '/sendmail <邮件正文>' 以继续.";
|
||||
public String SendMail_set_contents = "邮件的正文如下:\n '{contents}'\n使用 '/sendmail <发送者署名>' 以继续.";
|
||||
public String SendMail_set_message_sender = "邮件的发送者已设为 '{send}'.\n使用 '/sendmail <物品Id|物品名|finish(结束编辑并发送)> [数量] [等级]";
|
||||
public String SendMail_send = "已将 {amount} 个 {item} (等级 {lvl}) 作为邮件附件.\n你可以继续添加附件,也可以使用 `/sendmail finish` 来停止编辑并发送邮件.";
|
||||
public String SendMail_invalid_arguments_please_use = "无效的参数 \n 请使用 `/sendmail {args}`";
|
||||
public String SendMail_title = "<标题>";
|
||||
public String SendMail_message = "<正文>";
|
||||
public String SendMail_sender = "<发送者>";
|
||||
public String SendMail_arguments = "<物品Id|物品名|finish(结束编辑并发送)> [数量] [等级]";
|
||||
public String SendMail_error = "错误:无效的编写阶段 {stage}. 需要stacktrace请看服务器命令行.";
|
||||
|
||||
// SendMessage
|
||||
public String SendMessage_usage = "用法: sendmessage <玩家名> <消息>";
|
||||
public String SenaMessage_message_sent = "已发送.";
|
||||
|
||||
// SetFetterLevel
|
||||
public String SetFetterLevel_usage = "用法: setfetterlevel <等级>";
|
||||
public String SetFetterLevel_fetter_level_must_between_0_and_10 = "设置的好感等级必须位于 0 和 10 之间。";
|
||||
public String SetFetterLevel_fetter_set_level = "好感等级已设置为 {level}";
|
||||
public String SetFetterLevel_invalid_fetter_level = "无效的好感等级。";
|
||||
|
||||
// SetStats
|
||||
public String SetStats_usage = "用法: setstats|stats <stat> <value>";
|
||||
public String SetStats_setstats_help_message = "用法: /setstats|stats <hp(生命值) | mhp(最大生命值) | def(防御力) | atk(攻击) | em(元素精通) | crate(暴击率) | cdmg(暴击伤害)> <数值> 基本属性(整数)";
|
||||
public String SetStats_stats_help_message = "用法: /stats <er(元素充能) | epyro(火伤) | ecryo(冰伤) | ehydro(水伤) | eanemo(风伤) | egeo(岩伤) | edend(草伤) | eelec(雷伤) | ephys(物伤)> <数值> 元素属性(百分比)";
|
||||
public String SetStats_set_max_hp = "最大生命值已设为 {int}.";
|
||||
public String SetStats_set_max_hp_error = "无效的生命数值.";
|
||||
public String SetStats_set_hp = "生命设置为 {int}.";
|
||||
public String SetStats_set_hp_error = "无效的生命数值.";
|
||||
public String SetStats_set_def = "防御力设置为 {int}.";
|
||||
public String SetStats_set_def_error = "无效的防御力数值.";
|
||||
public String SetStats_set_atk = "攻击力设置为 {int}.";
|
||||
public String SetStats_set_atk_error = "无效的攻击力数值.";
|
||||
public String SetStats_set_em = "元素精通设置为 {int}.";
|
||||
public String SetStats_set_em_error = "无效的元素精通数值.";
|
||||
public String SetStats_set_er = "元素充能设置为 {int}%.";
|
||||
public String SetStats_set_er_error = "无效的元素充能数值.";
|
||||
public String SetStats_set_cr = "暴击率设置为 {int}%.";
|
||||
public String SetStats_set_cr_error = "无效的暴击率数值.";
|
||||
public String SetStats_set_cd = "暴击伤害设置为 {int}%.";
|
||||
public String SetStats_set_cd_error = "无效的暴击伤害数值.";
|
||||
public String SetStats_set_pdb = "火伤设置为 {int}%.";
|
||||
public String SetStats_set_pdb_error = "无效的火伤数值.";
|
||||
public String SetStats_set_cdb = "冰伤设置为 {int}%.";
|
||||
public String SetStats_set_cdb_error = "无效的冰伤数值.";
|
||||
public String SetStats_set_hdb = "水伤设置为 {int}%.";
|
||||
public String SetStats_set_hdb_error = "无效的水伤数值.";
|
||||
public String SetStats_set_adb = "风伤设置为 {int}%.";
|
||||
public String SetStats_set_adb_error = "无效的风伤数值.";
|
||||
public String SetStats_set_gdb = "岩伤设置为 {int}%.";
|
||||
public String SetStats_set_gdb_error = "无效的岩伤数值.";
|
||||
public String SetStats_set_edb = "雷伤设置为 {int}%.";
|
||||
public String SetStats_set_edb_error = "无效的雷伤数值.";
|
||||
public String SetStats_set_physdb = "物伤设置为 {int}%.";
|
||||
public String SetStats_set_physdb_error = "无效的物伤数值.";
|
||||
public String SetStats_set_ddb = "草伤设置为 {int}%.";
|
||||
public String SetStats_set_ddb_error = "无效的草伤数值.";
|
||||
|
||||
// SetWorldLevel
|
||||
public String SetWorldLevel_usage = "用法: setworldlevel <level>";
|
||||
public String SetWorldLevel_world_level_must_between_0_and_8 = "世界等级必须在0-8之间。";
|
||||
public String SetWorldLevel_set_world_level = "世界等级已设置为 {level}.";
|
||||
public String SetWorldLevel_invalid_world_level = "无效的世界等级.";
|
||||
|
||||
// Spawn
|
||||
public String Spawn_usage = "用法: spawn <实体ID|实体名> [数量] [等级(仅限怪物)]";
|
||||
public String Spawn_message = "已生成 {amount} 个 {id}.";
|
||||
|
||||
// Stop
|
||||
public String Stop_message = "正在关闭服务器...";
|
||||
|
||||
// Talent
|
||||
public String Talent_usage_1 = "设置技能等级: /talent set <技能ID> <数值>";
|
||||
public String Talent_usage_2 = "另一种方式: /talent <n 或 e 或 q> <数值>";
|
||||
public String Talent_usage_3 = "获取技能ID: /talent getid";
|
||||
public String Talent_lower_16 = "技能等级应低于16。";
|
||||
public String Talent_set_atk = "设置普通攻击等级为 {level}.";
|
||||
public String Talent_set_e = "设置元素战技(e技能)等级为 {level}.";
|
||||
public String Talent_set_q = "设置元素爆发(q技能)等级为 {level}.";
|
||||
public String Talent_invalid_skill_id = "无效的技能ID。";
|
||||
public String Talent_set_this = "技能等级已设为 {level}.";
|
||||
public String Talent_set_id = "将技能 {id} 的等级设为 {level}.";
|
||||
public String Talent_invalid_talent_level = "无效的技能等级。";
|
||||
public String Talent_normal_attack_id = "普通攻击技能ID {id}.";
|
||||
public String Talent_e_skill_id = "元素战技(e技能)ID {id}.";
|
||||
public String Talent_q_skill_id = "元素爆发(q技能)ID {id}.";
|
||||
|
||||
// TeleportAll
|
||||
public String TeleportAll_message = "此命令仅在多人游戏下可用。";
|
||||
|
||||
// Teleport
|
||||
public String Teleport_usage_server = "用法: /tp <x> <y> <z> [场景ID]";
|
||||
public String Teleport_invalid_position = "无效的位置。";
|
||||
public String Teleport_message = "已将 {name} 传送到场景 {id} ,坐标 {x},{y},{z}";
|
||||
|
||||
// Weather
|
||||
public String Weather_usage = "用法: weather <天气ID> [气候ID]";
|
||||
public String Weather_message = "已修改天气为 {weatherId} 气候为 {climateId}";
|
||||
public String Weather_invalid_id = "无效的ID。";
|
||||
}
|
@ -1,300 +0,0 @@
|
||||
package emu.grasscutter.languages;
|
||||
|
||||
public final class Language {
|
||||
public String An_error_occurred_during_game_update = "An error occurred during game update.";
|
||||
public String Starting_Grasscutter = "Starting Grasscutter...";
|
||||
public String Invalid_server_run_mode = "Invalid server run mode.";
|
||||
public String Server_run_mode = "Server run mode must be 'HYBRID', 'DISPATCH_ONLY', or 'GAME_ONLY'. Unable to start Grasscutter...";
|
||||
public String Shutting_down = "Shutting down...";
|
||||
public String Start_done = "Done! For help, type \"help\"";
|
||||
public String Dispatch_mode_not_support_command = "Commands are not supported in dispatch only mode.";
|
||||
public String Command_error = "Command error:";
|
||||
public String Error = "An error occurred.";
|
||||
public String Grasscutter_is_free = "Grasscutter is FREE software. If you have paid for this, you may have been scammed. Homepage: https://github.com/Grasscutters/Grasscutter";
|
||||
public String Game_start_port = "Game Server started on port {port}";
|
||||
public String Client_connect = "Client connected from {address}";
|
||||
public String Client_disconnect = "Client disconnected from {address}";
|
||||
public String Client_request = "[Dispatch] Client {ip} {method} request: {url}";
|
||||
public String Not_load_keystore = "[Dispatch] Unable to load keystore. Trying default keystore password...";
|
||||
public String Use_default_keystore = "[Dispatch] The default keystore password was loaded successfully. Please consider setting the password to 123456 in config.json.";
|
||||
public String Load_keystore_error = "[Dispatch] Error while loading keystore!";
|
||||
public String Not_find_ssl_cert = "[Dispatch] No SSL cert found! Falling back to HTTP server.";
|
||||
public String Welcome = "Welcome to Grasscutter";
|
||||
public String Potential_unhandled_request = "[Dispatch] Potential unhandled {method} request: {url}";
|
||||
public String Client_try_login = "[Dispatch] Client {ip} is trying to log in";
|
||||
public String Client_login_token = "[Dispatch] Client {ip} is trying to log in via token";
|
||||
public String Client_token_login_failed = "[Dispatch] Client {ip} failed to log in via token";
|
||||
public String Client_login_in_token = "[Dispatch] Client {ip} logged in via token as {uid}";
|
||||
public String Game_account_cache_error = "Game account cache information error";
|
||||
public String Wrong_session_key = "Wrong session key.";
|
||||
public String Client_exchange_combo_token = "[Dispatch] Client {ip} succeed to exchange combo token";
|
||||
public String Client_failed_exchange_combo_token = "[Dispatch] Client {ip} failed to exchange combo token";
|
||||
public String Dispatch_start_server_port = "[Dispatch] Dispatch server started on port {port}";
|
||||
public String Client_failed_login_account_create = "[Dispatch] Client {ip} failed to log in: Account {uid} created";
|
||||
public String Client_failed_login_account_create_failed = "[Dispatch] Client {ip} failed to log in: Account create failed";
|
||||
public String Client_failed_login_account_no_found = "[Dispatch] Client {ip} failed to log in: Account no found";
|
||||
public String Client_login = "[Dispatch] Client {ip} logged in as {uid}";
|
||||
public String Username_not_found = "Username not found.";
|
||||
public String Username_not_found_create_failed = "Username not found, create failed.";
|
||||
public String Create_resources_folder = "Creating resources folder...";
|
||||
public String Place_copy = "Place a copy of 'BinOutput' and 'ExcelBinOutput' in the resources folder.";
|
||||
|
||||
// Command
|
||||
public String No_command_specified = "No command specified.";
|
||||
public String Unknown_command = "Unknown command: ";
|
||||
public String You_not_permission_run_command = "You do not have permission to run this command.";
|
||||
public String This_command_can_only_run_from_console = "This command can only be run from the console.";
|
||||
public String Run_this_command_in_game = "Run this command in-game.";
|
||||
public String Invalid_amount = "Invalid amount.";
|
||||
public String Invalid_arguments = "Invalid arguments.";
|
||||
public String Invalid_artifact_id = "Invalid artifact ID.";
|
||||
public String Invalid_avatar_id = "Invalid avatar id.";
|
||||
public String Invalid_avatar_level = "Invalid avatar level.";
|
||||
public String Invalid_entity_id = "Invalid entity id.";
|
||||
public String Invalid_item_id = "Invalid item id.";
|
||||
public String Invalid_item_level = "Invalid item level.";
|
||||
public String Invalid_item_refinement = "Invalid item refinement level.";
|
||||
public String Invalid_playerId = "Invalid playerId.";
|
||||
public String Invalid_UID = "Invalid UID.";
|
||||
public String Player_not_found = "Player not found.";
|
||||
public String Player_is_offline = "Player is offline.";
|
||||
public String Enabled = "enabled";
|
||||
public String Disabled = "disabled";
|
||||
public String No_command_found = "No command found.";
|
||||
public String Help = "Help";
|
||||
public String Player_not_found_or_offline = "Player not found or offline.";
|
||||
public String Success = "Success";
|
||||
public String Target_cleared = "Target cleared.";
|
||||
public String Target_set = "Subsequent commands will target @{uid} by default.";
|
||||
public String Target_needed = "This command requires a target UID. Add a <@UID> argument or set a persistent target with /target @UID.";
|
||||
|
||||
// Help
|
||||
public String Help_usage = " Usage: ";
|
||||
public String Help_aliases = " Aliases: ";
|
||||
public String Help_available_command = "Available commands:";
|
||||
|
||||
// Account
|
||||
public String Modify_user_account = "Modify user accounts";
|
||||
public String Account_exists = "Account already exists.";
|
||||
public String Account_create_UID = "Account created with UID {uid}.";
|
||||
public String Account_delete = "Account deleted.";
|
||||
public String Account_not_find = "Account not found.";
|
||||
public String Account_command_usage = "Usage: account <create|delete> <username> [uid]";
|
||||
|
||||
// Broadcast
|
||||
public String Broadcast_command_usage = "Usage: broadcast <message>";
|
||||
public String Broadcast_message_sent = "Message sent.";
|
||||
|
||||
// ChangeScene
|
||||
public String Change_screen_usage = "Usage: changescene <scene id>";
|
||||
public String Change_screen_you_in_that_screen = "You are already in that scene";
|
||||
public String Change_screen = "Changed to scene ";
|
||||
public String Change_screen_not_exist = "Scene does not exist";
|
||||
|
||||
// Clear
|
||||
public String Clear_usage = "Usage: clear <all|wp|art|mat>";
|
||||
public String Clear_weapons = "Cleared weapons for {name} .";
|
||||
public String Clear_artifacts = "Cleared artifacts for {name} .";
|
||||
public String Clear_materials = "Cleared materials for {name} .";
|
||||
public String Clear_furniture = "Cleared furniture for {name} .";
|
||||
public String Clear_displays = "Cleared displays for {name} .";
|
||||
public String Clear_virtuals = "Cleared virtuals for {name} .";
|
||||
public String Clear_everything = "Cleared everything for {name} .";
|
||||
|
||||
// Coop
|
||||
public String Coop_usage = "Usage: coop <host UID>";
|
||||
public String Coop_success = "Summoned {target} to {host}'s world.";
|
||||
|
||||
// Drop
|
||||
public String Drop_usage = "Usage: drop <itemId|itemName> [amount]";
|
||||
public String Drop_dropped_of = "Dropped {amount} of {item}.";
|
||||
|
||||
// EnterDungeon
|
||||
public String EnterDungeon_usage = "Usage: enterdungeon <dungeon id>";
|
||||
public String EnterDungeon_changed_to_dungeon = "Changed to dungeon ";
|
||||
public String EnterDungeon_dungeon_not_found = "Dungeon does not exist";
|
||||
public String EnterDungeon_you_in_that_dungeon = "You are already in that dungeon";
|
||||
|
||||
// GiveAll
|
||||
public String GiveAll_usage = "Usage: giveall [amount]";
|
||||
public String GiveAll_item = "Giving all items...";
|
||||
public String GiveAll_done = "Giving all items done";
|
||||
|
||||
// GiveArtifact
|
||||
public String GiveArtifact_usage = "Usage: giveart|gart [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]";
|
||||
public String GiveArtifact_given = "Given {itemId} to {target}.";
|
||||
|
||||
// GiveChar
|
||||
public String GiveChar_usage = "Usage: givechar <player> <itemId|itemName> [amount]";
|
||||
public String GiveChar_given = "Given {avatarId} with level {level} to {target}.";
|
||||
|
||||
// Give
|
||||
public String Give_usage = "Usage: give <player> <itemId|itemName> [amount] [level]";
|
||||
public String Give_refinement_only_applicable_weapons = "Refinement is only applicable to weapons.";
|
||||
public String Give_refinement_must_between_1_and_5 = "Refinement must be between 1 and 5.";
|
||||
public String Give_given = "Given {amount} of {item} to {target}.";
|
||||
public String Give_given_with_level_and_refinement = "Given {item} with level {lvl}, refinement {refinement} {amount} times to {target}";
|
||||
public String Give_given_level = "Given {item} with level {lvl} {amount} times to {target}";
|
||||
|
||||
// GodMode
|
||||
public String Godmode_usage = "Usage: godmode [on|off|toggle]";
|
||||
public String Godmode_status = "Godmode is now {status} for {name}.";
|
||||
|
||||
// Heal
|
||||
public String Heal_message = "All characters have been healed.";
|
||||
|
||||
// Kick
|
||||
public String Kick_player_kick_player = "Player [{sendUid}:{sendName}] has kicked player [{kickUid}:{kickName}]";
|
||||
public String Kick_server_player = "Kicking player [{kickUid}:{kickName}]";
|
||||
|
||||
// Kill
|
||||
public String Kill_usage = "Usage: killall [playerUid] [sceneId]";
|
||||
public String Kill_scene_not_found_in_player_world = "Scene not found in player world";
|
||||
public String Kill_kill_monsters_in_scene = "Killing {size} monsters in scene {id}";
|
||||
|
||||
// KillCharacter
|
||||
public String KillCharacter_usage = "Usage: /killcharacter [playerId]";
|
||||
public String KillCharacter_kill_current_character = "Killed {name} current character.";
|
||||
|
||||
// List
|
||||
public String List_message = "There are {size} player(s) online:";
|
||||
|
||||
// Permission
|
||||
public String Permission_usage = "Usage: permission <add|remove> <permission>";
|
||||
public String Permission_add = "Permission added.";
|
||||
public String Permission_have_permission = "They already have this permission!";
|
||||
public String Permission_remove = "Permission removed.";
|
||||
public String Permission_not_have_permission = "They don't have this permission!";
|
||||
|
||||
// Position
|
||||
public String Position_message = "Coord: {x}, {y}, {z}\nScene id: {id}";
|
||||
|
||||
// Reload
|
||||
public String Reload_reload_start = "Reloading config.";
|
||||
public String Reload_reload_done = "Reload complete.";
|
||||
|
||||
// ResetConst
|
||||
public String ResetConst_reset_all = "Reset all avatars' constellations.";
|
||||
public String ResetConst_reset_all_done = "Constellations for {name} have been reset. Please relog to see changes.";
|
||||
|
||||
// ResetShopLimit
|
||||
public String ResetShopLimit_usage = "Usage: /resetshop <player id>";
|
||||
|
||||
// SendMail
|
||||
public String SendMail_usage = "Usage: give [player] <itemId|itemName> [amount]";
|
||||
public String SendMail_user_not_exist = "The user with an id of '{id}' does not exist";
|
||||
public String SendMail_start_composition = "Starting composition of message.\nPlease use `/sendmail <title>` to continue.\nYou can use `/sendmail stop` at any time";
|
||||
public String SendMail_templates = "Mail templates coming soon implemented...";
|
||||
public String SendMail_invalid_arguments = "Invalid arguments.\nUsage `/sendmail <userId|all|help> [templateId]`";
|
||||
public String SendMail_send_cancel = "Message sending cancelled";
|
||||
public String SendMail_send_done = "Message sent to user {name}!";
|
||||
public String SendMail_send_all_done = "Message sent to all users!";
|
||||
public String SendMail_not_composition_end = "Message composition not at final stage.\nPlease use `/sendmail {args}` or `/sendmail stop` to cancel";
|
||||
public String SendMail_please_use = "Please use `/sendmail {args}`";
|
||||
public String SendMail_set_title = "Message title set as '{title}'.\nUse '/sendmail <content>' to continue.";
|
||||
public String SendMail_set_contents = "Message contents set as '{contents}'.\nUse '/sendmail <sender>' to continue.";
|
||||
public String SendMail_set_message_sender = "Message sender set as '{send}'.\nUse '/sendmail <itemId|itemName|finish> [amount] [level]' to continue.";
|
||||
public String SendMail_send = "Attached {amount} of {item} (level {lvl}) to the message.\nContinue adding more items or use `/sendmail finish` to send the message.";
|
||||
public String SendMail_invalid_arguments_please_use = "Invalid arguments \n Please use `/sendmail {args}`";
|
||||
public String SendMail_title = "<title>";
|
||||
public String SendMail_message = "<message>";
|
||||
public String SendMail_sender = "<sender>";
|
||||
public String SendMail_arguments = "<itemId|itemName|finish> [amount] [level]";
|
||||
public String SendMail_error = "ERROR: invalid construction stage {stage}. Check console for stacktrace.";
|
||||
|
||||
// SendMessage
|
||||
public String SendMessage_usage = "Usage: sendmessage <player> <message>";
|
||||
public String SenaMessage_message_sent = "Message sent.";
|
||||
|
||||
// SetFetterLevel
|
||||
public String SetFetterLevel_usage = "Usage: setfetterlevel <level>";
|
||||
public String SetFetterLevel_fetter_level_must_between_0_and_10 = "Fetter level must be between 0 and 10.";
|
||||
public String SetFetterLevel_fetter_set_level = "Fetter level set to {level}";
|
||||
public String SetFetterLevel_invalid_fetter_level = "Invalid fetter level.";
|
||||
|
||||
// SetStats
|
||||
public String SetStats_usage_console = "Usage: setstats|stats @<UID> <stat> <value>";
|
||||
public String SetStats_usage_ingame = "Usage: setstats|stats [@UID] <stat> <value>";
|
||||
public String SetStats_help_message = """
|
||||
\n\tValues for <stat>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi
|
||||
\t(cont.) Elemental DMG Bonus: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys
|
||||
\t(cont.) Elemental RES: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys
|
||||
""";
|
||||
public String SetStats_value_error = "Invalid stat value.";
|
||||
public String SetStats_set_self = "{name} set to {value}.";
|
||||
public String SetStats_set_for_uid = "{name} for {uid} set to {value}.";
|
||||
public String Stats_FIGHT_PROP_MAX_HP = "Max HP";
|
||||
public String Stats_FIGHT_PROP_CUR_HP = "Current HP";
|
||||
public String Stats_FIGHT_PROP_CUR_ATTACK = "ATK";
|
||||
public String Stats_FIGHT_PROP_BASE_ATTACK = "Base ATK";
|
||||
public String Stats_FIGHT_PROP_DEFENSE = "DEF";
|
||||
public String Stats_FIGHT_PROP_ELEMENT_MASTERY = "Elemental Mastery";
|
||||
public String Stats_FIGHT_PROP_CHARGE_EFFICIENCY = "Energy Recharge";
|
||||
public String Stats_FIGHT_PROP_CRITICAL = "Crit Rate";
|
||||
public String Stats_FIGHT_PROP_CRITICAL_HURT = "Crit DMG";
|
||||
public String Stats_FIGHT_PROP_ADD_HURT = "DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_WIND_ADD_HURT = "Anemo DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_ICE_ADD_HURT = "Cryo DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_GRASS_ADD_HURT = "Dendro DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_ELEC_ADD_HURT = "Electro DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_ROCK_ADD_HURT = "Geo DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_WATER_ADD_HURT = "Hydro DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_FIRE_ADD_HURT = "Pyro DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_PHYSICAL_ADD_HURT = "Physical DMG Bonus";
|
||||
public String Stats_FIGHT_PROP_SUB_HURT = "DMG Reduction";
|
||||
public String Stats_FIGHT_PROP_WIND_SUB_HURT = "Anemo RES";
|
||||
public String Stats_FIGHT_PROP_ICE_SUB_HURT = "Cryo RES";
|
||||
public String Stats_FIGHT_PROP_GRASS_SUB_HURT = "Dendro RES";
|
||||
public String Stats_FIGHT_PROP_ELEC_SUB_HURT = "Electro RES";
|
||||
public String Stats_FIGHT_PROP_ROCK_SUB_HURT = "Geo RES";
|
||||
public String Stats_FIGHT_PROP_WATER_SUB_HURT = "Hydro RES";
|
||||
public String Stats_FIGHT_PROP_FIRE_SUB_HURT = "Pyro RES";
|
||||
public String Stats_FIGHT_PROP_PHYSICAL_SUB_HURT = "Physical RES";
|
||||
public String Stats_FIGHT_PROP_SKILL_CD_MINUS_RATIO = "Cooldown Reduction";
|
||||
public String Stats_FIGHT_PROP_HEAL_ADD = "Healing Bonus";
|
||||
public String Stats_FIGHT_PROP_HEALED_ADD = "Incoming Healing Bonus";
|
||||
public String Stats_FIGHT_PROP_SHIELD_COST_MINUS_RATIO = "Shield Strength";
|
||||
public String Stats_FIGHT_PROP_DEFENCE_IGNORE_RATIO = "DEF Ignore";
|
||||
|
||||
// SetWorldLevel
|
||||
public String SetWorldLevel_usage = "Usage: setworldlevel <level>";
|
||||
public String SetWorldLevel_world_level_must_between_0_and_8 = "World level must be between 0-8";
|
||||
public String SetWorldLevel_set_world_level = "World level set to {level}.";
|
||||
public String SetWorldLevel_invalid_world_level = "Invalid world level.";
|
||||
|
||||
// Spawn
|
||||
public String Spawn_usage = "Usage: spawn <entityId> [amount] [level(monster only)]";
|
||||
public String Spawn_message = "Spawned {amount} of {id}.";
|
||||
|
||||
// Stop
|
||||
public String Stop_message = "Server shutting down...";
|
||||
|
||||
// Talent
|
||||
public String Talent_usage_1 = "To set talent level: /talent set <talentID> <value>";
|
||||
public String Talent_usage_2 = "Another way to set talent level: /talent <n or e or q> <value>";
|
||||
public String Talent_usage_3 = "To get talent ID: /talent getid";
|
||||
public String Talent_lower_16 = "Invalid talent level. Level should be lower than 16";
|
||||
public String Talent_set_id = "Set talent {id} to {level}.";
|
||||
public String Talent_set_atk = "Set talent Normal ATK to {level}.";
|
||||
public String Talent_set_e = "Set talent E to {level}.";
|
||||
public String Talent_set_q = "Set talent Q to {level}.";
|
||||
public String Talent_invalid_skill_id = "Invalid skill ID.";
|
||||
public String Talent_set_this = "Set this talent to {level}.";
|
||||
public String Talent_invalid_talent_level = "Invalid talent level.";
|
||||
public String Talent_normal_attack_id = "Normal Attack ID {id}.";
|
||||
public String Talent_e_skill_id = "E skill ID {id}.";
|
||||
public String Talent_q_skill_id = "Q skill ID {id}.";
|
||||
|
||||
// TeleportAll
|
||||
public String TeleportAll_message = "You only can use this command in MP mode.";
|
||||
|
||||
// Teleport
|
||||
public String Teleport_usage = "Usage: /tp <x> <y> <z> [scene id]";
|
||||
public String Teleport_invalid_position = "Invalid position.";
|
||||
public String Teleport_message = "Teleported {name} to {x},{y},{z} in scene {id}";
|
||||
|
||||
// Weather
|
||||
public String Weather_usage = "Usage: weather <weatherId> [climateId]";
|
||||
public String Weather_message = "Changed weather to {weatherId} with climate {climateId}";
|
||||
public String Weather_invalid_id = "Invalid ID.";
|
||||
}
|
@ -28,6 +28,7 @@ public final class PlayerHook {
|
||||
|
||||
/**
|
||||
* Kicks a player from the server.
|
||||
* TODO: Refactor to kick using a packet.
|
||||
*/
|
||||
public void kick() {
|
||||
this.player.getSession().close();
|
||||
|
@ -1,2 +0,0 @@
|
||||
# Grasscutter Plugin API
|
||||
**Warning!** As of now, this is a work in progress and isn't completely documented.
|
@ -2,6 +2,7 @@ package emu.grasscutter.server.dispatch;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Arrays;
|
||||
import java.util.Objects;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.Grasscutter.ServerDebugMode;
|
||||
@ -9,6 +10,8 @@ import express.http.HttpContextHandler;
|
||||
import express.http.Request;
|
||||
import express.http.Response;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public final class DispatchHttpJsonHandler implements HttpContextHandler {
|
||||
private final String response;
|
||||
private final String[] missingRoutes = { // TODO: When http requests for theses routes are found please remove it from this list and update the route request type in the DispatchServer
|
||||
@ -31,8 +34,8 @@ public final class DispatchHttpJsonHandler implements HttpContextHandler {
|
||||
@Override
|
||||
public void handle(Request req, Response res) throws IOException {
|
||||
// Checking for ALL here isn't required as when ALL is enabled enableDevLogging() gets enabled
|
||||
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING && Arrays.stream(missingRoutes).anyMatch(x -> x == req.baseUrl())) {
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_request.replace("{ip}", req.ip()).replace("{method}", req.method()).replace("{url}", req.baseUrl()) + (Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING ? "(MISSING)" : ""));
|
||||
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING && Arrays.stream(missingRoutes).anyMatch(x -> Objects.equals(x, req.baseUrl()))) {
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.request", req.ip(), req.method(), req.baseUrl()) + (Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING ? "(MISSING)" : ""));
|
||||
}
|
||||
res.send(response);
|
||||
}
|
||||
|
@ -35,6 +35,8 @@ import java.io.*;
|
||||
import java.net.URLDecoder;
|
||||
import java.util.*;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public final class DispatchServer {
|
||||
public static String query_region_list = "";
|
||||
public static String query_cur_region = "";
|
||||
@ -213,21 +215,21 @@ public final class DispatchServer {
|
||||
sslContextFactory.setKeyStorePassword(Grasscutter.getConfig().getDispatchOptions().KeystorePassword);
|
||||
} catch (Exception e) {
|
||||
e.printStackTrace();
|
||||
Grasscutter.getLogger().warn(Grasscutter.getLanguage().Not_load_keystore);
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.password_error"));
|
||||
|
||||
try {
|
||||
sslContextFactory.setKeyStorePath(keystoreFile.getPath());
|
||||
sslContextFactory.setKeyStorePassword("123456");
|
||||
Grasscutter.getLogger().warn(Grasscutter.getLanguage().Use_default_keystore);
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.default_password"));
|
||||
} catch (Exception e2) {
|
||||
Grasscutter.getLogger().warn(Grasscutter.getLanguage().Load_keystore_error);
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.general_error"));
|
||||
e2.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
serverConnector = new ServerConnector(server, sslContextFactory);
|
||||
} else {
|
||||
Grasscutter.getLogger().warn(Grasscutter.getLanguage().Not_find_ssl_cert);
|
||||
Grasscutter.getLogger().warn(translate("messages.dispatch.keystore.no_keystore_error"));
|
||||
Grasscutter.getConfig().getDispatchOptions().UseSSL = false;
|
||||
|
||||
serverConnector = new ServerConnector(server);
|
||||
@ -250,11 +252,11 @@ public final class DispatchServer {
|
||||
else config.enableCorsForAllOrigins();
|
||||
}
|
||||
});
|
||||
httpServer.get("/", (req, res) -> res.send(Grasscutter.getLanguage().Welcome));
|
||||
httpServer.get("/", (req, res) -> res.send(translate("messages.status.welcome")));
|
||||
|
||||
httpServer.raw().error(404, ctx -> {
|
||||
if(Grasscutter.getConfig().DebugMode == ServerDebugMode.MISSING) {
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Potential_unhandled_request.replace("{method}", ctx.method()).replace("{url}", ctx.url()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.unhandled_request_error", ctx.method(), ctx.url()));
|
||||
}
|
||||
ctx.contentType("text/html");
|
||||
ctx.result("<!doctype html><html lang=\"en\"><body><img src=\"https://http.cat/404\" /></body></html>"); // I'm like 70% sure this won't break anything.
|
||||
@ -312,7 +314,7 @@ public final class DispatchServer {
|
||||
if (requestData == null) {
|
||||
return;
|
||||
}
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_try_login.replace("{ip}", req.ip()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_attempt", req.ip()));
|
||||
|
||||
res.send(this.getAuthHandler().handleGameLogin(req, requestData));
|
||||
});
|
||||
@ -332,7 +334,7 @@ public final class DispatchServer {
|
||||
return;
|
||||
}
|
||||
LoginResultJson responseData = new LoginResultJson();
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_login_token.replace("{ip}", req.ip()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_attempt"));
|
||||
|
||||
// Login
|
||||
Account account = DatabaseHelper.getAccountById(requestData.uid);
|
||||
@ -340,16 +342,16 @@ public final class DispatchServer {
|
||||
// Test
|
||||
if (account == null || !account.getSessionKey().equals(requestData.token)) {
|
||||
responseData.retcode = -111;
|
||||
responseData.message = Grasscutter.getLanguage().Game_account_cache_error;
|
||||
responseData.message = translate("messages.dispatch.account.account_cache_error");
|
||||
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_token_login_failed.replace("{ip}", req.ip()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_error", req.ip()));
|
||||
} else {
|
||||
responseData.message = "OK";
|
||||
responseData.data.account.uid = requestData.uid;
|
||||
responseData.data.account.token = requestData.token;
|
||||
responseData.data.account.email = account.getEmail();
|
||||
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_login_in_token.replace("{ip}", req.ip()).replace("{uid}", responseData.data.account.uid));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_token_success", req.ip(), requestData.uid));
|
||||
}
|
||||
|
||||
res.send(responseData);
|
||||
@ -379,16 +381,16 @@ public final class DispatchServer {
|
||||
// Test
|
||||
if (account == null || !account.getSessionKey().equals(loginData.token)) {
|
||||
responseData.retcode = -201;
|
||||
responseData.message = Grasscutter.getLanguage().Wrong_session_key;
|
||||
responseData.message = translate("messages.dispatch.account.session_key_error");
|
||||
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_failed_exchange_combo_token.replace("{ip}", req.ip()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.combo_token_error", req.ip()));
|
||||
} else {
|
||||
responseData.message = "OK";
|
||||
responseData.data.open_id = loginData.uid;
|
||||
responseData.data.combo_id = "157795300";
|
||||
responseData.data.combo_token = account.generateLoginToken();
|
||||
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_exchange_combo_token.replace("{ip}", req.ip()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.combo_token_success", req.ip()));
|
||||
}
|
||||
|
||||
res.send(responseData);
|
||||
@ -461,7 +463,7 @@ public final class DispatchServer {
|
||||
httpServer.raw().config.precompressStaticFiles = false; // If this isn't set to false, files such as images may appear corrupted when serving static files
|
||||
|
||||
httpServer.listen(Grasscutter.getConfig().getDispatchOptions().Port);
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Dispatch_start_server_port.replace("{port}", Integer.toString(httpServer.raw().port())));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.port_bind", Integer.toString(httpServer.raw().port())));
|
||||
}
|
||||
|
||||
private Map<String, String> parseQueryString(String qs) {
|
||||
|
@ -8,6 +8,8 @@ import emu.grasscutter.server.dispatch.json.LoginResultJson;
|
||||
import express.http.Request;
|
||||
import express.http.Response;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public class DefaultAuthenticationHandler implements AuthenticationHandler {
|
||||
|
||||
@Override
|
||||
@ -34,11 +36,9 @@ public class DefaultAuthenticationHandler implements AuthenticationHandler {
|
||||
|
||||
// Check if account exists, else create a new one.
|
||||
if (account == null) {
|
||||
// Account doesnt exist, so we can either auto create it if the config value is
|
||||
// set
|
||||
// Account doesn't exist, so we can either auto create it if the config value is set.
|
||||
if (Grasscutter.getConfig().getDispatchOptions().AutomaticallyCreateAccounts) {
|
||||
// This account has been created AUTOMATICALLY. There will be no permissions
|
||||
// added.
|
||||
// This account has been created AUTOMATICALLY. There will be no permissions added.
|
||||
account = DatabaseHelper.createAccountWithId(requestData.account, 0);
|
||||
|
||||
for (String permission : Grasscutter.getConfig().getDispatchOptions().defaultPermissions) {
|
||||
@ -51,19 +51,18 @@ public class DefaultAuthenticationHandler implements AuthenticationHandler {
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
responseData.data.account.email = account.getEmail();
|
||||
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_failed_login_account_create.replace("{ip}", req.ip()).replace("{uid}", responseData.data.account.uid));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_success", req.ip(), responseData.data.account.uid));
|
||||
} else {
|
||||
responseData.retcode = -201;
|
||||
responseData.message = Grasscutter.getLanguage().Username_not_found_create_failed;
|
||||
responseData.message = translate("messages.dispatch.account.username_create_error");
|
||||
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_failed_login_account_no_found.replace("{ip}", req.ip()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_create_error", req.ip()));
|
||||
}
|
||||
} else {
|
||||
responseData.retcode = -201;
|
||||
responseData.message = Grasscutter.getLanguage().Username_not_found;
|
||||
responseData.message = translate("messages.dispatch.account.username_error");
|
||||
|
||||
Grasscutter.getLogger().info(String
|
||||
.format(Grasscutter.getLanguage().Client_failed_login_account_no_found, req.ip()));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.account_login_exist_error", req.ip()));
|
||||
}
|
||||
} else {
|
||||
// Account was found, log the player in
|
||||
@ -72,7 +71,7 @@ public class DefaultAuthenticationHandler implements AuthenticationHandler {
|
||||
responseData.data.account.token = account.generateSessionKey();
|
||||
responseData.data.account.email = account.getEmail();
|
||||
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_login.replace("{ip}", req.ip()).replace("{uid}", responseData.data.account.uid));
|
||||
Grasscutter.getLogger().info(translate("messages.dispatch.account.login_success", req.ip(), responseData.data.account.uid));
|
||||
}
|
||||
|
||||
return responseData;
|
||||
|
@ -30,6 +30,8 @@ import java.time.OffsetDateTime;
|
||||
import java.util.*;
|
||||
import java.util.concurrent.ConcurrentHashMap;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public final class GameServer extends KcpServer {
|
||||
private final InetSocketAddress address;
|
||||
private final GameServerPacketHandler packetHandler;
|
||||
@ -50,6 +52,13 @@ public final class GameServer extends KcpServer {
|
||||
|
||||
private final CombineManger combineManger;
|
||||
|
||||
public GameServer() {
|
||||
this(new InetSocketAddress(
|
||||
Grasscutter.getConfig().getGameServerOptions().Ip,
|
||||
Grasscutter.getConfig().getGameServerOptions().Port
|
||||
));
|
||||
}
|
||||
|
||||
public GameServer(InetSocketAddress address) {
|
||||
super(address);
|
||||
|
||||
@ -79,7 +88,7 @@ public final class GameServer extends KcpServer {
|
||||
try {
|
||||
onTick();
|
||||
} catch (Exception e) {
|
||||
Grasscutter.getLogger().error(Grasscutter.getLanguage().An_error_occurred_during_game_update, e);
|
||||
Grasscutter.getLogger().error(translate("messages.game.game_update_error"), e);
|
||||
}
|
||||
}
|
||||
}, new Date(), 1000L);
|
||||
@ -222,8 +231,8 @@ public final class GameServer extends KcpServer {
|
||||
|
||||
@Override
|
||||
public void onStartFinish() {
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Grasscutter_is_free);
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Game_start_port.replace("{port}", Integer.toString(address.getPort())));
|
||||
Grasscutter.getLogger().info(translate("messages.status.free_software"));
|
||||
Grasscutter.getLogger().info(translate("messages.game.port_bind", Integer.toString(address.getPort())));
|
||||
ServerStartEvent event = new ServerStartEvent(ServerEvent.Type.GAME, OffsetDateTime.now()); event.call();
|
||||
}
|
||||
|
||||
|
@ -22,6 +22,8 @@ import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
public class GameSession extends KcpChannel {
|
||||
private GameServer server;
|
||||
|
||||
@ -113,21 +115,21 @@ public class GameSession extends KcpChannel {
|
||||
|
||||
@Override
|
||||
protected void onConnect() {
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_connect.replace("{address}", getAddress().getHostString().toLowerCase()));
|
||||
Grasscutter.getLogger().info(translate("messages.game.connect", this.getAddress().getHostString().toLowerCase()));
|
||||
}
|
||||
|
||||
@Override
|
||||
protected synchronized void onDisconnect() { // Synchronize so we dont add character at the same time
|
||||
Grasscutter.getLogger().info(Grasscutter.getLanguage().Client_disconnect.replace("{address}", getAddress().getHostString().toLowerCase()));
|
||||
protected synchronized void onDisconnect() { // Synchronize so we don't add character at the same time.
|
||||
Grasscutter.getLogger().info(translate("messages.game.disconnect", this.getAddress().getHostString().toLowerCase()));
|
||||
|
||||
// Set state so no more packets can be handled
|
||||
this.setState(SessionState.INACTIVE);
|
||||
|
||||
// Save after disconnecting
|
||||
if (this.isLoggedIn()) {
|
||||
// Save
|
||||
// Call logout event.
|
||||
getPlayer().onLogout();
|
||||
// Remove from gameserver
|
||||
// Remove from server.
|
||||
getServer().getPlayers().remove(getPlayer().getUid());
|
||||
}
|
||||
}
|
||||
|
@ -93,6 +93,7 @@ public final class Tools {
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().info("GM Handbook generated!");
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation")
|
||||
@ -180,6 +181,8 @@ public final class Tools {
|
||||
writer.println(",\"200\": \"Standard\", \"301\": \"Avatar Event\", \"302\": \"Weapon event\"");
|
||||
writer.println("}\n}");
|
||||
}
|
||||
|
||||
Grasscutter.getLogger().info("Mappings generated!");
|
||||
System.exit(0);
|
||||
}
|
||||
}
|
||||
|
82
src/main/java/emu/grasscutter/utils/Language.java
Normal file
82
src/main/java/emu/grasscutter/utils/Language.java
Normal file
@ -0,0 +1,82 @@
|
||||
package emu.grasscutter.utils;
|
||||
|
||||
import com.google.gson.JsonElement;
|
||||
import com.google.gson.JsonObject;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
|
||||
import javax.annotation.Nullable;
|
||||
import java.io.InputStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public final class Language {
|
||||
private final JsonObject languageData;
|
||||
private final Map<String, String> cachedTranslations = new HashMap<>();
|
||||
|
||||
/**
|
||||
* Creates a language instance from a code.
|
||||
* @param langCode The language code.
|
||||
* @return A language instance.
|
||||
*/
|
||||
public static Language getLanguage(String langCode) {
|
||||
return new Language(langCode + ".json");
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the translated value from the key while substituting arguments.
|
||||
* @param key The key of the translated value to return.
|
||||
* @param args The arguments to substitute.
|
||||
* @return A translated value with arguments substituted.
|
||||
*/
|
||||
public static String translate(String key, Object... args) {
|
||||
return Grasscutter.getLanguage().get(key).formatted(args);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads a file and creates a language instance.
|
||||
* @param fileName The name of the language file.
|
||||
*/
|
||||
private Language(String fileName) {
|
||||
@Nullable JsonObject languageData = null;
|
||||
|
||||
try {
|
||||
InputStream file = Grasscutter.class.getResourceAsStream("/lang/" + fileName);
|
||||
languageData = Grasscutter.getGsonFactory().fromJson(Utils.readFromInputStream(file), JsonObject.class);
|
||||
} catch (Exception exception) {
|
||||
Grasscutter.getLogger().error("Failed to load language file: " + fileName, exception);
|
||||
} this.languageData = languageData;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the value (as a string) from a nested key.
|
||||
* @param key The key to look for.
|
||||
* @return The value (as a string) from a nested key.
|
||||
*/
|
||||
public String get(String key) {
|
||||
if(this.cachedTranslations.containsKey(key)) {
|
||||
return this.cachedTranslations.get(key);
|
||||
}
|
||||
|
||||
String[] keys = key.split("\\.");
|
||||
JsonObject object = this.languageData;
|
||||
|
||||
int index = 0;
|
||||
String result = "This value does not exist. Please report this to the Discord: " + key;
|
||||
|
||||
while (true) {
|
||||
if(index == keys.length) break;
|
||||
|
||||
String currentKey = keys[index++];
|
||||
if(object.has(currentKey)) {
|
||||
JsonElement element = object.get(currentKey);
|
||||
if(element.isJsonObject())
|
||||
object = element.getAsJsonObject();
|
||||
else {
|
||||
result = element.getAsString(); break;
|
||||
}
|
||||
} else break;
|
||||
}
|
||||
|
||||
this.cachedTranslations.put(key, result); return result;
|
||||
}
|
||||
}
|
@ -1,23 +1,21 @@
|
||||
package emu.grasscutter.utils;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.time.*;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.Random;
|
||||
|
||||
import emu.grasscutter.Config;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.ByteBufUtil;
|
||||
import io.netty.buffer.Unpooled;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
|
||||
import java.io.*;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.StandardCopyOption;
|
||||
import java.time.DayOfWeek;
|
||||
import java.time.ZoneId;
|
||||
import java.time.ZoneOffset;
|
||||
import java.time.ZonedDateTime;
|
||||
import java.time.temporal.TemporalAdjusters;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Random;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@SuppressWarnings({"UnusedReturnValue", "BooleanMethodIsAlwaysInverted"})
|
||||
public final class Utils {
|
||||
@ -180,15 +178,15 @@ public final class Utils {
|
||||
|
||||
// Check for resources folder.
|
||||
if(!fileExists(resourcesFolder)) {
|
||||
logger.info(Grasscutter.getLanguage().Create_resources_folder);
|
||||
logger.info(Grasscutter.getLanguage().Place_copy);
|
||||
logger.info(translate("messages.status.create_resources"));
|
||||
logger.info(translate("messages.status.resources_error"));
|
||||
createFolder(resourcesFolder); exit = true;
|
||||
}
|
||||
|
||||
// Check for BinOutput + ExcelBinOuput.
|
||||
// Check for BinOutput + ExcelBinOutput.
|
||||
if(!fileExists(resourcesFolder + "BinOutput") ||
|
||||
!fileExists(resourcesFolder + "ExcelBinOutput")) {
|
||||
logger.info(Grasscutter.getLanguage().Place_copy);
|
||||
logger.info(translate("messages.status.resources_error"));
|
||||
exit = true;
|
||||
}
|
||||
|
||||
@ -199,7 +197,11 @@ public final class Utils {
|
||||
if(exit) System.exit(1);
|
||||
}
|
||||
|
||||
public static int GetNextTimestampOfThisHour(int hour, String timeZone, int param) {
|
||||
/**
|
||||
* Gets the timestamp of the next hour.
|
||||
* @return The timestamp in UNIX seconds.
|
||||
*/
|
||||
public static int getNextTimestampOfThisHour(int hour, String timeZone, int param) {
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of(timeZone));
|
||||
for (int i = 0; i < param; i ++){
|
||||
if (zonedDateTime.getHour() < hour) {
|
||||
@ -208,10 +210,14 @@ public final class Utils {
|
||||
zonedDateTime = zonedDateTime.plusDays(1).withHour(hour).withMinute(0).withSecond(0);
|
||||
}
|
||||
}
|
||||
return (int)zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();
|
||||
return (int) zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();
|
||||
}
|
||||
|
||||
public static int GetNextTimestampOfThisHourInNextWeek(int hour, String timeZone, int param) {
|
||||
/**
|
||||
* Gets the timestamp of the next hour in a week.
|
||||
* @return The timestamp in UNIX seconds.
|
||||
*/
|
||||
public static int getNextTimestampOfThisHourInNextWeek(int hour, String timeZone, int param) {
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of(timeZone));
|
||||
for (int i = 0; i < param; i++) {
|
||||
if (zonedDateTime.getDayOfWeek() == DayOfWeek.MONDAY && zonedDateTime.getHour() < hour) {
|
||||
@ -220,10 +226,14 @@ public final class Utils {
|
||||
zonedDateTime = zonedDateTime.with(TemporalAdjusters.next(DayOfWeek.MONDAY)).withHour(hour).withMinute(0).withSecond(0);
|
||||
}
|
||||
}
|
||||
return (int)zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();
|
||||
return (int) zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();
|
||||
}
|
||||
|
||||
public static int GetNextTimestampOfThisHourInNextMonth(int hour, String timeZone, int param) {
|
||||
/**
|
||||
* Gets the timestamp of the next hour in a month.
|
||||
* @return The timestamp in UNIX seconds.
|
||||
*/
|
||||
public static int getNextTimestampOfThisHourInNextMonth(int hour, String timeZone, int param) {
|
||||
ZonedDateTime zonedDateTime = ZonedDateTime.now(ZoneId.of(timeZone));
|
||||
for (int i = 0; i < param; i++) {
|
||||
if (zonedDateTime.getDayOfMonth() == 1 && zonedDateTime.getHour() < hour) {
|
||||
@ -232,41 +242,22 @@ public final class Utils {
|
||||
zonedDateTime = zonedDateTime.with(TemporalAdjusters.firstDayOfNextMonth()).withHour(hour).withMinute(0).withSecond(0);
|
||||
}
|
||||
}
|
||||
return (int)zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();
|
||||
return (int) zonedDateTime.toInstant().atZone(ZoneOffset.UTC).toEpochSecond();
|
||||
}
|
||||
|
||||
public static Map<String, Object> switchPropertiesUpperLowerCase(Map<String, Object> objMap, Class<?> cls) {
|
||||
Map<String, Object> map = new HashMap<>(objMap.size());
|
||||
for (String key : objMap.keySet()) {
|
||||
try {
|
||||
char c = key.charAt(0);
|
||||
if (c >= 'a' && c <= 'z') {
|
||||
try {
|
||||
cls.getDeclaredField(key);
|
||||
map.put(key, objMap.get(key));
|
||||
} catch (NoSuchFieldException e) {
|
||||
String s1 = String.valueOf(c).toUpperCase();
|
||||
String after = key.length() > 1 ? s1 + key.substring(1) : s1;
|
||||
cls.getDeclaredField(after);
|
||||
map.put(after, objMap.get(key));
|
||||
}
|
||||
} else if (c >= 'A' && c <= 'Z') {
|
||||
try {
|
||||
cls.getDeclaredField(key);
|
||||
map.put(key, objMap.get(key));
|
||||
} catch (NoSuchFieldException e) {
|
||||
String s1 = String.valueOf(c).toLowerCase();
|
||||
String after = key.length() > 1 ? s1 + key.substring(1) : s1;
|
||||
cls.getDeclaredField(after);
|
||||
map.put(after, objMap.get(key));
|
||||
}
|
||||
}
|
||||
} catch (NoSuchFieldException e) {
|
||||
map.put(key, objMap.get(key));
|
||||
}
|
||||
}
|
||||
|
||||
return map;
|
||||
/**
|
||||
* Retrieves a string from an input stream.
|
||||
* @param stream The input stream.
|
||||
* @return The string.
|
||||
*/
|
||||
public static String readFromInputStream(InputStream stream) {
|
||||
StringBuilder stringBuilder = new StringBuilder();
|
||||
try (BufferedReader reader = new BufferedReader(new InputStreamReader(stream))) {
|
||||
String line; while ((line = reader.readLine()) != null) {
|
||||
stringBuilder.append(line);
|
||||
} stream.close();
|
||||
} catch (IOException e) {
|
||||
Grasscutter.getLogger().warn("Failed to read from input stream.");
|
||||
} return stringBuilder.toString();
|
||||
}
|
||||
|
||||
}
|
||||
|
298
src/main/resources/languages/en_US.json
Normal file
298
src/main/resources/languages/en_US.json
Normal file
@ -0,0 +1,298 @@
|
||||
{
|
||||
"messages": {
|
||||
"game": {
|
||||
"port_bind": "Game Server started on port %s",
|
||||
"connect": "Client connected from %s",
|
||||
"disconnect": "Client disconnected from %s",
|
||||
"game_update_error": "An error occurred during game update.",
|
||||
"command_error": "Command error:"
|
||||
},
|
||||
"dispatch": {
|
||||
"port_bind": "[Dispatch] Dispatch server started on port %s",
|
||||
"request": "[Dispatch] Client %s %s request: %s",
|
||||
"keystore": {
|
||||
"general_error": "[Dispatch] Error while loading keystore!",
|
||||
"password_error": "[Dispatch] Unable to load keystore. Trying default keystore password...",
|
||||
"no_keystore_error": "[Dispatch] No SSL cert found! Falling back to HTTP server.",
|
||||
"default_password": "[Dispatch] The default keystore password was loaded successfully. Please consider setting the password to 123456 in config.json."
|
||||
},
|
||||
"no_commands_error": "Commands are not supported in dispatch only mode.",
|
||||
"unhandled_request_error": "[Dispatch] Potential unhandled %s request: %s",
|
||||
"account": {
|
||||
"login_attempt": "[Dispatch] Client %s is trying to log in",
|
||||
"login_success": "[Dispatch] Client %s logged in as %s",
|
||||
"login_token_attempt": "[Dispatch] Client %s is trying to log in via token",
|
||||
"login_token_error": "[Dispatch] Client %s failed to log in via token",
|
||||
"login_token_success": "[Dispatch] Client %s logged in via token as %s",
|
||||
"combo_token_success": "[Dispatch] Client %s succeed to exchange combo token",
|
||||
"combo_token_error": "[Dispatch] Client %s failed to exchange combo token",
|
||||
"account_login_create_success": "[Dispatch] Client %s failed to log in: Account %s created",
|
||||
"account_login_create_error": "[Dispatch] Client %s failed to log in: Account create failed",
|
||||
"account_login_exist_error": "[Dispatch] Client %s failed to log in: Account no found",
|
||||
"account_cache_error": "Game account cache information error",
|
||||
"session_key_error": "Wrong session key.",
|
||||
"username_error": "Username not found.",
|
||||
"username_create_error": "Username not found, create failed."
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"free_software": "Grasscutter is FREE software. If you have paid for this, you may have been scammed. Homepage: https://github.com/Grasscutters/Grasscutter",
|
||||
"starting": "Starting Grasscutter...",
|
||||
"shutdown": "Shutting down...",
|
||||
"done": "Done! For help, type \"help\"",
|
||||
"error": "An error occurred.",
|
||||
"welcome": "Welcome to Grasscutter",
|
||||
"run_mode_error": "Invalid server run mode: %s.",
|
||||
"run_mode_help": "Server run mode must be 'HYBRID', 'DISPATCH_ONLY', or 'GAME_ONLY'. Unable to start Grasscutter...",
|
||||
"create_resources": "Creating resources folder...",
|
||||
"resources_error": "Place a copy of 'BinOutput' and 'ExcelBinOutput' in the resources folder."
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"generic": {
|
||||
"not_specified": "No command specified.",
|
||||
"unknown_command": "Unknown command: %s",
|
||||
"permission_error": "You do not have permission to run this command.",
|
||||
"console_execute_error": "This command can only be run from the console.",
|
||||
"player_execute_error": "Run this command in-game.",
|
||||
"command_exist_error": "No command found.",
|
||||
"invalid": {
|
||||
"amount": "Invalid amount.",
|
||||
"artifactId": "Invalid artifactId.",
|
||||
"avatarId": "Invalid avatarId.",
|
||||
"avatarLevel": "Invalid avatarLevel.",
|
||||
"entityId": "Invalid entityId.",
|
||||
"itemId": "Invalid itemId.",
|
||||
"itemLevel": "Invalid itemLevel.",
|
||||
"itemRefinement": "Invalid itemRefinement.",
|
||||
"playerId": "Invalid playerId.",
|
||||
"uid": "Invalid UID."
|
||||
}
|
||||
},
|
||||
"execution": {
|
||||
"uid_error": "Invalid UID.",
|
||||
"player_exist_error": "Player not found.",
|
||||
"player_offline_error": "Player is not online.",
|
||||
"item_id_error": "Invalid item ID.",
|
||||
"item_player_exist_error": "Invalid item or UID.",
|
||||
"entity_id_error": "Invalid entity ID.",
|
||||
"player_exist_offline_error": "Player not found or is not online.",
|
||||
"argument_error": "Invalid arguments.",
|
||||
"clear_target": "Target cleared.",
|
||||
"set_target": "Subsequent commands will target @%s by default.",
|
||||
"need_target": "This command requires a target UID. Add a <@UID> argument or set a persistent target with /target @UID."
|
||||
},
|
||||
"status": {
|
||||
"enabled": "Enabled",
|
||||
"disabled": "Disabled",
|
||||
"help": "Help",
|
||||
"success": "Success"
|
||||
},
|
||||
"account": {
|
||||
"modify": "Modify user accounts",
|
||||
"invalid": "Invalid UID.",
|
||||
"exists": "Account already exists.",
|
||||
"create": "Account created with UID %s.",
|
||||
"delete": "Account deleted.",
|
||||
"no_account": "Account not found.",
|
||||
"command_usage": "Usage: account <create|delete> <username> [uid]"
|
||||
},
|
||||
"broadcast": {
|
||||
"command_usage": "Usage: broadcast <message>",
|
||||
"message_sent": "Message sent."
|
||||
},
|
||||
"changescene": {
|
||||
"usage": "Usage: changescene <sceneId>",
|
||||
"already_in_scene": "You are already in that scene.",
|
||||
"success": "Changed to scene %s.",
|
||||
"exists_error": "The specified scene does not exist."
|
||||
},
|
||||
"clear": {
|
||||
"command_usage": "Usage: clear <all|wp|art|mat>",
|
||||
"weapons": "Cleared weapons for %s.",
|
||||
"artifacts": "Cleared artifacts for %s.",
|
||||
"materials": "Cleared materials for %s.",
|
||||
"furniture": "Cleared furniture for %s.",
|
||||
"displays": "Cleared displays for %s.",
|
||||
"virtuals": "Cleared virtuals for %s.",
|
||||
"everything": "Cleared everything for %s."
|
||||
},
|
||||
"coop": {
|
||||
"usage": "Usage: coop <playerId> <target playerId>",
|
||||
"success": "Summoned %s to %s's world."
|
||||
},
|
||||
"enter_dungeon": {
|
||||
"usage": "Usage: enterdungeon <dungeon id>",
|
||||
"changed": "Changed to dungeon %s",
|
||||
"not_found_error": "Dungeon does not exist",
|
||||
"in_dungeon_error": "You are already in that dungeon"
|
||||
},
|
||||
"giveAll": {
|
||||
"usage": "Usage: giveall [player] [amount]",
|
||||
"started": "Receiving all items...",
|
||||
"success": "Successfully gave all items to %s.",
|
||||
"invalid_amount_or_playerId": "Invalid amount or player ID."
|
||||
},
|
||||
"giveArtifact": {
|
||||
"usage": "Usage: giveart|gart [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]",
|
||||
"id_error": "Invalid artifact ID.",
|
||||
"success": "Given %s to %s."
|
||||
},
|
||||
"giveChar": {
|
||||
"usage": "Usage: givechar <player> <itemId|itemName> [amount]",
|
||||
"given": "Given %s with level %s to %s.",
|
||||
"invalid_avatar_id": "Invalid avatar id.",
|
||||
"invalid_avatar_level": "Invalid avatar level.",
|
||||
"invalid_avatar_or_player_id": "Invalid avatar or player ID."
|
||||
},
|
||||
"give": {
|
||||
"usage": "Usage: give <player> <itemId|itemName> [amount] [level]",
|
||||
"refinement_only_applicable_weapons": "Refinement is only applicable to weapons.",
|
||||
"refinement_must_between_1_and_5": "Refinement must be between 1 and 5.",
|
||||
"given": "Given %s of %s to %s.",
|
||||
"given_with_level_and_refinement": "Given %s with level %s, refinement %s %s times to %s",
|
||||
"given_level": "Given %s with level %s %s times to %s"
|
||||
},
|
||||
"godmode": {
|
||||
"success": "Godmode is now %s for %s."
|
||||
},
|
||||
"heal": {
|
||||
"success": "All characters have been healed."
|
||||
},
|
||||
"kick": {
|
||||
"player_kick_player": "Player [%s:%s] has kicked player [%s:%s]",
|
||||
"server_kick_player": "Kicking player [%s:%s]"
|
||||
},
|
||||
"kill": {
|
||||
"usage": "Usage: killall [playerUid] [sceneId]",
|
||||
"scene_not_found_in_player_world": "Scene not found in player world",
|
||||
"kill_monsters_in_scene": "Killing %s monsters in scene %s"
|
||||
},
|
||||
"killCharacter": {
|
||||
"usage": "Usage: /killcharacter [playerId]",
|
||||
"success": "Killed %s's current character."
|
||||
},
|
||||
"list": {
|
||||
"success": "There are %s player(s) online:"
|
||||
},
|
||||
"permission": {
|
||||
"usage": "Usage: permission <add|remove> <username> <permission>",
|
||||
"add": "Permission added.",
|
||||
"has_error": "They already have this permission!",
|
||||
"remove": "Permission removed.",
|
||||
"not_have_error": "They don't have this permission!",
|
||||
"account_error": "The account cannot be found."
|
||||
},
|
||||
"position": {
|
||||
"success": "Coordinates: %.3f, %.3f, %.3f\nScene id: %d"
|
||||
},
|
||||
"reload": {
|
||||
"reload_start": "Reloading config.",
|
||||
"reload_done": "Reload complete."
|
||||
},
|
||||
"resetConst": {
|
||||
"reset_all": "Reset all avatars' constellations.",
|
||||
"success": "Constellations for %s have been reset. Please relog to see changes."
|
||||
},
|
||||
"resetShopLimit": {
|
||||
"usage": "Usage: /resetshop <player id>"
|
||||
},
|
||||
"sendMail": {
|
||||
"usage": "Usage: give [player] <itemId|itemName> [amount]",
|
||||
"user_not_exist": "The user with an id of '%s' does not exist",
|
||||
"start_composition": "Starting composition of message.\nPlease use `/sendmail <title>` to continue.\nYou can use `/sendmail stop` at any time",
|
||||
"templates": "Mail templates coming soon implemented...",
|
||||
"invalid_arguments": "Invalid arguments.\nUsage `/sendmail <userId|all|help> [templateId]`",
|
||||
"send_cancel": "Message sending cancelled",
|
||||
"send_done": "Message sent to user %s!",
|
||||
"send_all_done": "Message sent to all users!",
|
||||
"not_composition_end": "Message composition not at final stage.\nPlease use `/sendmail %s` or `/sendmail stop` to cancel",
|
||||
"please_use": "Please use `/sendmail %s`",
|
||||
"set_title": "Message title set as '%s'.\nUse '/sendmail <content>' to continue.",
|
||||
"set_contents": "Message contents set as '%s'.\nUse '/sendmail <sender>' to continue.",
|
||||
"set_message_sender": "Message sender set as '%s'.\nUse '/sendmail <itemId|itemName|finish> [amount] [level]' to continue.",
|
||||
"send": "Attached %s of %s (level %s) to the message.\nContinue adding more items or use `/sendmail finish` to send the message.",
|
||||
"invalid_arguments_please_use": "Invalid arguments \n Please use `/sendmail %s`",
|
||||
"title": "<title>",
|
||||
"message": "<message>",
|
||||
"sender": "<sender>",
|
||||
"arguments": "<itemId|itemName|finish> [amount] [level]",
|
||||
"error": "ERROR: invalid construction stage %s. Check console for stacktrace."
|
||||
},
|
||||
"sendMessage": {
|
||||
"usage": "Usage: sendmessage <player> <message>",
|
||||
"success": "Message sent."
|
||||
},
|
||||
"setFetterLevel": {
|
||||
"usage": "Usage: setfetterlevel <level>",
|
||||
"range_error": "Fetter level must be between 0 and 10.",
|
||||
"success": "Fetter level set to %s",
|
||||
"level_error": "Invalid fetter level."
|
||||
},
|
||||
"setStats": {
|
||||
"usage_console": "Usage: setstats|stats @<UID> <stat> <value>",
|
||||
"usage_ingame": "Usage: setstats|stats [@UID] <stat> <value>",
|
||||
"help_message": "\n\tValues for <stat>: hp | maxhp | def | atk | em | er | crate | cdmg | cdr | heal | heali | shield | defi\n\t(cont.) Elemental DMG Bonus: epyro | ecryo | ehydro | egeo | edendro | eelectro | ephys\n\t(cont.) Elemental RES: respyro | rescryo | reshydro | resgeo | resdendro | reselectro | resphys\n",
|
||||
"value_error": "Invalid stat value.",
|
||||
"uid_error": "Invalid UID.",
|
||||
"player_error": "Player not found or offline.",
|
||||
"set_self": "%s set to %s.",
|
||||
"set_for_uid": "%s for %s set to %s.",
|
||||
"set_max_hp": "MAX HP set to %s."
|
||||
},
|
||||
"setWorldLevel": {
|
||||
"usage": "Usage: setworldlevel <level>",
|
||||
"value_error": "World level must be between 0-8",
|
||||
"success": "World level set to %s.",
|
||||
"invalid_world_level": "Invalid world level."
|
||||
},
|
||||
"spawn": {
|
||||
"usage": "Usage: spawn <entityId> [amount] [level(monster only)]",
|
||||
"success": "Spawned %s of %s."
|
||||
},
|
||||
"stop": {
|
||||
"success": "Server shutting down..."
|
||||
},
|
||||
"talent": {
|
||||
"usage_1": "To set talent level: /talent set <talentID> <value>",
|
||||
"usage_2": "Another way to set talent level: /talent <n or e or q> <value>",
|
||||
"usage_3": "To get talent ID: /talent getid",
|
||||
"lower_16": "Invalid talent level. Level should be lower than 16",
|
||||
"set_id": "Set talent to %s.",
|
||||
"set_atk": "Set talent Normal ATK to %s.",
|
||||
"set_e": "Set talent E to %s.",
|
||||
"set_q": "Set talent Q to %s.",
|
||||
"invalid_skill_id": "Invalid skill ID.",
|
||||
"set_this": "Set this talent to %s.",
|
||||
"invalid_level": "Invalid talent level.",
|
||||
"normal_attack_id": "Normal Attack ID %s.",
|
||||
"e_skill_id": "E skill ID %s.",
|
||||
"q_skill_id": "Q skill ID %s."
|
||||
},
|
||||
"teleportAll": {
|
||||
"success": "Summoned all players to your location.",
|
||||
"error": "You only can use this command in MP mode."
|
||||
},
|
||||
"teleport": {
|
||||
"usage_server": "Usage: /tp @<player id> <x> <y> <z> [scene id]",
|
||||
"usage": "Usage: /tp [@<player id>] <x> <y> <z> [scene id]",
|
||||
"specify_player_id": "You must specify a player id.",
|
||||
"invalid_position": "Invalid position.",
|
||||
"success": "Teleported %s to %s, %s, %s in scene %s"
|
||||
},
|
||||
"weather": {
|
||||
"usage": "Usage: weather <weatherId> [climateId]",
|
||||
"success": "Changed weather to %s with climate %s",
|
||||
"invalid_id": "Invalid ID."
|
||||
},
|
||||
"drop": {
|
||||
"command_usage": "Usage: drop <itemId|itemName> [amount]",
|
||||
"success": "Dropped %s of %s."
|
||||
},
|
||||
"help": {
|
||||
"usage": "Usage: ",
|
||||
"aliases": "Aliases: ",
|
||||
"available_commands": "Available commands: "
|
||||
}
|
||||
}
|
||||
}
|
298
src/main/resources/languages/zh-TW.json
Normal file
298
src/main/resources/languages/zh-TW.json
Normal file
@ -0,0 +1,298 @@
|
||||
{
|
||||
"messages": {
|
||||
"game": {
|
||||
"port_bind": "遊戲伺服器已成功啟動。端口號:%s",
|
||||
"connect": "客戶端已連接至 %s",
|
||||
"disconnect": "客戶端 %s 已斷開連接。",
|
||||
"game_update_error": "遊戲更新時發生了錯誤。",
|
||||
"command_error": "指令發生錯誤:"
|
||||
},
|
||||
"dispatch": {
|
||||
"port_bind": "[Dispatch] 伺服器已在端口 %s 上開啟。",
|
||||
"request": "[Dispatch] 客戶端 %s 請求: %s %s",
|
||||
"keystore": {
|
||||
"general_error": "[Dispatch] 加載keystore文件時發生錯誤!",
|
||||
"password_error": "[Dispatch] 加載 keystore 失敗。正在嘗試使用預設 keystore 密碼...",
|
||||
"no_keystore_error": "[Dispatch] 未找到 SSL 憑證!已後降到 HTTP 伺服器。",
|
||||
"default_password": "[Dispatch] 默認的 keystore 密碼加載成功。請考慮將 config.json 的憑證密碼設定成 123456。"
|
||||
},
|
||||
"no_commands_error": "此指令不適用於Dispatch-only模式。",
|
||||
"unhandled_request_error": "[Dispatch] 潛在的未處理請求 %s 請求:%s",
|
||||
"account": {
|
||||
"login_attempt": "[Dispatch] 客戶端 %s 正在嘗試登入",
|
||||
"login_success": "[Dispatch] 客戶端 %s 已登入,UID為 %s",
|
||||
"login_token_attempt": "[Dispatch] 客戶端 %s 正在嘗試用憑證登入",
|
||||
"login_token_error": "[Dispatch] 客戶端 %s 使用憑證登入失敗",
|
||||
"login_token_success": "[Dispatch] 客戶端 %s 已透過憑證登入,UID為 %s",
|
||||
"combo_token_success": "[Dispatch] 客戶端 %s 交換憑證成功",
|
||||
"combo_token_error": "[Dispatch] 客戶端 %s 交換憑證失敗",
|
||||
"account_login_create_success": "[Dispatch] 客戶端 %s 登入失敗: 已註冊UID為 %s 的帳號",
|
||||
"account_login_create_error": "[Dispatch] 客戶端 %s 登入失敗:帳號建立失敗。",
|
||||
"account_login_exist_error": "[Dispatch] 客戶端 %s 登入失敗: 帳號不存在",
|
||||
"account_cache_error": "遊戲帳號緩存資訊錯誤",
|
||||
"session_key_error": "對話密鑰不符。",
|
||||
"username_error": "未找到此用戶名。",
|
||||
"username_create_error": "未找到用戶名,建立失敗。"
|
||||
}
|
||||
},
|
||||
"status": {
|
||||
"free_software": "Grasscutter 是免費開源軟體。如果你已經付錢了,那你可能被騙了。主頁:https://github.com/Grasscutters/Grasscutter",
|
||||
"starting": "正在啟動 Grasscutter...",
|
||||
"shutdown": "正在關閉...",
|
||||
"done": "加載完成!需要指令幫助請輸入 \"help\"",
|
||||
"error": "發生了一個錯誤。",
|
||||
"welcome": "歡迎使用 Grasscutter",
|
||||
"run_mode_error": "無效的伺服器運行模式: %s。",
|
||||
"run_mode_help": "伺服器運行模式必須為 HYBRID 或者 DISPATCH_ONLY 或者 GAME_ONLY。Grasscutter 啟動失敗...",
|
||||
"create_resources": "正在建立 resources 資料夾...",
|
||||
"resources_error": "請將 BinOutput 和 ExcelBinOutput 複製到 resources 資料夾。"
|
||||
}
|
||||
},
|
||||
"commands": {
|
||||
"generic": {
|
||||
"not_specified": "沒有指定指令。",
|
||||
"unknown_command": "未知的指令:%s",
|
||||
"permission_error": "您沒有執行此指令的權限。",
|
||||
"console_execute_error": "此指令只能在伺服器的命令提示字元執行。",
|
||||
"player_execute_error": "請在遊戲裡使用這條指令。",
|
||||
"command_exist_error": "找不到指令。",
|
||||
"invalid": {
|
||||
"amount": "無效的 數量.",
|
||||
"artifactId": "無效的聖遺物ID。",
|
||||
"avatarId": "無效的角色ID。",
|
||||
"avatarLevel": "無效的角色等級。",
|
||||
"entityId": "無效的實體ID。",
|
||||
"itemId": "無效的物品ID。",
|
||||
"itemLevel": "無效的物品等級。",
|
||||
"itemRefinement": "無效的物品精煉度。",
|
||||
"playerId": "無效的玩家ID。",
|
||||
"uid": "無效的UID。"
|
||||
}
|
||||
},
|
||||
"execution": {
|
||||
"uid_error": "無效的UID。",
|
||||
"player_exist_error": "用戶不存在。",
|
||||
"player_offline_error": "玩家已離線。",
|
||||
"item_id_error": "無效的物品ID。.",
|
||||
"item_player_exist_error": "無效的物品/玩家UID。",
|
||||
"entity_id_error": "無效的實體ID。",
|
||||
"player_exist_offline_error": "玩家不存在或已離線。",
|
||||
"argument_error": "無效的參數。",
|
||||
"clear_target": "目標已清除.",
|
||||
"set_target": "隨後的指令都會以@%s為預設。",
|
||||
"need_target": "此指令需要一個目標 UID。添加 <@UID> 引數或者使用 /target @UID 來設定持久目標。"
|
||||
},
|
||||
"status": {
|
||||
"enabled": "已啟用",
|
||||
"disabled": "未啟用",
|
||||
"help": "幫助",
|
||||
"success": "成功"
|
||||
},
|
||||
"account": {
|
||||
"modify": "修改使用者帳號",
|
||||
"invalid": "無效的UID。",
|
||||
"exists": "帳號已存在。",
|
||||
"create": "已建立帳號,UID 為 %s 。",
|
||||
"delete": "帳號已刪除。",
|
||||
"no_account": "帳號不存在。",
|
||||
"command_usage": "用法:account <create|delete> <username> [uid]"
|
||||
},
|
||||
"broadcast": {
|
||||
"command_usage": "用法:broadcast <message>",
|
||||
"message_sent": "公告已發送。"
|
||||
},
|
||||
"changescene": {
|
||||
"usage": "用法:changescene <scene id>",
|
||||
"already_in_scene": "你已經在這個場景中了。",
|
||||
"success": "已切換至場景 %s.",
|
||||
"exists_error": "此場景不存在。"
|
||||
},
|
||||
"clear": {
|
||||
"command_usage": "用法: clear <all|wp|art|mat>",
|
||||
"weapons": "已將 %s 的武器清空。",
|
||||
"artifacts": "已將 %s 的聖遺物清空。",
|
||||
"materials": "已將 %s 的材料清空。",
|
||||
"furniture": "已將 %s 的塵歌壺家具清空。",
|
||||
"displays": "已清除 %s 的顯示。",
|
||||
"virtuals": "已將 %s 的所有貨幣和經驗值清空。",
|
||||
"everything": "已將 %s 的所有物品清空。"
|
||||
},
|
||||
"coop": {
|
||||
"usage": "用法:coop <playerId> <target playerId>",
|
||||
"success": "Summoned %s to %s's world."
|
||||
},
|
||||
"enter_dungeon": {
|
||||
"usage": "用法:enterdungeon <dungeon id>",
|
||||
"changed": "已進入副本 %s",
|
||||
"not_found_error": "此副本不存在。",
|
||||
"in_dungeon_error": "你已經在祕境中了。"
|
||||
},
|
||||
"giveAll": {
|
||||
"usage": "用法:giveall [player] [amount]",
|
||||
"started": "正在賦予全部物品...",
|
||||
"success": "已賦予全部物品。",
|
||||
"invalid_amount_or_playerId": "無效的數量/玩家ID。"
|
||||
},
|
||||
"giveArtifact": {
|
||||
"usage": "用法:giveart|gart [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]",
|
||||
"id_error": "無效的聖遺物ID。",
|
||||
"success": "已把 %s 給予 %s。"
|
||||
},
|
||||
"giveChar": {
|
||||
"usage": "用法:givechar <player> <itemId|itemName> [amount]",
|
||||
"given": "Given %s with level %s to %s.",
|
||||
"invalid_avatar_id": "無效的角色ID。",
|
||||
"invalid_avatar_level": "無效的角色等級。.",
|
||||
"invalid_avatar_or_player_id": "無效的角色ID/玩家ID。"
|
||||
},
|
||||
"give": {
|
||||
"usage": "用法:give <player> <itemId|itemName> [amount] [level]",
|
||||
"refinement_only_applicable_weapons": "精煉度只能施加在武器上面。",
|
||||
"refinement_must_between_1_and_5": "精煉度必需在 1 到 5 之間。",
|
||||
"given": "已經將 %s 個 %s 給予 %s。",
|
||||
"given_with_level_and_refinement": "已將 %s [等級%s, 精煉%s] %s個給予 %s",
|
||||
"given_level": "已將 %s 等級 %s %s 個給予 %s"
|
||||
},
|
||||
"godmode": {
|
||||
"success": "上帝模式設定為 %s 。 [用戶:%s]"
|
||||
},
|
||||
"heal": {
|
||||
"success": "所有角色已被治療。"
|
||||
},
|
||||
"kick": {
|
||||
"player_kick_player": "玩家 [%s:%s] 已把 [%s:%s] 踢出",
|
||||
"server_kick_player": "正在踢出玩家 [%s:%s]"
|
||||
},
|
||||
"kill": {
|
||||
"usage": "用法:killall [playerUid] [sceneId]",
|
||||
"scene_not_found_in_player_world": "未在玩家世界中找到此場景",
|
||||
"kill_monsters_in_scene": "已殺死 %s 個怪物。 [場景ID: %s]"
|
||||
},
|
||||
"killCharacter": {
|
||||
"usage": "用法:/killcharacter [playerId]",
|
||||
"success": "已殺死 %s 目前的場上角色。"
|
||||
},
|
||||
"list": {
|
||||
"message": "目前總線上人數:%s"
|
||||
},
|
||||
"permission": {
|
||||
"usage": "用法:permission <add|remove> <username> <permission>",
|
||||
"add": "已指派權限。",
|
||||
"has_error": "此玩家已擁有權限!",
|
||||
"remove": "權限已移除。",
|
||||
"not_have_error": "此玩家未擁有權限!",
|
||||
"account_error": "The account cannot be found."
|
||||
},
|
||||
"position": {
|
||||
"success": "坐標:%.3f, %.3f, %.3f\n場景ID:%d"
|
||||
},
|
||||
"reload": {
|
||||
"reload_start": "正在重新加載設定檔。",
|
||||
"reload_done": "重新加載已完成。"
|
||||
},
|
||||
"resetConst": {
|
||||
"reset_all": "重設所有角色的命座。",
|
||||
"success": "已重設 %s 的命座,重新登入後將會生效。"
|
||||
},
|
||||
"resetShopLimit": {
|
||||
"usage": "用法:/resetshop <player id>"
|
||||
},
|
||||
"sendMail": {
|
||||
"usage": "用法:give [player] <itemId|itemName> [amount]",
|
||||
"user_not_exist": "ID '%s' 的使用者不存在。",
|
||||
"start_composition": "發送郵件流程。\n請使用`/send <郵件標題>`來進到下一步。\n你可以在任何時間使用`/sendmail stop`來停止發送。",
|
||||
"templates": "郵件模板尚未實裝...",
|
||||
"invalid_arguments": "無效的參數。\n指令使用方法 `/sendmail <userId|all|help> [templateId]`",
|
||||
"send_cancel": "取消傳送信息",
|
||||
"send_done": "已將消息發送給 %s!",
|
||||
"send_all_done": "消息已發送給全體用戶!",
|
||||
"not_composition_end": "現在郵件發送未到最後階段。\n請使用 `/sendmail %s` 繼續發送郵件,或者 `/sendmail stop` 來停止發送郵件。",
|
||||
"please_use": "請使用 `/sendmail %s`",
|
||||
"set_title": "成功將郵件標題設定成 '%s'。\n接下來請繼續使用 '/sendmail <content>' 來設定郵件內容。",
|
||||
"set_contents": "成功將'%s'為郵件內容。\n接下來請打出 '/sendmail <寄件者名稱>' 來設定郵件寄件者名稱。",
|
||||
"set_message_sender": "郵件寄件者已設為 '%s'。\n使用 '/sendmail <itemId|itemName|finish> [amount] [level]' 以繼續操作。",
|
||||
"send": "已添加 %s 個 %s (等級為 %s) 到郵件附件。\n如果沒有要繼續添加道具請使用 `/sendmail finish` 來完成郵件發送。",
|
||||
"invalid_arguments_please_use": "Invalid arguments \n Please use `/sendmail %s`",
|
||||
"title": "<標題>",
|
||||
"message": "<正文>",
|
||||
"sender": "<寄件者>",
|
||||
"arguments": "<itemId|itemName|finish> [數量] [等級]",
|
||||
"error": "錯誤:無效的編寫階段 %s。需要 stacktrace 請查看伺服器命令提示字元。"
|
||||
},
|
||||
"sendMessage": {
|
||||
"usage": "用法:sendmessage <player> <message>",
|
||||
"success": "訊息已發送。"
|
||||
},
|
||||
"setFetterLevel": {
|
||||
"usage": "用法:setfetterlevel <level>",
|
||||
"range_error": "好感度必須在 0 到 10 之間。",
|
||||
"fetter_set_level": "好感等級已設定為 %s",
|
||||
"level_error": "無效的好感度。"
|
||||
},
|
||||
"setStats": {
|
||||
"usage_console": "用法:setstats|stats @<UID> <stat> <value>",
|
||||
"usage_ingame": "用法:setstats|stats [@UID] <stat> <value>",
|
||||
"help_message": "\n\t可使用的數據類型:hp (生命值)| maxhp (最大生命值) | def(防禦力) | atk (攻擊力)| em (元素精通) | er (元素充能效率) | crate(暴擊率) | cdmg (暴擊傷害)| cdr (冷卻縮減) | heal(治療加成)| heali (受治療加成)| shield (護盾強效)| defi (無視防禦)\n\t(cont.) 元素增傷類:epyro (火傷) | ecryo (冰傷) | ehydro (水傷) | egeo (岩傷) | edendro (草傷) | eelectro (雷傷) | ephys (物傷)(cont.) 元素減傷類:respyro (火抗) | rescryo (冰抗) | reshydro (水抗) | resgeo (岩抗) | resdendro (草抗) | reselectro (雷抗) | resphys (物抗)\n",
|
||||
"value_error": "無效的數據值。",
|
||||
"uid_error": "無效的UID。",
|
||||
"player_error": "玩家不存在或已離線。",
|
||||
"set_self": "%s 已經設為 %s。",
|
||||
"set_for_uid": "%s 的使用者 %s 更改為 %s。",
|
||||
"set_max_hp": "最大生命值更改為 %s。"
|
||||
},
|
||||
"setWorldLevel": {
|
||||
"usage": "用法:setworldlevel <level>",
|
||||
"value_error": "世界等級必須設定在0-8之間。",
|
||||
"success": "已將世界等級設為%s。",
|
||||
"invalid_world_level": "無效的世界等級。"
|
||||
},
|
||||
"spawn": {
|
||||
"usage": "用法:spawn <entityId> [amount] [level(僅限怪物)]",
|
||||
"success": "已生成 %s 個 %s。"
|
||||
},
|
||||
"stop": {
|
||||
"success": "正在關閉伺服器..."
|
||||
},
|
||||
"talent": {
|
||||
"usage_1": "設定天賦等級:/talent set <talentID> <value>",
|
||||
"usage_2": "另一種設定天賦等級的指令使用方法:/talent <n or e or q> <value>",
|
||||
"usage_3": "獲取天賦ID指令用法:/talent getid",
|
||||
"lower_16": "無效的技能等級,技能等級應低於 16。",
|
||||
"set_id": "將天賦等級設為%s。",
|
||||
"set_atk": "將普通攻擊等級設為 %s。",
|
||||
"set_e": "設定天賦E等級至 %s。",
|
||||
"set_q": "設定天賦Q等級至 %s。",
|
||||
"invalid_skill_id": "無效的技能ID。",
|
||||
"set_this": "將天賦等級設為 %s。",
|
||||
"invalid_level": "無效的天賦等級。",
|
||||
"normal_attack_id": "普通攻擊的 ID 為 %s。",
|
||||
"e_skill_id": "E技能ID %s。",
|
||||
"q_skill_id": "Q技能ID %s。"
|
||||
},
|
||||
"teleportAll": {
|
||||
"success": "Summoned all players to your location.",
|
||||
"error": "此指令僅可在多人遊戲下可用。"
|
||||
},
|
||||
"teleport": {
|
||||
"usage_server": "用法:/tp @<player id> <x> <y> <z> [scene id]",
|
||||
"usage": "用法:/tp [@<player id>] <x> <y> <z> [scene id]",
|
||||
"specify_player_id": "你必須指定一個玩家ID。",
|
||||
"invalid_position": "無效的位置。",
|
||||
"success": "傳送 %s 到坐標 %s,%s,%s ,場景為 %s"
|
||||
},
|
||||
"weather": {
|
||||
"usage": "用法:weather <weatherId> [climateId]",
|
||||
"success": "已將當前天氣設定為 %s ,氣候則為 %s 。",
|
||||
"invalid_id": "無效的ID。"
|
||||
},
|
||||
"drop": {
|
||||
"command_usage": "用法:drop <itemId|itemName> [amount]",
|
||||
"success": "已將 %s x %s 丟在附近。"
|
||||
},
|
||||
"help": {
|
||||
"usage": "用法:",
|
||||
"aliases": "別名:",
|
||||
"available_commands": "可用指令:"
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user