PlayerCommands.java 26.6 KB
Newer Older
Melledy's avatar
Melledy committed
1
2
package emu.grasscutter.commands;

KingRainbow44's avatar
KingRainbow44 committed
3
import emu.grasscutter.Grasscutter;
Melledy's avatar
Melledy committed
4
5
import emu.grasscutter.data.GenshinData;
import emu.grasscutter.data.def.ItemData;
6
import emu.grasscutter.data.def.AvatarData;
7
import emu.grasscutter.data.def.AvatarSkillDepotData;
Melledy's avatar
Melledy committed
8
9
import emu.grasscutter.data.def.MonsterData;
import emu.grasscutter.game.GenshinPlayer;
Melledy's avatar
Melledy committed
10
import emu.grasscutter.game.GenshinScene;
KingRainbow44's avatar
KingRainbow44 committed
11
import emu.grasscutter.game.World;
Melledy's avatar
Melledy committed
12
13
14
15
16
import emu.grasscutter.game.avatar.GenshinAvatar;
import emu.grasscutter.game.entity.EntityAvatar;
import emu.grasscutter.game.entity.EntityItem;
import emu.grasscutter.game.entity.EntityMonster;
import emu.grasscutter.game.inventory.GenshinItem;
KingRainbow44's avatar
KingRainbow44 committed
17
import emu.grasscutter.game.inventory.Inventory;
Melledy's avatar
Melledy committed
18
import emu.grasscutter.game.inventory.ItemType;
Yazawazi's avatar
Yazawazi committed
19
import emu.grasscutter.game.props.ClimateType;
Melledy's avatar
Melledy committed
20
21
import emu.grasscutter.game.props.ActionReason;
import emu.grasscutter.game.props.FightProperty;
SpikeHD's avatar
SpikeHD committed
22
import emu.grasscutter.game.props.PlayerProperty;
Melledy's avatar
Melledy committed
23
import emu.grasscutter.server.packet.send.PacketEntityFightPropUpdateNotify;
Yazawazi's avatar
Yazawazi committed
24
import emu.grasscutter.server.packet.send.PacketSceneAreaWeatherNotify;
25
import emu.grasscutter.server.packet.send.PacketGetPlayerTokenRsp;
Melledy's avatar
Melledy committed
26
import emu.grasscutter.server.packet.send.PacketItemAddHintNotify;
27
import emu.grasscutter.server.packet.send.PacketPlayerLoginRsp;
Melledy's avatar
Melledy committed
28
29
import emu.grasscutter.utils.Position;

KingRainbow44's avatar
KingRainbow44 committed
30
31
32
33
34
35
36
37
import java.util.LinkedList;
import java.util.List;

/**
 * A container for player-related commands.
 */
public final class PlayerCommands {
    @Command(label = "give", aliases = {"g", "item", "giveitem"}, 
38
            usage = "give [player] <itemId|itemName> [amount]", description = "Gives an item to you or the specified player", permission = "player.give")
KingRainbow44's avatar
KingRainbow44 committed
39
40
41
42
43
44
    public static class GiveCommand implements CommandHandler {

        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            int target, item, amount = 1;

45
            switch (args.size()) {
KingRainbow44's avatar
KingRainbow44 committed
46
47
48
49
50
51
                default:
                    CommandHandler.sendMessage(player, "Usage: give <player> <itemId|itemName> [amount]");
                    return;
                case 1:
                    try {
                        item = Integer.parseInt(args.get(0));
KingRainbow44's avatar
KingRainbow44 committed
52
                        target = player.getAccount().getPlayerId();
KingRainbow44's avatar
KingRainbow44 committed
53
54
55
56
57
58
59
60
61
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from item name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid item id.");
                        return;
                    }
                    break;
                case 2:
                    try {
                        target = Integer.parseInt(args.get(0));
Melledy's avatar
Melledy committed
62

63
64
65
                        if (Grasscutter.getGameServer().getPlayerByUid(target) == null) {
                            target = player.getUid();
                            amount = Integer.parseInt(args.get(1));
KingRainbow44's avatar
KingRainbow44 committed
66
67
68
69
70
71
72
73
74
75
76
77
78
                            item = Integer.parseInt(args.get(0));
                        } else {
                            item = Integer.parseInt(args.get(1));
                        }
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from item name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid item or player ID.");
                        return;
                    }
                    break;
                case 3:
                    try {
                        target = Integer.parseInt(args.get(0));
79
80
81
82

                        if (Grasscutter.getGameServer().getPlayerByUid(target) == null) {
                            CommandHandler.sendMessage(player, "Invalid player ID.");
                            return;
KingRainbow44's avatar
KingRainbow44 committed
83
84
85
86
87
88
89
90
91
92
93
94
                        }

                        item = Integer.parseInt(args.get(1));
                        amount = Integer.parseInt(args.get(2));
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from item name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid item or player ID.");
                        return;
                    }
                    break;
            }

95
            GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
Melledy's avatar
Melledy committed
96

97
98
99
            if (targetPlayer == null) {
                CommandHandler.sendMessage(player, "Player not found.");
                return;
KingRainbow44's avatar
KingRainbow44 committed
100
101
102
            }

