Fix ServerWatcher, mcchat works
This commit is contained in:
parent
666f05ff12
commit
cd2132ba45
5 changed files with 59 additions and 9 deletions
13
pom.xml
13
pom.xml
|
@ -114,6 +114,10 @@
|
||||||
<id>Reactor-Tools</id>
|
<id>Reactor-Tools</id>
|
||||||
<url>https://repo.spring.io/milestone</url>
|
<url>https://repo.spring.io/milestone</url>
|
||||||
</repository> -->
|
</repository> -->
|
||||||
|
<repository>
|
||||||
|
<id>papermc</id>
|
||||||
|
<url>https://papermc.io/repo/repository/maven-public/</url>
|
||||||
|
</repository>
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
|
@ -141,6 +145,12 @@
|
||||||
<version>1.14.4-R0.1-SNAPSHOT</version>
|
<version>1.14.4-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency> <!-- From patched_1.16.3.jar -->
|
||||||
|
<groupId>com.destroystokyo.paper</groupId>
|
||||||
|
<artifactId>paper</artifactId>
|
||||||
|
<version>1.16.3-R0.1-SNAPSHOT</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/com.discord4j/Discord4J -->
|
<!-- https://mvnrepository.com/artifact/com.discord4j/Discord4J -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.discord4j</groupId>
|
<groupId>com.discord4j</groupId>
|
||||||
|
@ -201,10 +211,11 @@
|
||||||
<version>master-SNAPSHOT</version>
|
<version>master-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.mockito/mockito-core -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
<artifactId>mockito-core</artifactId>
|
<artifactId>mockito-core</artifactId>
|
||||||
<version>3.0.0</version>
|
<version>3.5.10</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.mockito</groupId>
|
<groupId>org.mockito</groupId>
|
||||||
|
|
|
@ -35,6 +35,7 @@ import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.configuration.file.YamlConfiguration;
|
import org.bukkit.configuration.file.YamlConfiguration;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
|
import org.mockito.internal.util.MockUtil;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.awt.*;
|
import java.awt.*;
|
||||||
|
@ -101,6 +102,17 @@ public class DiscordPlugin extends ButtonPlugin {
|
||||||
return getIConfig().getData("inviteLink", "");
|
return getIConfig().getData("inviteLink", "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void onLoad() { //Needed by ServerWatcher
|
||||||
|
var thread = Thread.currentThread();
|
||||||
|
getLogger().info("Setting context class loader for " + thread);
|
||||||
|
var cl = thread.getContextClassLoader();
|
||||||
|
thread.setContextClassLoader(getClassLoader());
|
||||||
|
MockUtil.isMock(null); //Load MockUtil to load Mockito plugins
|
||||||
|
getLogger().info("Restoring context class loader");
|
||||||
|
thread.setContextClassLoader(cl);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void pluginEnable() {
|
public void pluginEnable() {
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -1,12 +1,14 @@
|
||||||
package buttondevteam.discordplugin.playerfaker;
|
package buttondevteam.discordplugin.playerfaker;
|
||||||
|
|
||||||
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
||||||
|
import com.destroystokyo.paper.profile.CraftPlayerProfile;
|
||||||
import lombok.RequiredArgsConstructor;
|
import lombok.RequiredArgsConstructor;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.Server;
|
import org.bukkit.Server;
|
||||||
import org.bukkit.entity.Player;
|
import org.bukkit.entity.Player;
|
||||||
import org.mockito.Mockito;
|
import org.mockito.Mockito;
|
||||||
|
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
public class ServerWatcher {
|
public class ServerWatcher {
|
||||||
|
@ -19,8 +21,17 @@ public class ServerWatcher {
|
||||||
serverField.setAccessible(true);
|
serverField.setAccessible(true);
|
||||||
if (enable) {
|
if (enable) {
|
||||||
var serverClass = Bukkit.getServer().getClass();
|
var serverClass = Bukkit.getServer().getClass();
|
||||||
var mock = Mockito.mock(serverClass, Mockito.withSettings()
|
//var mockMaker = new InlineByteBuddyMockMaker();
|
||||||
.stubOnly().defaultAnswer(invocation -> {
|
//System.setProperty("net.bytebuddy.experimental", "true");
|
||||||
|
/*try {
|
||||||
|
var resources = cl.getResources("mockito-extensions/" + MockMaker.class.getName());
|
||||||
|
System.out.println("Found resources: " + resources);
|
||||||
|
Iterables.toIterable(resources).forEach(resource -> System.out.println("Resource: " + resource));
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new IllegalStateException("Failed to load " + MockMaker.class, e);
|
||||||
|
}*/
|
||||||
|
var settings = Mockito.withSettings().stubOnly()
|
||||||
|
.defaultAnswer(invocation -> {
|
||||||
var method = invocation.getMethod();
|
var method = invocation.getMethod();
|
||||||
int pc = method.getParameterCount();
|
int pc = method.getParameterCount();
|
||||||
Player player = null;
|
Player player = null;
|
||||||
|
@ -38,18 +49,34 @@ public class ServerWatcher {
|
||||||
break;
|
break;
|
||||||
case "getOnlinePlayers":
|
case "getOnlinePlayers":
|
||||||
if (playerList == null) {
|
if (playerList == null) {
|
||||||
@SuppressWarnings("unchecked") var list = (List<Player>) invocation.callRealMethod();
|
@SuppressWarnings("unchecked") var list = (List<Player>) method.invoke(origServer, invocation.getArguments());
|
||||||
playerList = new AppendListView<>(list, fakePlayers);
|
playerList = new AppendListView<>(list, fakePlayers);
|
||||||
}
|
}
|
||||||
return playerList;
|
return playerList;
|
||||||
|
case "createProfile": //Paper's method, casts the player to a CraftPlayer
|
||||||
|
if (pc == 2) {
|
||||||
|
UUID uuid = invocation.getArgument(0);
|
||||||
|
String name = invocation.getArgument(1);
|
||||||
|
player = uuid != null ? MCChatUtils.LoggedInPlayers.get(uuid) : null;
|
||||||
|
if (player == null && name != null)
|
||||||
|
player = MCChatUtils.LoggedInPlayers.values().stream()
|
||||||
|
.filter(dcp -> dcp.getName().equalsIgnoreCase(name)).findAny().orElse(null);
|
||||||
|
if (player != null)
|
||||||
|
return new CraftPlayerProfile(player.getUniqueId(), player.getName());
|
||||||
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
if (player != null)
|
if (player != null)
|
||||||
return player;
|
return player;
|
||||||
return invocation.callRealMethod();
|
return method.invoke(origServer, invocation.getArguments());
|
||||||
}));
|
});
|
||||||
|
//var mock = mockMaker.createMock(settings, MockHandlerFactory.createMockHandler(settings));
|
||||||
|
//thread.setContextClassLoader(cl);
|
||||||
|
var mock = Mockito.mock(serverClass, settings);
|
||||||
var originalServer = serverField.get(null);
|
var originalServer = serverField.get(null);
|
||||||
for (var field : serverClass.getFields()) //Copy public fields, private fields aren't accessible directly anyways
|
for (var field : serverClass.getFields()) //Copy public fields, private fields aren't accessible directly anyways
|
||||||
field.set(mock, field.get(originalServer));
|
if (!Modifier.isFinal(field.getModifiers()) && !Modifier.isStatic(field.getModifiers()))
|
||||||
|
field.set(mock, field.get(originalServer));
|
||||||
serverField.set(null, mock);
|
serverField.set(null, mock);
|
||||||
origServer = (Server) originalServer;
|
origServer = (Server) originalServer;
|
||||||
} else if (origServer != null)
|
} else if (origServer != null)
|
||||||
|
|
|
@ -79,7 +79,7 @@ public class VanillaCommandListener15<T extends DiscordSenderBase & IMCPlayer<T>
|
||||||
var server = Bukkit.getServer();
|
var server = Bukkit.getServer();
|
||||||
var cmap = (SimpleCommandMap) server.getClass().getMethod("getCommandMap").invoke(server);
|
var cmap = (SimpleCommandMap) server.getClass().getMethod("getCommandMap").invoke(server);
|
||||||
val cmd = cmap.getCommand(cmdstr.split(" ")[0].toLowerCase());
|
val cmd = cmap.getCommand(cmdstr.split(" ")[0].toLowerCase());
|
||||||
if (!(dsender instanceof Player) || !vcwcl.isAssignableFrom(cmd.getClass()))
|
if (!(dsender instanceof Player) || cmd == null || !vcwcl.isAssignableFrom(cmd.getClass()))
|
||||||
return Bukkit.dispatchCommand(dsender, cmdstr); // Unconnected users are treated well in vanilla cmds
|
return Bukkit.dispatchCommand(dsender, cmdstr); // Unconnected users are treated well in vanilla cmds
|
||||||
|
|
||||||
if (!(dsender instanceof IMCPlayer))
|
if (!(dsender instanceof IMCPlayer))
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
mock-maker-inline
|
org.mockito.internal.creation.bytebuddy.InlineByteBuddyMockMaker
|
Loading…
Reference in a new issue