diff --git a/src/main/java/kroppeb/server/command/commands/EffectCommand.java b/src/main/java/kroppeb/server/command/commands/EffectCommand.java new file mode 100644 index 0000000..b0b68cd --- /dev/null +++ b/src/main/java/kroppeb/server/command/commands/EffectCommand.java @@ -0,0 +1,153 @@ +/* +* Copyright (c) 2020 MadHau5 +* This Source Code Form is subject to the terms of the Mozilla Public +* License, v. 2.0. If a copy of the MPL was not distributed with this +* file, You can obtain one at http://mozilla.org/MPL/2.0/. +*/ + +package kroppeb.server.command.commands; + +import kroppeb.server.command.Command; +import kroppeb.server.command.arguments.Selector; +import kroppeb.server.command.reader.Reader; +import kroppeb.server.command.reader.ReaderException; +import net.minecraft.entity.Entity; +import net.minecraft.entity.LivingEntity; +import net.minecraft.entity.effect.StatusEffect; +import net.minecraft.entity.effect.StatusEffectInstance; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.util.registry.Registry; + +import java.util.Collection; + +abstract public class EffectCommand implements Command { + final Selector targets; + final StatusEffect effect; + + public static EffectCommand read(Reader reader) throws ReaderException { + String sub = reader.readLiteral(); + switch (sub) { + case "give": + return GiveCommand.read(reader); + case "clear": + return ClearCommand.read(reader); + default: + throw new ReaderException("Unexpected effect literal: " + sub); + } + + } + + public static class GiveCommand extends EffectCommand { + final int duration; + final int amplifier; + final boolean hideParticles; + + public GiveCommand(Selector targets, StatusEffect effect, int duration, int amplifier, boolean hideParticles) { + this.targets = targets; + this.effect = effect; + this.duration = duration; + this.amplifier = amplifier; + this.hideParticles = hideParticles; + } + + public static GiveCommand read(Reader reader) throws ReaderException { + Selector targets = Selector.read(reader); + StatusEffect effect = Registry.STATUS_EFFECT.get(reader.readIdentifier()); + int duration; + int amplifier = 0; + boolean hideParticles = false; + if (reader.hasNext()) { + reader.moveNext(); + duration = reader.readInt(); + } else { + duration = -1; + } + if (reader.hasNext()) { + reader.moveNext(); + amplifier = reader.readInt(); + } + if (reader.hasNext()) { + String bool = reader.readLiteral(); + switch (bool) { + case "true": + hideParticles = true; + break; + case "false": + hideParticles = false; + break; + default: + throw new ReaderException("Unexpected boolean literal: " + bool); + } + } + return new GiveCommand(targets, effect, duration, amplifier, hideParticles); + } + + public int execute(ServerCommandSource source) { + int e = 0; + Collection entities = targets.getEntities(source); + for (Entity entity : entities) { + if (entity instanceof LivingEntity) { + LivingEntity livingEntity = (LivingEntity) entity; + if (effect.isInstant()) { + if (duration == -1) { + duration = 1; + } + } else { + if (duration == -1) { + duration = 30; + } + duration *= 20; + } + livingEntity.addStatusEffect(new StatusEffectInstance(effect, + duration, amplifier, false, hideParticles)); + e++; + } + } + if (e == 0) { + // TODO: throw error on failed command + } + return e; + } + } + + public static class ClearCommand extends EffectCommand { + + public ClearCommand(Selector targets, StatusEffect effect) { + this.targets = targets; + this.effect = null; + } + + public static ClearCommand read(Reader reader) throws ReaderException { + Selector targets = Selector.read(reader); + StatusEffect effect; + if (reader.hasNext()) { + effect = Registry.STATUS_EFFECT.get(reader.readIdentifier()); + } + return new ClearCommand(targets, effect); + } + + public int execute(ServerCommandSource source) { + int e = 0; + Collection entities = targets.getEntities(source); + if (effect == null) { + for (Entity entity : entities) { + if (entity instanceof LivingEntity) { + ((LivingEntity) entity).clearStatusEffects(); + e++; + } + } + } else { + for (Entity entity : entities) { + if (entity instanceof LivingEntity) { + ((LivingEntity) entity).removeStatusEffect(effect); + e++; + } + } + } + if (e == 0) { + // TODO: throw error on failed command + } + return e; + } + } +} diff --git a/src/main/java/kroppeb/server/command/commands/GameModeCommand.java b/src/main/java/kroppeb/server/command/commands/GameModeCommand.java new file mode 100644 index 0000000..d3e7e42 --- /dev/null +++ b/src/main/java/kroppeb/server/command/commands/GameModeCommand.java @@ -0,0 +1,60 @@ +/* + * Copyright (c) 2020 MadHau5 + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package kroppeb.server.command.commands; + +import kroppeb.server.command.Command; +import kroppeb.server.command.arguments.Selector; +import kroppeb.server.command.reader.Reader; +import kroppeb.server.command.reader.ReaderException; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; +import net.minecraft.world.GameMode; + +import java.util.Collection; + +abstract public class GameModeCommand implements Command { + final Selector targets; + final GameMode gm; + + public GameModeCommand(Selector targets, GameMode gm) { + this.targets = targets; + this.gm = gm; + } + + public static GameModeCommand read(Reader reader) throws ReaderException { + Selector targets = null; + GameMode gm = GameMode.byName(reader.readLiteral()); // TODO: handle custom gamemodes + if (reader.hasNext()) { + targets = Selector.read(reader); + } + return new GameModeCommand(targets, gm); + } + + public int execute(ServerCommandSource source) { + int e = 0; + Collection entities; + if (targets == null) { + entities = Collections.singleton(source.getPlayer()); + } else { + entities = targets.getEntities(source); + } + for (Entity entity : entities) { + if (entity instanceof PlayerEntity) { + ((PlayerEntity) entity).setGameMode(gm); + e++; + } + } + if (e == 0) { + // TODO: throw error on failed command + } + return e; + } +} diff --git a/src/main/java/kroppeb/server/command/commands/GiveCommand.java b/src/main/java/kroppeb/server/command/commands/GiveCommand.java new file mode 100644 index 0000000..86e9ac0 --- /dev/null +++ b/src/main/java/kroppeb/server/command/commands/GiveCommand.java @@ -0,0 +1,85 @@ +/* + * Copyright (c) 2020 MadHau5 + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. + */ + +package kroppeb.server.command.commands; + +import kroppeb.server.command.Command; +import kroppeb.server.command.arguments.Selector; +import kroppeb.server.command.reader.Reader; +import kroppeb.server.command.reader.ReaderException; +import net.minecraft.entity.Entity; +import net.minecraft.entity.player.PlayerEntity; +import net.minecraft.item.Item; +import net.minecraft.item.ItemStack; +import net.minecraft.server.command.ServerCommandSource; +import net.minecraft.util.Identifier; +import net.minecraft.util.registry.Registry; + +import java.util.Collection; + +abstract public class GiveCommand implements Command { + final Selector targets; + final Identifier item; + final CompoundTag nbt; + final int count; + + public GiveCommand(Selector targets, Identifier item, CompoundTag nbt, int count) { + this.targets = targets; + this.item = item; + this.nbt = nbt; + this.count = count; + } + + public static GiveCommand read(Reader reader) throws ReaderException { + Selector targets = Selector.read(reader); + Identifier item = Registry.ITEM.get(reader.readIdentifier()); + CompoundTag nbt; + int count = 1; + if (reader.hasNext()) { + // nbt = ???; + // TODO: Process NBT tags + } + if (reader.hasNext()) { + reader.moveNext(); + count = reader.readInt(); + } + return new GiveCommand(targets, item, nbt, count); + } + + public int execute(ServerCommandSource source) { + int e = 0; + + int stackMax = item.getMaxCount(); + int stackCount = count / stackMax; + ItemStack stack = ItemStack(item, stackMax); + // TODO: throw error for 'illegal' item (not found) + + Collection entities = targets.getEntities(source); + for (Entity entity : entities) { + if (entity instanceof PlayerEntity) { + player = (PlayerEntity) entity; + for (int i = 0; i < stackCount + 1; i++) { + if (i == stackCount) { + stack.setCount(count % stackMax); + } + ItemEntity itemEntity = player.dropItem(stack, false); + if (itemEntity != null) { + itemEntity.setOwner(player); + itemEntity.resetPickupDelay(); + } else { + i--; + } + } + e++; + } + } + if (e == 0) { + // TODO: throw error on failed command + } + return e; + } +}