            ItemData itemData = GenshinData.getItemDataMap().get(item);
103
104
105
            if (itemData == null) {
                CommandHandler.sendMessage(player, "Invalid item id.");
                return;
KingRainbow44's avatar
KingRainbow44 committed
106
            }
107

KingRainbow44's avatar
KingRainbow44 committed
108
109
110
111
112
113
            this.item(targetPlayer, itemData, amount);
        }

        /**
         * give [player] [itemId|itemName] [amount]
         */
114
115
116
        @Override
        public void execute(List<String> args) {
            if (args.size() < 2) {
KingRainbow44's avatar
KingRainbow44 committed
117
118
119
                CommandHandler.sendMessage(null, "Usage: give <player> <itemId|itemName> [amount]");
                return;
            }
120

KingRainbow44's avatar
KingRainbow44 committed
121
122
123
            try {
                int target = Integer.parseInt(args.get(0));
                int item = Integer.parseInt(args.get(1));
124
125
126
127
                int amount = 1;
                if (args.size() > 2)
                    amount = Integer.parseInt(args.get(2));

128
                GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
Melledy's avatar
Melledy committed
129

130
131
132
                if (targetPlayer == null) {
                    CommandHandler.sendMessage(null, "Player not found.");
                    return;
KingRainbow44's avatar
KingRainbow44 committed
133
                }
134

KingRainbow44's avatar
KingRainbow44 committed
135
                ItemData itemData = GenshinData.getItemDataMap().get(item);
136
137
138
                if (itemData == null) {
                    CommandHandler.sendMessage(null, "Invalid item id.");
                    return;
KingRainbow44's avatar
KingRainbow44 committed
139
                }
140

KingRainbow44's avatar
KingRainbow44 committed
141
142
143
144
145
                this.item(targetPlayer, itemData, amount);
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid item or player ID.");
            }
        }
146

KingRainbow44's avatar
KingRainbow44 committed
147
148
        private void item(GenshinPlayer player, ItemData itemData, int amount) {
            GenshinItem genshinItem = new GenshinItem(itemData);
149
            if (itemData.isEquip()) {
KingRainbow44's avatar
KingRainbow44 committed
150
                List<GenshinItem> items = new LinkedList<>();
151
                for (int i = 0; i < amount; i++) {
KingRainbow44's avatar
KingRainbow44 committed
152
                    items.add(genshinItem);
153
154
                }
                player.getInventory().addItems(items);
KingRainbow44's avatar
KingRainbow44 committed
155
156
157
158
159
160
161
162
163
                player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.SubfieldDrop));
            } else {
                genshinItem.setCount(amount);
                player.getInventory().addItem(genshinItem);
                player.sendPacket(new PacketItemAddHintNotify(genshinItem, ActionReason.SubfieldDrop));
            }
        }
    }
    @Command(label = "drop", aliases = {"d", "dropitem"}, 
164
165
            usage = "drop <itemId|itemName> [amount]",
            execution = Command.Execution.PLAYER, description = "Drops an item near you", permission = "server.drop")
