From 528b234d5ab22de76c5cd10d5169dcb800c1b515 Mon Sep 17 00:00:00 2001 From: Myles Date: Sun, 6 Mar 2016 23:22:45 +0000 Subject: [PATCH] Add collision options, fixes #95. (By default auto teams players until they're added to a team so you can't push!) --- .../us/myles/ViaVersion/ConnectionInfo.java | 9 ++ .../us/myles/ViaVersion/ViaVersionPlugin.java | 11 +++ .../transformers/OutgoingTransformer.java | 94 ++++++++++++++++--- src/main/resources/config.yml | 5 + 4 files changed, 104 insertions(+), 15 deletions(-) diff --git a/src/main/java/us/myles/ViaVersion/ConnectionInfo.java b/src/main/java/us/myles/ViaVersion/ConnectionInfo.java index e13bc1fff..e89d3460a 100644 --- a/src/main/java/us/myles/ViaVersion/ConnectionInfo.java +++ b/src/main/java/us/myles/ViaVersion/ConnectionInfo.java @@ -18,6 +18,7 @@ public class ConnectionInfo { private int protocol = 0; private int compression = 0; private boolean active = true; + private String username; public ConnectionInfo(SocketChannel socketChannel) { this.channel = socketChannel; @@ -100,4 +101,12 @@ public class ConnectionInfo { public void closeWindow() { this.openWindow = null; } + + public void setUsername(String username) { + this.username = username; + } + + public String getUsername() { + return username; + } } diff --git a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java index b2876e289..872e7f2a1 100644 --- a/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java +++ b/src/main/java/us/myles/ViaVersion/ViaVersionPlugin.java @@ -28,6 +28,7 @@ import us.myles.ViaVersion.update.UpdateUtil; import us.myles.ViaVersion.util.ReflectionUtil; import java.lang.reflect.Field; +import java.util.Collection; import java.util.List; import java.util.Map; import java.util.UUID; @@ -158,6 +159,16 @@ public class ViaVersionPlugin extends JavaPlugin implements ViaVersionAPI { return getConfig().getBoolean("sync-chunks", true); } + public boolean isPreventCollision() { + return getConfig().getBoolean("prevent-collision", true); + } + + public boolean isAutoTeam() { + // Collision has to be enabled first + if(!isPreventCollision()) return false; + return getConfig().getBoolean("auto-team", true); + } + public void setDebug(boolean value) { this.debug = value; } diff --git a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java index 77544fc1a..fd5f81e7b 100644 --- a/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java +++ b/src/main/java/us/myles/ViaVersion/transformers/OutgoingTransformer.java @@ -253,10 +253,6 @@ public class OutgoingTransformer { return; } - // If login success - if (packet == PacketType.LOGIN_SUCCESS) { - info.setState(State.PLAY); - } if (packet == PacketType.LOGIN_SETCOMPRESSION) { int factor = PacketUtil.readVarInt(input); info.setCompression(factor); @@ -277,12 +273,16 @@ public class OutgoingTransformer { return; } if (packet == PacketType.LOGIN_SUCCESS) { - String uu = PacketUtil.readString(input); - PacketUtil.writeString(uu, output); - UUID uniqueId = UUID.fromString(uu); + info.setState(State.PLAY); + + String uuid = PacketUtil.readString(input); + PacketUtil.writeString(uuid, output); + UUID uniqueId = UUID.fromString(uuid); info.setUUID(uniqueId); plugin.addPortedClient(info); - output.writeBytes(input); + String username = PacketUtil.readString(input); + info.setUsername(username); + PacketUtil.writeString(username, output); return; } @@ -548,6 +548,10 @@ public class OutgoingTransformer { clientEntityTypes.put(id, EntityType.PLAYER); output.writeInt(id); output.writeBytes(input); + // send fake team + if (plugin.isAutoTeam()) { + sendTeamPacket(true); + } return; } if (packet == PacketType.PLAY_SPAWN_PLAYER) { @@ -612,7 +616,33 @@ public class OutgoingTransformer { output.writeByte(input.readByte()); PacketUtil.writeString(PacketUtil.readString(input), output); - PacketUtil.writeString("", output); // collission rule :) + PacketUtil.writeString(plugin.isPreventCollision() ? "never" : "", output); // collission rule :) + + output.writeByte(input.readByte()); + } + if (mode == 0 || mode == 3 || mode == 4) { + // add players + int count = PacketUtil.readVarInt(input); + PacketUtil.writeVarInt(count, output); + + for (int i = 0; i < count; i++) { + String name = PacketUtil.readString(input); + if (plugin.isAutoTeam() && name.equalsIgnoreCase(info.getUsername())) { + if (mode == 4) { + // since removing add to auto team + plugin.run(new Runnable() { + @Override + public void run() { + sendTeamPacket(true); + } + }, false); + } else { + // since adding remove from auto team + sendTeamPacket(false); + } + } + PacketUtil.writeString(name, output); + } } output.writeBytes(input); return; @@ -627,22 +657,20 @@ public class OutgoingTransformer { int index = input.readerIndex(); DataInputStream stream = new DataInputStream(new ByteBufInputStream(input)); CompoundTag tag = (CompoundTag) NBTIO.readTag(stream); - if(tag != null && tag.contains("EntityId")) { + if (tag != null && tag.contains("EntityId")) { String entity = (String) tag.get("EntityId").getValue(); CompoundTag spawn = new CompoundTag("SpawnData"); spawn.put(new StringTag("id", entity)); tag.put(spawn); DataOutputStream out = new DataOutputStream(new ByteBufOutputStream(output)); NBTIO.writeTag(out, tag); - } - else if(tag != null) { // EntityID does not exist + } else if (tag != null) { // EntityID does not exist CompoundTag spawn = new CompoundTag("SpawnData"); spawn.put(new StringTag("id", "AreaEffectCloud")); //Make spawners show up as empty when no EntityId is given. tag.put(spawn); DataOutputStream out = new DataOutputStream(new ByteBufOutputStream(output)); NBTIO.writeTag(out, tag); - } - else { //There doesn't exist any NBT tag + } else { //There doesn't exist any NBT tag input.readerIndex(index); output.writeBytes(input, input.readableBytes()); } @@ -720,12 +748,48 @@ public class OutgoingTransformer { } output.writeBytes(input); } + private void sendCreateTeam() { + ByteBuf buf = info.getChannel().alloc().buffer(); + PacketUtil.writeVarInt(PacketType.PLAY_TEAM.getNewPacketID(), buf); + PacketUtil.writeString("viaversion", buf); + buf.writeByte(0); // make team + PacketUtil.writeString("viaversion", buf); + PacketUtil.writeString("", buf); // prefix + PacketUtil.writeString("", buf); // suffix + buf.writeByte(0); // friendly fire + PacketUtil.writeString("", buf); // nametags + PacketUtil.writeString("never", buf); // collision rule :) + buf.writeByte(0); // color + PacketUtil.writeVarInt(0, buf); // player count + info.sendRawPacket(buf); + } + private void sendTeamPacket(boolean b) { + ByteBuf buf = info.getChannel().alloc().buffer(); + PacketUtil.writeVarInt(PacketType.PLAY_TEAM.getNewPacketID(), buf); + PacketUtil.writeString("viaversion", buf); // Use viaversion as name + if (b) { + // add + buf.writeByte(0); // make team + PacketUtil.writeString("viaversion", buf); + PacketUtil.writeString("", buf); // prefix + PacketUtil.writeString("", buf); // suffix + buf.writeByte(0); // friendly fire + PacketUtil.writeString("", buf); // nametags + PacketUtil.writeString("never", buf); // collision rule :) + buf.writeByte(0); // color + PacketUtil.writeVarInt(1, buf); // player count + PacketUtil.writeString(info.getUsername(), buf); // us + } else { + buf.writeByte(1); // remove team + } + info.sendRawPacket(buf); + } public static String fixJson(String line) { if (line == null || line.equalsIgnoreCase("null")) { line = "{\"text\":\"\"}"; } else { - if ((!line.startsWith("\"") || !line.endsWith("\"")) && (!line.startsWith("{")|| !line.endsWith("}"))) { + if ((!line.startsWith("\"") || !line.endsWith("\"")) && (!line.startsWith("{") || !line.endsWith("}"))) { JSONObject obj = new JSONObject(); obj.put("text", line); return obj.toJSONString(); diff --git a/src/main/resources/config.yml b/src/main/resources/config.yml index 45650f42a..63b8ad02c 100644 --- a/src/main/resources/config.yml +++ b/src/main/resources/config.yml @@ -3,3 +3,8 @@ checkforupdates: true # Should we send any bulk chunks, in sync (may be slower but fixes timings) # Currently broken due to sign updates, possibly will return sync-chunks: true +# No collide options, these allow you to configure how collision works. +# Do you want us to prevent collision? +prevent-collision: true +# If the above is true, should we automatically team players until you do? +auto-team: true