Mirror von
https://github.com/ViaVersion/ViaVersion.git
synchronisiert 2024-12-26 16:12:42 +01:00
Merge pull request #205 from Matsv/master
Fix commandblocks not able to change command on update
Dieser Commit ist enthalten in:
Commit
9954195a8f
@ -1,6 +1,7 @@
|
|||||||
package us.myles.ViaVersion.listeners;
|
package us.myles.ViaVersion.listeners;
|
||||||
|
|
||||||
import io.netty.buffer.ByteBuf;
|
import io.netty.buffer.ByteBuf;
|
||||||
|
import io.netty.buffer.ByteBufOutputStream;
|
||||||
import io.netty.buffer.Unpooled;
|
import io.netty.buffer.Unpooled;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.block.Block;
|
import org.bukkit.block.Block;
|
||||||
@ -12,12 +13,15 @@ import org.bukkit.event.Listener;
|
|||||||
import org.bukkit.event.block.Action;
|
import org.bukkit.event.block.Action;
|
||||||
import org.bukkit.event.player.PlayerInteractEvent;
|
import org.bukkit.event.player.PlayerInteractEvent;
|
||||||
import org.bukkit.event.player.PlayerJoinEvent;
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.spacehq.opennbt.tag.builtin.ByteTag;
|
||||||
|
import org.spacehq.opennbt.tag.builtin.CompoundTag;
|
||||||
import us.myles.ViaVersion.ViaVersionPlugin;
|
import us.myles.ViaVersion.ViaVersionPlugin;
|
||||||
import us.myles.ViaVersion.packets.PacketType;
|
import us.myles.ViaVersion.packets.PacketType;
|
||||||
import us.myles.ViaVersion.util.PacketUtil;
|
import us.myles.ViaVersion.util.PacketUtil;
|
||||||
import us.myles.ViaVersion.util.ReflectionUtil;
|
import us.myles.ViaVersion.util.ReflectionUtil;
|
||||||
|
|
||||||
import java.lang.reflect.InvocationTargetException;
|
import java.io.DataOutput;
|
||||||
|
import java.io.DataOutputStream;
|
||||||
import java.lang.reflect.Method;
|
import java.lang.reflect.Method;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
@ -41,22 +45,58 @@ public class CommandBlockListener implements Listener {
|
|||||||
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && plugin.isPorted(e.getPlayer()) && e.getPlayer().isOp()) {
|
if (e.getAction() == Action.RIGHT_CLICK_BLOCK && plugin.isPorted(e.getPlayer()) && e.getPlayer().isOp()) {
|
||||||
try {
|
try {
|
||||||
sendCommandBlockPacket(e.getClickedBlock(), e.getPlayer());
|
sendCommandBlockPacket(e.getClickedBlock(), e.getPlayer());
|
||||||
} catch (NoSuchFieldException | IllegalAccessException | InvocationTargetException | NoSuchMethodException | ClassNotFoundException e1) {
|
} catch (Exception ex) {
|
||||||
e1.printStackTrace();
|
ex.printStackTrace();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void sendCommandBlockPacket(Block b, Player player) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException, InvocationTargetException, ClassNotFoundException {
|
private void sendCommandBlockPacket(Block b, Player player) throws Exception {
|
||||||
if (!(b.getState() instanceof CommandBlock))
|
if (!(b.getState() instanceof CommandBlock))
|
||||||
return;
|
return;
|
||||||
CommandBlock cmd = (CommandBlock) b.getState();
|
CommandBlock cmd = (CommandBlock) b.getState();
|
||||||
|
|
||||||
Object tileEntityCommand = ReflectionUtil.get(cmd, "commandBlock", ReflectionUtil.nms("TileEntityCommand"));
|
Object tileEntityCommand = ReflectionUtil.get(cmd, "commandBlock", ReflectionUtil.nms("TileEntityCommand"));
|
||||||
Object updatePacket = ReflectionUtil.invoke(tileEntityCommand, "getUpdatePacket");
|
Object updatePacket = ReflectionUtil.invoke(tileEntityCommand, "getUpdatePacket");
|
||||||
Object nmsPlayer = ReflectionUtil.invoke(player, "getHandle");
|
ByteBuf buf = packetToByteBuf(updatePacket);
|
||||||
Object playerConnection = ReflectionUtil.get(nmsPlayer, "playerConnection", ReflectionUtil.nms("PlayerConnection"));
|
plugin.sendRawPacket(player, buf);
|
||||||
Method sendPacket = playerConnection.getClass().getMethod("sendPacket", ReflectionUtil.nms("Packet"));
|
}
|
||||||
sendPacket.invoke(playerConnection, updatePacket); //Let the transformer do the work
|
|
||||||
|
private ByteBuf packetToByteBuf(Object updatePacket) throws Exception {
|
||||||
|
ByteBuf buf = Unpooled.buffer();
|
||||||
|
PacketUtil.writeVarInt(PacketType.PLAY_UPDATE_BLOCK_ENTITY.getNewPacketID(), buf); //Packet ID
|
||||||
|
long[] pos = getPosition(ReflectionUtil.get(updatePacket, "a", ReflectionUtil.nms("BlockPosition")));
|
||||||
|
PacketUtil.writeBlockPosition(buf, pos[0], pos[1], pos[2]); //Block position
|
||||||
|
buf.writeByte(2); //Action id always 2
|
||||||
|
CompoundTag nbt = getNBT(ReflectionUtil.get(updatePacket, "c", ReflectionUtil.nms("NBTTagCompound")));
|
||||||
|
if (nbt == null) {
|
||||||
|
buf.writeByte(0); //If nbt is null. Use 0 as nbt
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
nbt.put(new ByteTag("powered", (byte) 0));
|
||||||
|
nbt.put(new ByteTag("auto", (byte) 0));
|
||||||
|
nbt.put(new ByteTag("conditionMet", (byte) 0));
|
||||||
|
PacketUtil.writeNBT(buf, nbt); //NBT tag
|
||||||
|
return buf;
|
||||||
|
}
|
||||||
|
|
||||||
|
private long[] getPosition(Object obj) throws ClassNotFoundException, NoSuchFieldException, IllegalAccessException {
|
||||||
|
return new long[]{
|
||||||
|
(long) ReflectionUtil.getSuper(obj, "a", int.class), //X
|
||||||
|
(long) ReflectionUtil.getSuper(obj, "c", int.class), //Y
|
||||||
|
(long) ReflectionUtil.getSuper(obj, "d", int.class) //Z
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private CompoundTag getNBT(Object obj) throws Exception {
|
||||||
|
ByteBuf buf = Unpooled.buffer();
|
||||||
|
Method m = ReflectionUtil.nms("NBTCompressedStreamTools").getMethod("a", ReflectionUtil.nms("NBTTagCompound"), DataOutput.class);
|
||||||
|
m.invoke(null, obj, new DataOutputStream(new ByteBufOutputStream(buf)));
|
||||||
|
try {
|
||||||
|
return PacketUtil.readNBT(buf);
|
||||||
|
} finally {
|
||||||
|
buf.release();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -759,20 +759,7 @@ public class OutgoingTransformer {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (action == 2) { //Update commandblock
|
if (action == 2) { //Update commandblock
|
||||||
try {
|
throw new CancelException(); //Only update if player interact with commandblock (The commandblock window will update every time this packet is sent, this would prevent you from change things that update every tick)
|
||||||
CompoundTag nbt = readNBT(input);
|
|
||||||
if (nbt == null)
|
|
||||||
throw new CancelException();
|
|
||||||
//Thanks http://www.minecraftforum.net/forums/minecraft-discussion/redstone-discussion-and/command-blocks/2488148-1-9-nbt-changes-and-additions#TileAllCommandBlocks
|
|
||||||
nbt.put(new ByteTag("powered", (byte) 0));
|
|
||||||
nbt.put(new ByteTag("auto", (byte) 0));
|
|
||||||
nbt.put(new ByteTag("conditionMet", (byte) 0));
|
|
||||||
writeNBT(output, nbt);
|
|
||||||
return;
|
|
||||||
} catch (IOException e) {
|
|
||||||
e.printStackTrace();
|
|
||||||
throw new CancelException();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
output.writeBytes(input, input.readableBytes());
|
output.writeBytes(input, input.readableBytes());
|
||||||
return;
|
return;
|
||||||
|
@ -37,6 +37,12 @@ public class ReflectionUtil {
|
|||||||
return (T) field.get(null);
|
return (T) field.get(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static <T> T getSuper(Object o, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
||||||
|
Field field = o.getClass().getSuperclass().getDeclaredField(f);
|
||||||
|
field.setAccessible(true);
|
||||||
|
return (T) field.get(o);
|
||||||
|
}
|
||||||
|
|
||||||
public static <T> T get(Object instance, Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
public static <T> T get(Object instance, Class<?> clazz, String f, Class<T> t) throws NoSuchFieldException, IllegalAccessException {
|
||||||
Field field = clazz.getDeclaredField(f);
|
Field field = clazz.getDeclaredField(f);
|
||||||
field.setAccessible(true);
|
field.setAccessible(true);
|
||||||
|
Laden…
In neuem Issue referenzieren
Einen Benutzer sperren