Commit 4db1724d authored by KingRainbow44's avatar KingRainbow44
Browse files

Merge branch 'development' into api

# Conflicts:
#	src/main/java/emu/grasscutter/Grasscutter.java
parents d359e511 92b1ba7a
name: "Build" name: "Build"
on: on:
workflow_dispatch: ~
push: push:
paths:
- "**.java"
branches: branches:
- "stable" - "stable"
- "development" - "development"
pull_request: pull_request:
paths:
- "**.java"
types: types:
- opened - opened
- synchronize - synchronize
......
...@@ -106,37 +106,38 @@ There is a dummy user named "Server" in every player's friends list that you can ...@@ -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 | | Commands | Usage | Permission node | Availability | description | Alias |
| -------------- | ------------------------------------------------- | ------------------------- | ------------ | ------------------------------------------------------------ | ----------------------------------------------- | | -------------- | ------------------------------------------------- | ------------------------- | ------------ | ------------------------------------------------------------ | ----------------------------------------------- |
| account | account <create\|delete> <username> [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. | | | account | account <create\|delete> \<username> [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 <message> | server.broadcast | Both side | Sends a message to all the players. | b | | broadcast | broadcast \<message> | server.broadcast | Both side | Sends a message to all the players. | b |
| coop | coop <playerId> <target playerId> | server.coop | Both side | Forces someone to join the world of others. | | | coop | coop \<playerId> \<target playerId> | server.coop | Both side | Forces someone to join the world of others. | |
| changescene | changescene <scene id> | player.changescene | Client only | Switch scenes by scene ID. | scene | | changescene | changescene \<scene id> | 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 | | 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 | | clearweapons | clearweapons | player.clearweapons | Client only | Deletes all unequipped and unlocked weapons, including 5-star rarity ones from your inventory. | clearwpns |
| drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` | | drop | drop <itemID\|itemName> [amount] | server.drop | Client only | Drops an item around you. | `d` `dropitem` |
| give | give [player] <itemId\|itemName> [amount] [level] | player.give | Both side | Gives item(s) to you or the specified player. | `g` `item` `giveitem` | | give | give [player] <itemId\|itemName> [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 <uid> <avatarId> | player.givechar | Both side | Gives the player a specified character. | givec | | givechar | givechar \<uid> \<avatarId> | player.givechar | Both side | Gives the player a specified character. | givec |
| giveart | giveart [player] \<artifactId> \<mainPropId> [\<appendPropId>[,\<times>]]... [level] | player.giveart | Both side | Gives the player a specified reliquary. | givea |
| giveall | giveall [uid] [amount] | player.giveall | Both side | Gives all items. | 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. | | | 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 | | 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. | | | help | help [command] | | Both side | Sends the help message or shows information about a specified command. | |
| kick | kick <player> | server.kick | Both side | Kicks the specified player from the server. (WIP) | k | | kick | kick \<player> | 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. | | | 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. | | | list | list | | Both side | Lists online players. | |
| permission | permission <add\|remove> <username> <permission> | * | Both side | Grants or removes a permission for a user. | | | permission | permission <add\|remove> \<username> \<permission> | * | Both side | Grants or removes a permission for a user. | |
| position | position | | Client only | Sends your current coordinates. | pos | | position | position | | Client only | Sends your current coordinates. | pos |
| reload | reload | server.reload | Both side | Reloads the server config | | | 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 | | 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 | | | restart | | | Both side | Restarts the current session | |
| say | say <player> <message> | server.sendmessage | Both side | Sends a message to a player as the server | `sendservmsg` `sendservermessage` `sendmessage` | | say | say \<player> \<message> | server.sendmessage | Both side | Sends a message to a player as the server | `sendservmsg` `sendservermessage` `sendmessage` |
| setfetterlevel | setfetterlevel <level> | player.setfetterlevel | Client only | Sets the friendship level for your currently selected character | setfetterlvl | | setfetterlevel | setfetterlevel \<level> | player.setfetterlevel | Client only | Sets the friendship level for your currently selected character | setfetterlvl |
| setstats | setstats <stat> <value> | player.setstats | Client only | Sets a stat for your currently selected character | stats | | setstats | setstats \<stat> \<value> | player.setstats | Client only | Sets a stat for your currently selected character | stats |
| setworldlevel | setworldlevel <level> | player.setworldlevel | Client only | Sets your world level (Relog to see proper effects) | setworldlvl | | setworldlevel | setworldlevel \<level> | player.setworldlevel | Client only | Sets your world level (Relog to see proper effects) | setworldlvl |
| spawn | spanw <entityID\|entityName> [level] [amount] | server.spawn | Client only | Spawns an entity near you | | | spawn | spanw <entityID\|entityName> [level] [amount] | server.spawn | Client only | Spawns an entity near you | |
| stop | stop | server.stop | Both side | Stops the server | | | stop | stop | server.stop | Both side | Stops the server | |
| talent | talent <talentID> <value> | player.settalent | Client only | Sets talent level for your currently selected character | | | talent | talent \<talentID> \<value> | player.settalent | Client only | Sets talent level for your currently selected character | |
| teleport | teleport <x> <y> <z> | player.teleport | Client only | Change the player's position. | tp | | teleport | teleport \<x> \<y> \<z> | player.teleport | Client only | Change the player's position. | tp |
| tpall | | player.tpall | Client only | Teleports all players in your world to your position | | | tpall | | player.tpall | Client only | Teleports all players in your world to your position | |
| weather | weather <weatherID> <climateID> | player.weather | Client only | Changes the weather | w | | weather | weather \<weatherID> \<climateID> | player.weather | Client only | Changes the weather | w |
### Bonus ### Bonus
......
...@@ -109,18 +109,19 @@ chmod +x gradlew ...@@ -109,18 +109,19 @@ chmod +x gradlew
| -------------- | -------------------------------------------- | ------------------------- | -------- | ------------------------------------------ | ----------------------------------------------- | | -------------- | -------------------------------------------- | ------------------------- | -------- | ------------------------------------------ | ----------------------------------------------- |
| account | account <create\|delete> <用户名> [uid] | | 仅服务端 | 通过指定用户名和uid增删账户 | | | account | account <create\|delete> <用户名> [uid] | | 仅服务端 | 通过指定用户名和uid增删账户 | |
| broadcast | broadcast <消息内容> | server.broadcast | 均可使用 | 给所有玩家发送公告 | b | | broadcast | broadcast <消息内容> | server.broadcast | 均可使用 | 给所有玩家发送公告 | b |
| coop | coop <uid> <目标uid> | server.coop | 均可使用 | 强制某位玩家进入指定玩家的多人世界 | | | coop | coop \<uid> <目标uid> | server.coop | 均可使用 | 强制某位玩家进入指定玩家的多人世界 | |
| changescene | changescene <场景ID> | player.changescene | 仅客户端 | 切换到指定场景 | scene | | changescene | changescene <场景ID> | player.changescene | 仅客户端 | 切换到指定场景 | scene |
| clearartifacts | clearartifacts | player.clearartifacts | 仅客户端 | 删除所有未装备及未解锁的圣遗物,包括五星 | clearart | | clearartifacts | clearartifacts | player.clearartifacts | 仅客户端 | 删除所有未装备及未解锁的圣遗物,包括五星 | clearart |
| clearweapons | clearweapons | player.clearweapons | 仅客户端 | 删除所有未装备及未解锁的武器,包括五星 | clearwp | | clearweapons | clearweapons | player.clearweapons | 仅客户端 | 删除所有未装备及未解锁的武器,包括五星 | clearwp |
| drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` | | drop | drop <物品ID\|物品名称> [数量] | server.drop | 仅客户端 | 在指定玩家周围掉落指定物品 | `d` `dropitem` |
| give | give [uid] <物品ID\|物品名称> [数量] [等级] | | | 给予指定玩家一定数量及等级的物品 | `g` `item` `giveitem` | | give | give [uid] <物品ID\|物品名称> [数量] [等级] [精炼等级] | | | 给予指定玩家一定数量及等级的物品 (精炼等级仅适用于武器) | `g` `item` `giveitem` |
| givechar | givechar <uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec | | givechar | givechar \<uid> <角色ID> [等级] | player.givechar | 均可使用 | 给予指定玩家对应角色 | givec |
| giveart | giveart [uid] \<圣遗物ID> \<主属性ID> [\<副属性ID>[,<次数>]]... [等级] | player.giveart | 均可使用 | 给予玩家指定属性的圣遗物 | givea |
| giveall | giveall [uid] [数量] | player.giveall | 均可使用 | 给予指定玩家全部物品 | givea | | giveall | giveall [uid] [数量] | player.giveall | 均可使用 | 给予指定玩家全部物品 | givea |
| godmode | godmode [uid] | player.godmode | 仅客户端 | 保护你不受到任何伤害(依然会被击退) | | | godmode | godmode [uid] | player.godmode | 仅客户端 | 保护你不受到任何伤害(依然会被击退) | |
| heal | heal | player.heal | 仅客户端 | 治疗队伍中所有角色 | h | | heal | heal | player.heal | 仅客户端 | 治疗队伍中所有角色 | h |
| help | help [命令] | | 均可使用 | 显示帮助或展示指定命令的帮助 | | | help | help [命令] | | 均可使用 | 显示帮助或展示指定命令的帮助 | |
| kick | kick <uid> | server.kick | 均可使用 | 从服务器中踢出指定玩家 (WIP) | k | | kick | kick \<uid> | server.kick | 均可使用 | 从服务器中踢出指定玩家 (WIP) | k |
| killall | killall [uid] [场景ID] | server.killall | 均可使用 | 杀死指定玩家世界中所在或指定场景的全部生物 | | | killall | killall [uid] [场景ID] | server.killall | 均可使用 | 杀死指定玩家世界中所在或指定场景的全部生物 | |
| list | list | | 均可使用 | 列出在线玩家 | | | list | list | | 均可使用 | 列出在线玩家 | |
| permission | permission <add\|remove> <用户名> <权限节点> | * | 均可使用 | 添加或移除玩家的权限 | | | permission | permission <add\|remove> <用户名> <权限节点> | * | 均可使用 | 添加或移除玩家的权限 | |
...@@ -128,14 +129,14 @@ chmod +x gradlew ...@@ -128,14 +129,14 @@ chmod +x gradlew
| reload | reload | server.reload | 均可使用 | 重载服务器配置 | | | reload | reload | server.reload | 均可使用 | 重载服务器配置 | |
| resetconst | resetconst [all] | player.resetconstellation | 仅客户端 | 重置当前角色的命座,重新登录即可生效 | resetconstellation | | resetconst | resetconst [all] | player.resetconstellation | 仅客户端 | 重置当前角色的命座,重新登录即可生效 | resetconstellation |
| restart | restart | | 均可使用 | 重启服务端 | | | restart | restart | | 均可使用 | 重启服务端 | |
| say | say <uid> <消息> | server.sendmessage | 均可使用 | 作为服务器发送消息给玩家 | `sendservmsg` `sendservermessage` `sendmessage` | | say | say \<uid> <消息> | server.sendmessage | 均可使用 | 作为服务器发送消息给玩家 | `sendservmsg` `sendservermessage` `sendmessage` |
| setfetterlevel | setfetterlevel <好感等级> | player.setfetterlevel | 仅客户端 | 设置当前角色的好感等级 | `setfetterlvl` `setfriendship` | | setfetterlevel | setfetterlevel <好感等级> | player.setfetterlevel | 仅客户端 | 设置当前角色的好感等级 | `setfetterlvl` `setfriendship` |
| setstats | setstats <属性> <数值> | player.setstats | 仅客户端 | 直接修改当前角色的面板 | stats | | setstats | setstats <属性> <数值> | player.setstats | 仅客户端 | 直接修改当前角色的面板 | stats |
| setworldlevel | setworldlevel <世界等级> | player.setworldlevel | 仅客户端 | 设置世界等级(重新登陆即可生效) | setworldlvl | | setworldlevel | setworldlevel <世界等级> | player.setworldlevel | 仅客户端 | 设置世界等级(重新登陆即可生效) | setworldlvl |
| spawn | spanw <实体ID\|实体名称> [等级] [数量] | server.spawn | 仅客户端 | 在你周围生成实体 | | | spawn | spanw <实体ID\|实体名称> [等级] [数量] | server.spawn | 仅客户端 | 在你周围生成实体 | |
| stop | stop | server.stop | 均可使用 | 停止服务器 | | | stop | stop | server.stop | 均可使用 | 停止服务器 | |
| talent | talent <天赋ID> <等级> | player.settalent | 仅客户端 | 设置当前角色的天赋等级 | | | talent | talent <天赋ID> <等级> | player.settalent | 仅客户端 | 设置当前角色的天赋等级 | |
| teleport | teleport <x> <y> <z> | player.teleport | 仅客户端 | 传送玩家到指定坐标 | tp | | teleport | teleport \<x> \<y> \<z> | player.teleport | 仅客户端 | 传送玩家到指定坐标 | tp |
| tpall | | player.tpall | 仅客户端 | 传送多人世界中所有的玩家到自身地点 | | | tpall | | player.tpall | 仅客户端 | 传送多人世界中所有的玩家到自身地点 | |
| weather | weather <天气ID> <气候ID> | player.weather | 仅客户端 | 改变天气 | w | | weather | weather <天气ID> <气候ID> | player.weather | 仅客户端 | 改变天气 | w |
......
...@@ -71,9 +71,10 @@ dependencies { ...@@ -71,9 +71,10 @@ dependencies {
implementation group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2' implementation group: 'org.quartz-scheduler', name: 'quartz', version: '2.3.2'
implementation group: 'org.quartz-scheduler', name: 'quartz-jobs', version: '2.3.2' implementation group: 'org.quartz-scheduler', name: 'quartz-jobs', version: '2.3.2'
implementation group: 'org.luaj', name: 'luaj-jse', version: '3.0.1'
protobuf files('proto/') protobuf files('proto/')
} }
application { application {
......
...@@ -10,6 +10,7 @@ public final class Config { ...@@ -10,6 +10,7 @@ public final class Config {
public String PACKETS_FOLDER = "./packets/"; public String PACKETS_FOLDER = "./packets/";
public String DUMPS_FOLDER = "./dumps/"; public String DUMPS_FOLDER = "./dumps/";
public String KEY_FOLDER = "./keys/"; public String KEY_FOLDER = "./keys/";
public String SCRIPTS_FOLDER = "./resources/Scripts/";
public String PLUGINS_FOLDER = "./plugins/"; public String PLUGINS_FOLDER = "./plugins/";
public String RunMode = "HYBRID"; // HYBRID, DISPATCH_ONLY, GAME_ONLY public String RunMode = "HYBRID"; // HYBRID, DISPATCH_ONLY, GAME_ONLY
......
...@@ -9,7 +9,7 @@ import java.net.InetSocketAddress; ...@@ -9,7 +9,7 @@ import java.net.InetSocketAddress;
import emu.grasscutter.command.CommandMap; import emu.grasscutter.command.CommandMap;
import emu.grasscutter.plugin.PluginManager; import emu.grasscutter.plugin.PluginManager;
import emu.grasscutter.plugin.api.ServerHook; import emu.grasscutter.scripts.ScriptLoader;
import emu.grasscutter.utils.Utils; import emu.grasscutter.utils.Utils;
import org.reflections.Reflections; import org.reflections.Reflections;
import org.slf4j.LoggerFactory; import org.slf4j.LoggerFactory;
...@@ -68,6 +68,7 @@ public final class Grasscutter { ...@@ -68,6 +68,7 @@ public final class Grasscutter {
// Load all resources. // Load all resources.
ResourceLoader.loadAll(); ResourceLoader.loadAll();
ScriptLoader.init();
// Database // Database
DatabaseManager.initialize(); DatabaseManager.initialize();
...@@ -78,9 +79,6 @@ public final class Grasscutter { ...@@ -78,9 +79,6 @@ public final class Grasscutter {
dispatchServer = new DispatchServer(); dispatchServer = new DispatchServer();
gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port)); gameServer = new GameServer(new InetSocketAddress(getConfig().getGameServerOptions().Ip, getConfig().getGameServerOptions().Port));
// Create server hook instance.
new ServerHook(gameServer, dispatchServer);
// Start servers. // Start servers.
if(getConfig().RunMode.equalsIgnoreCase("HYBRID")) { if(getConfig().RunMode.equalsIgnoreCase("HYBRID")) {
dispatchServer.start(); dispatchServer.start();
......
...@@ -18,79 +18,86 @@ public final class ClearCommand implements CommandHandler { ...@@ -18,79 +18,86 @@ public final class ClearCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, List<String> args) { public void execute(Player sender, List<String> args) {
int target; int target;
String cmdSwitch = "";
if (sender == null) { if (sender == null) {
CommandHandler.sendMessage(null, "Run this command in-game."); CommandHandler.sendMessage(null, "Run this command in-game.");
return; return;
} }
String cmdSwitch = args.get(1);
Inventory playerInventory = sender.getInventory(); Inventory playerInventory = sender.getInventory();
try { try {
if (args.size() == 1) {
cmdSwitch = args.get(0);
target = sender.getUid();
}else {
cmdSwitch = args.get(1);
target = Integer.parseInt(args.get(0)); target = Integer.parseInt(args.get(0));
Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target); }
if (targetPlayer == null) { Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
target = sender.getUid(); switch (cmdSwitch) {
} else { case "wp" -> {
switch (cmdSwitch) { playerInventory.getItems().values().stream()
case "wp" -> { .filter(item -> item.getItemType() == ItemType.ITEM_WEAPON)
playerInventory.getItems().values().stream() .filter(item -> !item.isLocked() && !item.isEquipped())
.filter(item -> item.getItemType() == ItemType.ITEM_WEAPON) .forEach(item -> playerInventory.removeItem(item, item.getCount()));
.filter(item -> !item.isLocked() && !item.isEquipped()) sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " .");
.forEach(item -> playerInventory.removeItem(item, item.getCount())); }
sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " ."); case "art" -> {
} playerInventory.getItems().values().stream()
case "art" -> { .filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY)
playerInventory.getItems().values().stream() .filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY) .filter(item -> !item.isLocked() && !item.isEquipped())
.filter(item -> item.getLevel() == 1 && item.getExp() == 0) .forEach(item -> playerInventory.removeItem(item, item.getCount()));
.filter(item -> !item.isLocked() && !item.isEquipped()) sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
.forEach(item -> playerInventory.removeItem(item, item.getCount())); }
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " ."); case "mat" -> {
} playerInventory.getItems().values().stream()
case "mat" -> { .filter(item -> item.getItemType() == ItemType.ITEM_MATERIAL)
playerInventory.getItems().values().stream() .filter(item -> item.getLevel() == 1 && item.getExp() == 0)
.filter(item -> item.getItemType() == ItemType.ITEM_MATERIAL) .filter(item -> !item.isLocked() && !item.isEquipped())
.filter(item -> item.getLevel() == 1 && item.getExp() == 0) .forEach(item -> playerInventory.removeItem(item, item.getCount()));
.filter(item -> !item.isLocked() && !item.isEquipped()) sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
.forEach(item -> playerInventory.removeItem(item, item.getCount())); }
sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " ."); case "all" -> {
} playerInventory.getItems().values().stream()
case "all" -> { .filter(item1 -> item1.getItemType() == ItemType.ITEM_RELIQUARY)
playerInventory.getItems().values().stream() .filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0)
.filter(item1 -> item1.getItemType() == ItemType.ITEM_RELIQUARY) .filter(item1 -> !item1.isLocked() && !item1.isEquipped())
.filter(item1 -> item1.getLevel() == 1 && item1.getExp() == 0) .forEach(item1 -> playerInventory.removeItem(item1, item1.getCount()));
.filter(item1 -> !item1.isLocked() && !item1.isEquipped()) sender.dropMessage("Cleared artifacts for " + targetPlayer.getNickname() + " .");
.forEach(item1 -> playerInventory.removeItem(item1, item1.getCount())); playerInventory.getItems().values().stream()
playerInventory.getItems().values().stream() .filter(item2 -> item2.getItemType() == ItemType.ITEM_MATERIAL)
.filter(item2 -> item2.getItemType() == ItemType.ITEM_MATERIAL) .filter(item2 -> !item2.isLocked() && !item2.isEquipped())
.filter(item2 -> !item2.isLocked() && !item2.isEquipped()) .forEach(item2 -> playerInventory.removeItem(item2, item2.getCount()));
.forEach(item2 -> playerInventory.removeItem(item2, item2.getCount())); sender.dropMessage("Cleared materials for " + targetPlayer.getNickname() + " .");
playerInventory.getItems().values().stream() playerInventory.getItems().values().stream()
.filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON) .filter(item3 -> item3.getItemType() == ItemType.ITEM_WEAPON)
.filter(item3 -> item3.getLevel() == 1 && item3.getExp() == 0) .filter(item3 -> item3.getLevel() == 1 && item3.getExp() == 0)
.filter(item3 -> !item3.isLocked() && !item3.isEquipped()) .filter(item3 -> !item3.isLocked() && !item3.isEquipped())
.forEach(item3 -> playerInventory.removeItem(item3, item3.getCount())); .forEach(item3 -> playerInventory.removeItem(item3, item3.getCount()));
playerInventory.getItems().values().stream() sender.dropMessage("Cleared weapons for " + targetPlayer.getNickname() + " .");
.filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE) playerInventory.getItems().values().stream()
.filter(item4 -> !item4.isLocked() && !item4.isEquipped()) .filter(item4 -> item4.getItemType() == ItemType.ITEM_FURNITURE)
.forEach(item4 -> playerInventory.removeItem(item4, item4.getCount())); .filter(item4 -> !item4.isLocked() && !item4.isEquipped())
playerInventory.getItems().values().stream() .forEach(item4 -> playerInventory.removeItem(item4, item4.getCount()));
.filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY) sender.dropMessage("Cleared furniture for " + targetPlayer.getNickname() + " .");
.filter(item5 -> !item5.isLocked() && !item5.isEquipped()) playerInventory.getItems().values().stream()
.forEach(item5 -> playerInventory.removeItem(item5, item5.getCount())); .filter(item5 -> item5.getItemType() == ItemType.ITEM_DISPLAY)
playerInventory.getItems().values().stream() .filter(item5 -> !item5.isLocked() && !item5.isEquipped())
.filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL) .forEach(item5 -> playerInventory.removeItem(item5, item5.getCount()));
.filter(item6 -> !item6.isLocked() && !item6.isEquipped()) sender.dropMessage("Cleared displays for " + targetPlayer.getNickname() + " .");
.forEach(item6 -> playerInventory.removeItem(item6, item6.getCount())); playerInventory.getItems().values().stream()
sender.dropMessage("Cleared everything for " + targetPlayer.getNickname() + " ."); .filter(item6 -> item6.getItemType() == ItemType.ITEM_VIRTUAL)
} .filter(item6 -> !item6.isLocked() && !item6.isEquipped())
} .forEach(item6 -> playerInventory.removeItem(item6, item6.getCount()));
sender.dropMessage("Cleared virtuals for " + targetPlayer.getNickname() + " .");
sender.dropMessage("Cleared everything for " + targetPlayer.getNickname() + " .");
} }
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid playerId.");
return;
} }
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid playerId.");
return;
}
Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target); Player targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
if (targetPlayer == null) { if (targetPlayer == null) {
......
...@@ -83,8 +83,8 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -83,8 +83,8 @@ public final class GiveAllCommand implements CommandHandler {
Avatar avatar = new Avatar(avatarData); Avatar avatar = new Avatar(avatarData);
avatar.setLevel(90); avatar.setLevel(90);
avatar.setPromoteLevel(6); avatar.setPromoteLevel(6);
for (int i = 1; i <= 6; ++i) { for(int i = 1;i <= 6;++i){
avatar.getTalentIdList().add((avatar.getAvatarId() - 10000000) * 10 + i); avatar.getTalentIdList().add((avatar.getAvatarId()-10000000)*10+i);
} }
// This will handle stats and talents // This will handle stats and talents
avatar.recalcStats(); avatar.recalcStats();
...@@ -98,7 +98,7 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -98,7 +98,7 @@ public final class GiveAllCommand implements CommandHandler {
if (isTestItem(itemdata.getId())) continue; if (isTestItem(itemdata.getId())) continue;
if (itemdata.isEquip()) { if (itemdata.isEquip()) {
for (int i = 0; i < 10; ++i) { for (int i = 0; i < 5; ++i) {
GameItem item = new GameItem(itemdata); GameItem item = new GameItem(itemdata);
if (itemdata.getItemType() == ItemType.ITEM_WEAPON) { if (itemdata.getItemType() == ItemType.ITEM_WEAPON) {
item.setLevel(90); item.setLevel(90);
...@@ -114,7 +114,7 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -114,7 +114,7 @@ public final class GiveAllCommand implements CommandHandler {
itemList.add(item); itemList.add(item);
} }
} }
int packetNum = 20; int packetNum = 10;
int itemLength = itemList.size(); int itemLength = itemList.size();
int number = itemLength / packetNum; int number = itemLength / packetNum;
int remainder = itemLength % packetNum; int remainder = itemLength % packetNum;
...@@ -167,15 +167,27 @@ public final class GiveAllCommand implements CommandHandler { ...@@ -167,15 +167,27 @@ public final class GiveAllCommand implements CommandHandler {
private static final Range[] testItemRanges = new Range[] { private static final Range[] testItemRanges = new Range[] {
new Range(106, 139), new Range(106, 139),
new Range(1000, 1099), new Range(1000, 1099),
new Range(2001, 2008), new Range(2001, 3022),
new Range(2017, 2029), new Range(23300, 23340),
// new Range(108001, 108387) //food new Range(23383, 23385),
new Range(78310, 78554),
new Range(99310, 99554),
new Range(100001, 100187),
new Range(100210, 100214),
new Range(100303, 100398),
new Range(100414, 100425),
new Range(100454, 103008),
new Range(109000, 109492),
new Range(115001, 118004),
new Range(141001, 141072),
new Range(220050, 221016),
}; };
private static final Integer[] testItemsIds = new Integer[] { private static final Integer[] testItemsIds = new Integer[] {
210, 211, 314, 315, 317, 1005, 1007, 1105, 1107, 1201, 1202, 2800, 210, 211, 314, 315, 317, 1005, 1007, 1105, 1107, 1201, 1202,10366,
100001, 100002, 100244, 100305, 100312, 100313, 101212, 11411, 11506, 11507, 11508, 12505, 101212, 11411, 11506, 11507, 11508, 12505, 12506, 12508, 12509, 13503,
12506, 12508, 12509, 13503, 13506, 14411, 14503, 14505, 14508, 15411, 15504, 15505, 13506, 14411, 14503, 14505, 14508, 15411, 15504, 15505, 15506, 15508,
15506, 15508, 20001, 10002, 10003, 10004, 10005, 10006, 10008 //9 20001, 10002, 10003, 10004, 10005, 10006, 10008,100231,100232,100431,
101689,105001,105004, 106000,106001,108000,110000
}; };
private static final Collection<Integer> testItemsList = Arrays.asList(testItemsIds); private static final Collection<Integer> testItemsList = Arrays.asList(testItemsIds);
......
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] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [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<String> args) {
int size = args.size(), target, itemId, mainPropId, level;
ArrayList<Integer> appendPropIdList = new ArrayList<>();
String msg = "Usage: giveart|givea [player] <artifactId> <mainPropId> [<appendPropId>[,<times>]]... [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));
}
}
...@@ -6,20 +6,20 @@ import emu.grasscutter.command.CommandHandler; ...@@ -6,20 +6,20 @@ import emu.grasscutter.command.CommandHandler;
import emu.grasscutter.data.GameData; import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.ItemData; import emu.grasscutter.data.def.ItemData;
import emu.grasscutter.game.inventory.GameItem; import emu.grasscutter.game.inventory.GameItem;
import emu.grasscutter.game.inventory.ItemType;
import emu.grasscutter.game.player.Player; import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.ActionReason; import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
import java.util.LinkedList; import java.util.LinkedList;
import java.util.List; import java.util.List;
@Command(label = "give", usage = "give [player] <itemId|itemName> [amount] [level]", description = "Gives an item to you or the specified player", aliases = { @Command(label = "give", usage = "give [player] <itemId|itemName> [amount] [level]", description = "Gives an item to you or the specified player", aliases = {
"g", "item", "giveitem" }, permission = "player.give") "g", "item", "giveitem"}, permission = "player.give")
public final class GiveCommand implements CommandHandler { public final class GiveCommand implements CommandHandler {
@Override @Override
public void execute(Player sender, List<String> args) { public void execute(Player sender, List<String> args) {
int target, item, lvl, amount = 1; int target, item, lvl, amount = 1, refinement = 0;
if (sender == null && args.size() < 2) { if (sender == null && args.size() < 2) {
CommandHandler.sendMessage(null, "Usage: give <player> <itemId|itemName> [amount] [level]"); CommandHandler.sendMessage(null, "Usage: give <player> <itemId|itemName> [amount] [level]");
return; return;
...@@ -79,7 +79,28 @@ public final class GiveCommand implements CommandHandler { ...@@ -79,7 +79,28 @@ public final class GiveCommand implements CommandHandler {
return; return;
} }
break; break;
case 4: // [player] <itemId|itemName> [amount] [level] case 4: // [player] <itemId|itemName> [amount] [level] | <itemId|itemName> [amount] [level] [refinement]
try {
target = Integer.parseInt(args.get(0));
if (Grasscutter.getGameServer().getPlayerByUid(target) == null && sender != null) {
target = sender.getUid();
item = Integer.parseInt(args.get(0));
amount = Integer.parseInt(args.get(1));
lvl = Integer.parseInt(args.get(2));
refinement = Integer.parseInt(args.get(3));
} else {
item = Integer.parseInt(args.get(1));
amount = Integer.parseInt(args.get(2));
lvl = Integer.parseInt(args.get(3));
}
} catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook.
CommandHandler.sendMessage(sender, "Invalid item or player ID.");
return;
}
break;
case 5: // [player] <itemId|itemName> [amount] [level] [refinement]
try { try {
target = Integer.parseInt(args.get(0)); target = Integer.parseInt(args.get(0));
...@@ -90,6 +111,7 @@ public final class GiveCommand implements CommandHandler { ...@@ -90,6 +111,7 @@ public final class GiveCommand implements CommandHandler {
item = Integer.parseInt(args.get(1)); item = Integer.parseInt(args.get(1));
amount = Integer.parseInt(args.get(2)); amount = Integer.parseInt(args.get(2));
lvl = Integer.parseInt(args.get(3)); lvl = Integer.parseInt(args.get(3));
refinement = Integer.parseInt(args.get(4));
} }
} catch (NumberFormatException ignored) { } catch (NumberFormatException ignored) {
// TODO: Parse from item name using GM Handbook. // TODO: Parse from item name using GM Handbook.
...@@ -111,37 +133,58 @@ public final class GiveCommand implements CommandHandler { ...@@ -111,37 +133,58 @@ public final class GiveCommand implements CommandHandler {
CommandHandler.sendMessage(sender, "Invalid item id."); CommandHandler.sendMessage(sender, "Invalid item id.");
return; return;
} }
if (refinement != 0) {
if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
if (refinement < 1 || refinement > 5) {
CommandHandler.sendMessage(sender, "Refinement must be between 1 and 5.");
return;
}
} else {
CommandHandler.sendMessage(sender, "Refinement is only applicable to weapons.");
return;
}
}
this.item(targetPlayer, itemData, amount, lvl); this.item(targetPlayer, itemData, amount, lvl, refinement);
if (!itemData.isEquip()) if (!itemData.isEquip()) {
CommandHandler.sendMessage(sender, String.format("Given %s of %s to %s.", amount, item, target)); CommandHandler.sendMessage(sender, String.format("Given %s of %s to %s.", amount, item, target));
else } else if (itemData.getItemType() == ItemType.ITEM_WEAPON) {
CommandHandler.sendMessage(sender,
String.format("Given %s with level %s, refinement %s %s times to %s", item, lvl, refinement, amount, target));
} else {
CommandHandler.sendMessage(sender, CommandHandler.sendMessage(sender,
String.format("Given %s with level %s %s times to %s", item, lvl, amount, target)); String.format("Given %s with level %s %s times to %s", item, lvl, amount, target));
}
} }
private void item(Player player, ItemData itemData, int amount, int lvl) { private void item(Player player, ItemData itemData, int amount, int lvl, int refinement) {
if (itemData.isEquip()) { if (itemData.isEquip()) {
List<GameItem> items = new LinkedList<>(); List<GameItem> items = new LinkedList<>();
for (int i = 0; i < amount; i++) { for (int i = 0; i < amount; i++) {
GameItem item = new GameItem(itemData); GameItem item = new GameItem(itemData);
item.setCount(amount); item.setCount(amount);
item.setLevel(lvl); item.setLevel(lvl);
item.setPromoteLevel(0); if (lvl > 20 && lvl < 40) {
if (lvl > 20) { // 20/40
item.setPromoteLevel(1); item.setPromoteLevel(1);
} else if (lvl > 40) { // 40/50 } else if (lvl > 40 && lvl <= 50) {
item.setPromoteLevel(2); item.setPromoteLevel(2);
} else if (lvl > 50) { // 50/60 } else if (lvl > 50 && lvl <= 60) {
item.setPromoteLevel(3); item.setPromoteLevel(3);
} else if (lvl > 60) { // 60/70 } else if (lvl > 60 && lvl <= 70) {
item.setPromoteLevel(4); item.setPromoteLevel(4);
} else if (lvl > 70) { // 70/80 } else if (lvl > 70 && lvl <= 80) {
item.setPromoteLevel(5); item.setPromoteLevel(5);
} else if (lvl > 80) { // 80/90 } else if (lvl > 80 && lvl <= 90) {
item.setPromoteLevel(6); item.setPromoteLevel(6);
} }
if (item.getItemType() == ItemType.ITEM_WEAPON) {
if (refinement > 0) {
item.setRefinement(refinement - 1);
} else {
item.setRefinement(0);
}
}
items.add(item); items.add(item);
} }
player.getInventory().addItems(items, ActionReason.SubfieldDrop); player.getInventory().addItems(items, ActionReason.SubfieldDrop);
......
...@@ -61,13 +61,15 @@ public class GameData { ...@@ -61,13 +61,15 @@ public class GameData {
private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<FetterCharacterCardData> fetterCharacterCardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<RewardData> rewardDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<WorldLevelData> worldLevelDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<DungeonData> dungeonDataMap = new Int2ObjectOpenHashMap<>();
private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>(); private static final Int2ObjectMap<ShopGoodsData> shopGoodsDataMap = new Int2ObjectOpenHashMap<>();
// Cache // Cache
private static Map<Integer, List<Integer>> fetters = new HashMap<>(); private static Map<Integer, List<Integer>> fetters = new HashMap<>();
private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>(); private static Map<Integer, List<ShopGoodsData>> shopGoods = new HashMap<>();
public static char EJWOA = 's';
public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) { public static Int2ObjectMap<?> getMapByResourceDef(Class<?> resourceDefinition) {
Int2ObjectMap<?> map = null; Int2ObjectMap<?> map = null;
...@@ -100,6 +102,11 @@ public class GameData { ...@@ -100,6 +102,11 @@ public class GameData {
public static Map<String, ScenePointEntry> getScenePointEntries() { public static Map<String, ScenePointEntry> getScenePointEntries() {
return scenePointEntries; return scenePointEntries;
} }
// TODO optimize
public static ScenePointEntry getScenePointEntryById(int sceneId, int pointId) {
return getScenePointEntries().get(sceneId + "_" + pointId);
}
public static Int2ObjectMap<AvatarData> getAvatarDataMap() { public static Int2ObjectMap<AvatarData> getAvatarDataMap() {
return avatarDataMap; return avatarDataMap;
...@@ -269,8 +276,10 @@ public class GameData { ...@@ -269,8 +276,10 @@ public class GameData {
return worldLevelDataMap; return worldLevelDataMap;
} }
public static char EJWOA = 's'; public static Int2ObjectMap<DungeonData> getDungeonDataMap() {
return dungeonDataMap;
}
public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() { public static Map<Integer, List<ShopGoodsData>> getShopGoodsDataEntries() {
if (shopGoods.isEmpty()) { if (shopGoods.isEmpty()) {
shopGoodsDataMap.forEach((k, v) -> { shopGoodsDataMap.forEach((k, v) -> {
......
...@@ -164,6 +164,7 @@ public class ResourceLoader { ...@@ -164,6 +164,7 @@ public class ResourceLoader {
for (Map.Entry<String, JsonElement> entry : config.points.entrySet()) { for (Map.Entry<String, JsonElement> entry : config.points.entrySet()) {
PointData pointData = Grasscutter.getGsonFactory().fromJson(entry.getValue(), PointData.class); PointData pointData = Grasscutter.getGsonFactory().fromJson(entry.getValue(), PointData.class);
pointData.setId(Integer.parseInt(entry.getKey()));
ScenePointEntry sl = new ScenePointEntry(sceneId + "_" + entry.getKey(), pointData); ScenePointEntry sl = new ScenePointEntry(sceneId + "_" + entry.getKey(), pointData);
scenePointList.add(sl); scenePointList.add(sl);
......
package emu.grasscutter.data.common; package emu.grasscutter.data.common;
public class PointData { import emu.grasscutter.utils.Position;
private pos tranPos;
public pos getTranPos() { public class PointData {
private int id;
private String $type;
private Position tranPos;
private int[] dungeonIds;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getType() {
return $type;
}
public Position getTranPos() {
return tranPos; return tranPos;
} }
public void setTranPos(pos tranPos) { public int[] getDungeonIds() {
this.tranPos = tranPos; return dungeonIds;
} }
public class pos {
private float x;
private float y;
private float z;
public float getX() {
return x;
}
public void setX(float x) {
this.x = x;
}
public float getY() {
return y;
}
public void setY(float y) {
this.y = y;
}
public float getZ() {
return z;
}
public void setZ(float z) {
this.z = z;
}
}
} }
package emu.grasscutter.data.def;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.SceneType;
@ResourceType(name = "DungeonExcelConfigData.json")
public class DungeonData extends GameResource {
private int Id;
private int SceneId;
private int ShowLevel;
private String InvolveType; // TODO enum
@Override
public int getId() {
return this.Id;
}
public int getSceneId() {
return SceneId;
}
public int getShowLevel() {
return ShowLevel;
}
@Override
public void onLoad() {
}
}
...@@ -2,12 +2,13 @@ package emu.grasscutter.data.def; ...@@ -2,12 +2,13 @@ package emu.grasscutter.data.def;
import emu.grasscutter.data.GameResource; import emu.grasscutter.data.GameResource;
import emu.grasscutter.data.ResourceType; import emu.grasscutter.data.ResourceType;
import emu.grasscutter.game.props.EntityType;
@ResourceType(name = "GadgetExcelConfigData.json") @ResourceType(name = "GadgetExcelConfigData.json")
public class GadgetData extends GameResource { public class GadgetData extends GameResource {
private int Id; private int Id;
private String Type; private EntityType Type;
private String JsonName; private String JsonName;
private boolean IsInteractive; private boolean IsInteractive;
private String[] Tags; private String[] Tags;
...@@ -22,7 +23,7 @@ public class GadgetData extends GameResource { ...@@ -22,7 +23,7 @@ public class GadgetData extends GameResource {
return this.Id; return this.Id;
} }
public String getType() { public EntityType getType() {
return Type; return Type;
} }
......
...@@ -9,8 +9,9 @@ import emu.grasscutter.game.props.SceneType; ...@@ -9,8 +9,9 @@ import emu.grasscutter.game.props.SceneType;
@ResourceType(name = "SceneExcelConfigData.json") @ResourceType(name = "SceneExcelConfigData.json")
public class SceneData extends GameResource { public class SceneData extends GameResource {
private int Id; private int Id;
private SceneType SceneType; private SceneType Type;
private String ScriptData; private String ScriptData;
@Override @Override
public int getId() { public int getId() {
...@@ -18,7 +19,7 @@ public class SceneData extends GameResource { ...@@ -18,7 +19,7 @@ public class SceneData extends GameResource {
} }
public SceneType getSceneType() { public SceneType getSceneType() {
return SceneType; return Type;
} }
public String getScriptData() { public String getScriptData() {
...@@ -27,6 +28,6 @@ public class SceneData extends GameResource { ...@@ -27,6 +28,6 @@ public class SceneData extends GameResource {
@Override @Override
public void onLoad() { public void onLoad() {
} }
} }
package emu.grasscutter.game.dungeons;
import java.util.ArrayList;
import java.util.List;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.entity.GameEntity;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.net.proto.VisionTypeOuterClass.VisionType;
import emu.grasscutter.scripts.constants.EventType;
import emu.grasscutter.scripts.data.SceneGroup;
import emu.grasscutter.scripts.data.SceneMonster;
import emu.grasscutter.server.packet.send.PacketChallengeDataNotify;
import emu.grasscutter.server.packet.send.PacketDungeonChallengeBeginNotify;
import emu.grasscutter.server.packet.send.PacketDungeonChallengeFinishNotify;
import emu.grasscutter.server.packet.send.PacketSceneEntityAppearNotify;
public class DungeonChallenge {
private final Scene scene;
private final SceneGroup group;
private int challengeIndex;
private int challengeId;
private boolean success;
private boolean progress;
private int score;
private int objective = 0;
public DungeonChallenge(Scene scene, SceneGroup group) {
this.scene = scene;
this.group = group;
objective += group.monsters.size();
}
public Scene getScene() {
return scene;
}
public SceneGroup getGroup() {
return group;
}
public int getChallengeIndex() {
return challengeIndex;
}
public void setChallengeIndex(int challengeIndex) {
this.challengeIndex = challengeIndex;
}
public int getChallengeId() {
return challengeId;
}
public void setChallengeId(int challengeId) {
this.challengeId = challengeId;
}
public boolean isSuccess() {
return success;
}
public void setSuccess(boolean isSuccess) {
this.success = isSuccess;
}
public boolean inProgress() {
return progress;
}
public int getScore() {
return score;
}
public void start() {
this.progress = true;
getScene().broadcastPacket(new PacketDungeonChallengeBeginNotify(this));
}
public void finish() {
this.progress = false;
getScene().broadcastPacket(new PacketDungeonChallengeFinishNotify(this));
if (this.isSuccess()) {
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_SUCCESS, null);
} else {
this.getScene().getScriptManager().callEvent(EventType.EVENT_CHALLENGE_FAIL, null);
}
}
public void onMonsterDie(EntityMonster entity) {
score = getScore() + 1;
getScene().broadcastPacket(new PacketChallengeDataNotify(this, 1, getScore()));
if (getScore() >= objective) {
this.setSuccess(true);
finish();
}
}
}
package emu.grasscutter.game.dungeons; package emu.grasscutter.game.dungeons;
import emu.grasscutter.GameConstants;
import emu.grasscutter.Grasscutter;
import emu.grasscutter.data.GameData;
import emu.grasscutter.data.custom.ScenePointEntry;
import emu.grasscutter.data.def.DungeonData;
import emu.grasscutter.game.player.Player;
import emu.grasscutter.game.props.SceneType;
import emu.grasscutter.net.packet.BasePacket;
import emu.grasscutter.net.packet.PacketOpcodes;
import emu.grasscutter.server.game.GameServer; import emu.grasscutter.server.game.GameServer;
import emu.grasscutter.server.packet.send.PacketDungeonEntryInfoRsp;
import emu.grasscutter.server.packet.send.PacketPlayerEnterDungeonRsp;
import emu.grasscutter.utils.Position;
public class DungeonManager { public class DungeonManager {
private final GameServer server; private final GameServer server;
...@@ -12,4 +24,59 @@ public class DungeonManager { ...@@ -12,4 +24,59 @@ public class DungeonManager {
public GameServer getServer() { public GameServer getServer() {
return server; return server;
} }
public void getEntryInfo(Player player, int pointId) {
ScenePointEntry entry = GameData.getScenePointEntryById(player.getScene().getId(), pointId);
if (entry == null || entry.getPointData().getDungeonIds() == null) {
// Error
player.sendPacket(new PacketDungeonEntryInfoRsp());
return;
}
player.sendPacket(new PacketDungeonEntryInfoRsp(player, entry.getPointData()));
}
public void enterDungeon(Player player, int pointId, int dungeonId) {
DungeonData data = GameData.getDungeonDataMap().get(dungeonId);
if (data == null) {
return;
}
Grasscutter.getLogger().info(player.getNickname() + " is trying to enter dungeon " + dungeonId);
int sceneId = data.getSceneId();
player.getScene().setPrevScene(sceneId);
player.getWorld().transferPlayerToScene(player, sceneId, data);
player.getScene().setPrevScenePoint(pointId);
player.sendPacket(new PacketPlayerEnterDungeonRsp(pointId, dungeonId));
}
public void exitDungeon(Player player) {
if (player.getScene().getSceneType() != SceneType.SCENE_DUNGEON) {
return;
}
// Get previous scene
int prevScene = player.getScene().getPrevScene() > 0 ? player.getScene().getPrevScene() : 3;
// Get previous position
DungeonData dungeonData = player.getScene().getDungeonData();
Position prevPos = new Position(GameConstants.START_POSITION);
if (dungeonData != null) {
ScenePointEntry entry = GameData.getScenePointEntryById(prevScene, player.getScene().getPrevScenePoint());
if (entry != null) {
prevPos.set(entry.getPointData().getTranPos());
}
}
// Transfer player back to world
player.getWorld().transferPlayerToScene(player, prevScene, prevPos);
player.sendPacket(new BasePacket(PacketOpcodes.PlayerQuitDungeonRsp));
}
} }
package emu.grasscutter.game.entity;
import emu.grasscutter.game.world.Scene;
import emu.grasscutter.game.world.World;
public abstract class EntityBaseGadget extends GameEntity {
public EntityBaseGadget(Scene scene) {
super(scene);
}
public abstract int getGadgetId();
@Override
public void onDeath(int killerId) {
}
}
...@@ -23,7 +23,7 @@ import emu.grasscutter.utils.Position; ...@@ -23,7 +23,7 @@ import emu.grasscutter.utils.Position;
import emu.grasscutter.utils.ProtoHelper; import emu.grasscutter.utils.ProtoHelper;
import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap; import it.unimi.dsi.fastutil.ints.Int2FloatOpenHashMap;
public class EntityClientGadget extends EntityGadget { public class EntityClientGadget extends EntityBaseGadget {
private final Player owner; private final Player owner;
private final Position pos; private final Position pos;
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment