Command handling improvement, PLW work
More correct fallback for command handling Getting closer to finish PlayerListWatcher
This commit is contained in:
parent
42e91409c7
commit
c456b24333
3 changed files with 68 additions and 48 deletions
|
@ -12,7 +12,7 @@ public class GeneralEventBroadcasterModule extends Component<DiscordPlugin> {
|
||||||
@Override
|
@Override
|
||||||
protected void enable() {
|
protected void enable() {
|
||||||
try {
|
try {
|
||||||
PlayerListWatcher.hookUp();
|
PlayerListWatcher.hookUpDown(true);
|
||||||
DPUtils.getLogger().info("Finished hooking into the player list");
|
DPUtils.getLogger().info("Finished hooking into the player list");
|
||||||
hooked = true;
|
hooked = true;
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -27,7 +27,7 @@ public class GeneralEventBroadcasterModule extends Component<DiscordPlugin> {
|
||||||
protected void disable() {
|
protected void disable() {
|
||||||
try {
|
try {
|
||||||
if (!hooked) return;
|
if (!hooked) return;
|
||||||
if (PlayerListWatcher.hookDown())
|
if (PlayerListWatcher.hookUpDown(false))
|
||||||
DPUtils.getLogger().info("Finished unhooking the player list!");
|
DPUtils.getLogger().info("Finished unhooking the player list!");
|
||||||
else
|
else
|
||||||
DPUtils.getLogger().info("Didn't have the player list hooked.");
|
DPUtils.getLogger().info("Didn't have the player list hooked.");
|
||||||
|
|
|
@ -1,8 +1,8 @@
|
||||||
package buttondevteam.discordplugin.broadcaster;
|
package buttondevteam.discordplugin.broadcaster;
|
||||||
|
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
|
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
import org.mockito.invocation.InvocationOnMock;
|
import org.mockito.invocation.InvocationOnMock;
|
||||||
import org.mockito.stubbing.Answer;
|
import org.mockito.stubbing.Answer;
|
||||||
|
@ -53,57 +53,75 @@ public class PlayerListWatcher {
|
||||||
}
|
}
|
||||||
}*/
|
}*/
|
||||||
|
|
||||||
static void hookUp() throws Exception {
|
static boolean hookUpDown(boolean up) throws Exception {
|
||||||
val csc = Bukkit.getServer().getClass();
|
val csc = Bukkit.getServer().getClass();
|
||||||
Field conf = csc.getDeclaredField("console");
|
Field conf = csc.getDeclaredField("console");
|
||||||
conf.setAccessible(true);
|
conf.setAccessible(true);
|
||||||
val server = conf.get(Bukkit.getServer());
|
val server = conf.get(Bukkit.getServer());
|
||||||
val nms = server.getClass().getPackage().getName();
|
val nms = server.getClass().getPackage().getName();
|
||||||
val dplc = Class.forName(nms + ".DedicatedPlayerList");
|
val dplc = Class.forName(nms + ".DedicatedPlayerList");
|
||||||
mock = Mockito.mock(dplc, new Answer() { // Cannot call super constructor
|
val currentPL = server.getClass().getMethod("getPlayerList").invoke(server);
|
||||||
@Override
|
if (up) {
|
||||||
public Object answer(InvocationOnMock invocation) throws Throwable {
|
mock = Mockito.mock(dplc, new Answer() { // Cannot call super constructor
|
||||||
return invocation.getMethod().invoke(plist, invocation.getArguments());
|
@Override
|
||||||
}
|
public Object answer(InvocationOnMock invocation) throws Throwable {
|
||||||
});
|
if (!invocation.getMethod().getName().equals("sendMessage"))
|
||||||
plist = server.getClass().getMethod("getPlayerList").invoke(server);
|
return invocation.getMethod().invoke(plist, invocation.getArguments());
|
||||||
try {
|
val args = invocation.getArguments();
|
||||||
Field mpf = mock.getClass().getField("maxPlayers");
|
val params = invocation.getMethod().getParameterTypes();
|
||||||
mpf.setAccessible(true);
|
if (params.length == 0) {
|
||||||
Field modf = mpf.getClass().getDeclaredField("modifiers");
|
TBMCCoreAPI.SendException("Found a strange method",
|
||||||
modf.setAccessible(true);
|
new Exception("Found a sendMessage() method without arguments."));
|
||||||
modf.set(mpf, mpf.getModifiers() & ~Modifier.FINAL);
|
return null;
|
||||||
mpf.set(mock, mpf.get(plist));
|
}
|
||||||
} catch (NoSuchFieldException ignored) {
|
if (params[0].getSimpleName().equals("IChatBaseComponent[]"))
|
||||||
//The field no longer exists on 1.14
|
for (val arg : (Object[]) args[0])
|
||||||
}
|
sendMessage(arg, true);
|
||||||
Field plf = mock.getClass().getField("players");
|
else if (params[0].getSimpleName().equals("IChatBaseComponent"))
|
||||||
plf.setAccessible(true);
|
if (params.length > 1 && params[1].getSimpleName().equalsIgnoreCase("boolean"))
|
||||||
Field modf = plf.getClass().getDeclaredField("modifiers");
|
sendMessage(args[0], (Boolean) args[1]);
|
||||||
modf.setAccessible(true);
|
else
|
||||||
modf.set(plf, plf.getModifiers() & ~Modifier.FINAL);
|
sendMessage(args[0], true);
|
||||||
plf.set(mock, plf.get(plist));
|
else
|
||||||
try {
|
TBMCCoreAPI.SendException("Found a method with interesting params",
|
||||||
server.getClass().getMethod("a", dplc).invoke(server, mock);
|
new Exception("Found a sendMessage(" + params[0].getSimpleName() + ") method"));
|
||||||
} catch (NoSuchMethodException e) {
|
return null;
|
||||||
server.getClass().getMethod("a", Class.forName(server.getClass().getPackage().getName() + ".PlayerList")).invoke(server, mock);
|
}
|
||||||
}
|
|
||||||
Field pllf = CraftServer.class.getDeclaredField("playerList");
|
|
||||||
pllf.setAccessible(true);
|
|
||||||
pllf.set(Bukkit.getServer(), mock);
|
|
||||||
}
|
|
||||||
|
|
||||||
static boolean hookDown() throws Exception {
|
private void sendMessage(Object chatComponent, boolean system) {
|
||||||
/*Field conf = CraftServer.class.getDeclaredField("console");
|
//TODO
|
||||||
conf.setAccessible(true);
|
}
|
||||||
val server = (MinecraftServer) conf.get(Bukkit.getServer());
|
});
|
||||||
val plist = (DedicatedPlayerList) server.getPlayerList();
|
plist = currentPL;
|
||||||
if (!(plist instanceof PlayerListWatcher))
|
try {
|
||||||
return false;
|
Field mpf = mock.getClass().getField("maxPlayers");
|
||||||
server.a(((PlayerListWatcher) plist).plist);
|
mpf.setAccessible(true);
|
||||||
Field pllf = CraftServer.class.getDeclaredField("playerList");
|
Field modf = mpf.getClass().getDeclaredField("modifiers");
|
||||||
|
modf.setAccessible(true);
|
||||||
|
modf.set(mpf, mpf.getModifiers() & ~Modifier.FINAL);
|
||||||
|
mpf.set(mock, mpf.get(plist));
|
||||||
|
} catch (NoSuchFieldException ignored) {
|
||||||
|
//The field no longer exists on 1.14
|
||||||
|
}
|
||||||
|
Field plf = mock.getClass().getField("players");
|
||||||
|
plf.setAccessible(true);
|
||||||
|
Field modf = plf.getClass().getDeclaredField("modifiers");
|
||||||
|
modf.setAccessible(true);
|
||||||
|
modf.set(plf, plf.getModifiers() & ~Modifier.FINAL);
|
||||||
|
plf.set(mock, plf.get(plist));
|
||||||
|
} else {
|
||||||
|
if (!(mock instanceof PlayerListWatcher))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
server.getClass().getMethod("a", dplc).invoke(server, up ? mock : plist);
|
||||||
|
} catch (NoSuchMethodException e) {
|
||||||
|
server.getClass().getMethod("a", Class.forName(server.getClass().getPackage().getName() + ".PlayerList"))
|
||||||
|
.invoke(server, up ? mock : plist);
|
||||||
|
}
|
||||||
|
Field pllf = csc.getDeclaredField("playerList");
|
||||||
pllf.setAccessible(true);
|
pllf.setAccessible(true);
|
||||||
pllf.set(Bukkit.getServer(), ((PlayerListWatcher) plist).plist);*/
|
pllf.set(Bukkit.getServer(), up ? mock : plist);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -347,10 +347,12 @@ public class MCChatListener implements Listener {
|
||||||
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
|
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd);
|
||||||
else if (mcpackage.contains("1_14"))
|
else if (mcpackage.contains("1_14"))
|
||||||
VanillaCommandListener14.runBukkitOrVanillaCommand(dsender, cmd);
|
VanillaCommandListener14.runBukkitOrVanillaCommand(dsender, cmd);
|
||||||
|
else
|
||||||
|
Bukkit.dispatchCommand(dsender, cmd);
|
||||||
} catch (NoClassDefFoundError e) {
|
} catch (NoClassDefFoundError e) {
|
||||||
Bukkit.dispatchCommand(dsender, cmd);
|
TBMCCoreAPI.SendException("A class is not found when trying to run command " + cmd + "!", e);
|
||||||
}
|
}
|
||||||
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased);
|
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmd);
|
||||||
if (clmd != null)
|
if (clmd != null)
|
||||||
channel.set(chtmp);
|
channel.set(chtmp);
|
||||||
});
|
});
|
||||||
|
|
Loading…
Reference in a new issue