KingRainbow44's avatar
KingRainbow44 committed
166
    public static class DropCommand implements CommandHandler {
167

KingRainbow44's avatar
KingRainbow44 committed
168
169
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
170
            if (args.size() < 1) {
KingRainbow44's avatar
KingRainbow44 committed
171
                CommandHandler.sendMessage(player, "Usage: drop <itemId|itemName> [amount]");
KingRainbow44's avatar
KingRainbow44 committed
172
173
                return;
            }
174

KingRainbow44's avatar
KingRainbow44 committed
175
176
            try {
                int item = Integer.parseInt(args.get(0));
177
178
179
                int amount = 1;
                if (args.size() > 1)
                    amount = Integer.parseInt(args.get(1));
Melledy's avatar
Melledy committed
180

KingRainbow44's avatar
KingRainbow44 committed
181
                ItemData itemData = GenshinData.getItemDataMap().get(item);
182
183
184
                if (itemData == null) {
                    CommandHandler.sendMessage(player, "Invalid item id.");
                    return;
KingRainbow44's avatar
KingRainbow44 committed
185
                }
186

KingRainbow44's avatar
KingRainbow44 committed
187
188
189
                if (itemData.isEquip()) {
                    float range = (5f + (.1f * amount));
                    for (int i = 0; i < amount; i++) {
190
191
                        Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2))
                                .addY(3f).addZ((float) (Math.random() * range) - (range / 2));
Melledy's avatar
Melledy committed
192
193
                        EntityItem entity = new EntityItem(player.getScene(), player, itemData, pos, 1);
                        player.getScene().addEntity(entity);
KingRainbow44's avatar
KingRainbow44 committed
194
195
                    }
                } else {
196
197
                    EntityItem entity = new EntityItem(player.getScene(), player, itemData,
                            player.getPos().clone().addY(3f), amount);
Melledy's avatar
Melledy committed
198
                    player.getScene().addEntity(entity);
KingRainbow44's avatar
KingRainbow44 committed
199
200
                }
            } catch (NumberFormatException ignored) {
KingRainbow44's avatar
KingRainbow44 committed
201
                CommandHandler.sendMessage(player, "Invalid item or player ID.");
KingRainbow44's avatar
KingRainbow44 committed
202
203
204
            }
        }
    }
SpikeHD's avatar
SpikeHD committed
205

206
207
    @Command(label = "givechar", aliases = { "givec" }, usage = "givechar <playerId> <avatarId> [level]",
            description = "Gives the player a specified character", permission = "player.givechar")
SpikeHD's avatar
SpikeHD committed
208
    public static class GiveCharCommand implements CommandHandler {
209
210
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
KingRainbow44's avatar
KingRainbow44 committed
211
            int target, avatarId, level = 1, ascension = 1;
SpikeHD's avatar
SpikeHD committed
212

213
            if (args.size() < 1) {
KingRainbow44's avatar
KingRainbow44 committed
214
                CommandHandler.sendMessage(player, "Usage: givechar <player> <avatarId> [level]");
215
216
                return;
            }
217
218

            switch (args.size()) {
219
                default:
220
                    CommandHandler.sendMessage(player, "Usage: givechar <player> <avatarId> [level]");
221
222
223
224
                    return;
                case 2:
                    try {
                        target = Integer.parseInt(args.get(0));
225
226
                        if (Grasscutter.getGameServer().getPlayerByUid(target) == null) {
                            target = player.getUid();
KingRainbow44's avatar
KingRainbow44 committed
227
                            level = Integer.parseInt(args.get(1));
KingRainbow44's avatar
KingRainbow44 committed
228
                            avatarId = Integer.parseInt(args.get(0));
229
                        } else {
KingRainbow44's avatar
KingRainbow44 committed
230
                            avatarId = Integer.parseInt(args.get(1));
231
232
233
234
235
236
237
238
239
240
                        }
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from avatar name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid avatar or player ID.");
                        return;
                    }
                    break;
                case 3:
                    try {
                        target = Integer.parseInt(args.get(0));
241
242
243
                        if (Grasscutter.getGameServer().getPlayerByUid(target) == null) {
                            CommandHandler.sendMessage(player, "Invalid player ID.");
                            return;
244
245
                        }

KingRainbow44's avatar
KingRainbow44 committed
246
                        avatarId = Integer.parseInt(args.get(1));
247
248
249
250
251
252
253
254
                        level = Integer.parseInt(args.get(2));
                    } catch (NumberFormatException ignored) {
                        // TODO: Parse from avatar name using GM Handbook.
                        CommandHandler.sendMessage(player, "Invalid avatar or player ID.");
                        return;
                    }
                    break;
            }
SpikeHD's avatar
SpikeHD committed
255

Melledy's avatar
Melledy committed
256
            GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
257
258
259
            if (targetPlayer == null) {
                CommandHandler.sendMessage(player, "Player not found.");
                return;
SpikeHD's avatar
SpikeHD committed
260
            }
261

KingRainbow44's avatar
KingRainbow44 committed
262
            AvatarData avatarData = GenshinData.getAvatarDataMap().get(avatarId);
263
264
265
            if (avatarData == null) {
                CommandHandler.sendMessage(player, "Invalid avatar id.");
                return;
SpikeHD's avatar
SpikeHD committed
266
267
            }

268
269
            // Calculate ascension level.
            if (level <= 40) {
KingRainbow44's avatar
KingRainbow44 committed
270
271
272
                ascension = (int) Math.ceil(level / 20f);
            } else {
                ascension = (int) Math.ceil(level / 10f) - 3;
273
274
            }

KingRainbow44's avatar
KingRainbow44 committed
275
            GenshinAvatar avatar = new GenshinAvatar(avatarId);
SpikeHD's avatar
SpikeHD committed
276
            avatar.setLevel(level);
277
            avatar.setPromoteLevel(ascension);
278

279
280
            // This will handle stats and talents
            avatar.recalcStats();
281

282
283
            targetPlayer.addAvatar(avatar);
        }
