From f85b56fe28691936bfc41c559e91a98bbe9e2056 Mon Sep 17 00:00:00 2001 From: NorbiPeti Date: Sun, 29 Oct 2017 02:00:44 +0200 Subject: [PATCH] Quite big hack for hooking into all broadcasts Right now it doesn't let anyone in. --- pom.xml | 8 + .../discordplugin/DiscordPlugin.java | 2 + .../discordplugin/PlayerListWatcher.java | 352 ++++++++++++++++++ 3 files changed, 362 insertions(+) create mode 100644 src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java diff --git a/pom.xml b/pom.xml index d2d1e7b..dea2593 100644 --- a/pom.xml +++ b/pom.xml @@ -210,5 +210,13 @@ + + + org.objenesis + objenesis + 2.6 + test + + diff --git a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java index e2d22e2..bfe0784 100644 --- a/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java +++ b/src/main/java/buttondevteam/discordplugin/DiscordPlugin.java @@ -49,6 +49,8 @@ public class DiscordPlugin extends JavaPlugin implements IListener { public void onEnable() { try { Bukkit.getLogger().info("Initializing DiscordPlugin..."); + PlayerListWatcher.hookUp(); + Bukkit.getLogger().info("Finished hooking into the player list"); plugin = this; lastannouncementtime = getConfig().getLong("lastannouncementtime"); lastseentime = getConfig().getLong("lastseentime"); diff --git a/src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java b/src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java new file mode 100644 index 0000000..16fd7a2 --- /dev/null +++ b/src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java @@ -0,0 +1,352 @@ +package buttondevteam.discordplugin; + +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.List; +import java.util.UUID; + +import org.bukkit.Bukkit; +import org.bukkit.Location; +import org.bukkit.craftbukkit.v1_12_R1.CraftServer; +import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause; +import org.objenesis.ObjenesisStd; + +import com.mojang.authlib.GameProfile; + +import buttondevteam.discordplugin.listeners.MCChatListener; +import buttondevteam.lib.TBMCCoreAPI; +import lombok.val; +import net.minecraft.server.v1_12_R1.AdvancementDataPlayer; +import net.minecraft.server.v1_12_R1.DedicatedPlayerList; +import net.minecraft.server.v1_12_R1.DedicatedServer; +import net.minecraft.server.v1_12_R1.Entity; +import net.minecraft.server.v1_12_R1.EntityHuman; +import net.minecraft.server.v1_12_R1.EntityPlayer; +import net.minecraft.server.v1_12_R1.GameProfileBanList; +import net.minecraft.server.v1_12_R1.IChatBaseComponent; +import net.minecraft.server.v1_12_R1.IpBanList; +import net.minecraft.server.v1_12_R1.LoginListener; +import net.minecraft.server.v1_12_R1.MinecraftServer; +import net.minecraft.server.v1_12_R1.NBTTagCompound; +import net.minecraft.server.v1_12_R1.NetworkManager; +import net.minecraft.server.v1_12_R1.OpList; +import net.minecraft.server.v1_12_R1.Packet; +import net.minecraft.server.v1_12_R1.ScoreboardServer; +import net.minecraft.server.v1_12_R1.ServerStatisticManager; +import net.minecraft.server.v1_12_R1.WhiteList; +import net.minecraft.server.v1_12_R1.World; +import net.minecraft.server.v1_12_R1.WorldServer; + +public class PlayerListWatcher extends DedicatedPlayerList { + private DedicatedPlayerList plist; + + public PlayerListWatcher(DedicatedServer minecraftserver) { + super(minecraftserver); // <-- Does some init stuff and calls Bukkit.setServer() so we have to use Objenesis + } + + @Override + public void sendMessage(IChatBaseComponent ichatbasecomponent, boolean flag) { + super.sendMessage(ichatbasecomponent, flag); + MCChatListener.sendSystemMessageToChat(ichatbasecomponent.toPlainText()); + } + + public static void hookUp() { + try { + Field conf = CraftServer.class.getDeclaredField("console"); + conf.setAccessible(true); + val server = (MinecraftServer) conf.get(Bukkit.getServer()); + val plw = new ObjenesisStd().newInstance(PlayerListWatcher.class); // Cannot call super constructor + plw.plist = (DedicatedPlayerList) server.getPlayerList(); + plw.maxPlayers = plw.plist.getMaxPlayers(); + Field plf = plw.getClass().getField("players"); + plf.setAccessible(true); + Field modf = plf.getClass().getDeclaredField("modifiers"); + modf.setAccessible(true); + modf.set(plf, plf.getModifiers() & ~Modifier.FINAL); + plf.set(plw, plw.plist.players); + server.a(plw); + } catch (Exception e) { + TBMCCoreAPI.SendException("Error while hacking the player list!", e); + } + } + + public void a(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) { + plist.a(entityhuman, ichatbasecomponent); + } + + public ServerStatisticManager a(EntityHuman entityhuman) { + return plist.a(entityhuman); + } + + public void a(EntityPlayer entityplayer, int i) { + plist.a(entityplayer, i); + } + + public void a(EntityPlayer entityplayer, WorldServer worldserver) { + plist.a(entityplayer, worldserver); + } + + public NBTTagCompound a(EntityPlayer entityplayer) { + return plist.a(entityplayer); + } + + public void a(int i) { + plist.a(i); + } + + public void a(NetworkManager networkmanager, EntityPlayer entityplayer) { + plist.a(networkmanager, entityplayer); + } + + public void a(Packet packet, int i) { + plist.a(packet, i); + } + + public EntityPlayer a(UUID uuid) { + return plist.a(uuid); + } + + public void addOp(GameProfile gameprofile) { + plist.addOp(gameprofile); + } + + public void addWhitelist(GameProfile gameprofile) { + plist.addWhitelist(gameprofile); + } + + public EntityPlayer attemptLogin(LoginListener loginlistener, GameProfile gameprofile, String hostname) { + return plist.attemptLogin(loginlistener, gameprofile, hostname); + } + + public String b(boolean flag) { + return plist.b(flag); + } + + public void b(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) { + plist.b(entityhuman, ichatbasecomponent); + } + + public void b(EntityPlayer entityplayer, WorldServer worldserver) { + plist.b(entityplayer, worldserver); + } + + public List b(String s) { + return plist.b(s); + } + + public Location calculateTarget(Location enter, World target) { + return plist.calculateTarget(enter, target); + } + + public void changeDimension(EntityPlayer entityplayer, int i, TeleportCause cause) { + plist.changeDimension(entityplayer, i, cause); + } + + public void changeWorld(Entity entity, int i, WorldServer worldserver, WorldServer worldserver1) { + plist.changeWorld(entity, i, worldserver, worldserver1); + } + + public int d() { + return plist.d(); + } + + public void d(EntityPlayer entityplayer) { + plist.d(entityplayer); + } + + public String disconnect(EntityPlayer entityplayer) { + return plist.disconnect(entityplayer); + } + + public boolean equals(Object obj) { + return plist.equals(obj); + } + + public String[] f() { + return plist.f(); + } + + public void f(EntityPlayer entityplayer) { + plist.f(entityplayer); + } + + public boolean f(GameProfile gameprofile) { + return plist.f(gameprofile); + } + + public GameProfile[] g() { + return plist.g(); + } + + public boolean getHasWhitelist() { + return plist.getHasWhitelist(); + } + + public IpBanList getIPBans() { + return plist.getIPBans(); + } + + public int getMaxPlayers() { + return plist.getMaxPlayers(); + } + + public OpList getOPs() { + return plist.getOPs(); + } + + public EntityPlayer getPlayer(String s) { + return plist.getPlayer(s); + } + + public int getPlayerCount() { + return plist.getPlayerCount(); + } + + public GameProfileBanList getProfileBans() { + return plist.getProfileBans(); + } + + public String[] getSeenPlayers() { + return plist.getSeenPlayers(); + } + + public DedicatedServer getServer() { + return plist.getServer(); + } + + public WhiteList getWhitelist() { + return plist.getWhitelist(); + } + + public String[] getWhitelisted() { + return plist.getWhitelisted(); + } + + public AdvancementDataPlayer h(EntityPlayer entityplayer) { + return plist.h(entityplayer); + } + + public int hashCode() { + return plist.hashCode(); + } + + public boolean isOp(GameProfile gameprofile) { + return plist.isOp(gameprofile); + } + + public boolean isWhitelisted(GameProfile gameprofile) { + return plist.isWhitelisted(gameprofile); + } + + public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag, Location location, + boolean avoidSuffocation) { + return plist.moveToWorld(entityplayer, i, flag, location, avoidSuffocation); + } + + public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag) { + return plist.moveToWorld(entityplayer, i, flag); + } + + public String[] n() { + return plist.n(); + } + + public void onPlayerJoin(EntityPlayer entityplayer, String joinMessage) { + plist.onPlayerJoin(entityplayer, joinMessage); + } + + public EntityPlayer processLogin(GameProfile gameprofile, EntityPlayer player) { + return plist.processLogin(gameprofile, player); + } + + public void reload() { + plist.reload(); + } + + public void reloadWhitelist() { + plist.reloadWhitelist(); + } + + public void removeOp(GameProfile gameprofile) { + plist.removeOp(gameprofile); + } + + public void removeWhitelist(GameProfile gameprofile) { + plist.removeWhitelist(gameprofile); + } + + public void repositionEntity(Entity entity, Location exit, boolean portal) { + plist.repositionEntity(entity, exit, portal); + } + + public int s() { + return plist.s(); + } + + public void savePlayers() { + plist.savePlayers(); + } + + @SuppressWarnings("rawtypes") + public void sendAll(Packet packet, EntityHuman entityhuman) { + plist.sendAll(packet, entityhuman); + } + + @SuppressWarnings("rawtypes") + public void sendAll(Packet packet, World world) { + plist.sendAll(packet, world); + } + + public void sendAll(Packet packet) { + plist.sendAll(packet); + } + + public void sendMessage(IChatBaseComponent ichatbasecomponent) { + plist.sendMessage(ichatbasecomponent); + } + + public void sendMessage(IChatBaseComponent[] iChatBaseComponents) { + plist.sendMessage(iChatBaseComponents); + } + + public void sendPacketNearby(EntityHuman entityhuman, double d0, double d1, double d2, double d3, int i, + Packet packet) { + plist.sendPacketNearby(entityhuman, d0, d1, d2, d3, i, packet); + } + + public void sendScoreboard(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) { + plist.sendScoreboard(scoreboardserver, entityplayer); + } + + public void setHasWhitelist(boolean flag) { + plist.setHasWhitelist(flag); + } + + public void setPlayerFileData(WorldServer[] aworldserver) { + plist.setPlayerFileData(aworldserver); + } + + public NBTTagCompound t() { + return plist.t(); + } + + public void tick() { + plist.tick(); + } + + public String toString() { + return plist.toString(); + } + + public void u() { + plist.u(); + } + + public void updateClient(EntityPlayer entityplayer) { + plist.updateClient(entityplayer); + } + + public List v() { + return plist.v(); + } +}