diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..74ba180 --- /dev/null +++ b/.gitignore @@ -0,0 +1,24 @@ +# Mac OS +.DS_Store + +# IntelliJ +*.iml +*.ipr +*.iws +.idea/ +out/ + +# Eclipse +.classpath +.project +.settings/ + +# Gradle +.gradle/ +build/ + +# Maven +target/ + +# Vim +*.swp diff --git a/modules/VirtualPlayers/pom.xml b/modules/VirtualPlayers/pom.xml index 11d30f8..dc2f66a 100644 --- a/modules/VirtualPlayers/pom.xml +++ b/modules/VirtualPlayers/pom.xml @@ -1,7 +1,12 @@ 4.0.0 - + + mc.alk + vp-parent + parent + ../../ + mc.alk VirtualPlayers 1.5.10 diff --git a/modules/VirtualPlayers/src/main/java/mc/alk/virtualplayers/VirtualPlayers.java b/modules/VirtualPlayers/src/main/java/mc/alk/virtualplayers/VirtualPlayers.java index 039f8d4..44b2981 100644 --- a/modules/VirtualPlayers/src/main/java/mc/alk/virtualplayers/VirtualPlayers.java +++ b/modules/VirtualPlayers/src/main/java/mc/alk/virtualplayers/VirtualPlayers.java @@ -13,7 +13,7 @@ public class VirtualPlayers extends JavaPlugin implements Listener { Version server; - public static final String MAX = "1.7.10-R9.9-SNAPSHOT"; + public static final String MAX = "1.7.10-R9.9"; public static final String MIN = "1.2.5"; String NMS; diff --git a/modules/v1_7_R4/pom.xml b/modules/v1_7_R4/pom.xml index 2633d9c..0c35142 100644 --- a/modules/v1_7_R4/pom.xml +++ b/modules/v1_7_R4/pom.xml @@ -30,8 +30,7 @@ org.bukkit craftbukkit 1.7.10-R0.1-SNAPSHOT - system - C:/Users/Nikolai/Documents/lib/bukkit/1.7.10/craftbukkit.jar + provided mc.alk @@ -39,12 +38,6 @@ parent true - - org.bukkit - bukkit - 1.7.5-R0.1-SNAPSHOT - provided - junit junit diff --git a/modules/v1_7_R4/src/main/java/mc/alk/virtualplayers/nms/v1_7_R4/VPPlayerConnection.java b/modules/v1_7_R4/src/main/java/mc/alk/virtualplayers/nms/v1_7_R4/VPPlayerConnection.java new file mode 100644 index 0000000..eaf1933 --- /dev/null +++ b/modules/v1_7_R4/src/main/java/mc/alk/virtualplayers/nms/v1_7_R4/VPPlayerConnection.java @@ -0,0 +1,570 @@ +package mc.alk.virtualplayers.nms.v1_7_R4; + +import net.minecraft.server.v1_7_R4.*; +import net.minecraft.util.io.netty.buffer.ByteBufAllocator; +import net.minecraft.util.io.netty.channel.*; +import net.minecraft.util.io.netty.util.Attribute; +import net.minecraft.util.io.netty.util.AttributeKey; +import net.minecraft.util.io.netty.util.concurrent.EventExecutorGroup; + +import java.lang.reflect.Field; +import java.net.SocketAddress; +import java.util.Iterator; +import java.util.List; +import java.util.Map; + +/* + * This provides compatibility for HoloAPI. + * + * HoloAPI looks for the following: + * - The EntityPlayer's handle must have a non-null PlayerConnection (field: playerConnection) + * - The PlayerConnection must have a non-null NetworkManager (set in the PlayerConnection constructor) + * - The NetworkManager must have: + * - In older versions, any declared field with type Channel + * - In newer versions, the Channel field in the base NetworkManager class must be set + * - The Channel must: + * - In older versions, return true for `isActive()` + */ +public class VPPlayerConnection extends PlayerConnection { + + // 'wraps' the EntityPlayer with a PlayerConnection + // PlayerConnection's constructor will set the player's `playerConnection` field + public static void wrap(EntityPlayer player) { + new VPPlayerConnection(player); + } + + private VPPlayerConnection(EntityPlayer player) { + super(MinecraftServer.getServer(), FAKE_NETWORK_MANAGER, player); + } + + + // ----- Stub implementations + // The declaration order here is *critical*: Pipeline -> Channel -> NetworkManager + + private static final ChannelPipeline FAKE_PIPELINE = new ChannelPipeline() { + + // These two are the only called by HoloAPI -- the return values do not matter + @Override + public ChannelPipeline addBefore(String s, String s2, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline remove(ChannelHandler channelHandler) { + return null; + } + + + // The rest of these don't matter. + @Override + public ChannelPipeline addFirst(String s, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline addFirst(EventExecutorGroup eventExecutors, String s, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline addLast(String s, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline addLast(EventExecutorGroup eventExecutors, String s, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline addBefore(EventExecutorGroup eventExecutors, String s, String s2, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline addAfter(String s, String s2, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline addAfter(EventExecutorGroup eventExecutors, String s, String s2, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelPipeline addFirst(ChannelHandler... channelHandlers) { + return null; + } + + @Override + public ChannelPipeline addFirst(EventExecutorGroup eventExecutors, ChannelHandler... channelHandlers) { + return null; + } + + @Override + public ChannelPipeline addLast(ChannelHandler... channelHandlers) { + return null; + } + + @Override + public ChannelPipeline addLast(EventExecutorGroup eventExecutors, ChannelHandler... channelHandlers) { + return null; + } + + @Override + public ChannelHandler remove(String s) { + return null; + } + + @Override + public T remove(Class tClass) { + return null; + } + + @Override + public ChannelHandler removeFirst() { + return null; + } + + @Override + public ChannelHandler removeLast() { + return null; + } + + @Override + public ChannelPipeline replace(ChannelHandler channelHandler, String s, ChannelHandler channelHandler2) { + return null; + } + + @Override + public ChannelHandler replace(String s, String s2, ChannelHandler channelHandler) { + return null; + } + + @Override + public T replace(Class tClass, String s, ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelHandler first() { + return null; + } + + @Override + public ChannelHandlerContext firstContext() { + return null; + } + + @Override + public ChannelHandler last() { + return null; + } + + @Override + public ChannelHandlerContext lastContext() { + return null; + } + + @Override + public ChannelHandler get(String s) { + return null; + } + + @Override + public T get(Class tClass) { + return null; + } + + @Override + public ChannelHandlerContext context(ChannelHandler channelHandler) { + return null; + } + + @Override + public ChannelHandlerContext context(String s) { + return null; + } + + @Override + public ChannelHandlerContext context(Class aClass) { + return null; + } + + @Override + public Channel channel() { + return null; + } + + @Override + public List names() { + return null; + } + + @Override + public Map toMap() { + return null; + } + + @Override + public ChannelPipeline fireChannelRegistered() { + return null; + } + + @Override + public ChannelPipeline fireChannelUnregistered() { + return null; + } + + @Override + public ChannelPipeline fireChannelActive() { + return null; + } + + @Override + public ChannelPipeline fireChannelInactive() { + return null; + } + + @Override + public ChannelPipeline fireExceptionCaught(Throwable throwable) { + return null; + } + + @Override + public ChannelPipeline fireUserEventTriggered(Object o) { + return null; + } + + @Override + public ChannelPipeline fireChannelRead(Object o) { + return null; + } + + @Override + public ChannelPipeline fireChannelReadComplete() { + return null; + } + + @Override + public ChannelPipeline fireChannelWritabilityChanged() { + return null; + } + + @Override + public ChannelPipeline flush() { + return null; + } + + @Override + public ChannelPipeline read() { + return null; + } + + @Override + public ChannelFuture bind(SocketAddress socketAddress) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress, SocketAddress socketAddress2) { + return null; + } + + @Override + public ChannelFuture disconnect() { + return null; + } + + @Override + public ChannelFuture close() { + return null; + } + + @Override + public ChannelFuture deregister() { + return null; + } + + @Override + public ChannelFuture bind(SocketAddress socketAddress, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress, SocketAddress socketAddress2, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture disconnect(ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture close(ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture deregister(ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture write(Object o) { + return null; + } + + @Override + public ChannelFuture write(Object o, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture writeAndFlush(Object o, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture writeAndFlush(Object o) { + return null; + } + + @Override + public Iterator> iterator() { + return null; + } + }; + + private static final Channel FAKE_CHANNEL = new Channel() { + + // These are the only two that matter. + @Override + public ChannelPipeline pipeline() { + return FAKE_PIPELINE; + } + + @Override + public boolean isActive() { + return true; + } + + + // The rest are junk ): + @Override + public EventLoop eventLoop() { + return null; + } + + @Override + public Channel parent() { + return null; + } + + @Override + public ChannelConfig config() { + return null; + } + + @Override + public boolean isOpen() { + return false; + } + + @Override + public boolean isRegistered() { + return false; + } + + @Override + public ChannelMetadata metadata() { + return null; + } + + @Override + public SocketAddress localAddress() { + return null; + } + + @Override + public SocketAddress remoteAddress() { + return null; + } + + @Override + public ChannelFuture closeFuture() { + return null; + } + + @Override + public boolean isWritable() { + return false; + } + + @Override + public Channel flush() { + return null; + } + + @Override + public Channel read() { + return null; + } + + @Override + public Unsafe unsafe() { + return null; + } + + @Override + public Attribute attr(AttributeKey tAttributeKey) { + return null; + } + + @Override + public ChannelFuture bind(SocketAddress socketAddress) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress, SocketAddress socketAddress2) { + return null; + } + + @Override + public ChannelFuture disconnect() { + return null; + } + + @Override + public ChannelFuture close() { + return null; + } + + @Override + public ChannelFuture deregister() { + return null; + } + + @Override + public ChannelFuture bind(SocketAddress socketAddress, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture connect(SocketAddress socketAddress, SocketAddress socketAddress2, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture disconnect(ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture close(ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture deregister(ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture write(Object o) { + return null; + } + + @Override + public ChannelFuture write(Object o, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture writeAndFlush(Object o, ChannelPromise channelPromise) { + return null; + } + + @Override + public ChannelFuture writeAndFlush(Object o) { + return null; + } + + @Override + public ByteBufAllocator alloc() { + return null; + } + + @Override + public ChannelPromise newPromise() { + return null; + } + + @Override + public ChannelProgressivePromise newProgressivePromise() { + return null; + } + + @Override + public ChannelFuture newSucceededFuture() { + return null; + } + + @Override + public ChannelFuture newFailedFuture(Throwable throwable) { + return null; + } + + @Override + public ChannelPromise voidPromise() { + return null; + } + + @Override + public int compareTo(Channel o) { + return 0; + } + }; + + private static final NetworkManager FAKE_NETWORK_MANAGER = new NetworkManager(false) { + private final Channel a = FAKE_CHANNEL; // Older versions of HoloAPI look for any field containing a Channel + + { + // Newer versions search the NetworkManager class to find a Channel field. + try { + for (Field field : this.getClass().getSuperclass().getDeclaredFields()) { + if (Channel.class.isAssignableFrom(field.getType())) { + field.setAccessible(true); + field.set(this, FAKE_CHANNEL); + break; + } + } + } catch (Exception ignored) {} + } + + @Override + public void a(PacketListener listener) {} // Called by PlayerConnection + }; +} diff --git a/modules/v1_7_R4/src/main/java/mc/alk/virtualplayers/nms/v1_7_R4/VirtualPlayer.java b/modules/v1_7_R4/src/main/java/mc/alk/virtualplayers/nms/v1_7_R4/VirtualPlayer.java index 0c78839..0308c97 100644 --- a/modules/v1_7_R4/src/main/java/mc/alk/virtualplayers/nms/v1_7_R4/VirtualPlayer.java +++ b/modules/v1_7_R4/src/main/java/mc/alk/virtualplayers/nms/v1_7_R4/VirtualPlayer.java @@ -1,10 +1,5 @@ package mc.alk.virtualplayers.nms.v1_7_R4; -import java.util.ArrayList; -import java.util.HashMap; -import java.util.List; -import java.util.Map; -import java.util.UUID; import net.minecraft.server.v1_7_R4.EntityPlayer; import net.minecraft.server.v1_7_R4.MinecraftServer; import net.minecraft.server.v1_7_R4.PlayerInteractManager; @@ -30,6 +25,8 @@ import org.bukkit.scoreboard.DisplaySlot; import org.bukkit.scoreboard.Scoreboard; +import java.util.*; + public class VirtualPlayer extends CraftPlayer implements Listener { Player keepInformed; // / who to send the messages to @@ -54,11 +51,20 @@ public VirtualPlayer(CraftServer cserver, MinecraftServer mcserver, WorldServer /// mcserver, worldserver, GameProfile, PlayerInteractManager super(cserver, new EntityPlayer(mcserver, worldServer, gameProfile, pim)); this.loc = this.getLocation(); + + VPPlayerConnection.wrap(getHandle()); } public VirtualPlayer(CraftServer cserver, EntityPlayer ep) { super(cserver, ep); this.loc = this.getLocation(); + + VPPlayerConnection.wrap(getHandle()); + } + + @Override + public EntityPlayer getHandle() { // Required for HoloAPI compatibility + return super.getHandle(); } @Override @@ -327,7 +333,7 @@ public static Player[] getOnlinePlayers() players.add(p);} } Player[] ps = players.toArray(new Player[players.size()]); - Player[] bps = Bukkit.getOnlinePlayers(); + Player[] bps = (Player[]) Bukkit.getOnlinePlayers().toArray(); return (Player[]) ArrayUtils.addAll(ps, bps); }