SpikeHD's avatar
SpikeHD committed
284

285
286
        @Override
        public void execute(List<String> args) {
287
            if (args.size() < 2) {
SpikeHD's avatar
SpikeHD committed
288
                CommandHandler.sendMessage(null, "Usage: givechar <player> <itemId|itemName> [amount]");
289
290
291
292
293
294
                return;
            }

            try {
                int target = Integer.parseInt(args.get(0));
                int avatarID = Integer.parseInt(args.get(1));
295
296
297
                int level = 1;
                if (args.size() > 2)
                    level = Integer.parseInt(args.get(2));
KingRainbow44's avatar
KingRainbow44 committed
298
                int ascension;
299

Melledy's avatar
Melledy committed
300
                GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
301
302
303
                if (targetPlayer == null) {
                    CommandHandler.sendMessage(null, "Player not found.");
                    return;
304
                }
305

306
                AvatarData avatarData = GenshinData.getAvatarDataMap().get(avatarID);
307
308
309
                if (avatarData == null) {
                    CommandHandler.sendMessage(null, "Invalid avatar id.");
                    return;
310
                }
311

312
313
                // Calculate ascension level.
                if (level <= 40) {
KingRainbow44's avatar
KingRainbow44 committed
314
315
316
                    ascension = (int) Math.ceil(level / 20f);
                } else {
                    ascension = (int) Math.ceil(level / 10f) - 3;
317
                }
318

319
320
                GenshinAvatar avatar = new GenshinAvatar(avatarID);
                avatar.setLevel(level);
321
                avatar.setPromoteLevel(ascension);
322
323
324

                // This will handle stats and talents
                avatar.recalcStats();
325

326
327
328
329
                targetPlayer.addAvatar(avatar);
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid item or player ID.");
            }
SpikeHD's avatar
SpikeHD committed
330
331
        }
    }
Melledy's avatar
Melledy committed
332

KingRainbow44's avatar
KingRainbow44 committed
333
    @Command(label = "spawn", execution = Command.Execution.PLAYER, 
334
            usage = "spawn <entityId|entityName> [level] [amount]", description = "Spawns an entity near you", permission = "server.spawn")
KingRainbow44's avatar
KingRainbow44 committed
335
    public static class SpawnCommand implements CommandHandler {
336

KingRainbow44's avatar
KingRainbow44 committed
337
338
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
339
            if (args.size() < 1) {
KingRainbow44's avatar
KingRainbow44 committed
340
341
342
                CommandHandler.sendMessage(null, "Usage: spawn <entityId|entityName> [amount]");
                return;
            }
343

KingRainbow44's avatar
KingRainbow44 committed
344
345
            try {
                int entity = Integer.parseInt(args.get(0));
346
347
348
349
350
351
                int level = 1;
                if (args.size() > 1)
                    level = Integer.parseInt(args.get(1));
                int amount = 1;
                if (args.size() > 2)
                    amount = Integer.parseInt(args.get(2));
352

KingRainbow44's avatar
KingRainbow44 committed
353
                MonsterData entityData = GenshinData.getMonsterDataMap().get(entity);
354
355
356
                if (entityData == null) {
                    CommandHandler.sendMessage(null, "Invalid entity id.");
                    return;
KingRainbow44's avatar
KingRainbow44 committed
357
                }
358

KingRainbow44's avatar
KingRainbow44 committed
359
360
                float range = (5f + (.1f * amount));
                for (int i = 0; i < amount; i++) {
361
362
                    Position pos = player.getPos().clone().addX((float) (Math.random() * range) - (range / 2)).addY(3f)
                            .addZ((float) (Math.random() * range) - (range / 2));
Melledy's avatar
Melledy committed
363
364
                    EntityMonster monster = new EntityMonster(player.getScene(), entityData, pos, level);
                    player.getScene().addEntity(monster);
KingRainbow44's avatar
KingRainbow44 committed
365
366
367
368
369
370
371
372
                }
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid item or player ID.");
            }
        }
    }
    
    @Command(label = "killall", 
373
            usage = "killall [playerUid] [sceneId]", description = "Kill all entities", permission = "server.killall")
KingRainbow44's avatar
KingRainbow44 committed
374
    public static class KillAllCommand implements CommandHandler {
375

KingRainbow44's avatar
KingRainbow44 committed
376
377
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
Melledy's avatar
Melledy committed
378
379
            GenshinScene scene = player.getScene();
            scene.getEntities().values().stream()
KingRainbow44's avatar
KingRainbow44 committed
380
                    .filter(entity -> entity instanceof EntityMonster)
Melledy's avatar
Melledy committed
381
382
                    .forEach(entity -> scene.killEntity(entity, 0));
            CommandHandler.sendMessage(null, "Killing all monsters in scene " + scene.getId());
KingRainbow44's avatar
KingRainbow44 committed
383
        }
384

KingRainbow44's avatar
KingRainbow44 committed
385
386
        @Override
        public void execute(List<String> args) {
387
388
389
            if (args.size() < 2) {
                CommandHandler.sendMessage(null, "Usage: killall [playerUid] [sceneId]");
                return;
KingRainbow44's avatar
KingRainbow44 committed
390
            }
391

KingRainbow44's avatar
KingRainbow44 committed
392
            try {
393
                int playerUid = Integer.parseInt(args.get(0));
Melledy's avatar
Melledy committed
394
                int sceneId = Integer.parseInt(args.get(1));
395

396
                GenshinPlayer player = Grasscutter.getGameServer().getPlayerByUid(playerUid);
Melledy's avatar
Melledy committed
397
                if (player == null) {
398
399
                    CommandHandler.sendMessage(null, "Player not found or offline.");
                    return;
Melledy's avatar
Melledy committed
400
                }
401

Melledy's avatar
Melledy committed
402
403
                GenshinScene scene = player.getWorld().getSceneById(sceneId);
                if (scene == null) {
404
405
                    CommandHandler.sendMessage(null, "Scene not found in player world");
                    return;
Melledy's avatar
Melledy committed
406
                }
407

Melledy's avatar
Melledy committed
408
409
410
411
                scene.getEntities().values().stream()
                        .filter(entity -> entity instanceof EntityMonster)
                        .forEach(entity -> scene.killEntity(entity, 0));
                CommandHandler.sendMessage(null, "Killing all monsters in scene " + scene.getId());
KingRainbow44's avatar
KingRainbow44 committed
412
            } catch (NumberFormatException ignored) {
Melledy's avatar
Melledy committed
413
                CommandHandler.sendMessage(null, "Invalid arguments.");
KingRainbow44's avatar
KingRainbow44 committed
414
415
416
            }
        }
    }
417

KingRainbow44's avatar
KingRainbow44 committed
418
    @Command(label = "resetconst", aliases = {"resetconstellation"}, 
419
420
            usage = "resetconst [all]", execution = Command.Execution.PLAYER, permission = "player.resetconstellation",
            description = "Resets the constellation level on your current active character, will need to relog after using the command to see any changes.")
KingRainbow44's avatar
KingRainbow44 committed
421
    public static class ResetConstellationCommand implements CommandHandler {
422

KingRainbow44's avatar
KingRainbow44 committed
423
424
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
425
            if (args.size() > 0 && args.get(0).equalsIgnoreCase("all")) {
KingRainbow44's avatar
KingRainbow44 committed
426
427
428
                player.getAvatars().forEach(this::resetConstellation);
                player.dropMessage("Reset all avatars' constellations.");
            } else {
429
430
                EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                if (entity == null)
KingRainbow44's avatar
KingRainbow44 committed
431
                    return;
432

KingRainbow44's avatar
KingRainbow44 committed
433
434
                GenshinAvatar avatar = entity.getAvatar();
                this.resetConstellation(avatar);
435

436
437
                player.dropMessage("Constellations for " + avatar.getAvatarData().getName()
                        + " have been reset. Please relog to see changes.");
KingRainbow44's avatar
KingRainbow44 committed
438
439
            }
        }
440

KingRainbow44's avatar
KingRainbow44 committed
441
442
443
444
445
446
447
        private void resetConstellation(GenshinAvatar avatar) {
            avatar.getTalentIdList().clear();
            avatar.setCoreProudSkillLevel(0);
            avatar.recalcStats();
            avatar.save();
        }
    }
memetrollsXD's avatar
memetrollsXD committed
448
  
KingRainbow44's avatar
KingRainbow44 committed
449
    @Command(label = "godmode",
450
            usage = "godmode", execution = Command.Execution.PLAYER, description = "Prevents you from taking damage", permission = "player.godmode")
KingRainbow44's avatar
KingRainbow44 committed
451
    public static class GodModeCommand implements CommandHandler {
452

KingRainbow44's avatar
KingRainbow44 committed
453
454
455
456
457
458
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            player.setGodmode(!player.inGodmode());
            player.dropMessage("Godmode is now " + (player.inGodmode() ? "enabled" : "disabled") + ".");
        }
    }
459

KingRainbow44's avatar
KingRainbow44 committed
460
    @Command(label = "sethealth", aliases = {"sethp"}, 
461
462
            usage = "sethealth <hp>", execution = Command.Execution.PLAYER, description = "Sets your health to the specified value",
            permission = "player.sethealth")
KingRainbow44's avatar
KingRainbow44 committed
463
    public static class SetHealthCommand implements CommandHandler {
464

KingRainbow44's avatar
KingRainbow44 committed
465
466
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
467
468
469
            if (args.size() < 1) {
                CommandHandler.sendMessage(null, "Usage: sethealth <hp>");
                return;
KingRainbow44's avatar
KingRainbow44 committed
470
            }
471

KingRainbow44's avatar
KingRainbow44 committed
472
473
474
            try {
                int health = Integer.parseInt(args.get(0));
                EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
475
                if (entity == null)
KingRainbow44's avatar
KingRainbow44 committed
476
                    return;
477

KingRainbow44's avatar
KingRainbow44 committed
478
                entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, health);
479
480
                entity.getWorld().broadcastPacket(
                        new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
KingRainbow44's avatar
KingRainbow44 committed
481
482
483
484
485
486
                player.dropMessage("Health set to " + health + ".");
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid health value.");
            }
        }
    }
SpikeHD's avatar
SpikeHD committed
487

488
489
490
    @Command(label = "setworldlevel", aliases = {"setworldlvl"}, usage = "setworldlevel <level>",
            description = "Sets your world level (Relog to see proper effects)", permission = "player.setworldlevel",
            execution = Command.Execution.PLAYER)
SpikeHD's avatar
SpikeHD committed
491
492
493
    public static class SetWorldLevelCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
494
495
496
            if (args.size() < 1) {
                CommandHandler.sendMessage(player, "Usage: setworldlevel <level>");
                return;
SpikeHD's avatar
SpikeHD committed
497
            }
498

SpikeHD's avatar
SpikeHD committed
499
500
501
502
503
504
505
506
507
508
509
510
511
            try {
                int level = Integer.parseInt(args.get(0));

                // Set in both world and player props
                player.getWorld().setWorldLevel(level);
                player.setProperty(PlayerProperty.PROP_PLAYER_WORLD_LEVEL, level);

                player.dropMessage("World level set to " + level + ".");
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid world level.");
            }
        }
    }
memetrollsXD's avatar
memetrollsXD committed
512
  
KingRainbow44's avatar
KingRainbow44 committed
513
    @Command(label = "clearartifacts", aliases = {"clearart"}, 
514
515
            usage = "clearartifacts", execution = Command.Execution.PLAYER, permission = "player.clearartifacts",
            description = "Deletes all unequipped and unlocked level 0 artifacts, including yellow rarity ones from your inventory")
