From 66421e806eaef3e746a8a18846242007f605e9a0 Mon Sep 17 00:00:00 2001 From: Sen Date: Tue, 25 Mar 2025 17:02:41 +0100 Subject: [PATCH] effect command --- java/src/game/command/EntityListParser.java | 84 +++++++++++++++++++ java/src/game/command/EntityParser.java | 59 +++++++++++++ java/src/game/command/PlayerEntityParser.java | 27 ++++++ java/src/game/command/PlayerParser.java | 34 ++++++++ java/src/game/command/ScriptEnvironment.java | 11 ++- java/src/game/command/ScriptExecutable.java | 24 ++++++ java/src/game/command/ScriptExecutor.java | 4 + .../game/command/commands/CommandMilk.java | 45 ++++++++++ .../game/command/commands/CommandPotion.java | 43 ++++++++++ java/src/game/gui/GuiConsole.java | 26 +++--- java/src/game/gui/GuiInfo.java | 2 +- java/src/game/init/EntityRegistry.java | 5 ++ .../game/network/NetHandlerPlayServer.java | 13 +++ java/src/game/packet/CPacketComplete.java | 24 +++++- java/src/game/potion/Potion.java | 6 ++ java/src/game/renderer/EntityRenderer.java | 2 +- 16 files changed, 393 insertions(+), 16 deletions(-) create mode 100644 java/src/game/command/EntityListParser.java create mode 100644 java/src/game/command/EntityParser.java create mode 100644 java/src/game/command/PlayerEntityParser.java create mode 100644 java/src/game/command/PlayerParser.java create mode 100644 java/src/game/command/commands/CommandMilk.java create mode 100644 java/src/game/command/commands/CommandPotion.java diff --git a/java/src/game/command/EntityListParser.java b/java/src/game/command/EntityListParser.java new file mode 100644 index 0000000..1912c5e --- /dev/null +++ b/java/src/game/command/EntityListParser.java @@ -0,0 +1,84 @@ +package game.command; + +import java.util.List; + +import game.collect.Lists; +import game.entity.Entity; +import game.entity.types.EntityLiving; +import game.init.EntityRegistry; +import game.network.NetHandlerPlayServer; +import game.world.WorldServer; + +public class EntityListParser extends EntityParser { + public EntityListParser(String name, boolean useSender, boolean livingOnly) { + super(name, useSender, livingOnly); + } + + public Object parse(ScriptEnvironment env, String input) { + if(input.equals("**")) { + List list = Lists.newArrayList(); + for(WorldServer world : env.getServer().getWorlds()) { + if(this.livingOnly) { + for(Entity ent : world.getEntities()) { + if(ent instanceof EntityLiving) + list.add(ent); + } + } + else { + list.addAll(world.getEntities()); + } + } + if(list.isEmpty()) + throw new ScriptException(this.livingOnly ? "Keine lebendigen Objekte gefunden" : "Keine Objekte gefunden"); + return list; + } + else if(input.equals("*")) { + List list = Lists.newArrayList(); + for(NetHandlerPlayServer plr : env.getServer().getPlayers()) { + if(plr.getEntity() != null) + list.add(plr.getEntity()); + } + if(list.isEmpty()) + throw new ScriptException("Keine Spieler gefunden"); + return list; + } + Class clazz = EntityRegistry.getEntityClass(input); + if(clazz != null) { + if(this.livingOnly && !EntityLiving.class.isAssignableFrom(clazz)) + throw new ScriptException("Objekttyp %s ist nicht lebendig", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz))); + List list = Lists.newArrayList(); + for(WorldServer world : env.getServer().getWorlds()) { + for(Entity ent : world.getEntities()) { + if(clazz.isAssignableFrom(ent.getClass())) + list.add(ent); + } + } + if(list.isEmpty()) + throw new ScriptException("Kein Objekt des Typs %s gefunden", EntityRegistry.getEntityName(EntityRegistry.getEntityString(clazz))); + return list; + } + return Lists.newArrayList((Entity)super.parse(env, input)); + } + + public Object getDefault(ScriptEnvironment env) { + Entity entity = (Entity)super.getDefault(env); + return entity == null ? null : Lists.newArrayList(entity); + } + + public String[] getCompletions(ScriptEnvironment env) { + Entity target = env.getExecutor().getPointedEntity(); + List comp = target == null || (this.livingOnly && !(target instanceof EntityLiving)) ? Lists.newArrayList() : Lists.newArrayList("#" + target.getId()); + comp.addAll(env.getServer().getAllUsernames()); + comp.add("*"); + for(Class clazz : EntityRegistry.getAllClasses()) { + if(!this.livingOnly || EntityLiving.class.isAssignableFrom(clazz)) + comp.add(EntityRegistry.getEntityString(clazz)); + } + comp.add("**"); + return comp.toArray(new String[comp.size()]); + } + + public Class getTypeClass() { + return List.class; + } +} diff --git a/java/src/game/command/EntityParser.java b/java/src/game/command/EntityParser.java new file mode 100644 index 0000000..cbeed90 --- /dev/null +++ b/java/src/game/command/EntityParser.java @@ -0,0 +1,59 @@ +package game.command; + +import java.util.List; + +import game.collect.Lists; +import game.entity.Entity; +import game.entity.types.EntityLiving; +import game.world.WorldServer; + +public class EntityParser extends PlayerEntityParser { + protected final boolean livingOnly; + + public EntityParser(String name, boolean useSender, boolean livingOnly) { + super(name, useSender); + this.livingOnly = livingOnly; + } + + public Object parse(ScriptEnvironment env, String input) { + Entity entity = null; + if(input.startsWith("#")) { + int id = -1; + try { + id = Integer.parseInt(input.substring(1)); + } + catch(NumberFormatException e) { + } + if(id != -1) { + for(WorldServer world : env.getServer().getWorlds()) { + entity = world.getEntityByID(id); + if(entity != null) + break; + } + } + } + else { + entity = (Entity)super.parse(env, input); + } + if(entity == null) + throw new ScriptException("Objekt '%s' wurde nicht gefunden", input); + else if(this.livingOnly && !(entity instanceof EntityLiving)) + throw new ScriptException("Objekt muss lebendig sein"); + return entity; + } + + public Object getDefault(ScriptEnvironment env) { + return this.useSender && (this.livingOnly ? (env.getExecutor() instanceof EntityLiving) : (env.getExecutor() instanceof Entity)) ? env.getExecutor() : super.getDefault(env); + } + + public String[] getCompletions(ScriptEnvironment env) { + Entity target = env.getExecutor().getPointedEntity(); + List comp = target == null || (this.livingOnly && !(target instanceof EntityLiving)) ? Lists.newArrayList() : Lists.newArrayList("#" + target.getId()); + comp.addAll(env.getServer().getAllUsernames()); + return comp.toArray(new String[comp.size()]); + } + + public Class getTypeClass() { + return this.livingOnly ? EntityLiving.class : Entity.class; + } +} diff --git a/java/src/game/command/PlayerEntityParser.java b/java/src/game/command/PlayerEntityParser.java new file mode 100644 index 0000000..18630d4 --- /dev/null +++ b/java/src/game/command/PlayerEntityParser.java @@ -0,0 +1,27 @@ +package game.command; + +import game.entity.npc.EntityNPC; +import game.network.NetHandlerPlayServer; + +public class PlayerEntityParser extends PlayerParser { + public PlayerEntityParser(String name, boolean useSender) { + super(name, useSender); + } + + public Object parse(ScriptEnvironment env, String input) { + NetHandlerPlayServer net = (NetHandlerPlayServer)super.parse(env, input); + EntityNPC entity = net.getEntity(); + if(entity == null) + throw new ScriptException("Spieler-Objekt von '%s' wurde nicht gefunden", input); + return entity; + } + + public Object getDefault(ScriptEnvironment env) { + NetHandlerPlayServer net = (NetHandlerPlayServer)super.getDefault(env); + return net == null ? null : net.getEntity(); + } + + public Class getTypeClass() { + return EntityNPC.class; + } +} diff --git a/java/src/game/command/PlayerParser.java b/java/src/game/command/PlayerParser.java new file mode 100644 index 0000000..861785e --- /dev/null +++ b/java/src/game/command/PlayerParser.java @@ -0,0 +1,34 @@ +package game.command; + +import java.util.List; + +import game.network.NetHandlerPlayServer; + +public class PlayerParser extends CompletingParser { + protected final boolean useSender; + + public PlayerParser(String name, boolean useSender) { + super(name); + this.useSender = useSender; + } + + public Object parse(ScriptEnvironment env, String input) { + NetHandlerPlayServer net = env.getServer().getPlayer(input); + if(net == null) + throw new ScriptException("Spieler '%s' wurde nicht gefunden", input); + return net; + } + + public Object getDefault(ScriptEnvironment env) { + return this.useSender && env.getExecutor() instanceof NetHandlerPlayServer ? (NetHandlerPlayServer)env.getExecutor() : null; + } + + public String[] getCompletions(ScriptEnvironment env) { + List comp = env.getServer().getAllUsernames(); + return comp.toArray(new String[comp.size()]); + } + + public Class getTypeClass() { + return NetHandlerPlayServer.class; + } +} diff --git a/java/src/game/command/ScriptEnvironment.java b/java/src/game/command/ScriptEnvironment.java index 75d1229..6f43407 100644 --- a/java/src/game/command/ScriptEnvironment.java +++ b/java/src/game/command/ScriptEnvironment.java @@ -12,6 +12,8 @@ import game.collect.Maps; import game.Server; import game.color.TextColor; import game.command.commands.CommandHelp; +import game.command.commands.CommandMilk; +import game.command.commands.CommandPotion; import game.command.commands.CommandSpawn; import game.log.Log; @@ -148,6 +150,7 @@ public class ScriptEnvironment { } public List complete(String cmd, ScriptExecutor exec) { + this.currentExecutor = exec; List list = Lists.newArrayList(); try { String[][] cmds = ArgumentParser.splitString(cmd.endsWith(" ") ? cmd + "END" : cmd); @@ -174,6 +177,10 @@ public class ScriptEnvironment { } catch(Throwable t) { list.clear(); + Log.CONSOLE.error(t, "Konnte Befehl nicht vervollständigen"); + } + finally { + this.currentExecutor = null; } return list; } @@ -194,8 +201,10 @@ public class ScriptEnvironment { return ScriptEnvironment.this.previousOutput == null ? null : ScriptEnvironment.this.previousOutput.toString(); } }); - + this.registerExecutable(new CommandSpawn()); + this.registerExecutable(new CommandPotion()); + this.registerExecutable(new CommandMilk()); this.registerExecutable(new CommandHelp(this)); } diff --git a/java/src/game/command/ScriptExecutable.java b/java/src/game/command/ScriptExecutable.java index 7c55f8a..32167d5 100644 --- a/java/src/game/command/ScriptExecutable.java +++ b/java/src/game/command/ScriptExecutable.java @@ -126,6 +126,30 @@ public abstract class ScriptExecutable implements Executable { // this.getClass().getDeclaredMethod(name, null) // return null; // } + + protected ScriptExecutable addPlayer(String name, boolean defaulted) { + return this.addParameter(new PlayerParser(name, defaulted)); + } + + protected ScriptExecutable addPlayerEntity(String name, boolean defaulted) { + return this.addParameter(new PlayerEntityParser(name, defaulted)); + } + + protected ScriptExecutable addEntity(String name, boolean defaulted) { + return this.addParameter(new EntityParser(name, defaulted, false)); + } + + protected ScriptExecutable addEntityList(String name, boolean defaulted) { + return this.addParameter(new EntityListParser(name, defaulted, false)); + } + + protected ScriptExecutable addLivingEntity(String name, boolean defaulted) { + return this.addParameter(new EntityParser(name, defaulted, true)); + } + + protected ScriptExecutable addLivingEntityList(String name, boolean defaulted) { + return this.addParameter(new EntityListParser(name, defaulted, true)); + } public Map getParameters() { return this.parameters; diff --git a/java/src/game/command/ScriptExecutor.java b/java/src/game/command/ScriptExecutor.java index 59e2ee1..b79fcb2 100644 --- a/java/src/game/command/ScriptExecutor.java +++ b/java/src/game/command/ScriptExecutor.java @@ -1,5 +1,7 @@ package game.command; +import game.entity.Entity; +import game.world.BlockPos; import game.world.Position; public interface ScriptExecutor { @@ -7,6 +9,8 @@ public interface ScriptExecutor { String getExecId(); String getExecName(); Position getExecPos(); + Entity getPointedEntity(); + BlockPos getPointedPosition(); default void logConsole(String fmt, Object ... args) { this.logConsole(String.format(fmt, args)); diff --git a/java/src/game/command/commands/CommandMilk.java b/java/src/game/command/commands/CommandMilk.java new file mode 100644 index 0000000..6401fd2 --- /dev/null +++ b/java/src/game/command/commands/CommandMilk.java @@ -0,0 +1,45 @@ +package game.command.commands; + +import java.util.List; +import game.collect.Lists; +import game.command.ScriptEnvironment; +import game.command.ScriptExecutable; +import game.command.ScriptExecutor; +import game.entity.types.EntityLiving; +import game.potion.Potion; + +public class CommandMilk extends ScriptExecutable { + public CommandMilk() { + super("milk"); + + this.addLivingEntityList("entities", true); + this.setParamsOptional(); + List potions = Lists.newArrayList(); + for(Potion potion : Potion.POTION_TYPES) { + if(potion != null) + potions.add(potion); + } + this.addEnum("type", Potion.class, potions); + + this.addFlag("negative", 'n'); + } + + public Object exec(ScriptEnvironment env, ScriptExecutor exec, List entities, Potion type, boolean negative) { + int done = 0; + for(EntityLiving entity : entities) { + if(type != null && entity.hasEffect(type)) { + entity.removeEffect(type.id); + exec.logConsole("%s von %s entfernt", type.getDisplay(), entity.getCommandName()); + done++; + } + else if(type == null && !entity.getEffects().isEmpty()) { + entity.clearEffects(negative); + exec.logConsole("Alle Effekte von %s entfernt", entity.getCommandName()); + done++; + } + } + if(done > 1) + exec.logConsole(type == null ? "Alle Effekte von %d Objekten entfernt" : "%d Effekte entfernt", entities.size()); + return null; + } +} diff --git a/java/src/game/command/commands/CommandPotion.java b/java/src/game/command/commands/CommandPotion.java new file mode 100644 index 0000000..96ba237 --- /dev/null +++ b/java/src/game/command/commands/CommandPotion.java @@ -0,0 +1,43 @@ +package game.command.commands; + +import java.util.List; +import game.collect.Lists; +import game.command.ScriptEnvironment; +import game.command.ScriptExecutable; +import game.command.ScriptExecutor; +import game.entity.types.EntityLiving; +import game.potion.Potion; +import game.potion.PotionEffect; + +public class CommandPotion extends ScriptExecutable { + public CommandPotion() { + super("potion"); + + List potions = Lists.newArrayList(); + for(Potion potion : Potion.POTION_TYPES) { + if(potion != null) + potions.add(potion); + } + this.addLivingEntityList("entities", true); + this.addEnum("type", Potion.class, potions); + this.setParamsOptional(); + this.addInt("duration", 1, 1000000, 1000000); + this.addInt("strength", 1, 256, 1); + + this.addFlag("particles", 'p'); + this.addFlag("ambient", 'a'); + this.addFlag("keep", 'k'); + } + + public Object exec(ScriptEnvironment env, ScriptExecutor exec, List entities, Potion type, int duration, int strength, boolean particles, boolean ambient, boolean keep) { + for(EntityLiving entity : entities) { + if(!keep && entity.hasEffect(type)) + entity.removeEffect(type.id); + entity.addEffect(new PotionEffect(type.id, duration * 20, strength - 1, ambient, particles)); + exec.logConsole("%d * %s für %d Sekunden an %s gegeben", strength, type.getDisplay(), duration, entity.getCommandName()); + } + if(entities.size() > 1) + exec.logConsole("%d Effekte vergeben", entities.size()); + return null; + } +} diff --git a/java/src/game/gui/GuiConsole.java b/java/src/game/gui/GuiConsole.java index c4b1ef7..8e8165a 100644 --- a/java/src/game/gui/GuiConsole.java +++ b/java/src/game/gui/GuiConsole.java @@ -17,6 +17,8 @@ import game.util.ExtMath; import game.vars.BoolVar; import game.vars.CVar; import game.window.Keysym; +import game.world.BlockPos; +import game.world.HitPosition; public class GuiConsole extends Gui implements Textbox.Callback { public static final GuiConsole INSTANCE = new GuiConsole(); @@ -238,22 +240,22 @@ public class GuiConsole extends Gui implements Textbox.Callback { { if (currentText.length() >= 1) { -// BlockPos blockpos = null; -// int eid = -1; -// -// if (this.gm.pointed != null && this.gm.pointed.type == HitPosition.ObjectType.BLOCK) -// { -// blockpos = this.gm.pointed.block; -// } -// else if (this.gm.pointed != null && this.gm.pointed.type == HitPosition.ObjectType.ENTITY) -// { -// eid = this.gm.pointed.entity.getId(); -// } + BlockPos blockpos = null; + int eid = -1; + if (this.gm.pointed != null && this.gm.pointed.type == HitPosition.ObjectType.BLOCK) + { + blockpos = this.gm.pointed.block; + } + else if (this.gm.pointed != null && this.gm.pointed.type == HitPosition.ObjectType.ENTITY) + { + eid = this.gm.pointed.entity.getId(); + blockpos = new BlockPos(this.gm.pointed.entity); + } if(currentText.startsWith("/")) { if(this.gm.thePlayer != null) { currentText = currentText.substring(1); this.prefixFirst = currentText.split(" ", -1).length == 1 ? "/" : null; - this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketComplete(currentText)); + this.gm.thePlayer.sendQueue.addToSendQueue(new CPacketComplete(currentText, eid, blockpos)); this.waitingOnAutocomplete = true; } } diff --git a/java/src/game/gui/GuiInfo.java b/java/src/game/gui/GuiInfo.java index 4c773ef..224de16 100644 --- a/java/src/game/gui/GuiInfo.java +++ b/java/src/game/gui/GuiInfo.java @@ -24,7 +24,7 @@ public class GuiInfo extends Gui { "Albert Pham - WorldEdit (Snippets)", "Joonas Vali - NameGenerator", "LWJGL 2.9.4-nightly-20150209 - Project, Vector*, Matrix*", - "Guava 17.0 - collect + future + Predicates", + "Guava 17.0 - collect, future, Predicates", "JOrbis 20101023 (JCraft) - jogg, jorbis, CodecJOrbis", "MC 1.8.9" }; diff --git a/java/src/game/init/EntityRegistry.java b/java/src/game/init/EntityRegistry.java index 225d203..d43d4d4 100755 --- a/java/src/game/init/EntityRegistry.java +++ b/java/src/game/init/EntityRegistry.java @@ -284,6 +284,11 @@ public abstract class EntityRegistry { return CLASS_TO_STRING.get(clazz); } + public static Class getEntityClass(String id) { + return STRING_TO_CLASS.get(id); + } + + // public static List getEntityNameList(boolean lower) { // Set set = STRING_TO_CLASS.keySet(); // List list = Lists.newArrayList(); diff --git a/java/src/game/network/NetHandlerPlayServer.java b/java/src/game/network/NetHandlerPlayServer.java index 93ddedf..1853f26 100755 --- a/java/src/game/network/NetHandlerPlayServer.java +++ b/java/src/game/network/NetHandlerPlayServer.java @@ -213,6 +213,9 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip private int lastExperience = -99999999; private int currentWindowId; + private int pointedEntity; + private BlockPos pointedPosition; + public final List loadedChunks = new LinkedList(); private final List destroyedItemsNetCache = new LinkedList(); // private final Set statsQueue = Sets.newHashSet(); @@ -2065,6 +2068,8 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip public void processComplete(CPacketComplete packetIn) { NetHandler.checkThread(packetIn, this, this.server); + this.pointedEntity = packetIn.getEntityId(); + this.pointedPosition = packetIn.getPosition(); if(packetIn.getMessage().startsWith(" ")) { this.entity.connection.sendPacket(new S3APacketTabComplete(new String[0])); return; @@ -3090,6 +3095,14 @@ public class NetHandlerPlayServer extends NetHandler implements ICrafting, Scrip } } + public Entity getPointedEntity() { + return this.pointedEntity != -1 && this.entity != null ? this.entity.worldObj.getEntityByID(this.pointedEntity) : null; + } + + public BlockPos getPointedPosition() { + return this.pointedPosition; + } + // public void processCmdBlock(CPacketCmdBlock packetIn) { // NetHandler.checkThread(packetIn, this, this.serverController); // diff --git a/java/src/game/packet/CPacketComplete.java b/java/src/game/packet/CPacketComplete.java index f13995d..18e44d4 100755 --- a/java/src/game/packet/CPacketComplete.java +++ b/java/src/game/packet/CPacketComplete.java @@ -5,28 +5,40 @@ import java.io.IOException; import game.network.NetHandlerPlayServer; import game.network.Packet; import game.network.PacketBuffer; +import game.world.BlockPos; public class CPacketComplete implements Packet { private String message; + private int entityId; + private BlockPos position; public CPacketComplete() { } - public CPacketComplete(String msg) + public CPacketComplete(String msg, int entity, BlockPos pos) { this.message = msg; + this.entityId = entity; + this.position = pos; } public void readPacketData(PacketBuffer buf) throws IOException { this.message = buf.readStringFromBuffer(32767); + this.entityId = buf.readVarIntFromBuffer(); + if(buf.readBoolean()) + this.position = buf.readBlockPos(); } public void writePacketData(PacketBuffer buf) throws IOException { buf.writeString(this.message.length() > 32767 ? this.message.substring(0, 32767) : this.message); + buf.writeVarIntToBuffer(this.entityId); + buf.writeBoolean(this.position != null); + if(this.position != null) + buf.writeBlockPos(this.position); } public void processPacket(NetHandlerPlayServer handler) @@ -38,4 +50,14 @@ public class CPacketComplete implements Packet { return this.message; } + + public int getEntityId() + { + return this.entityId; + } + + public BlockPos getPosition() + { + return this.position; + } } diff --git a/java/src/game/potion/Potion.java b/java/src/game/potion/Potion.java index f087edf..5e4ce25 100755 --- a/java/src/game/potion/Potion.java +++ b/java/src/game/potion/Potion.java @@ -78,6 +78,7 @@ public class Potion // public static final Potion field_180146_G = null; public final int id; + public final String sid; private final Map modifiers = Maps.newHashMap(); private final boolean bad; private final int color; @@ -91,6 +92,7 @@ public class Potion protected Potion(int potionID, String location, boolean badEffect, int potionColor) { this.id = potionID; + this.sid = location; POTION_TYPES[potionID] = this; POTION_MAP.put(location, this); this.bad = badEffect; @@ -404,4 +406,8 @@ public class Potion { return modifier.getAmount() * (double)(p_111183_1_ + 1); } + + public String toString() { + return this.sid; + } } diff --git a/java/src/game/renderer/EntityRenderer.java b/java/src/game/renderer/EntityRenderer.java index 512c487..1ebb36f 100755 --- a/java/src/game/renderer/EntityRenderer.java +++ b/java/src/game/renderer/EntityRenderer.java @@ -406,7 +406,7 @@ public class EntityRenderer { GL11.glRotatef(40.0F - 8000.0F / (f1 + 200.0F), 0.0F, 0.0F, 1.0F); } - if (f < 0.0F) + if (f < 0.0F || entitylivingbase.hasEffect(Potion.stability)) { return; }