PlayerCommands.java 31.5 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
import java.util.LinkedList;
import java.util.List;

/**
 * A container for player-related commands.
 */
public final class PlayerCommands {
memetrollsXD's avatar
memetrollsXD committed
37
38
    @Command(label = "give", aliases = {"g", "item", "giveitem"}, 
            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
                player.sendPacket(new PacketItemAddHintNotify(items, ActionReason.SubfieldDrop));
            } else {
                genshinItem.setCount(amount);
                player.getInventory().addItem(genshinItem);
                player.sendPacket(new PacketItemAddHintNotify(genshinItem, ActionReason.SubfieldDrop));
            }
        }
    }
memetrollsXD's avatar
memetrollsXD committed
163
164
165
    @Command(label = "drop", aliases = {"d", "dropitem"}, 
            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

memetrollsXD's avatar
memetrollsXD committed
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

memetrollsXD's avatar
memetrollsXD committed
333
334
    @Command(label = "spawn", execution = Command.Execution.PLAYER, 
            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
                }
            } catch (NumberFormatException ignored) {
                CommandHandler.sendMessage(null, "Invalid item or player ID.");
            }
        }
    }
memetrollsXD's avatar
memetrollsXD committed
371
372
373
    
    @Command(label = "killall", 
            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

memetrollsXD's avatar
memetrollsXD committed
418
419
420
    @Command(label = "resetconst", aliases = {"resetconstellation"}, 
            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
449
450
  
    @Command(label = "godmode",
            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

alt3ri's avatar
alt3ri committed
460
461
462
463
@Command(label = "setstats", aliases = {"stats"}, 
            usage = "Usage: setstats|stats <hp|def|atk|em|er|crate|cdmg> <value>", execution = Command.Execution.PLAYER)
    public static class SetStatsCommand implements CommandHandler {
        @Override    
KingRainbow44's avatar
KingRainbow44 committed
464
        public void execute(GenshinPlayer player, List<String> args) {
alt3ri's avatar
alt3ri committed
465
466
467
468
            String stat = args.get(0);
            switch(stat){
                default:
                    CommandHandler.sendMessage(player, "Usage: setstats|stats <hp|def|atk|em|er|crate|cdmg> <value>");
KingRainbow44's avatar
KingRainbow44 committed
469
                    return;
alt3ri's avatar
alt3ri committed
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
                case "hp":
                    try {
                        int health = Integer.parseInt(args.get(1));
                        EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                        entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_HP, health);
                        entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_HP));
                        player.dropMessage("HP set to " + health + ".");
                    } catch (NumberFormatException ignored) {
                        CommandHandler.sendMessage(null, "Invalid HP value.");
                       return;
                    }
                    break;
                case "def":
                    try {
                        int def = Integer.parseInt(args.get(1));
                        EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                        entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_DEFENSE, def);
                        entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_DEFENSE));
                        player.dropMessage("DEF set to " + def + ".");
                    } catch (NumberFormatException ignored) {
                        CommandHandler.sendMessage(null, "Invalid DEF value.");
                        return;
                    }
                    break; 
                case "atk":
                    try {
                        int atk = Integer.parseInt(args.get(1));
                        EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                        entity.setFightProperty(FightProperty.FIGHT_PROP_CUR_ATTACK, atk);
                        entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CUR_ATTACK));
                        player.dropMessage("ATK set to " + atk + ".");
                    } catch (NumberFormatException ignored) {
                        CommandHandler.sendMessage(null, "Invalid ATK value.");
                        return;
                    }
                    break; 
                case "em":
                    try {
                        int em = Integer.parseInt(args.get(1));
                        EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity(); 
                        entity.setFightProperty(FightProperty.FIGHT_PROP_ELEMENT_MASTERY, em);
                        entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_ELEMENT_MASTERY));
                        player.dropMessage("Elemental Mastery set to " + em + ".");
                    } catch (NumberFormatException ignored) {
                        CommandHandler.sendMessage(null, "Invalid EM value.");
                        return;
                    }
                    break;
                case "er":
                    try {
                        float er = Integer.parseInt(args.get(1));                    
                        EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                        float erecharge = er / 10000;
                        entity.setFightProperty(FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY, erecharge);
                        entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CHARGE_EFFICIENCY));                      
                        float iger = erecharge * 100;
                        player.dropMessage("Energy recharge set to " + iger + "%.");     
                    } catch (NumberFormatException ignored) {
                        CommandHandler.sendMessage(null, "Invalid ER value.");
                        return;
                    }
                    break; 
                case "crate":
                    try {
                        float cr = Integer.parseInt(args.get(1));
                        EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                        float crate = cr / 10000;
                        entity.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL, crate);
                        entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CRITICAL));
                        float igcrate = crate * 100;
                        player.dropMessage("Crit Rate set to " + igcrate + "%.");
                        
                    } catch (NumberFormatException ignored) {
                        CommandHandler.sendMessage(null, "Invalid Crit Rate value.");
                        return;
                    }
                    break;     
                case "cdmg":
                    try {
                        float cdmg = Integer.parseInt(args.get(1));
                        EntityAvatar entity = player.getTeamManager().getCurrentAvatarEntity();
                        float cdamage = cdmg / 10000;
                        entity.setFightProperty(FightProperty.FIGHT_PROP_CRITICAL_HURT, cdamage);
                        entity.getWorld().broadcastPacket(new PacketEntityFightPropUpdateNotify(entity, FightProperty.FIGHT_PROP_CRITICAL_HURT));
                        float igcdmg = cdamage * 100;
                        player.dropMessage("Crit DMG set to " + igcdmg + "%");
                        
                    } catch (NumberFormatException ignored) {
                        CommandHandler.sendMessage(null, "Invalid Crit DMG value.");
                        return;
                    }
                    break;    
                
