diff --git a/src/main/java/emu/grasscutter/command/Command.java b/src/main/java/emu/grasscutter/command/Command.java index d8a57e1a8..a0edc5cdc 100644 --- a/src/main/java/emu/grasscutter/command/Command.java +++ b/src/main/java/emu/grasscutter/command/Command.java @@ -14,4 +14,6 @@ public @interface Command { String[] aliases() default {}; String permission() default ""; + + boolean threading() default false; } diff --git a/src/main/java/emu/grasscutter/command/CommandMap.java b/src/main/java/emu/grasscutter/command/CommandMap.java index f735bc642..19ab687ad 100644 --- a/src/main/java/emu/grasscutter/command/CommandMap.java +++ b/src/main/java/emu/grasscutter/command/CommandMap.java @@ -11,7 +11,6 @@ import java.util.*; public final class CommandMap { private final Map commands = new HashMap<>(); private final Map annotations = new HashMap<>(); - public CommandMap() { this(false); } @@ -106,8 +105,9 @@ public final class CommandMap { */ public void invoke(GenshinPlayer player, String rawMessage) { rawMessage = rawMessage.trim(); - if(rawMessage.length() == 0) { - CommandHandler.sendMessage(player, "No command specified."); return; + if (rawMessage.length() == 0) { + CommandHandler.sendMessage(player, "No command specified."); + return; } // Remove prefix if present. @@ -118,7 +118,6 @@ public final class CommandMap { String[] split = rawMessage.split(" "); List args = new LinkedList<>(Arrays.asList(split)); String label = args.remove(0); - // Get command handler. CommandHandler handler = this.commands.get(label); if (handler == null) { @@ -130,14 +129,22 @@ public final class CommandMap { if (player != null) { String permissionNode = this.annotations.get(label).permission(); Account account = player.getAccount(); - if(!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) { + if (!permissionNode.isEmpty() && !account.hasPermission(permissionNode)) { CommandHandler.sendMessage(player, "You do not have permission to run this command."); return; } } // Invoke execute method for handler. - handler.execute(player, args); + boolean threading = this.annotations.get(label).threading(); + Runnable runnable = () -> handler.execute(player, args); + if(threading) { + Thread command = new Thread(runnable); + command.start(); + } + else { + runnable.run(); + } } /** diff --git a/src/main/java/emu/grasscutter/command/commands/GiveAllCommand.java b/src/main/java/emu/grasscutter/command/commands/GiveAllCommand.java new file mode 100644 index 000000000..47ac08405 --- /dev/null +++ b/src/main/java/emu/grasscutter/command/commands/GiveAllCommand.java @@ -0,0 +1,189 @@ +package emu.grasscutter.command.commands; + +import emu.grasscutter.Grasscutter; +import emu.grasscutter.command.Command; +import emu.grasscutter.command.CommandHandler; +import emu.grasscutter.data.GenshinData; +import emu.grasscutter.data.def.AvatarData; +import emu.grasscutter.data.def.ItemData; +import emu.grasscutter.game.GenshinPlayer; +import emu.grasscutter.game.avatar.GenshinAvatar; +import emu.grasscutter.game.inventory.GenshinItem; +import emu.grasscutter.game.inventory.ItemType; + +import java.util.*; + +@Command(label = "giveall", usage = "giveall [player] ", + description = "Gives all items", aliases = {"givea"}, permission = "player.giveall", threading = true) +public class GiveAllCommand implements CommandHandler { + + @Override + public void execute(GenshinPlayer sender, List args) { + int target, amount = 99999; + + switch (args.size()) { + case 0: // *no args* + if (sender == null) { + CommandHandler.sendMessage(null, "This usage can only be run in-game"); + return; + } + target = sender.getUid(); + break; + + case 1: // [player] + try { + target = Integer.parseInt(args.get(0)); + if (Grasscutter.getGameServer().getPlayerByUid(target) == null) { + CommandHandler.sendMessage(sender, "Invalid player ID."); + return; + } + }catch (NumberFormatException ignored){ + CommandHandler.sendMessage(sender, "Invalid player ID."); + return; + } + break; + + case 2: // [player] [amount] + try { + target = Integer.parseInt(args.get(0)); + if (Grasscutter.getGameServer().getPlayerByUid(target) == null) { + target = sender.getUid(); + amount = Integer.parseInt(args.get(0)); + } else { + amount = Integer.parseInt(args.get(1)); + } + } catch (NumberFormatException ignored) { + CommandHandler.sendMessage(sender, "Invalid amount or player ID."); + return; + } + break; + + default: // invalid + CommandHandler.sendMessage(null, "Usage: giveall [player] "); + return; + } + + GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target); + if (targetPlayer == null) { + CommandHandler.sendMessage(sender, "Player not found."); + return; + } + + this.giveAllItems(targetPlayer, amount); + CommandHandler.sendMessage(sender, "Giving all items done"); + } + + public void giveAllItems(GenshinPlayer player, int amount) { + CommandHandler.sendMessage(player, "Giving all items..."); + + for (AvatarData avatarData: GenshinData.getAvatarDataMap().values()) { + //Exclude test avatar + if (isTestAvatar(avatarData.getId())) continue; + + GenshinAvatar avatar = new GenshinAvatar(avatarData); + avatar.setLevel(90); + avatar.setPromoteLevel(6); + for (int i = 1; i <= 6; ++i) { + avatar.getTalentIdList().add((avatar.getAvatarId() - 10000000) * 10 + i); + } + // This will handle stats and talents + avatar.recalcStats(); + player.addAvatar(avatar); + } + + //some test items + List genshinItemList = new ArrayList<>(); + for (ItemData itemdata: GenshinData.getItemDataMap().values()) { + //Exclude test item + if (isTestItem(itemdata.getId())) continue; + + if (itemdata.isEquip()) { + for (int i = 0; i < 10; ++i) { + GenshinItem genshinItem = new GenshinItem(itemdata); + if (itemdata.getItemType() == ItemType.ITEM_WEAPON) { + genshinItem.setLevel(90); + genshinItem.setPromoteLevel(6); + genshinItem.setRefinement(4); + } + genshinItemList.add(genshinItem); + } + } + else { + GenshinItem genshinItem = new GenshinItem(itemdata); + genshinItem.setCount(amount); + genshinItemList.add(genshinItem); + } + } + int packetNum = 20; + int itemLength = genshinItemList.size(); + int number = itemLength / packetNum; + int remainder = itemLength % packetNum; + int offset = 0; + for (int i = 0; i < packetNum; ++i) { + if (remainder > 0) { + player.getInventory().addItems(genshinItemList.subList(i * number + offset, (i + 1) * number + offset + 1)); + --remainder; + ++offset; + } + else { + player.getInventory().addItems(genshinItemList.subList(i * number + offset, (i + 1) * number + offset)); + } + } + } + + public boolean isTestAvatar(int avatarId) { + return avatarId < 10000002 || avatarId >= 11000000; + } + + public boolean isTestItem(int itemId) { + for (Range range: testItemRanges) { + if (range.check(itemId)) { + return true; + } + } + + if (testItemsList.contains(itemId)) { + return true; + } + + return false; + } + + static class Range { + private int min; + private int max; + + public Range(int min, int max) { + if(min > max){ + min ^= max; + max ^= min; + min ^= max; + } + this.min = min; + this.max = max; + } + + public boolean check(int value) { + return value >= this.min && value <= this.max; + } + } + + private static final Range[] testItemRanges = new Range[] { + new Range(106, 139), + new Range(1000, 1099), + new Range(2001, 2008), + new Range(2017, 2029), + // new Range(108001, 108387) //food + }; + + private static final Integer[] testItemsIds = new Integer[] { + 210, 211, 314, 315, 317, 1005, 1007, 1105, 1107, 1201, 1202, 2800, + 100001, 100002, 100244, 100305, 100312, 100313, 101212, 11411, 11506, 11507, 11508, 12505, + 12506, 12508, 12509, 13503, 13506, 14411, 14503, 14505, 14508, 15411, 15504, 15505, + 15506, 15508, 20001, 10002, 10003, 10004, 10005, 10006, 10008 //9 + }; + + private static final Collection testItemsList = Arrays.asList(testItemsIds); + +} +