KingRainbow44's avatar
KingRainbow44 committed
516
517
518
519
520
521
522
523
524
525
526
    public static class ClearArtifactsCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            Inventory playerInventory = player.getInventory();
            playerInventory.getItems().values().stream()
                    .filter(item -> item.getItemType() == ItemType.ITEM_RELIQUARY)
                    .filter(item -> item.getLevel() == 1 && item.getExp() == 0)
                    .filter(item -> !item.isLocked() && !item.isEquipped())
                    .forEach(item -> playerInventory.removeItem(item, item.getCount()));
        }
    }
527

Melledy's avatar
Melledy committed
528
    @Command(label = "changescene", aliases = {"scene"}, 
529
            usage = "changescene <scene id>", description = "Changes your scene", permission = "player.changescene", execution = Command.Execution.PLAYER)
Melledy's avatar
Melledy committed
530
531
532
    public static class ChangeSceneCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
533
534
535
            if (args.size() < 1) {
                CommandHandler.sendMessage(player, "Usage: changescene <scene id>");
                return;
Melledy's avatar
Melledy committed
536
            }
537

Melledy's avatar
Melledy committed
538
            try {
KingRainbow44's avatar
KingRainbow44 committed
539
540
541
542
543
544
                int sceneId = Integer.parseInt(args.get(0));
                boolean result = player.getWorld().transferPlayerToScene(player, sceneId, player.getPos());

                if (!result) {
                    CommandHandler.sendMessage(null, "Scene does not exist or you are already in it");
                }
Melledy's avatar
Melledy committed
545
            } catch (Exception e) {
546
547
                CommandHandler.sendMessage(player, "Usage: changescene <scene id>");
                return;
Melledy's avatar
Melledy committed
548
549
550
            }
        }
    }
551

552
553
554
555
556
557
558
559
560
561
562
563
564
565
    @Command(label = "sendservermessage", aliases = {"sendservmsg"},
            usage = "sendservermessage <player> <message>", description = "Sends a message to a player as the server",
            execution = Command.Execution.PLAYER, permission = "server.sendmessage")
    public static class SendServerMessageCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if(args.size() < 2) {
                CommandHandler.sendMessage(null, "Usage: sendmessage <player> <message>"); return;
            }

            try {
                int target = Integer.parseInt(args.get(0));
                String message = String.join(" ", args.subList(1, args.size()));

566
                GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
567
568
569
570
571
572
573
574
575
576
577
                if(targetPlayer == null) {
                    CommandHandler.sendMessage(null, "Player not found."); return;
                }

                targetPlayer.dropMessage(message);
                CommandHandler.sendMessage(null, "Message sent.");
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid player ID.");
            }
        }
    }
Yazawazi's avatar
Yazawazi committed
578
    
alt3ri's avatar
alt3ri committed
579
580
581
582
583
584
585
586
587
588
    @Command(label = "pos",
            usage = "Usage: pos", description = "Get coordinates.",
            execution = Command.Execution.PLAYER)
    public static class CordCommand implements CommandHandler {
        
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            player.dropMessage(String.format("Coord: %.3f, %.3f, %.3f", player.getPos().getX(), player.getPos().getY(), player.getPos().getZ()));
        }
    }
589
  
Yazawazi's avatar
Yazawazi committed
590
591
592
593
    @Command(label = "weather", aliases = {"weather", "w"},
        usage = "weather <weather id>", description = "Changes the weather.",
        execution = Command.Execution.PLAYER, permission = "player.weather"
    )
594
    public static class ChangeWeatherCommand implements CommandHandler {
Yazawazi's avatar
Yazawazi committed
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
            if (args.size() < 1) {
                CommandHandler.sendMessage(player, "Usage: weather <weather id>");
                return;
            }
            
            try {
                int weatherId = Integer.parseInt(args.get(0));

                ClimateType climate = ClimateType.getTypeByValue(weatherId);

                player.getScene().setClimate(climate);
                player.getScene().broadcastPacket(new PacketSceneAreaWeatherNotify(player));
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(player, "Invalid weather ID.");
            }
        }
    }
614

memetrollsXD's avatar
memetrollsXD committed
615
616
    @Command(label = "restart", usage = "Usage: restart", description = "Restarts the current session", execution = Command.Execution.PLAYER, permission = "player.restart")
    public static class RestartCommand implements CommandHandler {
617
618
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
619
            player.getSession().close();
620
621
        }
    }
Melledy's avatar
Melledy committed
622
}