Commit a8293102 authored by Melledy's avatar Melledy Committed by GitHub
Browse files

Merge branch 'development' into stable

parents 304b9cb8 ecf7a81a
package emu.grasscutter.auth;
import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest;
/**
* Handles authentication via external routes.
*/
public interface ExternalAuthenticator {
/**
* Called when an external login request is made.
* @param request The authentication request.
*/
void handleLogin(AuthenticationRequest request);
/**
* Called when an external account creation request is made.
* @param request The authentication request.
*
* For developers: Use {@link AuthenticationRequest#getRequest()} to get the request body.
* Use {@link AuthenticationRequest#getResponse()} to get the response body.
*/
void handleAccountCreation(AuthenticationRequest request);
/**
* Called when an external password reset request is made.
* @param request The authentication request.
*
* For developers: Use {@link AuthenticationRequest#getRequest()} to get the request body.
* Use {@link AuthenticationRequest#getResponse()} to get the response body.
*/
void handlePasswordReset(AuthenticationRequest request);
}
package emu.grasscutter.auth;
import emu.grasscutter.auth.AuthenticationSystem.AuthenticationRequest;
/**
* Handles authentication via OAuth routes.
*/
public interface OAuthAuthenticator {
/**
* Called when an OAuth login request is made.
* @param request The authentication request.
*/
void handleLogin(AuthenticationRequest request);
/**
* Called when a client requests to redirect to login page.
* @param request The authentication request.
*/
void handleRedirection(AuthenticationRequest request, ClientType clientType);
/**
* Called when an OAuth login requests callback.
* @param request The authentication request.
*/
void handleTokenProcess(AuthenticationRequest request);
/**
* The type of the client.
* Used for handling redirection.
*/
enum ClientType {
DESKTOP, MOBILE
}
}
...@@ -9,7 +9,7 @@ public @interface Command { ...@@ -9,7 +9,7 @@ public @interface Command {
String usage() default "No usage specified"; String usage() default "No usage specified";
String description() default "No description specified"; String description() default "commands.generic.no_description_specified";
String[] aliases() default {}; String[] aliases() default {};
...@@ -17,5 +17,13 @@ public @interface Command { ...@@ -17,5 +17,13 @@ public @interface Command {
String permissionTargeted() default ""; String permissionTargeted() default "";
public enum TargetRequirement {
NONE, // targetPlayer is not required
OFFLINE, // targetPlayer must be offline
PLAYER, // targetPlayer can be online or offline
ONLINE // targetPlayer must be online
}
TargetRequirement targetRequirement() default TargetRequirement.ONLINE;
boolean threading() default false; boolean threading() default false;
} }
...@@ -2,10 +2,14 @@ package emu.grasscutter.command; ...@@ -2,10 +2,14 @@ package emu.grasscutter.command;
import emu.grasscutter.Grasscutter; import emu.grasscutter.Grasscutter;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.server.event.game.CommandResponseEvent;
import emu.grasscutter.server.event.types.ServerEvent;
import static emu.grasscutter.utils.Language.translate;
import java.util.List; import java.util.List;
public interface CommandHandler { public interface CommandHandler {
/** /**
* Send a message to the target. * Send a message to the target.
* *
...@@ -18,6 +22,12 @@ public interface CommandHandler { ...@@ -18,6 +22,12 @@ public interface CommandHandler {
} else { } else {
player.dropMessage(message); player.dropMessage(message);
} }
CommandResponseEvent event = new CommandResponseEvent(ServerEvent.Type.GAME,player, message);
event.call();
}
static void sendTranslatedMessage(Player player, String messageKey, Object... args) {
sendMessage(player, translate(player, messageKey, args));
} }
/** /**
......
...@@ -8,8 +8,6 @@ import org.reflections.Reflections; ...@@ -8,8 +8,6 @@ import org.reflections.Reflections;
import java.util.*; import java.util.*;
import static emu.grasscutter.utils.Language.translate;
@SuppressWarnings({"UnusedReturnValue", "unused"}) @SuppressWarnings({"UnusedReturnValue", "unused"})
public final class CommandMap { public final class CommandMap {
private final Map<String, CommandHandler> commands = new HashMap<>(); private final Map<String, CommandHandler> commands = new HashMap<>();
...@@ -117,7 +115,7 @@ public final class CommandMap { ...@@ -117,7 +115,7 @@ public final class CommandMap {
public void invoke(Player player, Player targetPlayer, String rawMessage) { public void invoke(Player player, Player targetPlayer, String rawMessage) {
rawMessage = rawMessage.trim(); rawMessage = rawMessage.trim();
if (rawMessage.length() == 0) { if (rawMessage.length() == 0) {
CommandHandler.sendMessage(player, translate("commands.generic.not_specified")); CommandHandler.sendTranslatedMessage(player, "commands.generic.not_specified");
return; return;
} }
...@@ -144,19 +142,20 @@ public final class CommandMap { ...@@ -144,19 +142,20 @@ public final class CommandMap {
if (targetUidStr != null) { if (targetUidStr != null) {
if (targetUidStr.equals("")) { // Clears the default targetPlayer. if (targetUidStr.equals("")) { // Clears the default targetPlayer.
targetPlayerIds.remove(playerId); targetPlayerIds.remove(playerId);
CommandHandler.sendMessage(player, translate("commands.execution.clear_target")); CommandHandler.sendTranslatedMessage(player, "commands.execution.clear_target");
} else { // Sets default targetPlayer to the UID provided. } else { // Sets default targetPlayer to the UID provided.
try { try {
int uid = Integer.parseInt(targetUidStr); int uid = Integer.parseInt(targetUidStr);
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(uid); targetPlayer = Grasscutter.getGameServer().getPlayerByUid(uid, true);
if (targetPlayer == null) { if (targetPlayer == null) {
CommandHandler.sendMessage(player, translate("commands.generic.execution.player_exist_offline_error")); CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error");
} else { } else {
targetPlayerIds.put(playerId, uid); targetPlayerIds.put(playerId, uid);
CommandHandler.sendMessage(player, translate("commands.execution.set_target", targetUidStr)); CommandHandler.sendTranslatedMessage(player, "commands.execution.set_target", targetUidStr);
CommandHandler.sendTranslatedMessage(player, targetPlayer.isOnline()? "commands.execution.set_target_online" : "commands.execution.set_target_offline", targetUidStr);
} }
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
CommandHandler.sendMessage(player, translate("commands.execution.uid_error")); CommandHandler.sendTranslatedMessage(player, "commands.execution.uid_error");
} }
} }
return; return;
...@@ -165,7 +164,7 @@ public final class CommandMap { ...@@ -165,7 +164,7 @@ public final class CommandMap {
// Get command handler. // Get command handler.
CommandHandler handler = this.commands.get(label); CommandHandler handler = this.commands.get(label);
if (handler == null) { if (handler == null) {
CommandHandler.sendMessage(player, translate("commands.generic.unknown_command", label)); CommandHandler.sendTranslatedMessage(player, "commands.generic.unknown_command", label);
return; return;
} }
...@@ -176,14 +175,14 @@ public final class CommandMap { ...@@ -176,14 +175,14 @@ public final class CommandMap {
arg = args.remove(i).substring(1); arg = args.remove(i).substring(1);
try { try {
int uid = Integer.parseInt(arg); int uid = Integer.parseInt(arg);
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(uid); targetPlayer = Grasscutter.getGameServer().getPlayerByUid(uid, true);
if (targetPlayer == null) { if (targetPlayer == null) {
CommandHandler.sendMessage(player, translate("commands.generic.execution.player_exist_offline_error")); CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error");
return; return;
} }
break; break;
} catch (NumberFormatException e) { } catch (NumberFormatException e) {
CommandHandler.sendMessage(player, translate("commands.execution.uid_error")); CommandHandler.sendTranslatedMessage(player, "commands.execution.uid_error");
return; return;
} }
} }
...@@ -192,9 +191,9 @@ public final class CommandMap { ...@@ -192,9 +191,9 @@ public final class CommandMap {
// If there's still no targetPlayer at this point, use previously-set target // If there's still no targetPlayer at this point, use previously-set target
if (targetPlayer == null) { if (targetPlayer == null) {
if (targetPlayerIds.containsKey(playerId)) { if (targetPlayerIds.containsKey(playerId)) {
targetPlayer = Grasscutter.getGameServer().getPlayerByUid(targetPlayerIds.get(playerId)); // We check every time in case the target goes offline after being targeted targetPlayer = Grasscutter.getGameServer().getPlayerByUid(targetPlayerIds.get(playerId), true); // We check every time in case the target is deleted after being targeted
if (targetPlayer == null) { if (targetPlayer == null) {
CommandHandler.sendMessage(player, translate("commands.generic.execution.player_exist_offline_error")); CommandHandler.sendTranslatedMessage(player, "commands.execution.player_exist_error");
return; return;
} }
} else { } else {
...@@ -210,12 +209,29 @@ public final class CommandMap { ...@@ -210,12 +209,29 @@ public final class CommandMap {
Account account = player.getAccount(); Account account = player.getAccount();
if (player != targetPlayer) { // Additional permission required for targeting another player if (player != targetPlayer) { // Additional permission required for targeting another player
if (!permissionNodeTargeted.isEmpty() && !account.hasPermission(permissionNodeTargeted)) { if (!permissionNodeTargeted.isEmpty() && !account.hasPermission(permissionNodeTargeted)) {
CommandHandler.sendMessage(player, translate("commands.generic.permission_error")); CommandHandler.sendTranslatedMessage(player, "commands.generic.permission_error");
return; return;
} }
} }
if (!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) { if (!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) {
CommandHandler.sendMessage(player, translate("commands.generic.permission_error")); CommandHandler.sendTranslatedMessage(player, "commands.generic.permission_error");
return;
}
}
// Check if command has unfulfilled constraints on targetPlayer
Command.TargetRequirement targetRequirement = this.annotations.get(label).targetRequirement();
if (targetRequirement != Command.TargetRequirement.NONE) {
if (targetPlayer == null) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target");
return;
}
if ((targetRequirement == Command.TargetRequirement.ONLINE) && !targetPlayer.isOnline()) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target_online");
return;
}
if ((targetRequirement == Command.TargetRequirement.OFFLINE) && targetPlayer.isOnline()) {
CommandHandler.sendTranslatedMessage(player, "commands.execution.need_target_offline");
return; return;
} }
} }
......
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.database.DatabaseHelper; import emu.grasscutter.database.DatabaseHelper;
import emu.grasscutter.game.Account;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import java.util.List; import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "account", usage = "account <create|delete> <username> [uid]", description = "Modify user accounts") @Command(label = "account", usage = "account <create|delete> <username> [uid]", description = "commands.account.description", targetRequirement = Command.TargetRequirement.NONE)
public final class AccountCommand implements CommandHandler { public final class AccountCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (sender != null) { if (sender != null) {
CommandHandler.sendMessage(sender, translate("commands.generic.console_execute_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.console_execute_error"));
return; return;
} }
if (args.size() < 2) { if (args.size() < 2) {
CommandHandler.sendMessage(null, translate("commands.account.command_usage")); CommandHandler.sendMessage(null, translate(sender, "commands.account.command_usage"));
return; return;
} }
...@@ -29,7 +31,7 @@ public final class AccountCommand implements CommandHandler { ...@@ -29,7 +31,7 @@ public final class AccountCommand implements CommandHandler {
switch (action) { switch (action) {
default: default:
CommandHandler.sendMessage(null, translate("commands.account.command_usage")); CommandHandler.sendMessage(null, translate(sender, "commands.account.command_usage"));
return; return;
case "create": case "create":
int uid = 0; int uid = 0;
...@@ -37,28 +39,41 @@ public final class AccountCommand implements CommandHandler { ...@@ -37,28 +39,41 @@ public final class AccountCommand implements CommandHandler {
try { try {
uid = Integer.parseInt(args.get(2)); uid = Integer.parseInt(args.get(2));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(null, translate("commands.account.invalid")); CommandHandler.sendMessage(null, translate(sender, "commands.account.invalid"));
return; return;
} }
} }
emu.grasscutter.game.Account account = DatabaseHelper.createAccountWithId(username, uid); emu.grasscutter.game.Account account = DatabaseHelper.createAccountWithUid(username, uid);
if (account == null) { if (account == null) {
CommandHandler.sendMessage(null, translate("commands.account.exists")); CommandHandler.sendMessage(null, translate(sender, "commands.account.exists"));
return; return;
} else { } else {
account.addPermission("*"); account.addPermission("*");
account.save(); // Save account to database. account.save(); // Save account to database.
CommandHandler.sendMessage(null, translate("commands.account.create", Integer.toString(account.getPlayerUid()))); CommandHandler.sendMessage(null, translate(sender, "commands.account.create", Integer.toString(account.getReservedPlayerUid())));
} }
return; return;
case "delete": case "delete":
if (DatabaseHelper.deleteAccount(username)) { // Get the account we want to delete.
CommandHandler.sendMessage(null, translate("commands.account.delete")); Account toDelete = DatabaseHelper.getAccountByName(username);
} else {
CommandHandler.sendMessage(null, translate("commands.account.no_account")); if (toDelete == null) {
CommandHandler.sendMessage(null, translate(sender, "commands.account.no_account"));
return;
} }
// Get the player for the account.
// If that player is currently online, we kick them before proceeding with the deletion.
Player player = Grasscutter.getGameServer().getPlayerByAccountId(toDelete.getId());
if (player != null) {
player.getSession().close();
}
// Finally, we do the actual deletion.
DatabaseHelper.deleteAccount(toDelete);
CommandHandler.sendMessage(null, translate(sender, "commands.account.delete"));
} }
} }
} }
...@@ -9,14 +9,13 @@ import java.util.List; ...@@ -9,14 +9,13 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "broadcast", usage = "broadcast <message>", @Command(label = "broadcast", usage = "broadcast <message>", aliases = {"b"}, permission = "server.broadcast", description = "commands.broadcast.description", targetRequirement = Command.TargetRequirement.NONE)
description = "Sends a message to all the players", aliases = {"b"}, permission = "server.broadcast")
public final class BroadcastCommand implements CommandHandler { public final class BroadcastCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (args.size() < 1) { if (args.size() < 1) {
CommandHandler.sendMessage(sender, translate("commands.broadcast.command_usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.broadcast.command_usage"));
return; return;
} }
...@@ -26,6 +25,6 @@ public final class BroadcastCommand implements CommandHandler { ...@@ -26,6 +25,6 @@ public final class BroadcastCommand implements CommandHandler {
CommandHandler.sendMessage(p, message); CommandHandler.sendMessage(p, message);
} }
CommandHandler.sendMessage(sender, translate("commands.broadcast.message_sent")); CommandHandler.sendMessage(sender, translate(sender, "commands.broadcast.message_sent"));
} }
} }
...@@ -8,36 +8,32 @@ import java.util.List; ...@@ -8,36 +8,32 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "changescene", usage = "changescene <scene id>", @Command(label = "changescene", usage = "changescene <sceneId>", aliases = {"scene"}, permission = "player.changescene", permissionTargeted = "player.changescene.others", description = "commands.changescene.description")
description = "Changes your scene", aliases = {"scene"}, permission = "player.changescene")
public final class ChangeSceneCommand implements CommandHandler { public final class ChangeSceneCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
if (args.size() != 1) { if (args.size() != 1) {
CommandHandler.sendMessage(sender, translate("commands.changescene.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.changescene.usage"));
return; return;
} }
try { try {
int sceneId = Integer.parseInt(args.get(0)); int sceneId = Integer.parseInt(args.get(0));
if (sceneId == targetPlayer.getSceneId()) { if (sceneId == targetPlayer.getSceneId()) {
CommandHandler.sendMessage(sender, translate("commands.changescene.already_in_scene")); CommandHandler.sendMessage(sender, translate(sender, "commands.changescene.already_in_scene"));
return; return;
} }
boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, targetPlayer.getPos()); boolean result = targetPlayer.getWorld().transferPlayerToScene(targetPlayer, sceneId, targetPlayer.getPos());
CommandHandler.sendMessage(sender, translate("commands.changescene.result", Integer.toString(sceneId)));
if (!result) { if (!result) {
CommandHandler.sendMessage(sender, translate("commands.changescene.exists_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.changescene.exists_error"));
return;
} }
CommandHandler.sendMessage(sender, translate(sender, "commands.changescene.success", Integer.toString(sceneId)));
} catch (Exception e) { } catch (Exception e) {
CommandHandler.sendMessage(sender, translate("commands.execution.argument_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
} }
} }
} }
...@@ -13,19 +13,15 @@ import java.util.List; ...@@ -13,19 +13,15 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "clear", usage = "clear <all|wp|art|mat>", //Merged /clearartifacts and /clearweapons to /clear <args> [uid] @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", description = "commands.clear.description",
aliases = {"clear"}, permission = "player.clearinv") aliases = {"clear"}, permission = "player.clearinv", permissionTargeted = "player.clearinv.others")
public final class ClearCommand implements CommandHandler { public final class ClearCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
if (args.size() < 1) { if (args.size() < 1) {
CommandHandler.sendMessage(sender, translate("commands.clear.command_usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.command_usage"));
return; return;
} }
Inventory playerInventory = targetPlayer.getInventory(); Inventory playerInventory = targetPlayer.getInventory();
...@@ -37,7 +33,7 @@ public final class ClearCommand implements CommandHandler { ...@@ -37,7 +33,7 @@ public final class ClearCommand implements CommandHandler {
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON) .filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
.filter(item -> !item.isLocked() && !item.isEquipped()) .filter(item -> !item.isLocked() && !item.isEquipped())
.toList(); .toList();
CommandHandler.sendMessage(sender, translate("commands.clear.weapons", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.weapons", targetPlayer.getNickname()));
} }
case "art" -> { case "art" -> {
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
...@@ -45,7 +41,7 @@ public final class ClearCommand implements CommandHandler { ...@@ -45,7 +41,7 @@ public final class ClearCommand implements CommandHandler {
.filter(item -> item.getLevel() == 1 && item.getExp() == 0) .filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped()) .filter(item -> !item.isLocked() && !item.isEquipped())
.toList(); .toList();
CommandHandler.sendMessage(sender, translate("commands.clear.artifacts", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.artifacts", targetPlayer.getNickname()));
} }
case "mat" -> { case "mat" -> {
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
...@@ -53,7 +49,7 @@ public final class ClearCommand implements CommandHandler { ...@@ -53,7 +49,7 @@ public final class ClearCommand implements CommandHandler {
.filter(item -> item.getLevel() == 1 && item.getExp() == 0) .filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> !item.isLocked() && !item.isEquipped()) .filter(item -> !item.isLocked() && !item.isEquipped())
.toList(); .toList();
CommandHandler.sendMessage(sender, translate("commands.clear.materials", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.materials", targetPlayer.getNickname()));
} }
case "all" -> { case "all" -> {
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
...@@ -61,7 +57,7 @@ public final class ClearCommand implements CommandHandler { ...@@ -61,7 +57,7 @@ public final class ClearCommand implements CommandHandler {
.filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0) .filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0)
.filter(item1 -> !item1.isLocked() && !item1.isEquipped()) .filter(item1 -> !item1.isLocked() && !item1.isEquipped())
.toList(); .toList();
CommandHandler.sendMessage(sender, translate("commands.clear.artifacts", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.artifacts", targetPlayer.getNickname()));
playerInventory.removeItems(toDelete); playerInventory.removeItems(toDelete);
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
...@@ -69,7 +65,7 @@ public final class ClearCommand implements CommandHandler { ...@@ -69,7 +65,7 @@ public final class ClearCommand implements CommandHandler {
.filter(item2 -> !item2.isLocked() && !item2.isEquipped()) .filter(item2 -> !item2.isLocked() && !item2.isEquipped())
.toList(); .toList();
playerInventory.removeItems(toDelete); playerInventory.removeItems(toDelete);
CommandHandler.sendMessage(sender, translate("commands.clear.materials", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.materials", targetPlayer.getNickname()));
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
.filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON) .filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON)
...@@ -77,28 +73,28 @@ public final class ClearCommand implements CommandHandler { ...@@ -77,28 +73,28 @@ public final class ClearCommand implements CommandHandler {
.filter(item3 -> !item3.isLocked() && !item3.isEquipped()) .filter(item3 -> !item3.isLocked() && !item3.isEquipped())
.toList(); .toList();
playerInventory.removeItems(toDelete); playerInventory.removeItems(toDelete);
CommandHandler.sendMessage(sender, translate("commands.clear.weapons", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.weapons", targetPlayer.getNickname()));
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
.filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE) .filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE)
.filter(item4 -> !item4.isLocked() && !item4.isEquipped()) .filter(item4 -> !item4.isLocked() && !item4.isEquipped())
.toList(); .toList();
playerInventory.removeItems(toDelete); playerInventory.removeItems(toDelete);
CommandHandler.sendMessage(sender, translate("commands.clear.furniture", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.furniture", targetPlayer.getNickname()));
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
.filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY) .filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY)
.filter(item5 -> !item5.isLocked() && !item5.isEquipped()) .filter(item5 -> !item5.isLocked() && !item5.isEquipped())
.toList(); .toList();
playerInventory.removeItems(toDelete); playerInventory.removeItems(toDelete);
CommandHandler.sendMessage(sender, translate("commands.clear.displays", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.displays", targetPlayer.getNickname()));
toDelete = playerInventory.getItems().values().stream() toDelete = playerInventory.getItems().values().stream()
.filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL) .filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL)
.filter(item6 -> !item6.isLocked() && !item6.isEquipped()) .filter(item6 -> !item6.isLocked() && !item6.isEquipped())
.toList(); .toList();
CommandHandler.sendMessage(sender, translate("commands.clear.virtuals", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.virtuals", targetPlayer.getNickname()));
CommandHandler.sendMessage(sender, translate("commands.clear.everything", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.clear.everything", targetPlayer.getNickname()));
} }
} }
......
...@@ -9,20 +9,15 @@ import java.util.List; ...@@ -9,20 +9,15 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "coop", usage = "coop [host UID]", @Command(label = "coop", usage = "coop [host uid]", permission = "server.coop", permissionTargeted = "server.coop.others", description = "commands.coop.description")
description = "Forces someone to join the world of others", permission = "server.coop")
public final class CoopCommand implements CommandHandler { public final class CoopCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
Player host = sender; Player host = sender;
switch (args.size()) { switch (args.size()) {
case 0: // Summon target to self case 0: // Summon target to self
CommandHandler.sendMessage(sender, translate("commands.coop.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.coop.usage"));
if (sender == null) // Console doesn't have a self to summon to if (sender == null) // Console doesn't have a self to summon to
return; return;
break; break;
...@@ -31,16 +26,16 @@ public final class CoopCommand implements CommandHandler { ...@@ -31,16 +26,16 @@ public final class CoopCommand implements CommandHandler {
int hostId = Integer.parseInt(args.get(0)); int hostId = Integer.parseInt(args.get(0));
host = Grasscutter.getGameServer().getPlayerByUid(hostId); host = Grasscutter.getGameServer().getPlayerByUid(hostId);
if (host == null) { if (host == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.player_offline_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.execution.player_offline_error"));
return; return;
} }
break; break;
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.execution.uid_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.execution.uid_error"));
return; return;
} }
default: default:
CommandHandler.sendMessage(sender, translate("commands.coop.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.coop.usage"));
return; return;
} }
...@@ -50,6 +45,6 @@ public final class CoopCommand implements CommandHandler { ...@@ -50,6 +45,6 @@ public final class CoopCommand implements CommandHandler {
} }
host.getServer().getMultiplayerManager().applyEnterMp(targetPlayer, host.getUid()); host.getServer().getMultiplayerManager().applyEnterMp(targetPlayer, host.getUid());
targetPlayer.getServer().getMultiplayerManager().applyEnterMpReply(host, targetPlayer.getUid(), true); targetPlayer.getServer().getMultiplayerManager().applyEnterMpReply(host, targetPlayer.getUid(), true);
CommandHandler.sendMessage(sender, translate("commands.coop.success", targetPlayer.getNickname(), host.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.coop.success", targetPlayer.getNickname(), host.getNickname()));
} }
} }
...@@ -4,7 +4,7 @@ import emu.grasscutter.Grasscutter; ...@@ -4,7 +4,7 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.game.entity.EntityItem; import emu.grasscutter.game.entity.EntityItem;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.utils.Position; import emu.grasscutter.utils.Position;
...@@ -13,17 +13,11 @@ import java.util.List; ...@@ -13,17 +13,11 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "drop", usage = "drop <itemId|itemName> [amount]", @Command(label = "drop", usage = "drop <itemId|itemName> [amount]", aliases = {"d", "dropitem"}, permission = "server.drop", permissionTargeted = "server.drop.others", description = "commands.drop.description")
description = "Drops an item near you", aliases = {"d", "dropitem"}, permission = "server.drop")
public final class DropCommand implements CommandHandler { public final class DropCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(null, translate("commands.execution.need_target"));
return;
}
int item = 0; int item = 0;
int amount = 1; int amount = 1;
...@@ -32,25 +26,25 @@ public final class DropCommand implements CommandHandler { ...@@ -32,25 +26,25 @@ public final class DropCommand implements CommandHandler {
try { try {
amount = Integer.parseInt(args.get(1)); amount = Integer.parseInt(args.get(1));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.amount")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.amount"));
return; 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: case 1:
try { try {
item = Integer.parseInt(args.get(0)); item = Integer.parseInt(args.get(0));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemId"));
return; return;
} }
break; break;
default: default:
CommandHandler.sendMessage(sender, translate("commands.drop.command_usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.drop.command_usage"));
return; return;
} }
ItemData itemData = GameData.getItemDataMap().get(item); ItemData itemData = GameData.getItemDataMap().get(item);
if (itemData == null) { if (itemData == null) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemId"));
return; return;
} }
if (itemData.isEquip()) { if (itemData.isEquip()) {
...@@ -64,6 +58,6 @@ public final class DropCommand implements CommandHandler { ...@@ -64,6 +58,6 @@ public final class DropCommand implements CommandHandler {
EntityItem entity = new EntityItem(targetPlayer.getScene(), targetPlayer, itemData, targetPlayer.getPos().clone().addY(3f), amount); EntityItem entity = new EntityItem(targetPlayer.getScene(), targetPlayer, itemData, targetPlayer.getPos().clone().addY(3f), amount);
targetPlayer.getScene().addEntity(entity); targetPlayer.getScene().addEntity(entity);
} }
CommandHandler.sendMessage(sender, translate("commands.drop.success", Integer.toString(amount), Integer.toString(item))); CommandHandler.sendMessage(sender, translate(sender, "commands.drop.success", Integer.toString(amount), Integer.toString(item)));
} }
} }
...@@ -8,36 +8,31 @@ import java.util.List; ...@@ -8,36 +8,31 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "enterdungeon", usage = "enterdungeon <dungeon id>", @Command(label = "enterdungeon", usage = "enterdungeon <dungeonId>", aliases = {"dungeon"}, permission = "player.enterdungeon", permissionTargeted = "player.enterdungeon.others", description = "commands.enter_dungeon.description")
description = "Enter a dungeon", aliases = {"dungeon"}, permission = "player.enterdungeon")
public final class EnterDungeonCommand implements CommandHandler { public final class EnterDungeonCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(null, translate("commands.execution.need_target"));
return;
}
if (args.size() < 1) { if (args.size() < 1) {
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.usage"));
return; return;
} }
try { try {
int dungeonId = Integer.parseInt(args.get(0)); int dungeonId = Integer.parseInt(args.get(0));
if (dungeonId == targetPlayer.getSceneId()) { if (dungeonId == targetPlayer.getSceneId()) {
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.in_dungeon_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.in_dungeon_error"));
return; return;
} }
boolean result = targetPlayer.getServer().getDungeonManager().enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId); boolean result = targetPlayer.getServer().getDungeonManager().enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId);
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.changed", dungeonId)); CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.changed", dungeonId));
if (!result) { if (!result) {
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.not_found_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.not_found_error"));
} }
} catch (Exception e) { } catch (Exception e) {
CommandHandler.sendMessage(sender, translate("commands.enter_dungeon.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.usage"));
} }
} }
} }
...@@ -4,8 +4,8 @@ import emu.grasscutter.Grasscutter; ...@@ -4,8 +4,8 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.AvatarData; import emu.grasscutter.data.excels.AvatarData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType; import emu.grasscutter.game.inventory.ItemType;
...@@ -15,16 +15,11 @@ import java.util.*; ...@@ -15,16 +15,11 @@ import java.util.*;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "giveall", usage = "giveall [amount]", @Command(label = "giveall", usage = "giveall [amount]", aliases = {"givea"}, permission = "player.giveall", permissionTargeted = "player.giveall.others", threading = true, description = "commands.giveAll.description")
description = "Gives all items", aliases = {"givea"}, permission = "player.giveall", threading = true)
public final class GiveAllCommand implements CommandHandler { public final class GiveAllCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
int amount = 99999; int amount = 99999;
switch (args.size()) { switch (args.size()) {
...@@ -34,21 +29,21 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -34,21 +29,21 @@ public final class GiveAllCommand implements CommandHandler {
try { try {
amount = Integer.parseInt(args.get(0)); amount = Integer.parseInt(args.get(0));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.amount")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.amount"));
return; return;
} }
break; break;
default: // invalid default: // invalid
CommandHandler.sendMessage(sender, translate("commands.giveAll.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.giveAll.usage"));
return; return;
} }
this.giveAllItems(targetPlayer, amount); this.giveAllItems(targetPlayer, amount);
CommandHandler.sendMessage(sender, translate("commands.giveAll.success", targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(targetPlayer, "commands.giveAll.success", targetPlayer.getNickname()));
} }
public void giveAllItems(Player player, int amount) { public void giveAllItems(Player player, int amount) {
CommandHandler.sendMessage(player, translate("commands.giveAll.started")); CommandHandler.sendMessage(player, translate(player, "commands.giveAll.started"));
for (AvatarData avatarData: GameData.getAvatarDataMap().values()) { for (AvatarData avatarData: GameData.getAvatarDataMap().values()) {
//Exclude test avatar //Exclude test avatar
...@@ -62,7 +57,8 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -62,7 +57,8 @@ public final class GiveAllCommand implements CommandHandler {
} }
// This will handle stats and talents // This will handle stats and talents
avatar.recalcStats(); avatar.recalcStats();
player.addAvatar(avatar); // Don't try to add each avatar to the current team
player.addAvatar(avatar, false);
} }
//some test items //some test items
...@@ -159,7 +155,7 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -159,7 +155,7 @@ public final class GiveAllCommand implements CommandHandler {
private static final Integer[] testItemsIds = new Integer[] { private static final Integer[] testItemsIds = new Integer[] {
210, 211, 314, 315, 317, 1005, 1007, 1105, 1107, 1201, 1202,10366, 210, 211, 314, 315, 317, 1005, 1007, 1105, 1107, 1201, 1202,10366,
101212, 11411, 11506, 11507, 11508, 12505, 12506, 12508, 12509, 13503, 101212, 11411, 11506, 11507, 11508, 12505, 12506, 12508, 12509, 13503,
13506, 14411, 14503, 14505, 14508, 15411, 15504, 15505, 15506, 15508, 13506, 14411, 14503, 14505, 14508, 15504, 15505, 15506,
20001, 10002, 10003, 10004, 10005, 10006, 10008,100231,100232,100431, 20001, 10002, 10003, 10004, 10005, 10006, 10008,100231,100232,100431,
101689,105001,105004, 106000,106001,108000,110000 101689,105001,105004, 106000,106001,108000,110000
}; };
......
...@@ -4,53 +4,158 @@ import emu.grasscutter.Grasscutter; ...@@ -4,53 +4,158 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType; import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.inventory.EquipType;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.Map;
import static java.util.Map.entry;
import static emu.grasscutter.utils.Language.translate; 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") @Command(label = "giveart", usage = "giveart <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [level]", aliases = {"gart"}, permission = "player.giveart", permissionTargeted = "player.giveart.others", description = "commands.giveArtifact.description")
public final class GiveArtifactCommand implements CommandHandler { public final class GiveArtifactCommand implements CommandHandler {
@Override private static final Map<String, Map<EquipType, Integer>> mainPropMap = Map.ofEntries(
public void execute(Player sender, Player targetPlayer, List<String> args) { entry("hp", Map.ofEntries(entry(EquipType.EQUIP_BRACER, 14001))),
if (targetPlayer == null) { entry("hp%", Map.ofEntries(entry(EquipType.EQUIP_SHOES, 10980), entry(EquipType.EQUIP_RING, 50980), entry(EquipType.EQUIP_DRESS, 30980))),
CommandHandler.sendMessage(sender, translate("commands.execution.need_target")); entry("atk", Map.ofEntries(entry(EquipType.EQUIP_NECKLACE, 12001))),
return; entry("atk%", Map.ofEntries(entry(EquipType.EQUIP_SHOES, 10990), entry(EquipType.EQUIP_RING, 50990), entry(EquipType.EQUIP_DRESS, 30990))),
entry("def%", Map.ofEntries(entry(EquipType.EQUIP_SHOES, 10970), entry(EquipType.EQUIP_RING, 50970), entry(EquipType.EQUIP_DRESS, 30970))),
entry("er", Map.ofEntries(entry(EquipType.EQUIP_SHOES, 10960))),
entry("em", Map.ofEntries(entry(EquipType.EQUIP_SHOES, 10950), entry(EquipType.EQUIP_RING, 50880), entry(EquipType.EQUIP_DRESS, 30930))),
entry("hb", Map.ofEntries(entry(EquipType.EQUIP_DRESS, 30940))),
entry("cdmg", Map.ofEntries(entry(EquipType.EQUIP_DRESS, 30950))),
entry("cr", Map.ofEntries(entry(EquipType.EQUIP_DRESS, 30960))),
entry("phys%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50890))),
entry("dendro%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50900))),
entry("geo%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50910))),
entry("anemo%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50920))),
entry("hydro%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50930))),
entry("cryo%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50940))),
entry("electro%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50950))),
entry("pyro%", Map.ofEntries(entry(EquipType.EQUIP_RING, 50960)))
);
private static final Map<String, String> appendPropMap = Map.ofEntries(
entry("hp", "0102"),
entry("hp%", "0103"),
entry("atk", "0105"),
entry("atk%", "0106"),
entry("def", "0108"),
entry("def%", "0109"),
entry("er", "0123"),
entry("em", "0124"),
entry("cr", "0120"),
entry("cdmg", "0122")
);
private int getAppendPropId(String substatText, ItemData itemData) {
int res;
// If the given substat text is an integer, we just use that
// as the append prop ID.
try {
res = Integer.parseInt(substatText);
return res;
}
catch (NumberFormatException ignores) {
// No need to handle this here. We just continue with the
// possibility of the argument being a substat string.
}
// If the argument was not an integer, we try to determine
// the append prop ID from the given text + artifact information.
// A substat string has the format `substat_tier`, with the
// `_tier` part being optional.
String[] substatArgs = substatText.split("_");
String substatType;
int substatTier;
if (substatArgs.length == 1) {
substatType = substatArgs[0];
substatTier =
itemData.getRankLevel() == 1 ? 2
: itemData.getRankLevel() == 2 ? 3
: 4;
}
else if (substatArgs.length == 2) {
substatType = substatArgs[0];
substatTier = Integer.parseInt(substatArgs[1]);
}
else {
throw new IllegalArgumentException();
}
// Check if the specified tier is legal for the artifact rarity.
if (substatTier < 1 || substatTier > 4) {
throw new IllegalArgumentException();
}
if (itemData.getRankLevel() == 1 && substatTier > 2) {
throw new IllegalArgumentException();
}
if (itemData.getRankLevel() == 2 && substatTier > 3) {
throw new IllegalArgumentException();
}
// Check if the given substat type string is a legal stat.
if (!appendPropMap.containsKey(substatType)) {
throw new IllegalArgumentException();
}
// Build the append prop ID.
return Integer.parseInt(Integer.toString(itemData.getRankLevel()) + appendPropMap.get(substatType) + Integer.toString(substatTier));
} }
@Override
public void execute(Player sender, Player targetPlayer, List<String> args) {
// Sanity check
if (args.size() < 2) { if (args.size() < 2) {
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.giveArtifact.usage"));
return; return;
} }
// Get the artifact piece ID from the arguments.
int itemId; int itemId;
try { try {
itemId = Integer.parseInt(args.remove(0)); itemId = Integer.parseInt(args.remove(0));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.id_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.giveArtifact.id_error"));
return; return;
} }
ItemData itemData = GameData.getItemDataMap().get(itemId); ItemData itemData = GameData.getItemDataMap().get(itemId);
if (itemData.getItemType() != ItemType.ITEM_RELIQUARY) { if (itemData.getItemType() != ItemType.ITEM_RELIQUARY) {
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.id_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.giveArtifact.id_error"));
return; return;
} }
// Get the main stat from the arguments.
// If the given argument is an integer, we use that.
// If not, we check if the argument string is in the main prop map.
String mainPropIdString = args.remove(0);
int mainPropId; int mainPropId;
try { try {
mainPropId = Integer.parseInt(args.remove(0)); mainPropId = Integer.parseInt(mainPropIdString);
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.generic.execution.argument_error")); mainPropId = -1;
}
if (mainPropMap.containsKey(mainPropIdString) && mainPropMap.get(mainPropIdString).containsKey(itemData.getEquipType())) {
mainPropId = mainPropMap.get(mainPropIdString).get(itemData.getEquipType());
}
if (mainPropId == -1) {
CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
return; return;
} }
// Get the level from the arguments.
int level = 1; int level = 1;
try { try {
int last = Integer.parseInt(args.get(args.size()-1)); int last = Integer.parseInt(args.get(args.size()-1));
...@@ -61,9 +166,13 @@ public final class GiveArtifactCommand implements CommandHandler { ...@@ -61,9 +166,13 @@ public final class GiveArtifactCommand implements CommandHandler {
} catch (NumberFormatException ignored) { // Could be a stat,times string so no need to panic } catch (NumberFormatException ignored) { // Could be a stat,times string so no need to panic
} }
List<Integer> appendPropIdList = new ArrayList<>(); // Get substats.
ArrayList<Integer> appendPropIdList = new ArrayList<>();
try { try {
// Every remaining argument is a substat.
args.forEach(it -> { args.forEach(it -> {
// The substat syntax permits specifying a number of rolls for the given
// substat. Split the string into stat and number if that is the case here.
String[] arr; String[] arr;
int n = 1; int n = 1;
if ((arr = it.split(",")).length == 2) { if ((arr = it.split(",")).length == 2) {
...@@ -73,13 +182,19 @@ public final class GiveArtifactCommand implements CommandHandler { ...@@ -73,13 +182,19 @@ public final class GiveArtifactCommand implements CommandHandler {
n = 200; n = 200;
} }
} }
appendPropIdList.addAll(Collections.nCopies(n, Integer.parseInt(it)));
// Determine the substat ID.
int appendPropId = getAppendPropId(it, itemData);
// Add the current substat.
appendPropIdList.addAll(Collections.nCopies(n, appendPropId));
}); });
} catch (Exception ignored) { } catch (Exception ignored) {
CommandHandler.sendMessage(sender, translate("commands.execution.argument_error")); CommandHandler.sendMessage(sender, translate(sender, "commands.execution.argument_error"));
return; return;
} }
// Create item for the artifact.
GameItem item = new GameItem(itemData); GameItem item = new GameItem(itemData);
item.setLevel(level); item.setLevel(level);
item.setMainPropId(mainPropId); item.setMainPropId(mainPropId);
...@@ -87,7 +202,7 @@ public final class GiveArtifactCommand implements CommandHandler { ...@@ -87,7 +202,7 @@ public final class GiveArtifactCommand implements CommandHandler {
item.getAppendPropIdList().addAll(appendPropIdList); item.getAppendPropIdList().addAll(appendPropIdList);
targetPlayer.getInventory().addItem(item, ActionReason.SubfieldDrop); targetPlayer.getInventory().addItem(item, ActionReason.SubfieldDrop);
CommandHandler.sendMessage(sender, translate("commands.giveArtifact.success", Integer.toString(itemId), Integer.toString(targetPlayer.getUid()))); CommandHandler.sendMessage(sender, translate(sender, "commands.giveArtifact.success", Integer.toString(itemId), Integer.toString(targetPlayer.getUid())));
} }
} }
...@@ -4,7 +4,7 @@ import emu.grasscutter.Grasscutter; ...@@ -4,7 +4,7 @@ import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.AvatarData; import emu.grasscutter.data.excels.AvatarData;
import emu.grasscutter.game.avatar.Avatar; import emu.grasscutter.game.avatar.Avatar;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
...@@ -12,17 +12,11 @@ import java.util.List; ...@@ -12,17 +12,11 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "givechar", usage = "givechar <avatarId> [level]", @Command(label = "givechar", usage = "givechar <avatarId> [level]", aliases = {"givec"}, permission = "player.givechar", permissionTargeted = "player.givechar.others", description = "commands.giveChar.description")
description = "Gives the player a specified character", aliases = {"givec"}, permission = "player.givechar")
public final class GiveCharCommand implements CommandHandler { public final class GiveCharCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
int avatarId; int avatarId;
int level = 1; int level = 1;
...@@ -32,7 +26,7 @@ public final class GiveCharCommand implements CommandHandler { ...@@ -32,7 +26,7 @@ public final class GiveCharCommand implements CommandHandler {
level = Integer.parseInt(args.get(1)); level = Integer.parseInt(args.get(1));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
// TODO: Parse from avatar name using GM Handbook. // TODO: Parse from avatar name using GM Handbook.
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarLevel")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.avatarLevel"));
return; return;
} // Cheeky fall-through to parse first argument too } // Cheeky fall-through to parse first argument too
case 1: case 1:
...@@ -40,33 +34,34 @@ public final class GiveCharCommand implements CommandHandler { ...@@ -40,33 +34,34 @@ public final class GiveCharCommand implements CommandHandler {
avatarId = Integer.parseInt(args.get(0)); avatarId = Integer.parseInt(args.get(0));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
// TODO: Parse from avatar name using GM Handbook. // TODO: Parse from avatar name using GM Handbook.
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.avatarId"));
return; return;
} }
break; break;
default: default:
CommandHandler.sendMessage(sender, translate("commands.giveChar.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.giveChar.usage"));
return; return;
} }
AvatarData avatarData = GameData.getAvatarDataMap().get(avatarId); AvatarData avatarData = GameData.getAvatarDataMap().get(avatarId);
if (avatarData == null) { if (avatarData == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.avatarId"));
return; return;
} }
// Check level. // Check level.
if (level > 90) { if (level > 90) {
CommandHandler.sendMessage(sender, translate("commands.execution.invalid.avatarLevel")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.avatarLevel"));
return; return;
} }
// Calculate ascension level. // Calculate ascension level.
int ascension; int ascension;
if (level <= 40) { if (level <= 40) {
ascension = (int) Math.ceil(level / 20f); ascension = (int) Math.ceil(level / 20f) - 1;
} else { } else {
ascension = (int) Math.ceil(level / 10f) - 3; ascension = (int) Math.ceil(level / 10f) - 3;
ascension = Math.min(ascension, 6);
} }
Avatar avatar = new Avatar(avatarId); Avatar avatar = new Avatar(avatarId);
...@@ -77,6 +72,6 @@ public final class GiveCharCommand implements CommandHandler { ...@@ -77,6 +72,6 @@ public final class GiveCharCommand implements CommandHandler {
avatar.recalcStats(); avatar.recalcStats();
targetPlayer.addAvatar(avatar); targetPlayer.addAvatar(avatar);
CommandHandler.sendMessage(sender, translate("commands.giveChar.given", Integer.toString(avatarId), Integer.toString(level), Integer.toString(targetPlayer.getUid()))); CommandHandler.sendMessage(sender, translate(sender, "commands.giveChar.given", Integer.toString(avatarId), Integer.toString(level), Integer.toString(targetPlayer.getUid())));
} }
} }
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.excels.ItemData;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType; import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
...@@ -12,13 +11,13 @@ import emu.grasscutter.game.props.ActionReason; ...@@ -12,13 +11,13 @@ import emu.grasscutter.game.props.ActionReason;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.regex.Pattern;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern;
import static emu.grasscutter.utils.Language.translate; 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 = { @Command(label = "give", usage = "give <itemId|itemName> [amount] [level]", aliases = {
"g", "item", "giveitem"}, permission = "player.give") "g", "item", "giveitem"}, permission = "player.give", permissionTargeted = "player.give.others", description = "commands.give.description")
public final class GiveCommand implements CommandHandler { public final class GiveCommand implements CommandHandler {
Pattern lvlRegex = Pattern.compile("l(?:vl?)?(\\d+)"); // Java is a joke of a proglang that doesn't have raw string literals Pattern lvlRegex = Pattern.compile("l(?:vl?)?(\\d+)"); // Java is a joke of a proglang that doesn't have raw string literals
Pattern refineRegex = Pattern.compile("r(\\d+)"); Pattern refineRegex = Pattern.compile("r(\\d+)");
...@@ -34,10 +33,6 @@ public final class GiveCommand implements CommandHandler { ...@@ -34,10 +33,6 @@ public final class GiveCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
int item; int item;
int lvl = 1; int lvl = 1;
int amount = 1; int amount = 1;
...@@ -69,21 +64,21 @@ public final class GiveCommand implements CommandHandler { ...@@ -69,21 +64,21 @@ public final class GiveCommand implements CommandHandler {
try { try {
refinement = Integer.parseInt(args.get(3)); refinement = Integer.parseInt(args.get(3));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemRefinement")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemRefinement"));
return; return;
} // Fallthrough } // Fallthrough
case 3: // <itemId|itemName> [amount] [level] case 3: // <itemId|itemName> [amount] [level]
try { try {
lvl = Integer.parseInt(args.get(2)); lvl = Integer.parseInt(args.get(2));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemLevel")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemLevel"));
return; return;
} // Fallthrough } // Fallthrough
case 2: // <itemId|itemName> [amount] case 2: // <itemId|itemName> [amount]
try { try {
amount = Integer.parseInt(args.get(1)); amount = Integer.parseInt(args.get(1));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.amount")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.amount"));
return; return;
} // Fallthrough } // Fallthrough
case 1: // <itemId|itemName> case 1: // <itemId|itemName>
...@@ -91,28 +86,28 @@ public final class GiveCommand implements CommandHandler { ...@@ -91,28 +86,28 @@ public final class GiveCommand implements CommandHandler {
item = Integer.parseInt(args.get(0)); item = Integer.parseInt(args.get(0));
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook. // TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemId"));
return; return;
} }
break; break;
default: // *No args* default: // *No args*
CommandHandler.sendMessage(sender, translate("commands.give.usage")); CommandHandler.sendMessage(sender, translate(sender, "commands.give.usage"));
return; return;
} }
ItemData itemData = GameData.getItemDataMap().get(item); ItemData itemData = GameData.getItemDataMap().get(item);
if (itemData == null) { if (itemData == null) {
CommandHandler.sendMessage(sender, translate("commands.generic.invalid.itemId")); CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.itemId"));
return; return;
} }
if (refinement != 0) { if (refinement != 0) {
if (itemData.getItemType() == ItemType.ITEM_WEAPON) { if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
if (refinement < 1 || refinement > 5) { if (refinement < 1 || refinement > 5) {
CommandHandler.sendMessage(sender, translate("commands.give.refinement_must_between_1_and_5")); CommandHandler.sendMessage(sender, translate(sender, "commands.give.refinement_must_between_1_and_5"));
return; return;
} }
} else { } else {
CommandHandler.sendMessage(sender, translate("commands.give.refinement_only_applicable_weapons")); CommandHandler.sendMessage(sender, translate(sender, "commands.give.refinement_only_applicable_weapons"));
return; return;
} }
} }
...@@ -120,11 +115,11 @@ public final class GiveCommand implements CommandHandler { ...@@ -120,11 +115,11 @@ public final class GiveCommand implements CommandHandler {
this.item(targetPlayer, itemData, amount, lvl, refinement); this.item(targetPlayer, itemData, amount, lvl, refinement);
if (!itemData.isEquip()) { if (!itemData.isEquip()) {
CommandHandler.sendMessage(sender, translate("commands.give.given", Integer.toString(amount), Integer.toString(item), Integer.toString(targetPlayer.getUid()))); CommandHandler.sendMessage(sender, translate(sender, "commands.give.given", Integer.toString(amount), Integer.toString(item), Integer.toString(targetPlayer.getUid())));
} else if (itemData.getItemType() == ItemType.ITEM_WEAPON) { } else if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
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()))); CommandHandler.sendMessage(sender, translate(sender, "commands.give.given_with_level_and_refinement", Integer.toString(item), Integer.toString(lvl), Integer.toString(refinement), Integer.toString(amount), Integer.toString(targetPlayer.getUid())));
} else { } else {
CommandHandler.sendMessage(sender, translate("commands.give.given_level", Integer.toString(item), Integer.toString(lvl), Integer.toString(amount))); CommandHandler.sendMessage(sender, translate(sender, "commands.give.given_level", Integer.toString(item), Integer.toString(lvl), Integer.toString(amount), Integer.toString(targetPlayer.getUid())));
} }
} }
......
package emu.grasscutter.command.commands; package emu.grasscutter.command.commands;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.command.Command; import emu.grasscutter.command.Command;
import emu.grasscutter.command.CommandHandler; import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
...@@ -9,17 +8,11 @@ import java.util.List; ...@@ -9,17 +8,11 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "godmode", usage = "godmode [on|off|toggle]", @Command(label = "godmode", usage = "godmode [on|off|toggle]", permission = "player.godmode", permissionTargeted = "player.godmode.others", description = "commands.godmode.description")
description = "Prevents you from taking damage. Defaults to toggle.", permission = "player.godmode")
public final class GodModeCommand implements CommandHandler { public final class GodModeCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
boolean enabled = !targetPlayer.inGodmode(); boolean enabled = !targetPlayer.inGodmode();
if (args.size() == 1) { if (args.size() == 1) {
switch (args.get(0).toLowerCase()) { switch (args.get(0).toLowerCase()) {
...@@ -37,6 +30,6 @@ public final class GodModeCommand implements CommandHandler { ...@@ -37,6 +30,6 @@ public final class GodModeCommand implements CommandHandler {
} }
targetPlayer.setGodmode(enabled); targetPlayer.setGodmode(enabled);
CommandHandler.sendMessage(sender, translate("commands.godmode.success", (enabled ? translate("commands.status.enabled") : translate("commands.status.disabled")), targetPlayer.getNickname())); CommandHandler.sendMessage(sender, translate(sender, "commands.godmode.success", (enabled ? translate(sender, "commands.status.enabled") : translate(sender, "commands.status.disabled")), targetPlayer.getNickname()));
} }
} }
...@@ -11,16 +11,11 @@ import java.util.List; ...@@ -11,16 +11,11 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "heal", usage = "heal|h", aliases = {"h"}, @Command(label = "heal", usage = "heal|h", aliases = {"h"}, permission = "player.heal", permissionTargeted = "player.heal.others", description = "commands.heal.description")
description = "Heal all characters in your current team.", permission = "player.heal")
public final class HealCommand implements CommandHandler { public final class HealCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
targetPlayer.getTeamManager().getActiveTeam().forEach(entity -> { targetPlayer.getTeamManager().getActiveTeam().forEach(entity -> {
boolean isAlive = entity.isAlive(); boolean isAlive = entity.isAlive();
entity.setFightProperty( entity.setFightProperty(
...@@ -32,6 +27,6 @@ public final class HealCommand implements CommandHandler { ...@@ -32,6 +27,6 @@ public final class HealCommand implements CommandHandler {
entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar())); entity.getWorld().broadcastPacket(new PacketAvatarLifeStateChangeNotify(entity.getAvatar()));
} }
}); });
CommandHandler.sendMessage(sender, translate("commands.heal.success")); CommandHandler.sendMessage(sender, translate(sender, "commands.heal.success"));
} }
} }
...@@ -10,8 +10,7 @@ import java.util.*; ...@@ -10,8 +10,7 @@ import java.util.*;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "help", usage = "help [command]", @Command(label = "help", usage = "help [command]", description = "commands.help.description", targetRequirement = Command.TargetRequirement.NONE)
description = "Sends the help message or shows information about a specified command")
public final class HelpCommand implements CommandHandler { public final class HelpCommand implements CommandHandler {
@Override @Override
...@@ -33,16 +32,16 @@ public final class HelpCommand implements CommandHandler { ...@@ -33,16 +32,16 @@ public final class HelpCommand implements CommandHandler {
} else { } else {
String command = args.get(0); String command = args.get(0);
CommandHandler handler = CommandMap.getInstance().getHandler(command); CommandHandler handler = CommandMap.getInstance().getHandler(command);
StringBuilder builder = new StringBuilder(player == null ? "\n" + translate("commands.status.help") + " - " : translate("commands.status.help") + " - ").append(command).append(": \n"); StringBuilder builder = new StringBuilder(player == null ? "\n" + translate(player, "commands.status.help") + " - " : translate(player, "commands.status.help") + " - ").append(command).append(": \n");
if (handler == null) { if (handler == null) {
builder.append(translate("commands.generic.command_exist_error")); builder.append(translate(player, "commands.generic.command_exist_error"));
} else { } else {
Command annotation = handler.getClass().getAnnotation(Command.class); Command annotation = handler.getClass().getAnnotation(Command.class);
builder.append(" ").append(annotation.description()).append("\n"); builder.append(" ").append(translate(player, annotation.description())).append("\n");
builder.append(translate("commands.help.usage")).append(annotation.usage()); builder.append(translate(player, "commands.help.usage")).append(annotation.usage());
if (annotation.aliases().length >= 1) { if (annotation.aliases().length >= 1) {
builder.append("\n").append(translate("commands.help.aliases")); builder.append("\n").append(translate(player, "commands.help.aliases"));
for (String alias : annotation.aliases()) { for (String alias : annotation.aliases()) {
builder.append(alias).append(" "); builder.append(alias).append(" ");
} }
...@@ -58,13 +57,13 @@ public final class HelpCommand implements CommandHandler { ...@@ -58,13 +57,13 @@ public final class HelpCommand implements CommandHandler {
void SendAllHelpMessage(Player player, List<Command> annotations) { void SendAllHelpMessage(Player player, List<Command> annotations) {
if (player == null) { if (player == null) {
StringBuilder builder = new StringBuilder("\n" + translate("commands.help.available_commands") + "\n"); StringBuilder builder = new StringBuilder("\n" + translate(player, "commands.help.available_commands") + "\n");
annotations.forEach(annotation -> { annotations.forEach(annotation -> {
builder.append(annotation.label()).append("\n"); builder.append(annotation.label()).append("\n");
builder.append(" ").append(annotation.description()).append("\n"); builder.append(" ").append(translate(player, annotation.description())).append("\n");
builder.append(translate("commands.help.usage")).append(annotation.usage()); builder.append(translate(player, "commands.help.usage")).append(annotation.usage());
if (annotation.aliases().length >= 1) { if (annotation.aliases().length >= 1) {
builder.append("\n").append(translate("commands.help.aliases")); builder.append("\n").append(translate(player, "commands.help.aliases"));
for (String alias : annotation.aliases()) { for (String alias : annotation.aliases()) {
builder.append(alias).append(" "); builder.append(alias).append(" ");
} }
...@@ -75,13 +74,13 @@ public final class HelpCommand implements CommandHandler { ...@@ -75,13 +74,13 @@ public final class HelpCommand implements CommandHandler {
CommandHandler.sendMessage(null, builder.toString()); CommandHandler.sendMessage(null, builder.toString());
} else { } else {
CommandHandler.sendMessage(player, translate("commands.help.available_commands")); CommandHandler.sendMessage(player, translate(player, "commands.help.available_commands"));
annotations.forEach(annotation -> { annotations.forEach(annotation -> {
StringBuilder builder = new StringBuilder(annotation.label()).append("\n"); StringBuilder builder = new StringBuilder(annotation.label()).append("\n");
builder.append(" ").append(annotation.description()).append("\n"); builder.append(" ").append(translate(player, annotation.description())).append("\n");
builder.append(translate("commands.help.usage")).append(annotation.usage()); builder.append(translate(player, "commands.help.usage")).append(annotation.usage());
if (annotation.aliases().length >= 1) { if (annotation.aliases().length >= 1) {
builder.append("\n").append(translate("commands.help.aliases")); builder.append("\n").append(translate(player, "commands.help.aliases"));
for (String alias : annotation.aliases()) { for (String alias : annotation.aliases()) {
builder.append(alias).append(" "); builder.append(alias).append(" ");
} }
......
...@@ -8,23 +8,17 @@ import java.util.List; ...@@ -8,23 +8,17 @@ import java.util.List;
import static emu.grasscutter.utils.Language.translate; import static emu.grasscutter.utils.Language.translate;
@Command(label = "kick", usage = "kick", @Command(label = "kick", usage = "kick", permission = "server.kick", description = "commands.kick.description")
description = "Kicks the specified player from the server (WIP)", permission = "server.kick")
public final class KickCommand implements CommandHandler { public final class KickCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, Player targetPlayer, List<String> args) { public void execute(Player sender, Player targetPlayer, List<String> args) {
if (targetPlayer == null) {
CommandHandler.sendMessage(sender, translate("commands.execution.need_target"));
return;
}
if (sender != null) { if (sender != null) {
CommandHandler.sendMessage(sender, translate("commands.kick.player_kick_player", CommandHandler.sendMessage(sender, translate(sender, "commands.kick.player_kick_player",
Integer.toString(sender.getAccount().getPlayerUid()), sender.getAccount().getUsername(), Integer.toString(sender.getUid()), sender.getAccount().getUsername(),
Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername())); Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
} else { } else {
CommandHandler.sendMessage(null, translate("commands.kick.server_kick_player", Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername())); CommandHandler.sendMessage(null, translate(sender, "commands.kick.server_kick_player", Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
} }
targetPlayer.getSession().close(); targetPlayer.getSession().close();
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment