mirror of
https://github.com/Grasscutters/Grasscutter.git
synced 2026-02-06 10:06:51 +01:00
Merge branch 'development' into more-events
# Conflicts: # src/main/java/emu/grasscutter/command/commands/TeleportAllCommand.java # src/main/java/emu/grasscutter/game/entity/EntityAvatar.java # src/main/java/emu/grasscutter/game/entity/GameEntity.java # src/main/java/emu/grasscutter/game/managers/mapmark/MapMarksManager.java
This commit is contained in:
@@ -7,14 +7,12 @@ import java.lang.annotation.RetentionPolicy;
|
||||
public @interface Command {
|
||||
String label() default "";
|
||||
|
||||
String usage() default "commands.generic.no_usage_specified";
|
||||
|
||||
String description() default "commands.generic.no_description_specified";
|
||||
|
||||
String[] aliases() default {};
|
||||
|
||||
String[] usage() default {""};
|
||||
|
||||
String permission() default "";
|
||||
|
||||
|
||||
String permissionTargeted() default "";
|
||||
|
||||
public enum TargetRequirement {
|
||||
|
||||
@@ -2,12 +2,11 @@ package emu.grasscutter.command;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.event.game.CommandResponseEvent;
|
||||
import emu.grasscutter.server.event.game.ReceiveCommandFeedbackEvent;
|
||||
import emu.grasscutter.server.event.types.ServerEvent;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.StringJoiner;
|
||||
|
||||
public interface CommandHandler {
|
||||
|
||||
@@ -37,6 +36,41 @@ public interface CommandHandler {
|
||||
sendMessage(player, translate(player, messageKey, args));
|
||||
}
|
||||
|
||||
default String getUsageString(Player player, String... args) {
|
||||
Command annotation = this.getClass().getAnnotation(Command.class);
|
||||
String usage_prefix = translate(player, "commands.execution.usage_prefix");
|
||||
String command = annotation.label();
|
||||
for (String alias : annotation.aliases()) {
|
||||
if (alias.length() < command.length())
|
||||
command = alias;
|
||||
}
|
||||
String target = switch (annotation.targetRequirement()) {
|
||||
case NONE -> "";
|
||||
case OFFLINE -> "@<UID> "; // TODO: make translation keys for offline and online players
|
||||
case ONLINE -> (player == null) ? "@<UID> " : "[@<UID>] "; // TODO: make translation keys for offline and online players
|
||||
case PLAYER -> (player == null) ? "@<UID> " : "[@<UID>] ";
|
||||
};
|
||||
String[] usages = annotation.usage();
|
||||
StringJoiner joiner = new StringJoiner("\n\t");
|
||||
for (String usage : usages)
|
||||
joiner.add(usage_prefix + command + " " + target + usage);
|
||||
return joiner.toString();
|
||||
}
|
||||
|
||||
default void sendUsageMessage(Player player, String... args) {
|
||||
sendMessage(player, getUsageString(player, args));
|
||||
}
|
||||
|
||||
default String getLabel() {
|
||||
return this.getClass().getAnnotation(Command.class).label();
|
||||
}
|
||||
|
||||
default String getDescriptionString(Player player) {
|
||||
Command annotation = this.getClass().getAnnotation(Command.class);
|
||||
String key = "commands.%s.description".formatted(annotation.label());
|
||||
return translate(player, key);
|
||||
}
|
||||
|
||||
/**
|
||||
* Called when a player/console invokes a command.
|
||||
* @param sender The player/console that invoked the command.
|
||||
|
||||
@@ -8,9 +8,9 @@ import java.util.*;
|
||||
|
||||
@SuppressWarnings({"UnusedReturnValue", "unused"})
|
||||
public final class CommandMap {
|
||||
private final Map<String, CommandHandler> commands = new HashMap<>();
|
||||
private final Map<String, CommandHandler> aliases = new HashMap<>();
|
||||
private final Map<String, Command> annotations = new HashMap<>();
|
||||
private final Map<String, CommandHandler> commands = new TreeMap<>();
|
||||
private final Map<String, CommandHandler> aliases = new TreeMap<>();
|
||||
private final Map<String, Command> annotations = new TreeMap<>();
|
||||
private final Map<String, Integer> targetPlayerIds = new HashMap<>();
|
||||
private static final String consoleId = "console";
|
||||
|
||||
@@ -35,6 +35,7 @@ public final class CommandMap {
|
||||
*/
|
||||
public CommandMap registerCommand(String label, CommandHandler command) {
|
||||
Grasscutter.getLogger().debug("Registered command: " + label);
|
||||
label = label.toLowerCase();
|
||||
|
||||
// Get command data.
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
@@ -167,7 +168,7 @@ public final class CommandMap {
|
||||
CommandHandler.sendTranslatedMessage(player, "commands.execution.clear_target");
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
// Sets default targetPlayer to the UID provided.
|
||||
try {
|
||||
int uid = Integer.parseInt(targetUid);
|
||||
@@ -203,7 +204,7 @@ public final class CommandMap {
|
||||
// Parse message.
|
||||
String[] split = rawMessage.split(" ");
|
||||
List<String> args = new LinkedList<>(Arrays.asList(split));
|
||||
String label = args.remove(0);
|
||||
String label = args.remove(0).toLowerCase();
|
||||
String playerId = (player == null) ? consoleId : player.getAccount().getId();
|
||||
|
||||
// Check for special cases - currently only target command.
|
||||
@@ -237,7 +238,7 @@ public final class CommandMap {
|
||||
Command annotation = this.annotations.get(label);
|
||||
|
||||
// Resolve targetPlayer
|
||||
try{
|
||||
try {
|
||||
targetPlayer = getTargetPlayer(playerId, player, targetPlayer, args);
|
||||
} catch (IllegalArgumentException e) {
|
||||
return;
|
||||
|
||||
@@ -1,8 +1,10 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import at.favre.lib.crypto.bcrypt.BCrypt;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.config.Configuration;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
@@ -11,18 +13,24 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "account", usage = "account <create|delete> <username> [uid]", description = "commands.account.description", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "account",
|
||||
usage = {
|
||||
"create <username> [<UID>]", // Only with EXPERIMENTAL_RealPassword == false
|
||||
"delete <username>",
|
||||
"create <username> <password> [<UID>]", // Only with EXPERIMENTAL_RealPassword == true
|
||||
"resetpass <username> <password>"}, // Only with EXPERIMENTAL_RealPassword == true
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class AccountCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (sender != null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.console_execute_error"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.console_execute_error");
|
||||
return;
|
||||
}
|
||||
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.command_usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -31,28 +39,55 @@ public final class AccountCommand implements CommandHandler {
|
||||
|
||||
switch (action) {
|
||||
default:
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.command_usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
case "create":
|
||||
int uid = 0;
|
||||
if (args.size() > 2) {
|
||||
try {
|
||||
uid = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.invalid"));
|
||||
String password = "";
|
||||
|
||||
if(Configuration.ACCOUNT.EXPERIMENTAL_RealPassword == true) {
|
||||
if(args.size() < 3) {
|
||||
CommandHandler.sendMessage(sender, "EXPERIMENTAL_RealPassword requires a password argument");
|
||||
CommandHandler.sendMessage(sender, "Usage: account create <username> <password> [uid]");
|
||||
return;
|
||||
}
|
||||
password = args.get(2);
|
||||
|
||||
if (args.size() == 4) {
|
||||
try {
|
||||
uid = Integer.parseInt(args.get(3));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.invalid"));
|
||||
if(Configuration.ACCOUNT.EXPERIMENTAL_RealPassword == true) {
|
||||
CommandHandler.sendMessage(sender, "EXPERIMENTAL_RealPassword requires argument 2 to be a password, not a uid");
|
||||
CommandHandler.sendMessage(sender, "Usage: account create <username> <password> [uid]");
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
if (args.size() > 2) {
|
||||
try {
|
||||
uid = Integer.parseInt(args.get(2));
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.invalid"));
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
emu.grasscutter.game.Account account = DatabaseHelper.createAccountWithUid(username, uid);
|
||||
if (account == null) {
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.exists"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.exists"));
|
||||
return;
|
||||
} else {
|
||||
if (Configuration.ACCOUNT.EXPERIMENTAL_RealPassword == true) {
|
||||
account.setPassword(BCrypt.withDefaults().hashToString(12, password.toCharArray()));
|
||||
}
|
||||
account.addPermission("*");
|
||||
account.save(); // Save account to database.
|
||||
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.create", Integer.toString(account.getReservedPlayerUid())));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.create", Integer.toString(account.getReservedPlayerUid())));
|
||||
}
|
||||
return;
|
||||
case "delete":
|
||||
@@ -60,20 +95,50 @@ public final class AccountCommand implements CommandHandler {
|
||||
Account toDelete = DatabaseHelper.getAccountByName(username);
|
||||
|
||||
if (toDelete == null) {
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.no_account"));
|
||||
CommandHandler.sendMessage(sender, 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();
|
||||
}
|
||||
|
||||
// Make sure player isn't online as we delete their account.
|
||||
kickAccount(toDelete);
|
||||
|
||||
// Finally, we do the actual deletion.
|
||||
DatabaseHelper.deleteAccount(toDelete);
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.account.delete"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.delete"));
|
||||
return;
|
||||
case "resetpass":
|
||||
if(Configuration.ACCOUNT.EXPERIMENTAL_RealPassword != true) {
|
||||
CommandHandler.sendMessage(sender, "resetpass requires EXPERIMENTAL_RealPassword to be true.");
|
||||
return;
|
||||
}
|
||||
|
||||
if(args.size() != 3) {
|
||||
CommandHandler.sendMessage(sender, "Invalid Args");
|
||||
CommandHandler.sendMessage(sender, "Usage: account resetpass <username> <password>");
|
||||
return;
|
||||
}
|
||||
|
||||
Account toUpdate = DatabaseHelper.getAccountByName(username);
|
||||
|
||||
if (toUpdate == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.account.no_account"));
|
||||
return;
|
||||
}
|
||||
|
||||
// Make sure player can't stay logged in with old password.
|
||||
kickAccount(toUpdate);
|
||||
|
||||
toUpdate.setPassword(BCrypt.withDefaults().hashToString(12, args.get(2).toCharArray()));
|
||||
toUpdate.save();
|
||||
CommandHandler.sendMessage(sender, "Password Updated.");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
private void kickAccount(Account account) {
|
||||
Player player = Grasscutter.getGameServer().getPlayerByAccountId(account.getId());
|
||||
if (player != null) {
|
||||
player.getSession().close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,31 +13,30 @@ import java.util.Random;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "announce",
|
||||
usage = "announce|a <\"tpl\" templateId|\"refresh\"|\"revoke\" templateId|content>",
|
||||
usage = {"<content>", "refresh", "(tpl|revoke) <templateId>"},
|
||||
permission = "server.announce",
|
||||
aliases = {"a"},
|
||||
description = "commands.announce.description",
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class AnnounceCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
var manager = Grasscutter.getGameServer().getAnnouncementManager();
|
||||
var manager = Grasscutter.getGameServer().getAnnouncementSystem();
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.announce.command_usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args.get(0)){
|
||||
switch (args.get(0)) {
|
||||
case "tpl":
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.announce.command_usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
var templateId = Integer.parseInt(args.get(1));
|
||||
var tpl = manager.getAnnounceConfigItemMap().get(templateId);
|
||||
if(tpl == null){
|
||||
if (tpl == null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.announce.not_found", templateId));
|
||||
return;
|
||||
}
|
||||
@@ -53,7 +52,7 @@ public final class AnnounceCommand implements CommandHandler {
|
||||
|
||||
case "revoke":
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.announce.command_usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -10,8 +10,7 @@ import emu.grasscutter.server.game.GameSession;
|
||||
|
||||
@Command(
|
||||
label = "ban",
|
||||
usage = "ban <@player> [time] [reason]",
|
||||
description = "commands.ban.description",
|
||||
usage = {"[<time> [<reason>]]"},
|
||||
permission = "server.ban",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER
|
||||
)
|
||||
|
||||
@@ -12,10 +12,11 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import java.util.stream.Stream;
|
||||
|
||||
@Command(label = "clear", usage = "clear <all|wp|art|mat> [lv<max level>] [r<max refinement>] [<max rarity>*]",
|
||||
description = "commands.clear.description",
|
||||
aliases = {"clear"}, permission = "player.clearinv", permissionTargeted = "player.clearinv.others")
|
||||
|
||||
@Command(
|
||||
label = "clear",
|
||||
usage = {"(all|wp|art|mat) [lv<max level>] [r<max refinement>] [<max rarity>*]"},
|
||||
permission = "player.clearinv",
|
||||
permissionTargeted = "player.clearinv.others")
|
||||
public final class ClearCommand implements CommandHandler {
|
||||
private static Pattern lvlRegex = Pattern.compile("l(?:vl?)?(\\d+)"); // Java doesn't have raw string literals :(
|
||||
private static Pattern refineRegex = Pattern.compile("r(\\d+)");
|
||||
@@ -82,7 +83,7 @@ public final class ClearCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.clear.command_usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,9 +7,7 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "coop", usage = "coop [host uid]", permission = "server.coop", permissionTargeted = "server.coop.others", description = "commands.coop.description")
|
||||
@Command(label = "coop", usage = {"[<host UID>]"}, permission = "server.coop", permissionTargeted = "server.coop.others")
|
||||
public final class CoopCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -17,34 +15,35 @@ public final class CoopCommand implements CommandHandler {
|
||||
Player host = sender;
|
||||
switch (args.size()) {
|
||||
case 0: // Summon target to self
|
||||
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
|
||||
sendUsageMessage(sender);
|
||||
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, translate(sender, "commands.execution.player_offline_error"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.execution.player_offline_error");
|
||||
return;
|
||||
}
|
||||
break;
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.uid"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.uid");
|
||||
return;
|
||||
}
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.coop.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
// There's no target==host check but this just places them in multiplayer in their own world which seems fine.
|
||||
if (targetPlayer.isInMultiplayer()) {
|
||||
targetPlayer.getServer().getMultiplayerManager().leaveCoop(targetPlayer);
|
||||
targetPlayer.getServer().getMultiplayerSystem().leaveCoop(targetPlayer);
|
||||
}
|
||||
host.getServer().getMultiplayerManager().applyEnterMp(targetPlayer, host.getUid());
|
||||
targetPlayer.getServer().getMultiplayerManager().applyEnterMpReply(host, targetPlayer.getUid(), true);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.coop.success", targetPlayer.getNickname(), host.getNickname()));
|
||||
host.getServer().getMultiplayerSystem().applyEnterMp(targetPlayer, host.getUid());
|
||||
targetPlayer.getServer().getMultiplayerSystem().applyEnterMpReply(host, targetPlayer.getUid(), true);
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.coop.success", targetPlayer.getNickname(), host.getNickname());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,24 +8,24 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "enterdungeon", usage = "enterdungeon <dungeonId>", aliases = {"dungeon"}, permission = "player.enterdungeon", permissionTargeted = "player.enterdungeon.others", description = "commands.enter_dungeon.description")
|
||||
@Command(label = "enter_dungeon", aliases = {"enterdungeon", "dungeon"}, usage = {"<dungeonId>"}, permission = "player.enterdungeon", permissionTargeted = "player.enterdungeon.others")
|
||||
public final class EnterDungeonCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
try {
|
||||
int dungeonId = Integer.parseInt(args.get(0));
|
||||
if (dungeonId == targetPlayer.getSceneId()) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.in_dungeon_error"));
|
||||
return;
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.in_dungeon_error"));
|
||||
return;
|
||||
}
|
||||
|
||||
boolean result = targetPlayer.getServer().getDungeonManager().enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId);
|
||||
|
||||
boolean result = targetPlayer.getServer().getDungeonSystem().enterDungeon(targetPlayer.getSession().getPlayer(), 0, dungeonId);
|
||||
|
||||
if (!result) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.not_found_error"));
|
||||
@@ -33,7 +33,7 @@ public final class EnterDungeonCommand implements CommandHandler {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.changed", dungeonId));
|
||||
}
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.enter_dungeon.usage"));
|
||||
sendUsageMessage(sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -23,8 +23,15 @@ import java.util.List;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
|
||||
@Command(label = "give", usage = "give <itemId|avatarId|\"all\"|\"weapons\"|\"mats\"|\"avatars\"> [lv<level>] [r<refinement>] [x<amount>] | give <artifactId> [lv<level>] [x<amount>] [mainPropId] [<appendPropId>[,<times>]]...", aliases = {
|
||||
"g", "item", "giveitem"}, permission = "player.give", permissionTargeted = "player.give.others", description = "commands.give.description")
|
||||
@Command(
|
||||
label = "give",
|
||||
aliases = {"g", "item", "giveitem"},
|
||||
usage = {
|
||||
"(<itemId>|<avatarId>|all|weapons|mats|avatars) [lv<level>] [r<refinement>] [x<amount>] [c<constellation>]",
|
||||
"<artifactId> [lv<level>] [x<amount>] [<mainPropId>] [<appendPropId>[,<times>]]..."},
|
||||
permission = "player.give",
|
||||
permissionTargeted = "player.give.others",
|
||||
threading = true)
|
||||
public final class GiveCommand implements CommandHandler {
|
||||
private static Pattern lvlRegex = Pattern.compile("l(?:vl?)?(\\d+)"); // Java doesn't have raw string literals :(
|
||||
private static Pattern refineRegex = Pattern.compile("r(\\d+)");
|
||||
@@ -60,7 +67,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
public GiveAllType giveAllType = GiveAllType.NONE;
|
||||
};
|
||||
|
||||
private static GiveItemParameters parseArgs(Player sender, List<String> args) throws IllegalArgumentException {
|
||||
private GiveItemParameters parseArgs(Player sender, List<String> args) throws IllegalArgumentException {
|
||||
GiveItemParameters param = new GiveItemParameters();
|
||||
|
||||
// Extract any tagged arguments (e.g. "lv90", "x100", "r5")
|
||||
@@ -92,7 +99,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
|
||||
// At this point, first remaining argument MUST be itemId/avatarId
|
||||
if (args.size() < 1) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.give.usage"); // Reachable if someone does `/give lv90` or similar
|
||||
sendUsageMessage(sender); // Reachable if someone does `/give lv90` or similar
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
String id = args.remove(0);
|
||||
@@ -162,7 +169,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
throw e;
|
||||
}
|
||||
} else {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.give.usage");
|
||||
sendUsageMessage(sender);
|
||||
throw new IllegalArgumentException();
|
||||
}
|
||||
}
|
||||
@@ -173,7 +180,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) { // *No args*
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.give.usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -257,7 +264,7 @@ public final class GiveCommand implements CommandHandler {
|
||||
if (avatar.getAvatarId() == GameConstants.MAIN_CHARACTER_MALE) {
|
||||
avatar.setSkillDepotData(GameData.getAvatarSkillDepotDataMap().get(504));
|
||||
}
|
||||
else if(avatar.getAvatarId() == GameConstants.MAIN_CHARACTER_FEMALE) {
|
||||
else if (avatar.getAvatarId() == GameConstants.MAIN_CHARACTER_FEMALE) {
|
||||
avatar.setSkillDepotData(GameData.getAvatarSkillDepotDataMap().get(704));
|
||||
}
|
||||
|
||||
@@ -352,11 +359,11 @@ public final class GiveCommand implements CommandHandler {
|
||||
return affixes;
|
||||
}
|
||||
|
||||
private static int getAppendPropId(String substatText, ItemData itemData) throws IllegalArgumentException {
|
||||
// If the given substat text is an integer, we just use that as the append prop ID.
|
||||
try {
|
||||
return Integer.parseInt(substatText);
|
||||
} catch (NumberFormatException ignored) {
|
||||
private static int getAppendPropId(String substatText, ItemData itemData) throws IllegalArgumentException {
|
||||
// If the given substat text is an integer, we just use that as the append prop ID.
|
||||
try {
|
||||
return Integer.parseInt(substatText);
|
||||
} catch (NumberFormatException ignored) {
|
||||
// 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
|
||||
@@ -378,8 +385,8 @@ public final class GiveCommand implements CommandHandler {
|
||||
substatTier -= 1; // 1-indexed to 0-indexed
|
||||
substatTier = Math.min(Math.max(0, substatTier), substats.size() - 1);
|
||||
return substats.get(substatTier);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static void parseRelicArgs(GiveItemParameters param, List<String> args) throws IllegalArgumentException {
|
||||
// Get the main stat from the arguments.
|
||||
@@ -476,11 +483,11 @@ public final class GiveCommand implements CommandHandler {
|
||||
10000-10008, 11411, 11506-11508, 12505, 12506, 12508, 12509,
|
||||
13503, 13506, 14411, 14503, 14505, 14508, 15504-15506
|
||||
""");
|
||||
|
||||
|
||||
private static final SparseSet illegalRelicIds = new SparseSet("""
|
||||
20001, 23300-23340, 23383-23385, 78310-78554, 99310-99554
|
||||
""");
|
||||
|
||||
|
||||
private static final SparseSet illegalItemIds = new SparseSet("""
|
||||
100086, 100087, 100100-101000, 101106-101110, 101306, 101500-104000,
|
||||
105001, 105004, 106000-107000, 107011, 108000, 109000-110000,
|
||||
|
||||
@@ -11,7 +11,7 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "heal", usage = "heal|h", aliases = {"h"}, permission = "player.heal", permissionTargeted = "player.heal.others", description = "commands.heal.description")
|
||||
@Command(label = "heal", aliases = {"h"}, permission = "player.heal", permissionTargeted = "player.heal.others")
|
||||
public final class HealCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -3,80 +3,81 @@ package emu.grasscutter.command.commands;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.command.CommandMap;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.*;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "help", usage = "help [command]", description = "commands.help.description", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(label = "help", usage = {"[<command>]"}, targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class HelpCommand implements CommandHandler {
|
||||
private final boolean SHOW_COMMANDS_WITHOUT_PERMISSIONS = false; // TODO: Make this into a server config key
|
||||
|
||||
private void createCommand(StringBuilder builder, Player player, Command annotation) {
|
||||
builder.append("\n").append(annotation.label()).append(" - ").append(translate(player, annotation.description()));
|
||||
builder.append("\n\t").append(translate(player, "commands.help.usage"));
|
||||
if (annotation.aliases().length >= 1) {
|
||||
private String createCommand(Player player, CommandHandler command, List<String> args) {
|
||||
StringBuilder builder = new StringBuilder(command.getLabel())
|
||||
.append(" - ")
|
||||
.append(command.getDescriptionString(player))
|
||||
.append("\n\t")
|
||||
.append(command.getUsageString(player, args.toArray(new String[0])));
|
||||
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
if (annotation.aliases().length > 0) {
|
||||
builder.append("\n\t").append(translate(player, "commands.help.aliases"));
|
||||
for (String alias : annotation.aliases()) {
|
||||
builder.append(alias).append(" ");
|
||||
}
|
||||
}
|
||||
|
||||
builder.append("\n\t").append(translate(player, "commands.help.tip_need_permission"));
|
||||
if(annotation.permission().isEmpty() || annotation.permission().isBlank()) {
|
||||
builder.append(translate(player, "commands.help.tip_need_no_permission"));
|
||||
} else {
|
||||
if (!annotation.permission().isEmpty()) {
|
||||
builder.append(annotation.permission());
|
||||
} else {
|
||||
builder.append(translate(player, "commands.help.tip_need_no_permission"));
|
||||
}
|
||||
|
||||
if(!annotation.permissionTargeted().isEmpty() && !annotation.permissionTargeted().isBlank()) {
|
||||
if (!annotation.permissionTargeted().isEmpty()) {
|
||||
String permissionTargeted = annotation.permissionTargeted();
|
||||
builder.append(" ").append(translate(player, "commands.help.tip_permission_targeted", permissionTargeted));
|
||||
}
|
||||
return builder.toString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player player, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1) {
|
||||
HashMap<String, CommandHandler> handlers = CommandMap.getInstance().getHandlers();
|
||||
List<Command> annotations = new ArrayList<>();
|
||||
Account account = (player == null) ? null : player.getAccount();
|
||||
Map<String, CommandHandler> handlers = CommandMap.getInstance().getHandlers();
|
||||
List<String> commands = new ArrayList<>();
|
||||
List<String> commands_no_permission = new ArrayList<>();
|
||||
if (args.isEmpty()) {
|
||||
for (String key : handlers.keySet()) {
|
||||
Command annotation = handlers.get(key).getClass().getAnnotation(Command.class);
|
||||
|
||||
if (!Arrays.asList(annotation.aliases()).contains(key)) {
|
||||
if (player != null && !Objects.equals(annotation.permission(), "") && !player.getAccount().hasPermission(annotation.permission()))
|
||||
continue;
|
||||
annotations.add(annotation);
|
||||
CommandHandler command = handlers.get(key);
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
if (player == null || account.hasPermission(annotation.permission())) {
|
||||
commands.add(createCommand(player, command, args));
|
||||
} else if (SHOW_COMMANDS_WITHOUT_PERMISSIONS) {
|
||||
commands_no_permission.add(createCommand(player, command, args));
|
||||
}
|
||||
}
|
||||
|
||||
SendAllHelpMessage(player, annotations);
|
||||
CommandHandler.sendTranslatedMessage(player, "commands.help.available_commands");
|
||||
} else {
|
||||
String command = args.get(0);
|
||||
CommandHandler handler = CommandMap.getInstance().getHandler(command);
|
||||
StringBuilder builder = new StringBuilder("");
|
||||
if (handler == null) {
|
||||
builder.append(translate(player, "commands.generic.command_exist_error"));
|
||||
String command_str = args.remove(0).toLowerCase();
|
||||
CommandHandler command = handlers.get(command_str);
|
||||
if (command == null) {
|
||||
CommandHandler.sendTranslatedMessage(player, "commands.generic.command_exist_error");
|
||||
return;
|
||||
} else {
|
||||
Command annotation = handler.getClass().getAnnotation(Command.class);
|
||||
|
||||
this.createCommand(builder, player, annotation);
|
||||
|
||||
if (player != null && !Objects.equals(annotation.permission(), "") && !player.getAccount().hasPermission(annotation.permission())) {
|
||||
builder.append("\n\t").append(translate(player, "commands.help.warn_player_has_no_permission"));
|
||||
Command annotation = command.getClass().getAnnotation(Command.class);
|
||||
if (player == null || account.hasPermission(annotation.permission())) {
|
||||
commands.add(createCommand(player, command, args));
|
||||
} else {
|
||||
commands_no_permission.add(createCommand(player, command, args));
|
||||
}
|
||||
}
|
||||
|
||||
CommandHandler.sendMessage(player, builder.toString());
|
||||
}
|
||||
}
|
||||
|
||||
void SendAllHelpMessage(Player player, List<Command> annotations) {
|
||||
StringBuilder builder = new StringBuilder(translate(player, "commands.help.available_commands"));
|
||||
annotations.forEach(annotation -> {
|
||||
this.createCommand(builder, player, annotation);
|
||||
builder.append("\n");
|
||||
});
|
||||
|
||||
CommandHandler.sendMessage(player, builder.toString());
|
||||
for (String s : commands)
|
||||
CommandHandler.sendMessage(player, s);
|
||||
for (String s : commands_no_permission)
|
||||
CommandHandler.sendMessage(player, s + "\n\t" + translate(player, "commands.help.warn_player_has_no_permission"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,19 +6,18 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "kick", usage = "kick", aliases = {"restart"}, permissionTargeted = "server.kick", description = "commands.kick.description")
|
||||
@Command(label = "kick", aliases = {"restart"}, permissionTargeted = "server.kick")
|
||||
public final class KickCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (sender != null) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.kick.player_kick_player",
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.kick.player_kick_player",
|
||||
Integer.toString(sender.getUid()), sender.getAccount().getUsername(),
|
||||
Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
||||
Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername());
|
||||
} else {
|
||||
CommandHandler.sendMessage(null, translate(sender, "commands.kick.server_kick_player", Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername()));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.kick.server_kick_player",
|
||||
Integer.toString(targetPlayer.getUid()), targetPlayer.getAccount().getUsername());
|
||||
}
|
||||
|
||||
targetPlayer.getSession().close();
|
||||
|
||||
@@ -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.EntityMonster;
|
||||
@@ -12,7 +11,7 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "killall", usage = "killall [sceneId]", permission = "server.killall", permissionTargeted = "server.killall.others", description = "commands.killall.description")
|
||||
@Command(label = "killall", usage = {"[<sceneId>]"}, permission = "server.killall", permissionTargeted = "server.killall.others")
|
||||
public final class KillAllCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -26,7 +25,7 @@ public final class KillAllCommand implements CommandHandler {
|
||||
scene = targetPlayer.getWorld().getSceneById(Integer.parseInt(args.get(0)));
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.killall.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
} catch (NumberFormatException ignored) {
|
||||
|
||||
@@ -13,16 +13,11 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "killcharacter", usage = "killcharacter", aliases = {"suicide", "kill"}, permission = "player.killcharacter", permissionTargeted = "player.killcharacter.others", description = "commands.killCharacter.description")
|
||||
@Command(label = "killCharacter", aliases = {"suicide", "kill"}, permission = "player.killcharacter", permissionTargeted = "player.killcharacter.others")
|
||||
public final class KillCharacterCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.killCharacter.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
EntityAvatar entity = targetPlayer.getTeamManager().getCurrentAvatarEntity();
|
||||
entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, 0f);
|
||||
// Packets
|
||||
|
||||
@@ -3,8 +3,6 @@ package emu.grasscutter.command.commands;
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.database.DatabaseHelper;
|
||||
import emu.grasscutter.game.Account;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.utils.Utils;
|
||||
|
||||
@@ -13,7 +11,7 @@ import java.util.Locale;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "language", usage = "language [language code]", description = "commands.language.description", aliases = {"lang"}, targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(label = "language", usage = {"[<language code>]"}, aliases = {"lang"}, targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class LanguageCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -10,7 +10,7 @@ import java.util.Map;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "list", usage = "list [uid]", aliases = {"players"}, description = "commands.list.description", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(label = "list", aliases = {"players"}, usage = {"[<UID>]"}, targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class ListCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -11,13 +11,13 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "permission", usage = "permission <add|remove> <permission>", permission = "permission", description = "commands.permission.description", targetRequirement = TargetRequirement.PLAYER)
|
||||
@Command(label = "permission", usage = "(add|remove) <permission>", permission = "permission", targetRequirement = TargetRequirement.PLAYER)
|
||||
public final class PermissionCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() != 2) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.permission.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -37,7 +37,7 @@ public final class PermissionCommand implements CommandHandler {
|
||||
|
||||
switch (action) {
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.permission.usage"));
|
||||
sendUsageMessage(sender);
|
||||
break;
|
||||
case "add":
|
||||
if (account.addPermission(permission)) {
|
||||
|
||||
@@ -7,16 +7,14 @@ import emu.grasscutter.utils.Position;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "position", usage = "position", aliases = {"pos"}, description = "commands.position.description")
|
||||
@Command(label = "position", aliases = {"pos"})
|
||||
public final class PositionCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
Position pos = targetPlayer.getPos();
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.position.success",
|
||||
Position pos = targetPlayer.getPosition();
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.position.success",
|
||||
Float.toString(pos.getX()), Float.toString(pos.getY()), Float.toString(pos.getZ()),
|
||||
Integer.toString(targetPlayer.getSceneId())));
|
||||
Integer.toString(targetPlayer.getSceneId()));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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,13 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "quest", usage = "quest <add|finish> [questId]", permission = "player.quest", permissionTargeted = "player.quest.others", description = "commands.quest.description")
|
||||
@Command(label = "quest", usage = {"(add|finish) [<questId>]"}, permission = "player.quest", permissionTargeted = "player.quest.others")
|
||||
public final class QuestCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() != 2) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -54,7 +53,7 @@ public final class QuestCommand implements CommandHandler {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.finished", questId));
|
||||
}
|
||||
default -> {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.quest.usage"));
|
||||
sendUsageMessage(sender);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,19 +9,19 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "reload", usage = "reload", permission = "server.reload", description = "commands.reload.description", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(label = "reload", permission = "server.reload", targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class ReloadCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.reload.reload_start"));
|
||||
|
||||
|
||||
Grasscutter.loadConfig();
|
||||
Grasscutter.loadLanguage();
|
||||
Grasscutter.getGameServer().getGachaManager().load();
|
||||
Grasscutter.getGameServer().getDropManager().load();
|
||||
Grasscutter.getGameServer().getShopManager().load();
|
||||
|
||||
Grasscutter.getGameServer().getGachaSystem().load();
|
||||
Grasscutter.getGameServer().getDropSystem().load();
|
||||
Grasscutter.getGameServer().getShopSystem().load();
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.reload.reload_done"));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,8 +10,12 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "resetconst", usage = "resetconst [all]",
|
||||
aliases = {"resetconstellation"}, permission = "player.resetconstellation", permissionTargeted = "player.resetconstellation.others", description = "commands.resetConst.description")
|
||||
@Command(
|
||||
label = "resetConst",
|
||||
aliases = {"resetconstellation"},
|
||||
usage = "[all]",
|
||||
permission = "player.resetconstellation",
|
||||
permissionTargeted = "player.resetconstellation.others")
|
||||
public final class ResetConstCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -9,16 +9,11 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "resetshop", usage = "resetshop", permission = "server.resetshop", permissionTargeted = "server.resetshop.others", description = "commands.resetShopLimit.description")
|
||||
@Command(label = "resetShopLimit", aliases = {"resetshop"}, permission = "server.resetshop", permissionTargeted = "server.resetshop.others")
|
||||
public final class ResetShopLimitCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.resetShopLimit.usage"));
|
||||
return;
|
||||
}
|
||||
|
||||
targetPlayer.getShopLimit().forEach(x -> x.setNextRefreshTime(0));
|
||||
targetPlayer.save();
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.resetShopLimit.success"));
|
||||
|
||||
@@ -13,7 +13,11 @@ import java.util.List;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@SuppressWarnings("ConstantConditions")
|
||||
@Command(label = "sendmail", usage = "sendmail <userId|all|help> [templateId]", permission = "server.sendmail", description = "commands.sendMail.description", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "sendMail",
|
||||
usage = {"(<userId>|all) [<templateId>]", "help"},
|
||||
permission = "server.sendmail",
|
||||
targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class SendMailCommand implements CommandHandler {
|
||||
|
||||
// TODO: You should be able to do /sendmail and then just send subsequent messages until you finish
|
||||
@@ -27,7 +31,7 @@ public final class SendMailCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
int senderId;
|
||||
if(sender != null) {
|
||||
if (sender != null) {
|
||||
senderId = sender.getUid();
|
||||
} else {
|
||||
senderId = -1;
|
||||
@@ -39,7 +43,7 @@ public final class SendMailCommand implements CommandHandler {
|
||||
MailBuilder mailBuilder;
|
||||
switch (args.get(0).toLowerCase()) {
|
||||
case "help" -> {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMail.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
case "all" -> mailBuilder = new MailBuilder(true, new Mail());
|
||||
@@ -146,7 +150,7 @@ public final class SendMailCommand implements CommandHandler {
|
||||
}
|
||||
break;
|
||||
default: // *No args*
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.give.usage"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.sendMail.give_usage");
|
||||
return;
|
||||
}
|
||||
mailBuilder.mail.itemList.add(new Mail.MailItem(item, amount, lvl));
|
||||
@@ -162,7 +166,7 @@ public final class SendMailCommand implements CommandHandler {
|
||||
}
|
||||
|
||||
private String getConstructionArgs(int stage, Player sender) {
|
||||
return switch(stage) {
|
||||
return switch (stage) {
|
||||
case 0 -> translate(sender, "commands.sendMail.title");
|
||||
case 1 -> translate(sender, "commands.sendMail.message");
|
||||
case 2 -> translate(sender, "commands.sendMail.sender");
|
||||
|
||||
@@ -8,16 +8,19 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "sendmessage", usage = "sendmessage <message>",
|
||||
aliases = {"say", "sendservmsg", "sendservermessage", "b", "broadcast"}, permission = "server.sendmessage", permissionTargeted = "server.sendmessage.others", description = "commands.sendMessage.description", targetRequirement = TargetRequirement.NONE)
|
||||
@Command(
|
||||
label = "sendMessage",
|
||||
aliases = {"say", "sendservmsg", "sendservermessage", "b", "broadcast"},
|
||||
usage = {"<message>"},
|
||||
permission = "server.sendmessage",
|
||||
permissionTargeted = "server.sendmessage.others",
|
||||
targetRequirement = TargetRequirement.NONE)
|
||||
public final class SendMessageCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() == 0) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMessage.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -30,6 +33,6 @@ public final class SendMessageCommand implements CommandHandler {
|
||||
} else {
|
||||
CommandHandler.sendMessage(targetPlayer, message);
|
||||
}
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.sendMessage.success"));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.sendMessage.success");
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,14 +11,18 @@ import emu.grasscutter.server.packet.send.PacketAvatarFetterDataNotify;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "setfetterlevel", usage = "setfetterlevel <level>",
|
||||
aliases = {"setfetterlvl", "setfriendship"}, permission = "player.setfetterlevel", permissionTargeted = "player.setfetterlevel.others", description = "commands.setFetterLevel.description")
|
||||
@Command(
|
||||
label = "setFetterLevel",
|
||||
usage = {"<level>"},
|
||||
aliases = {"setfetterlvl", "setfriendship"},
|
||||
permission = "player.setfetterlevel",
|
||||
permissionTargeted = "player.setfetterlevel.others")
|
||||
public final class SetFetterLevelCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() != 1) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.setFetterLevel.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,205 +1,205 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.tower.TowerLevelRecord;
|
||||
|
||||
@Command(label = "setprop", usage = "setprop|prop <prop> <value>", aliases = {"prop"}, permission = "player.setprop", permissionTargeted = "player.setprop.others", description = "commands.setProp.description")
|
||||
public final class SetPropCommand implements CommandHandler {
|
||||
static enum PseudoProp {
|
||||
NONE,
|
||||
WORLD_LEVEL,
|
||||
TOWER_LEVEL,
|
||||
BP_LEVEL,
|
||||
GOD_MODE,
|
||||
NO_STAMINA,
|
||||
UNLIMITED_ENERGY
|
||||
}
|
||||
|
||||
static class Prop {
|
||||
String name;
|
||||
PlayerProperty prop;
|
||||
PseudoProp pseudoProp;
|
||||
|
||||
public Prop(PlayerProperty prop) {
|
||||
this(prop.toString(), prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name) {
|
||||
this(name, PlayerProperty.PROP_NONE, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PseudoProp pseudoProp) {
|
||||
this(name, PlayerProperty.PROP_NONE, pseudoProp);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop) {
|
||||
this(name, prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop, PseudoProp pseudoProp) {
|
||||
this.name = name;
|
||||
this.prop = prop;
|
||||
this.pseudoProp = pseudoProp;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Prop> props;
|
||||
|
||||
public SetPropCommand() {
|
||||
this.props = new HashMap<>();
|
||||
// Full PlayerProperty enum that won't be advertised but can be used by devs
|
||||
for (PlayerProperty prop : PlayerProperty.values()) {
|
||||
String name = prop.toString().substring(5); // PROP_EXP -> EXP
|
||||
String key = name.toLowerCase(); // EXP -> exp
|
||||
this.props.put(key, new Prop(name, prop));
|
||||
}
|
||||
// Add special props
|
||||
Prop worldlevel = new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL);
|
||||
this.props.put("worldlevel", worldlevel);
|
||||
this.props.put("wl", worldlevel);
|
||||
|
||||
Prop abyss = new Prop("Tower Level", PseudoProp.TOWER_LEVEL);
|
||||
this.props.put("abyss", abyss);
|
||||
this.props.put("abyssfloor", abyss);
|
||||
this.props.put("ut", abyss);
|
||||
this.props.put("tower", abyss);
|
||||
this.props.put("towerlevel", abyss);
|
||||
this.props.put("unlocktower", abyss);
|
||||
|
||||
Prop bplevel = new Prop("BP Level", PseudoProp.BP_LEVEL);
|
||||
this.props.put("bplevel", bplevel);
|
||||
this.props.put("bp", bplevel);
|
||||
this.props.put("battlepass", bplevel);
|
||||
|
||||
Prop godmode = new Prop("godmode", PseudoProp.GOD_MODE);
|
||||
this.props.put("godmode", godmode);
|
||||
this.props.put("god", godmode);
|
||||
|
||||
Prop nostamina = new Prop("nostamina", PseudoProp.NO_STAMINA);
|
||||
this.props.put("nostamina", nostamina);
|
||||
this.props.put("nostam", nostamina);
|
||||
this.props.put("ns", nostamina);
|
||||
|
||||
Prop unlimitedenergy = new Prop("unlimitedenergy", PseudoProp.UNLIMITED_ENERGY);
|
||||
this.props.put("unlimitedenergy", unlimitedenergy);
|
||||
this.props.put("ue", unlimitedenergy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() != 2) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setProp.usage");
|
||||
return;
|
||||
}
|
||||
String propStr = args.get(0).toLowerCase();
|
||||
String valueStr = args.get(1).toLowerCase();
|
||||
int value;
|
||||
|
||||
if (!props.containsKey(propStr)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setProp.usage");
|
||||
return;
|
||||
}
|
||||
try {
|
||||
value = switch(valueStr.toLowerCase()) {
|
||||
case "on", "true" -> 1;
|
||||
case "off", "false" -> 0;
|
||||
case "toggle" -> -1;
|
||||
default -> Integer.parseInt(valueStr);
|
||||
};
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean success = false;
|
||||
Prop prop = props.get(propStr);
|
||||
|
||||
success = switch (prop.pseudoProp) {
|
||||
case WORLD_LEVEL -> targetPlayer.setWorldLevel(value);
|
||||
case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value);
|
||||
case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value);
|
||||
case GOD_MODE, NO_STAMINA, UNLIMITED_ENERGY -> this.setBool(sender, targetPlayer, prop.pseudoProp, value);
|
||||
default -> targetPlayer.setProperty(prop.prop, value);
|
||||
};
|
||||
|
||||
if (success) {
|
||||
if (targetPlayer == sender) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_to", prop.name, valueStr);
|
||||
} else {
|
||||
String uidStr = targetPlayer.getAccount().getId();
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr);
|
||||
}
|
||||
} else {
|
||||
if (prop.prop != PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages
|
||||
String min = Integer.toString(targetPlayer.getPropertyMin(prop.prop));
|
||||
String max = Integer.toString(targetPlayer.getPropertyMax(prop.prop));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.value_between", prop.name, min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setTowerLevel(Player sender, Player targetPlayer, int topFloor) {
|
||||
List<Integer> floorIds = targetPlayer.getServer().getTowerScheduleManager().getAllFloors();
|
||||
if (topFloor < 0 || topFloor > floorIds.size()) {
|
||||
String min = Integer.toString(0);
|
||||
String max = Integer.toString(floorIds.size());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.value_between", "Tower Level", min, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<Integer, TowerLevelRecord> recordMap = targetPlayer.getTowerManager().getRecordMap();
|
||||
// Add records for each unlocked floor
|
||||
for (int floor : floorIds.subList(0, topFloor)) {
|
||||
if (!recordMap.containsKey(floor)) {
|
||||
recordMap.put(floor, new TowerLevelRecord(floor));
|
||||
}
|
||||
}
|
||||
// Remove records for each floor past our target
|
||||
for (int floor : floorIds.subList(topFloor, floorIds.size())) {
|
||||
if (recordMap.containsKey(floor)) {
|
||||
recordMap.remove(floor);
|
||||
}
|
||||
}
|
||||
// Six stars required on Floor 8 to unlock Floor 9+
|
||||
if (topFloor > 8) {
|
||||
recordMap.get(floorIds.get(7)).setLevelStars(0, 6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at all
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setBool(Player sender, Player targetPlayer, PseudoProp pseudoProp, int value) {
|
||||
boolean enabled = switch (pseudoProp) {
|
||||
case GOD_MODE -> targetPlayer.inGodmode();
|
||||
case NO_STAMINA -> targetPlayer.getUnlimitedStamina();
|
||||
case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().getEnergyUsage();
|
||||
default -> false;
|
||||
};
|
||||
enabled = switch (value) {
|
||||
case -1 -> !enabled;
|
||||
case 0 -> false;
|
||||
default -> true;
|
||||
};
|
||||
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE:
|
||||
targetPlayer.setGodmode(enabled);
|
||||
break;
|
||||
case NO_STAMINA:
|
||||
targetPlayer.setUnlimitedStamina(enabled);
|
||||
break;
|
||||
case UNLIMITED_ENERGY:
|
||||
targetPlayer.getEnergyManager().setEnergyUsage(!enabled);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.PlayerProperty;
|
||||
import emu.grasscutter.game.tower.TowerLevelRecord;
|
||||
|
||||
@Command(label = "setProp", aliases = {"prop"}, usage = {"<prop> <value>"}, permission = "player.setprop", permissionTargeted = "player.setprop.others")
|
||||
public final class SetPropCommand implements CommandHandler {
|
||||
static enum PseudoProp {
|
||||
NONE,
|
||||
WORLD_LEVEL,
|
||||
TOWER_LEVEL,
|
||||
BP_LEVEL,
|
||||
GOD_MODE,
|
||||
NO_STAMINA,
|
||||
UNLIMITED_ENERGY
|
||||
}
|
||||
|
||||
static class Prop {
|
||||
String name;
|
||||
PlayerProperty prop;
|
||||
PseudoProp pseudoProp;
|
||||
|
||||
public Prop(PlayerProperty prop) {
|
||||
this(prop.toString(), prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name) {
|
||||
this(name, PlayerProperty.PROP_NONE, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PseudoProp pseudoProp) {
|
||||
this(name, PlayerProperty.PROP_NONE, pseudoProp);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop) {
|
||||
this(name, prop, PseudoProp.NONE);
|
||||
}
|
||||
|
||||
public Prop(String name, PlayerProperty prop, PseudoProp pseudoProp) {
|
||||
this.name = name;
|
||||
this.prop = prop;
|
||||
this.pseudoProp = pseudoProp;
|
||||
}
|
||||
}
|
||||
|
||||
Map<String, Prop> props;
|
||||
|
||||
public SetPropCommand() {
|
||||
this.props = new HashMap<>();
|
||||
// Full PlayerProperty enum that won't be advertised but can be used by devs
|
||||
for (PlayerProperty prop : PlayerProperty.values()) {
|
||||
String name = prop.toString().substring(5); // PROP_EXP -> EXP
|
||||
String key = name.toLowerCase(); // EXP -> exp
|
||||
this.props.put(key, new Prop(name, prop));
|
||||
}
|
||||
// Add special props
|
||||
Prop worldlevel = new Prop("World Level", PlayerProperty.PROP_PLAYER_WORLD_LEVEL, PseudoProp.WORLD_LEVEL);
|
||||
this.props.put("worldlevel", worldlevel);
|
||||
this.props.put("wl", worldlevel);
|
||||
|
||||
Prop abyss = new Prop("Tower Level", PseudoProp.TOWER_LEVEL);
|
||||
this.props.put("abyss", abyss);
|
||||
this.props.put("abyssfloor", abyss);
|
||||
this.props.put("ut", abyss);
|
||||
this.props.put("tower", abyss);
|
||||
this.props.put("towerlevel", abyss);
|
||||
this.props.put("unlocktower", abyss);
|
||||
|
||||
Prop bplevel = new Prop("BP Level", PseudoProp.BP_LEVEL);
|
||||
this.props.put("bplevel", bplevel);
|
||||
this.props.put("bp", bplevel);
|
||||
this.props.put("battlepass", bplevel);
|
||||
|
||||
Prop godmode = new Prop("godmode", PseudoProp.GOD_MODE);
|
||||
this.props.put("godmode", godmode);
|
||||
this.props.put("god", godmode);
|
||||
|
||||
Prop nostamina = new Prop("nostamina", PseudoProp.NO_STAMINA);
|
||||
this.props.put("nostamina", nostamina);
|
||||
this.props.put("nostam", nostamina);
|
||||
this.props.put("ns", nostamina);
|
||||
|
||||
Prop unlimitedenergy = new Prop("unlimitedenergy", PseudoProp.UNLIMITED_ENERGY);
|
||||
this.props.put("unlimitedenergy", unlimitedenergy);
|
||||
this.props.put("ue", unlimitedenergy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() != 2) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
String propStr = args.get(0).toLowerCase();
|
||||
String valueStr = args.get(1).toLowerCase();
|
||||
int value;
|
||||
|
||||
if (!props.containsKey(propStr)) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
value = switch (valueStr.toLowerCase()) {
|
||||
case "on", "true" -> 1;
|
||||
case "off", "false" -> 0;
|
||||
case "toggle" -> -1;
|
||||
default -> Integer.parseInt(valueStr);
|
||||
};
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.execution.argument_error");
|
||||
return;
|
||||
}
|
||||
|
||||
boolean success = false;
|
||||
Prop prop = props.get(propStr);
|
||||
|
||||
success = switch (prop.pseudoProp) {
|
||||
case WORLD_LEVEL -> targetPlayer.setWorldLevel(value);
|
||||
case BP_LEVEL -> targetPlayer.getBattlePassManager().setLevel(value);
|
||||
case TOWER_LEVEL -> this.setTowerLevel(sender, targetPlayer, value);
|
||||
case GOD_MODE, NO_STAMINA, UNLIMITED_ENERGY -> this.setBool(sender, targetPlayer, prop.pseudoProp, value);
|
||||
default -> targetPlayer.setProperty(prop.prop, value);
|
||||
};
|
||||
|
||||
if (success) {
|
||||
if (targetPlayer == sender) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_to", prop.name, valueStr);
|
||||
} else {
|
||||
String uidStr = targetPlayer.getAccount().getId();
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_for_to", prop.name, uidStr, valueStr);
|
||||
}
|
||||
} else {
|
||||
if (prop.prop != PlayerProperty.PROP_NONE) { // PseudoProps need to do their own error messages
|
||||
String min = Integer.toString(targetPlayer.getPropertyMin(prop.prop));
|
||||
String max = Integer.toString(targetPlayer.getPropertyMax(prop.prop));
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.value_between", prop.name, min, max);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private boolean setTowerLevel(Player sender, Player targetPlayer, int topFloor) {
|
||||
List<Integer> floorIds = targetPlayer.getServer().getTowerSystem().getAllFloors();
|
||||
if (topFloor < 0 || topFloor > floorIds.size()) {
|
||||
String min = Integer.toString(0);
|
||||
String max = Integer.toString(floorIds.size());
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.value_between", "Tower Level", min, max);
|
||||
return false;
|
||||
}
|
||||
|
||||
Map<Integer, TowerLevelRecord> recordMap = targetPlayer.getTowerManager().getRecordMap();
|
||||
// Add records for each unlocked floor
|
||||
for (int floor : floorIds.subList(0, topFloor)) {
|
||||
if (!recordMap.containsKey(floor)) {
|
||||
recordMap.put(floor, new TowerLevelRecord(floor));
|
||||
}
|
||||
}
|
||||
// Remove records for each floor past our target
|
||||
for (int floor : floorIds.subList(topFloor, floorIds.size())) {
|
||||
if (recordMap.containsKey(floor)) {
|
||||
recordMap.remove(floor);
|
||||
}
|
||||
}
|
||||
// Six stars required on Floor 8 to unlock Floor 9+
|
||||
if (topFloor > 8) {
|
||||
recordMap.get(floorIds.get(7)).setLevelStars(0, 6); // levelIds seem to start at 1 for Floor 1 Chamber 1, so this doesn't get shown at all
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setBool(Player sender, Player targetPlayer, PseudoProp pseudoProp, int value) {
|
||||
boolean enabled = switch (pseudoProp) {
|
||||
case GOD_MODE -> targetPlayer.inGodmode();
|
||||
case NO_STAMINA -> targetPlayer.getUnlimitedStamina();
|
||||
case UNLIMITED_ENERGY -> !targetPlayer.getEnergyManager().getEnergyUsage();
|
||||
default -> false;
|
||||
};
|
||||
enabled = switch (value) {
|
||||
case -1 -> !enabled;
|
||||
case 0 -> false;
|
||||
default -> true;
|
||||
};
|
||||
|
||||
switch (pseudoProp) {
|
||||
case GOD_MODE:
|
||||
targetPlayer.setGodmode(enabled);
|
||||
break;
|
||||
case NO_STAMINA:
|
||||
targetPlayer.setUnlimitedStamina(enabled);
|
||||
break;
|
||||
case UNLIMITED_ENERGY:
|
||||
targetPlayer.getEnergyManager().setEnergyUsage(!enabled);
|
||||
break;
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,7 +11,7 @@ import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
|
||||
|
||||
@Command(label = "setstats", usage = "setstats|stats <stat> <value>", aliases = {"stats"}, permission = "player.setstats", permissionTargeted = "player.setstats.others", description = "commands.setStats.description")
|
||||
@Command(label = "setStats", aliases = {"stats", "stat"}, usage = {"<stat> <value>"}, permission = "player.setstats", permissionTargeted = "player.setstats.others")
|
||||
public final class SetStatsCommand implements CommandHandler {
|
||||
static class Stat {
|
||||
String name;
|
||||
@@ -71,7 +71,7 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
statStr = args.get(0).toLowerCase();
|
||||
valueStr = args.get(1);
|
||||
} else {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setStats.usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -105,7 +105,7 @@ public final class SetStatsCommand implements CommandHandler {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.set_for_to", stat.name, uidStr, valueStr);
|
||||
}
|
||||
} else {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.setStats.usage");
|
||||
sendUsageMessage(sender);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -1,29 +1,28 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.Grasscutter;
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.data.GameData;
|
||||
import emu.grasscutter.data.excels.AvatarData;
|
||||
import emu.grasscutter.data.excels.GadgetData;
|
||||
import emu.grasscutter.data.excels.ItemData;
|
||||
import emu.grasscutter.data.excels.MonsterData;
|
||||
import emu.grasscutter.game.avatar.Avatar;
|
||||
import emu.grasscutter.game.entity.*;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.EntityType;
|
||||
import emu.grasscutter.game.props.FightProperty;
|
||||
import emu.grasscutter.utils.Position;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
|
||||
import javax.swing.text.html.parser.Entity;
|
||||
import java.util.List;
|
||||
import java.util.Random;
|
||||
|
||||
import static emu.grasscutter.Configuration.*;
|
||||
import static emu.grasscutter.config.Configuration.*;
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "spawn", usage = "spawn <entityId> [amount] [level(monster only)] [<x> <y> <z>(monster only, optional)]", aliases = {"drop"}, permission = "server.spawn", permissionTargeted = "server.spawn.others", description = "commands.spawn.description")
|
||||
@Command(
|
||||
label = "spawn",
|
||||
usage = {"spawn <entityId> [amount] [level(monster only)] [<x> <y> <z>(monster only)]"},
|
||||
aliases = {"drop"},
|
||||
permission = "server.spawn",
|
||||
permissionTargeted = "server.spawn.others")
|
||||
public final class SpawnCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -31,7 +30,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
int id = 0; // This is just to shut up the linter, it's not a real default
|
||||
int amount = 1;
|
||||
int level = 1;
|
||||
float x = 0, y = 0, z = 0;
|
||||
float x = 0, y = 0, z = 0;
|
||||
switch (args.size()) {
|
||||
case 6:
|
||||
try {
|
||||
@@ -61,10 +60,10 @@ public final class SpawnCommand implements CommandHandler {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
MonsterData monsterData = GameData.getMonsterDataMap().get(id);
|
||||
GadgetData gadgetData = GameData.getGadgetDataMap().get(id);
|
||||
ItemData itemData = GameData.getItemDataMap().get(id);
|
||||
@@ -72,21 +71,21 @@ public final class SpawnCommand implements CommandHandler {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.generic.invalid.entityId"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
Scene scene = targetPlayer.getScene();
|
||||
|
||||
|
||||
if (scene.getEntities().size() + amount > GAME_OPTIONS.sceneEntityLimit) {
|
||||
amount = Math.max(Math.min(GAME_OPTIONS.sceneEntityLimit - scene.getEntities().size(), amount), 0);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.limit_reached", amount));
|
||||
if (amount <= 0) {
|
||||
return;
|
||||
}
|
||||
amount = Math.max(Math.min(GAME_OPTIONS.sceneEntityLimit - scene.getEntities().size(), amount), 0);
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.limit_reached", amount));
|
||||
if (amount <= 0) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
double maxRadius = Math.sqrt(amount * 0.2 / Math.PI);
|
||||
for (int i = 0; i < amount; i++) {
|
||||
Position pos = GetRandomPositionInCircle(targetPlayer.getPos(), maxRadius).addY(3);
|
||||
if(x != 0 && y != 0 && z != 0) {
|
||||
Position pos = GetRandomPositionInCircle(targetPlayer.getPosition(), maxRadius).addY(3);
|
||||
if (x != 0 && y != 0 && z != 0) {
|
||||
pos = GetRandomPositionInCircle(new Position(x, y, z), maxRadius).addY(3);
|
||||
}
|
||||
GameEntity entity = null;
|
||||
@@ -120,7 +119,7 @@ public final class SpawnCommand implements CommandHandler {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.spawn.success", Integer.toString(amount), Integer.toString(id)));
|
||||
}
|
||||
|
||||
private Position GetRandomPositionInCircle(Position origin, double radius){
|
||||
private Position GetRandomPositionInCircle(Position origin, double radius) {
|
||||
Position target = origin.clone();
|
||||
double angle = Math.random() * 360;
|
||||
double r = Math.sqrt(Math.random() * radius * radius);
|
||||
|
||||
@@ -9,7 +9,7 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "stop", usage = "stop", permission = "server.stop", description = "commands.stop.description", targetRequirement = Command.TargetRequirement.NONE)
|
||||
@Command(label = "stop", permission = "server.stop", targetRequirement = Command.TargetRequirement.NONE)
|
||||
public final class StopCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
|
||||
@@ -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.data.excels.AvatarSkillDepotData;
|
||||
@@ -14,7 +13,11 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "talent", usage = "talent <talentId> <value>", permission = "player.settalent", permissionTargeted = "player.settalent.others", description = "commands.talent.description")
|
||||
@Command(
|
||||
label = "talent",
|
||||
usage = {"set <talentId> <level>", "(n|e|q) <level>", "getid"},
|
||||
permission = "player.settalent",
|
||||
permissionTargeted = "player.settalent.others")
|
||||
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);
|
||||
@@ -46,9 +49,7 @@ public final class TalentCommand implements CommandHandler {
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 1){
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_1"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_2"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_3"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -57,15 +58,13 @@ public final class TalentCommand implements CommandHandler {
|
||||
String cmdSwitch = args.get(0);
|
||||
switch (cmdSwitch) {
|
||||
default -> {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_1"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_2"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_3"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
case "set" -> {
|
||||
if (args.size() < 3) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_1"));
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_3"));
|
||||
sendUsageMessage(sender);
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
try {
|
||||
@@ -79,7 +78,7 @@ public final class TalentCommand implements CommandHandler {
|
||||
}
|
||||
case "n", "e", "q" -> {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.talent.usage_2"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
AvatarSkillDepotData SkillDepot = avatar.getData().getSkillDepot();
|
||||
|
||||
@@ -1,254 +1,259 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
import static emu.grasscutter.Configuration.*;
|
||||
|
||||
@Command(label = "team", usage = "team <add|remove|set> [avatarId,...] [index|first|last|index-index,...]",
|
||||
permission = "player.team", permissionTargeted = "player.team.others", description = "commands.team.description")
|
||||
public final class TeamCommand implements CommandHandler {
|
||||
private static final int BASE_AVATARID = 10000000;
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.usage");
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args.get(0)) {
|
||||
case "add":
|
||||
if (!addCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
case "remove":
|
||||
if (!removeCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
case "set":
|
||||
if (!setCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
default:
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.usage");
|
||||
return;
|
||||
}
|
||||
|
||||
targetPlayer.getTeamManager().updateTeamEntities(
|
||||
new PacketChangeMpTeamAvatarRsp(targetPlayer, targetPlayer.getTeamManager().getCurrentTeamInfo()));
|
||||
}
|
||||
|
||||
private boolean addCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.add_usage");
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
if (args.size() > 2) {
|
||||
try {
|
||||
index = Integer.parseInt(args.get(2)) - 1;
|
||||
if (index < 0) index = 0;
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_index");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var avatarIds = args.get(1).split(",");
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
|
||||
if (currentTeamAvatars.size() + avatarIds.length > GAME_OPTIONS.avatarLimits.singlePlayerTeam) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.add_too_much", GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var avatarId: avatarIds) {
|
||||
int id = Integer.parseInt(avatarId);
|
||||
var success = addAvatar(sender, targetPlayer, id, index);
|
||||
if (index > 0) ++index;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean removeCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.remove_usage");
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
var avatarCount = currentTeamAvatars.size();
|
||||
|
||||
var metaIndexList = args.get(1).split(",");
|
||||
var indexes = new HashSet<Integer>();
|
||||
var ignoreList = new ArrayList<Integer>();
|
||||
for (var metaIndex: metaIndexList) {
|
||||
// step 1: parse metaIndex to indexes
|
||||
var subIndexes = transformToIndexes(metaIndex, avatarCount);
|
||||
if (subIndexes == null) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", metaIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// step 2: get all of the avatar id through indexes
|
||||
for (var avatarIndex: subIndexes) {
|
||||
try {
|
||||
indexes.add(currentTeamAvatars.get(avatarIndex - 1));
|
||||
} catch (Exception e) {
|
||||
ignoreList.add(avatarIndex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// step 3: check if user remove all of the avatar
|
||||
if (indexes.size() >= avatarCount) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.remove_too_much");
|
||||
return false;
|
||||
}
|
||||
|
||||
// step 4: hint user for ignore index
|
||||
if (!ignoreList.isEmpty()) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.ignore_index", ignoreList);
|
||||
}
|
||||
|
||||
// step 5: remove
|
||||
currentTeamAvatars.removeAll(indexes);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 3) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.set_usage");
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
|
||||
int index;
|
||||
try {
|
||||
index = Integer.parseInt(args.get(1)) - 1;
|
||||
if (index < 0) index = 0;
|
||||
} catch(Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index + 1 > currentTeamAvatars.size()) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.index_out_of_range");
|
||||
return false;
|
||||
}
|
||||
|
||||
int avatarId;
|
||||
try {
|
||||
avatarId = Integer.parseInt(args.get(2));
|
||||
} catch(Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_parse_avatar_id", args.get(2));
|
||||
return false;
|
||||
}
|
||||
if (avatarId < BASE_AVATARID) {
|
||||
avatarId += BASE_AVATARID;
|
||||
}
|
||||
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!targetPlayer.getAvatars().hasAvatar(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_not_found", avatarId);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentTeamAvatars.set(index, avatarId);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean addAvatar(Player sender, Player targetPlayer, int avatarId, int index) {
|
||||
if (avatarId < BASE_AVATARID) {
|
||||
avatarId += BASE_AVATARID;
|
||||
}
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
if (!targetPlayer.getAvatars().hasAvatar(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_not_found", avatarId);
|
||||
return false;
|
||||
}
|
||||
if (index < 0) {
|
||||
currentTeamAvatars.add(avatarId);
|
||||
} else {
|
||||
currentTeamAvatars.add(index, avatarId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<Integer> transformToIndexes(String metaIndexes, int listLength) {
|
||||
// step 1: check if metaIndexes is a special constants
|
||||
if (metaIndexes.equals("first")) {
|
||||
return List.of(1);
|
||||
} else if (metaIndexes.equals("last")) {
|
||||
return List.of(listLength);
|
||||
}
|
||||
|
||||
// step 2: check if metaIndexes is a range
|
||||
if (metaIndexes.contains("-")) {
|
||||
var range = metaIndexes.split("-");
|
||||
if (range.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int min, max;
|
||||
try {
|
||||
min = switch (range[0]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[0]);
|
||||
};
|
||||
|
||||
max = switch (range[1]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[1]);
|
||||
};
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (min > max) {
|
||||
min ^= max;
|
||||
max ^= min;
|
||||
min ^= max;
|
||||
}
|
||||
|
||||
var indexes = new ArrayList<Integer>();
|
||||
for (int i = min; i <= max; ++i) {
|
||||
indexes.add(i);
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
// step 3: index is a value, simply return
|
||||
try {
|
||||
int index = Integer.parseInt(metaIndexes);
|
||||
return List.of(index);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.server.packet.send.PacketChangeMpTeamAvatarRsp;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import static emu.grasscutter.config.Configuration.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
|
||||
@Command(
|
||||
label = "team",
|
||||
usage = {"add <avatarId,...>", "(remove|set) [index|first|last|index-index,...]"},
|
||||
permission = "player.team",
|
||||
permissionTargeted = "player.team.others")
|
||||
public final class TeamCommand implements CommandHandler {
|
||||
private static final int BASE_AVATARID = 10000000;
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.isEmpty()) {
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
switch (args.get(0)) {
|
||||
case "add":
|
||||
if (!addCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
case "remove":
|
||||
if (!removeCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
case "set":
|
||||
if (!setCommand(sender, targetPlayer, args)) return;
|
||||
break;
|
||||
|
||||
default:
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
targetPlayer.getTeamManager().updateTeamEntities(
|
||||
new PacketChangeMpTeamAvatarRsp(targetPlayer, targetPlayer.getTeamManager().getCurrentTeamInfo()));
|
||||
}
|
||||
|
||||
private boolean addCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
sendUsageMessage(sender);
|
||||
return false;
|
||||
}
|
||||
|
||||
int index = -1;
|
||||
if (args.size() > 2) {
|
||||
try {
|
||||
index = Integer.parseInt(args.get(2)) - 1;
|
||||
if (index < 0) index = 0;
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_index");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
var avatarIds = args.get(1).split(",");
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
|
||||
if (currentTeamAvatars.size() + avatarIds.length > GAME_OPTIONS.avatarLimits.singlePlayerTeam) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.add_too_much", GAME_OPTIONS.avatarLimits.singlePlayerTeam);
|
||||
return false;
|
||||
}
|
||||
|
||||
for (var avatarId: avatarIds) {
|
||||
int id = Integer.parseInt(avatarId);
|
||||
if (!addAvatar(sender, targetPlayer, id, index))
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_add_avatar", avatarId);
|
||||
if (index > 0) ++index;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean removeCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 2) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
sendUsageMessage(sender);
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
var avatarCount = currentTeamAvatars.size();
|
||||
|
||||
var metaIndexList = args.get(1).split(",");
|
||||
var indexes = new HashSet<Integer>();
|
||||
var ignoreList = new ArrayList<Integer>();
|
||||
for (var metaIndex: metaIndexList) {
|
||||
// step 1: parse metaIndex to indexes
|
||||
var subIndexes = transformToIndexes(metaIndex, avatarCount);
|
||||
if (subIndexes == null) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", metaIndex);
|
||||
continue;
|
||||
}
|
||||
|
||||
// step 2: get all of the avatar id through indexes
|
||||
for (var avatarIndex: subIndexes) {
|
||||
try {
|
||||
indexes.add(currentTeamAvatars.get(avatarIndex - 1));
|
||||
} catch (Exception e) {
|
||||
ignoreList.add(avatarIndex);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// step 3: check if user remove all of the avatar
|
||||
if (indexes.size() >= avatarCount) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.remove_too_much");
|
||||
return false;
|
||||
}
|
||||
|
||||
// step 4: hint user for ignore index
|
||||
if (!ignoreList.isEmpty()) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.ignore_index", ignoreList);
|
||||
}
|
||||
|
||||
// step 5: remove
|
||||
currentTeamAvatars.removeAll(indexes);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean setCommand(Player sender, Player targetPlayer, List<String> args) {
|
||||
if (args.size() < 3) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.invalid_usage");
|
||||
sendUsageMessage(sender);
|
||||
return false;
|
||||
}
|
||||
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
|
||||
int index;
|
||||
try {
|
||||
index = Integer.parseInt(args.get(1)) - 1;
|
||||
if (index < 0) index = 0;
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_to_parse_index", args.get(1));
|
||||
return false;
|
||||
}
|
||||
|
||||
if (index + 1 > currentTeamAvatars.size()) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.index_out_of_range");
|
||||
return false;
|
||||
}
|
||||
|
||||
int avatarId;
|
||||
try {
|
||||
avatarId = Integer.parseInt(args.get(2));
|
||||
} catch (Exception e) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.failed_parse_avatar_id", args.get(2));
|
||||
return false;
|
||||
}
|
||||
if (avatarId < BASE_AVATARID) {
|
||||
avatarId += BASE_AVATARID;
|
||||
}
|
||||
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!targetPlayer.getAvatars().hasAvatar(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_not_found", avatarId);
|
||||
return false;
|
||||
}
|
||||
|
||||
currentTeamAvatars.set(index, avatarId);
|
||||
return true;
|
||||
}
|
||||
|
||||
private boolean addAvatar(Player sender, Player targetPlayer, int avatarId, int index) {
|
||||
if (avatarId < BASE_AVATARID) {
|
||||
avatarId += BASE_AVATARID;
|
||||
}
|
||||
var currentTeamAvatars = targetPlayer.getTeamManager().getCurrentTeamInfo().getAvatars();
|
||||
if (currentTeamAvatars.contains(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_already_in_team", avatarId);
|
||||
return false;
|
||||
}
|
||||
if (!targetPlayer.getAvatars().hasAvatar(avatarId)) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.team.avatar_not_found", avatarId);
|
||||
return false;
|
||||
}
|
||||
if (index < 0) {
|
||||
currentTeamAvatars.add(avatarId);
|
||||
} else {
|
||||
currentTeamAvatars.add(index, avatarId);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
private List<Integer> transformToIndexes(String metaIndexes, int listLength) {
|
||||
// step 1: check if metaIndexes is a special constants
|
||||
if (metaIndexes.equals("first")) {
|
||||
return List.of(1);
|
||||
} else if (metaIndexes.equals("last")) {
|
||||
return List.of(listLength);
|
||||
}
|
||||
|
||||
// step 2: check if metaIndexes is a range
|
||||
if (metaIndexes.contains("-")) {
|
||||
var range = metaIndexes.split("-");
|
||||
if (range.length < 2) {
|
||||
return null;
|
||||
}
|
||||
|
||||
int min, max;
|
||||
try {
|
||||
min = switch (range[0]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[0]);
|
||||
};
|
||||
|
||||
max = switch (range[1]) {
|
||||
case "first" -> 1;
|
||||
case "last" -> listLength;
|
||||
default -> Integer.parseInt(range[1]);
|
||||
};
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if (min > max) {
|
||||
min ^= max;
|
||||
max ^= min;
|
||||
min ^= max;
|
||||
}
|
||||
|
||||
var indexes = new ArrayList<Integer>();
|
||||
for (int i = min; i <= max; ++i) {
|
||||
indexes.add(i);
|
||||
}
|
||||
return indexes;
|
||||
}
|
||||
|
||||
// step 3: index is a value, simply return
|
||||
try {
|
||||
int index = Integer.parseInt(metaIndexes);
|
||||
return List.of(index);
|
||||
} catch (Exception e) {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
@@ -11,7 +10,7 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "tpall", usage = "tpall", permission = "player.tpall", permissionTargeted = "player.tpall.others", description = "commands.teleportAll.description")
|
||||
@Command(label = "teleportAll", aliases = {"tpall"}, permission = "player.tpall", permissionTargeted = "player.tpall.others")
|
||||
public final class TeleportAllCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -25,9 +24,9 @@ public final class TeleportAllCommand implements CommandHandler {
|
||||
if (player.equals(targetPlayer))
|
||||
continue;
|
||||
|
||||
Position pos = targetPlayer.getPos();
|
||||
Position pos = targetPlayer.getPosition();
|
||||
PlayerTeleportEvent event = new PlayerTeleportEvent(targetPlayer, PlayerTeleportEvent.TeleportType.COMMAND,
|
||||
targetPlayer.getPos(), pos);
|
||||
targetPlayer.getPosition(), pos);
|
||||
event.call();
|
||||
|
||||
if(!event.isCanceled())
|
||||
|
||||
@@ -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;
|
||||
@@ -11,7 +10,7 @@ import java.util.List;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "teleport", usage = "teleport <x> <y> <z> [sceneId]", aliases = {"tp"}, permission = "player.teleport", permissionTargeted = "player.teleport.others", description = "commands.teleport.description")
|
||||
@Command(label = "teleport", aliases = {"tp"}, usage = {"<x> <y> <z> [sceneId]"}, permission = "player.teleport", permissionTargeted = "player.teleport.others")
|
||||
public final class TeleportCommand implements CommandHandler {
|
||||
|
||||
private float parseRelative(String input, Float current) { // TODO: Maybe this will be useful elsewhere later
|
||||
@@ -27,7 +26,7 @@ public final class TeleportCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
Position pos = targetPlayer.getPos();
|
||||
Position pos = targetPlayer.getPosition();
|
||||
float x = pos.getX();
|
||||
float y = pos.getY();
|
||||
float z = pos.getZ();
|
||||
@@ -50,7 +49,7 @@ public final class TeleportCommand implements CommandHandler {
|
||||
}
|
||||
break;
|
||||
default:
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.teleport.usage"));
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -9,8 +9,6 @@ import emu.grasscutter.game.player.Player;
|
||||
|
||||
@Command(
|
||||
label = "unban",
|
||||
usage = "unban <@player>",
|
||||
description = "commands.unban.description",
|
||||
permission = "server.ban",
|
||||
targetRequirement = Command.TargetRequirement.PLAYER
|
||||
)
|
||||
|
||||
@@ -0,0 +1,35 @@
|
||||
package emu.grasscutter.command.commands;
|
||||
|
||||
import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.OpenState;
|
||||
import emu.grasscutter.server.packet.send.PacketOpenStateChangeNotify;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import static emu.grasscutter.utils.Language.translate;
|
||||
|
||||
@Command(label = "unlockall", usage = {""}, permission = "player.unlockall", permissionTargeted = "player.unlockall.others")
|
||||
public final class UnlockAllCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
public void execute(Player sender, Player targetPlayer, List<String> args) {
|
||||
Map<Integer, Integer> changed = new HashMap<>();
|
||||
|
||||
for (OpenState state : OpenState.values()) {
|
||||
if (state == OpenState.OPEN_STATE_NONE || state == OpenState.OPEN_STATE_LIMIT_REGION_GLOBAL) continue;
|
||||
|
||||
if (targetPlayer.getOpenStateManager().getOpenStateMap().getOrDefault(state.getValue(), 0) == 0) {
|
||||
targetPlayer.getOpenStateManager().getOpenStateMap().put(state.getValue(), 1);
|
||||
changed.put(state.getValue(), 1);
|
||||
}
|
||||
}
|
||||
|
||||
targetPlayer.sendPacket(new PacketOpenStateChangeNotify(changed));
|
||||
|
||||
CommandHandler.sendMessage(sender, translate(sender, "commands.unlockall.success", targetPlayer.getNickname()));
|
||||
}
|
||||
}
|
||||
@@ -4,11 +4,10 @@ import emu.grasscutter.command.Command;
|
||||
import emu.grasscutter.command.CommandHandler;
|
||||
import emu.grasscutter.game.player.Player;
|
||||
import emu.grasscutter.game.props.ClimateType;
|
||||
import emu.grasscutter.game.world.Scene;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
@Command(label = "weather", usage = "weather [weatherId] [climateType]", aliases = {"w"}, permission = "player.weather", permissionTargeted = "player.weather.others", description = "commands.weather.description")
|
||||
@Command(label = "weather", aliases = {"w"}, usage = {"weather [<weatherId>] [<climateType>]"}, permission = "player.weather", permissionTargeted = "player.weather.others")
|
||||
public final class WeatherCommand implements CommandHandler {
|
||||
|
||||
@Override
|
||||
@@ -31,7 +30,7 @@ public final class WeatherCommand implements CommandHandler {
|
||||
weatherId = Integer.parseInt(arg);
|
||||
} catch (NumberFormatException ignored) {
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.generic.invalid.id");
|
||||
CommandHandler.sendTranslatedMessage(sender, "commands.weather.usage");
|
||||
sendUsageMessage(sender);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user