From 79165aa4029973df989a40ca6a52f66a07ad0c02 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E8=B5=A4=E5=BA=A7=E3=81=82=E3=81=8B=E3=82=8A?= Date: Fri, 29 Apr 2022 22:31:22 +0800 Subject: [PATCH] Add command to get reliquary with specific props (#300) --- README.md | 29 +++--- README_zh-CN.md | 11 +-- .../command/commands/GiveArtifactCommand.java | 88 +++++++++++++++++++ .../grasscutter/game/inventory/GameItem.java | 4 + 4 files changed, 113 insertions(+), 19 deletions(-) create mode 100644 src/main/java/emu/grasscutter/command/commands/GiveArtifactCommand.java diff --git a/README.md b/README.md index 927fc7a8c..e40ffe12a 100644 --- a/README.md +++ b/README.md @@ -106,37 +106,38 @@ There is a dummy user named "Server" in every player's friends list that you can | Commands | Usage | Permission node | Availability | description | Alias | | -------------- | ------------------------------------------------- | ------------------------- | ------------ | ------------------------------------------------------------ | ----------------------------------------------- | -| account | account [UID] | | Server only | Creates an account with the specified username and the in-game UID for that account. The UID will be auto generated if not set. | | -| broadcast | broadcast | server.broadcast | Both side | Sends a message to all the players. | b | -| coop | coop | server.coop | Both side | Forces someone to join the world of others. | | -| changescene | changescene | player.changescene | Client only | Switch scenes by scene ID. | scene | +| account | account \ [UID] | | Server only | Creates an account with the specified username and the in-game UID for that account. The UID will be auto generated if not set. | | +| broadcast | broadcast \ | server.broadcast | Both side | Sends a message to all the players. | b | +| coop | coop \ \ | server.coop | Both side | Forces someone to join the world of others. | | +| changescene | changescene \ | player.changescene | Client only | Switch scenes by scene ID. | scene | | clearartifacts | clearartifacts | player.clearartifacts | Client only | Deletes all unequipped and unlocked level 0 artifacts, including 5-star rarity ones from your inventory. | clearart | | clearweapons | clearweapons | player.clearweapons | Client only | Deletes all unequipped and unlocked weapons, including 5-star rarity ones from your inventory. | clearwpns | | drop | drop [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` | | give | give [player] [amount] [level] [finement] | player.give | Both side | Gives item(s) to you or the specified player. (finement option only weapon.) | `g` `item` `giveitem` | -| givechar | givechar | player.givechar | Both side | Gives the player a specified character. | givec | +| givechar | givechar \ \ | player.givechar | Both side | Gives the player a specified character. | givec | +| giveart | giveart [player] \ \ [\[,\]]... [level] | player.giveart | Both side | Gives the player a specified reliquary. | givea | | giveall | giveall [uid] [amount] | player.giveall | Both side | Gives all items. | givea | | godmode | godmode [uid] | player.godmode | Client only | Prevents you from taking damage. | | | heal | heal | player.heal | Client only | Heals all characters in your current team. | h | | help | help [command] | | Both side | Sends the help message or shows information about a specified command. | | -| kick | kick | server.kick | Both side | Kicks the specified player from the server. (WIP) | k | +| kick | kick \ | server.kick | Both side | Kicks the specified player from the server. (WIP) | k | | killall | killall [playerUid] [sceneId] | server.killall | Both side | Kills all entities in the current scene or specified scene of the corresponding player. | | | list | list | | Both side | Lists online players. | | -| permission | permission | * | Both side | Grants or removes a permission for a user. | | +| permission | permission \ \ | * | Both side | Grants or removes a permission for a user. | | | position | position | | Client only | Sends your current coordinates. | pos | | reload | reload | server.reload | Both side | Reloads the server config | | | resetconst | resetconst [all] | player.resetconstellation | Client only | Resets the constellation level on your currently selected character, will need to relog after using the command to see any changes. | resetconstellation | | restart | | | Both side | Restarts the current session | | -| say | say | server.sendmessage | Both side | Sends a message to a player as the server | `sendservmsg` `sendservermessage` `sendmessage` | -| setfetterlevel | setfetterlevel | player.setfetterlevel | Client only | Sets the friendship level for your currently selected character | setfetterlvl | -| setstats | setstats | player.setstats | Client only | Sets a stat for your currently selected character | stats | -| setworldlevel | setworldlevel | player.setworldlevel | Client only | Sets your world level (Relog to see proper effects) | setworldlvl | +| say | say \ \ | server.sendmessage | Both side | Sends a message to a player as the server | `sendservmsg` `sendservermessage` `sendmessage` | +| setfetterlevel | setfetterlevel \ | player.setfetterlevel | Client only | Sets the friendship level for your currently selected character | setfetterlvl | +| setstats | setstats \ \ | player.setstats | Client only | Sets a stat for your currently selected character | stats | +| setworldlevel | setworldlevel \ | player.setworldlevel | Client only | Sets your world level (Relog to see proper effects) | setworldlvl | | spawn | spanw [level] [amount] | server.spawn | Client only | Spawns an entity near you | | | stop | stop | server.stop | Both side | Stops the server | | -| talent | talent | player.settalent | Client only | Sets talent level for your currently selected character | | -| teleport | teleport | player.teleport | Client only | Change the player's position. | tp | +| talent | talent \ \ | player.settalent | Client only | Sets talent level for your currently selected character | | +| teleport | teleport \ \ \ | player.teleport | Client only | Change the player's position. | tp | | tpall | | player.tpall | Client only | Teleports all players in your world to your position | | -| weather | weather | player.weather | Client only | Changes the weather | w | +| weather | weather \ \ | player.weather | Client only | Changes the weather | w | ### Bonus diff --git a/README_zh-CN.md b/README_zh-CN.md index 6d3c92626..63a328f9f 100644 --- a/README_zh-CN.md +++ b/README_zh-CN.md @@ -109,18 +109,19 @@ chmod +x gradlew | -------------- | -------------------------------------------- | ------------------------- | -------- | ------------------------------------------ | ----------------------------------------------- | | account | account <用户名> [uid] | | 仅服务端 | 通过指定用户名和uid增删账户 | | | broadcast | broadcast <消息内容> | server.broadcast | 均可使用 | 给所有玩家发送公告 | b | -| coop | coop <目标uid> | server.coop | 均可使用 | 强制某位玩家进入指定玩家的多人世界 | | +| coop | coop \ <目标uid> | server.coop | 均可使用 | 强制某位玩家进入指定玩家的多人世界 | | | changescene | changescene <场景ID> | player.changescene | 仅客户端 | 切换到指定场景 | scene | | clearartifacts | clearartifacts | player.clearartifacts | 仅客户端 | 删除所有未装备及未解锁的圣遗物,包括五星 | clearart | | clearweapons | clearweapons | player.clearweapons | 仅客户端 | 删除所有未装备及未解锁的武器,包括五星 | clearwp | | drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` | | give | give [uid] <物品ID\|物品名称> [数量] [等级] [精炼等级] | | | 给予指定玩家一定数量及等级的物品 (精炼等级仅适用于武器) | `g` `item` `giveitem` | -| givechar | givechar <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec | +| givechar | givechar \ <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec | +| giveart | giveart [uid] \<圣遗物ID> \<主属性ID> [\<副属性ID>[,<次数>]]... [等级] | player.giveart | 均可使用 | 给予玩家指定属性的圣遗物 | givea | | giveall | giveall [uid] [数量] | player.giveall | 均可使用 | 给予指定玩家全部物品 | givea | | godmode | godmode [uid] | player.godmode | 仅客户端 | 保护你不受到任何伤害(依然会被击退) | | | heal | heal | player.heal | 仅客户端 | 治疗队伍中所有角色 | h | | help | help [命令] | | 均可使用 | 显示帮助或展示指定命令的帮助 | | -| kick | kick | server.kick | 均可使用 | 从服务器中踢出指定玩家 (WIP) | k | +| kick | kick \ | server.kick | 均可使用 | 从服务器中踢出指定玩家 (WIP) | k | | killall | killall [uid] [场景ID] | server.killall | 均可使用 | 杀死指定玩家世界中所在或指定场景的全部生物 | | | list | list | | 均可使用 | 列出在线玩家 | | | permission | permission <用户名> <权限节点> | * | 均可使用 | 添加或移除玩家的权限 | | @@ -128,14 +129,14 @@ chmod +x gradlew | reload | reload | server.reload | 均可使用 | 重载服务器配置 | | | resetconst | resetconst [all] | player.resetconstellation | 仅客户端 | 重置当前角色的命座,重新登录即可生效 | resetconstellation | | restart | restart | | 均可使用 | 重启服务端 | | -| say | say <消息> | server.sendmessage | 均可使用 | 作为服务器发送消息给玩家 | `sendservmsg` `sendservermessage` `sendmessage` | +| say | say \ <消息> | server.sendmessage | 均可使用 | 作为服务器发送消息给玩家 | `sendservmsg` `sendservermessage` `sendmessage` | | setfetterlevel | setfetterlevel <好感等级> | player.setfetterlevel | 仅客户端 | 设置当前角色的好感等级 | `setfetterlvl` `setfriendship` | | setstats | setstats <属性> <数值> | player.setstats | 仅客户端 | 直接修改当前角色的面板 | stats | | setworldlevel | setworldlevel <世界等级> | player.setworldlevel | 仅客户端 | 设置世界等级(重新登陆即可生效) | setworldlvl | | spawn | spanw <实体ID\|实体名称> [等级] [数量] | server.spawn | 仅客户端 | 在你周围生成实体 | | | stop | stop | server.stop | 均可使用 | 停止服务器 | | | talent | talent <天赋ID> <等级> | player.settalent | 仅客户端 | 设置当前角色的天赋等级 | | -| teleport | teleport | player.teleport | 仅客户端 | 传送玩家到指定坐标 | tp | +| teleport | teleport \ \ \ | player.teleport | 仅客户端 | 传送玩家到指定坐标 | tp | | tpall | | player.tpall | 仅客户端 | 传送多人世界中所有的玩家到自身地点 | | | weather | weather <天气ID> <气候ID> | player.weather | 仅客户端 | 改变天气 | w | diff --git a/src/main/java/emu/grasscutter/command/commands/GiveArtifactCommand.java b/src/main/java/emu/grasscutter/command/commands/GiveArtifactCommand.java new file mode 100644 index 000000000..e33a287e3 --- /dev/null +++ b/src/main/java/emu/grasscutter/command/commands/GiveArtifactCommand.java @@ -0,0 +1,88 @@ +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.def.ItemData; +import emu.grasscutter.game.inventory.GameItem; +import emu.grasscutter.game.inventory.ItemType; +import emu.grasscutter.game.player.Player; +import emu.grasscutter.game.props.ActionReason; + +import java.util.ArrayList; +import java.util.Collections; +import java.util.List; + +@Command(label = "giveart", usage = "giveart [player] [[,]]... [level]", description = "Gives the player a specified reliquary", aliases = {"givea"}, permission = "player.giveart") +public final class GiveArtifactCommand implements CommandHandler { + @Override + public void execute(Player sender, List args) { + int size = args.size(), target, itemId, mainPropId, level; + ArrayList appendPropIdList = new ArrayList<>(); + String msg = "Usage: giveart|givea [player] [[,]]... [level]"; + + if (sender == null && size < 2) { + CommandHandler.sendMessage(null, msg); + return; + } + + if (size >= 2) { + try { + level = Integer.parseInt(args.get(size - 1)); + if (level <= 21) size--; + else level = 1; + target = Integer.parseInt(args.get(0)); + int fromIdx; + if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) { + target = sender.getUid(); + itemId = Integer.parseInt(args.get(0)); + mainPropId = Integer.parseInt(args.get(1)); + fromIdx = 2; + } else { + target = Integer.parseInt(args.get(0)); + itemId = Integer.parseInt(args.get(1)); + mainPropId = Integer.parseInt(args.get(2)); + fromIdx = 3; + } + args.subList(fromIdx, size).forEach(it -> { + String[] arr; + int n = 1; + if ((arr = it.split(",")).length == 2) { + it = arr[0]; + n = Integer.parseInt(arr[1]); + } + appendPropIdList.addAll(Collections.nCopies(n, Integer.parseInt(it))); + }); + } catch (Exception ignored) { + CommandHandler.sendMessage(sender, msg); + return; + } + } else { + CommandHandler.sendMessage(sender, msg); + return; + } + + Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target); + if (targetPlayer == null) { + CommandHandler.sendMessage(sender, "Player not found."); + return; + } + + ItemData itemData = GameData.getItemDataMap().get(itemId); + + if (itemData.getItemType() != ItemType.ITEM_RELIQUARY) { + CommandHandler.sendMessage(sender, "Invalid artifact ID."); + return; + } + + GameItem item = new GameItem(itemData); + item.setLevel(level); + item.setMainPropId(mainPropId); + item.getAppendPropIdList().addAll(appendPropIdList); + targetPlayer.getInventory().addItem(item, ActionReason.SubfieldDrop); + + CommandHandler.sendMessage(sender, String.format("Given %s to %s.", itemId, target)); + } +} + diff --git a/src/main/java/emu/grasscutter/game/inventory/GameItem.java b/src/main/java/emu/grasscutter/game/inventory/GameItem.java index 8f3bef7f2..252c0a01c 100644 --- a/src/main/java/emu/grasscutter/game/inventory/GameItem.java +++ b/src/main/java/emu/grasscutter/game/inventory/GameItem.java @@ -244,6 +244,10 @@ public class GameItem { return mainPropId; } + public void setMainPropId(int mainPropId) { + this.mainPropId = mainPropId; + } + public List getAppendPropIdList() { return appendPropIdList; }