KingRainbow44's avatar
KingRainbow44 committed
563
            }
alt3ri's avatar
alt3ri committed
564
        }  
KingRainbow44's avatar
KingRainbow44 committed
565
    }
SpikeHD's avatar
SpikeHD committed
566

memetrollsXD's avatar
memetrollsXD committed
567
568
569
    @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
570
571
572
    public static class SetWorldLevelCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
573
574
575
            if (args.size() < 1) {
                CommandHandler.sendMessage(player, "Usage: setworldlevel <level>");
                return;
SpikeHD's avatar
SpikeHD committed
576
            }
577

SpikeHD's avatar
SpikeHD committed
578
579
580
581
582
583
584
585
586
587
588
589
590
            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
591
592
593
594
  
    @Command(label = "clearartifacts", aliases = {"clearart"}, 
            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
595
596
597
598
599
600
601
602
603
604
605
    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()));
        }
    }
606

memetrollsXD's avatar
memetrollsXD committed
607
608
    @Command(label = "changescene", aliases = {"scene"}, 
            usage = "changescene <scene id>", description = "Changes your scene", permission = "player.changescene", execution = Command.Execution.PLAYER)
Melledy's avatar
Melledy committed
609
610
611
    public static class ChangeSceneCommand implements CommandHandler {
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
612
613
614
            if (args.size() < 1) {
                CommandHandler.sendMessage(player, "Usage: changescene <scene id>");
                return;
Melledy's avatar
Melledy committed
615
            }
616

Melledy's avatar
Melledy committed
617
            try {
KingRainbow44's avatar
KingRainbow44 committed
618
619
620
621
622
623
                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
624
            } catch (Exception e) {
625
626
                CommandHandler.sendMessage(player, "Usage: changescene <scene id>");
                return;
Melledy's avatar
Melledy committed
627
628
629
            }
        }
    }
630

memetrollsXD's avatar
memetrollsXD committed
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
    @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()));

                GenshinPlayer targetPlayer = Grasscutter.getGameServer().getPlayerByUid(target);
                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.");
            }
        }
    }
alt3ri's avatar
alt3ri committed
657
658
659
660
661
662
663
664
665
666
667
    
    @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()));
        }
    }
668
  
Yazawazi's avatar
Yazawazi committed
669
670
671
672
    @Command(label = "weather", aliases = {"weather", "w"},
        usage = "weather <weather id>", description = "Changes the weather.",
        execution = Command.Execution.PLAYER, permission = "player.weather"
    )
673
    public static class ChangeWeatherCommand implements CommandHandler {
Yazawazi's avatar
Yazawazi committed
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
        @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.");
            }
        }
    }
693

memetrollsXD's avatar
memetrollsXD committed
694
695
    @Command(label = "restart", usage = "Usage: restart", description = "Restarts the current session", execution = Command.Execution.PLAYER, permission = "player.restart")
    public static class RestartCommand implements CommandHandler {
696
697
        @Override
        public void execute(GenshinPlayer player, List<String> args) {
698
            player.getSession().close();
699
700
        }
    }
Melledy's avatar
Melledy committed
701
}