It compiles! Remove LPInjector for now

The IDE and the Scala compiler don't agree on what is or isn't needed
This commit is contained in:
Norbi Peti 2021-03-09 23:55:02 +01:00
parent a84cd4e8e3
commit 1b1a592a1e
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
11 changed files with 303 additions and 403 deletions

12
pom.xml
View file

@ -84,7 +84,7 @@
<version>4.4.0</version>
<executions>
<execution>
<phase>generate-sources</phase>
<phase>compile</phase>
<goals>
<goal>compile</goal>
</goals>
@ -92,9 +92,6 @@
</executions>
<configuration>
<!-- <sendJavaToScalac>false</sendJavaToScalac> -->
<addToClasspath>target/generated-sourcess</addToClasspath>
<removeFromClasspath>src/main/java</removeFromClasspath>
<sourceDir>src/main/scala</sourceDir>
</configuration>
</plugin>
</plugins>
@ -208,13 +205,6 @@
<version>2.17.1</version>
<scope>provided</scope>
</dependency>
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.10</version>
<scope>provided</scope>
</dependency>
<!-- <dependency>
<groupId>ru.tehkode</groupId>
<artifactId>PermissionsEx</artifactId>

View file

@ -4,11 +4,8 @@ import buttondevteam.discordplugin.mcchat.MinecraftChatModule
import buttondevteam.discordplugin.playerfaker.{DiscordInventory, VCMDWrapper}
import discord4j.core.`object`.entity.User
import discord4j.core.`object`.entity.channel.MessageChannel
import net.md_5.bungee.api.ChatMessageType
import net.md_5.bungee.api.chat.BaseComponent
import org.bukkit._
import org.bukkit.attribute.{Attribute, AttributeInstance, AttributeModifier}
import org.bukkit.entity.Player.Spigot
import org.bukkit.entity.{Entity, Player}
import org.bukkit.event.player.{AsyncPlayerChatEvent, PlayerTeleportEvent}
import org.bukkit.inventory.{Inventory, PlayerInventory}
@ -19,7 +16,6 @@ import org.mockito.invocation.InvocationOnMock
import org.mockito.{MockSettings, Mockito}
import java.lang.reflect.Modifier
import java.net.InetSocketAddress
import java.util
import java.util._
@ -202,7 +198,7 @@ abstract class DiscordConnectedPlayer(user: User, channel: MessageChannel, val u
override def getGameMode = GameMode.SPECTATOR
//noinspection ScalaDeprecation
@SuppressWarnings(Array("deprecation")) override def spigot: Spigot = new Spigot() {
/*@SuppressWarnings(Array("deprecation")) override def spigot: super.Spigot = new super.Spigot() {
override def getRawAddress: InetSocketAddress = null
override def playEffect(location: Location, effect: Effect, id: Int, data: Int, offsetX: Float, offsetY: Float, offsetZ: Float, speed: Float, particleCount: Int, radius: Int): Unit = {
@ -233,5 +229,5 @@ abstract class DiscordConnectedPlayer(user: User, channel: MessageChannel, val u
sendMessage(components: _*)
override def isInvulnerable = true
}
}*/
}

View file

@ -56,5 +56,5 @@ class DiscordSender(user: User, channel: MessageChannel, pname: String) extends
override def getName: String = name
override def spigot = new CommandSender.Spigot
//override def spigot(): CommandSender.Spigot = new CommandSender.Spigot
}

View file

@ -134,7 +134,7 @@ class MinecraftChatModule extends Component[DiscordPlugin] {
}
}
}
try if (lpInjector == null) lpInjector = new LPInjector(DiscordPlugin.plugin)
try if (lpInjector == null) lpInjector = new LPInjector //new LPInjector(DiscordPlugin.plugin)
catch {
case e: Exception =>
TBMCCoreAPI.SendException("Failed to init LuckPerms injector", e, this)

View file

@ -1,102 +0,0 @@
package buttondevteam.discordplugin.playerfaker;
import buttondevteam.discordplugin.DiscordSenderBase;
import buttondevteam.discordplugin.IMCPlayer;
import lombok.Getter;
import lombok.val;
import net.minecraft.server.v1_12_R1.*;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_12_R1.command.VanillaCommandWrapper;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class VanillaCommandListener<T extends DiscordSenderBase & IMCPlayer<T>> implements ICommandListener {
private @Getter T player;
private Player bukkitplayer;
/**
* This constructor will only send raw vanilla messages to the sender in plain text.
*
* @param player The Discord sender player (the wrapper)
*/
public VanillaCommandListener(T player) {
this.player = player;
this.bukkitplayer = null;
}
/**
* This constructor will send both raw vanilla messages to the sender in plain text and forward the raw message to the provided player.
*
* @param player The Discord sender player (the wrapper)
* @param bukkitplayer The Bukkit player to send the raw message to
*/
public VanillaCommandListener(T player, Player bukkitplayer) {
this.player = player;
this.bukkitplayer = bukkitplayer;
if (bukkitplayer != null && !(bukkitplayer instanceof CraftPlayer))
throw new ClassCastException("bukkitplayer must be a Bukkit player!");
}
@Override
public MinecraftServer C_() {
return ((CraftServer) Bukkit.getServer()).getServer();
}
@Override
public boolean a(int oplevel, String cmd) {
// return oplevel <= 2; // Value from CommandBlockListenerAbstract, found what it is in EntityPlayer - Wait, that'd always allow OP commands
return oplevel == 0 || player.isOp();
}
@Override
public String getName() {
return player.getName();
}
@Override
public World getWorld() {
return ((CraftWorld) player.getWorld()).getHandle();
}
@Override
public void sendMessage(IChatBaseComponent arg0) {
player.sendMessage(arg0.toPlainText());
if (bukkitplayer != null)
((CraftPlayer) bukkitplayer).getHandle().sendMessage(arg0);
}
public static boolean runBukkitOrVanillaCommand(DiscordSenderBase dsender, String cmdstr) {
val cmd = ((CraftServer) Bukkit.getServer()).getCommandMap().getCommand(cmdstr.split(" ")[0].toLowerCase());
if (!(dsender instanceof Player) || !(cmd instanceof VanillaCommandWrapper))
return Bukkit.dispatchCommand(dsender, cmdstr); // Unconnected users are treated well in vanilla cmds
if (!(dsender instanceof IMCPlayer))
throw new ClassCastException(
"dsender needs to implement IMCPlayer to use vanilla commands as it implements Player.");
IMCPlayer<?> sender = (IMCPlayer<?>) dsender; // Don't use val on recursive interfaces :P
val vcmd = (VanillaCommandWrapper) cmd;
if (!vcmd.testPermission(sender))
return true;
ICommandListener icommandlistener = (ICommandListener) sender.getVanillaCmdListener().getListener();
if (icommandlistener == null)
return VCMDWrapper.compatResponse(dsender);
String[] args = cmdstr.split(" ");
args = Arrays.copyOfRange(args, 1, args.length);
try {
vcmd.dispatchVanillaCommand(sender, icommandlistener, args);
} catch (CommandException commandexception) {
// Taken from CommandHandler
ChatMessage chatmessage = new ChatMessage(commandexception.getMessage(), commandexception.getArgs());
chatmessage.getChatModifier().setColor(EnumChatFormat.RED);
icommandlistener.sendMessage(chatmessage);
}
return true;
}
}

View file

@ -0,0 +1,85 @@
package buttondevteam.discordplugin.playerfaker
import buttondevteam.discordplugin.{DiscordSenderBase, IMCPlayer}
import lombok.Getter
import net.minecraft.server.v1_12_R1._
import org.bukkit.Bukkit
import org.bukkit.craftbukkit.v1_12_R1.command.VanillaCommandWrapper
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer
import org.bukkit.craftbukkit.v1_12_R1.{CraftServer, CraftWorld}
import org.bukkit.entity.Player
import java.util
object VanillaCommandListener {
def runBukkitOrVanillaCommand(dsender: DiscordSenderBase, cmdstr: String): Boolean = {
val cmd = Bukkit.getServer.asInstanceOf[CraftServer].getCommandMap.getCommand(cmdstr.split(" ")(0).toLowerCase)
if (!dsender.isInstanceOf[Player] || !cmd.isInstanceOf[VanillaCommandWrapper])
return Bukkit.dispatchCommand(dsender, cmdstr) // Unconnected users are treated well in vanilla cmds
if (!dsender.isInstanceOf[IMCPlayer[_]])
throw new ClassCastException("dsender needs to implement IMCPlayer to use vanilla commands as it implements Player.")
val sender = dsender.asInstanceOf[IMCPlayer[_]]
val vcmd = cmd.asInstanceOf[VanillaCommandWrapper]
if (!vcmd.testPermission(sender)) return true
val icommandlistener = sender.getVanillaCmdListener.getListener.asInstanceOf[ICommandListener]
if (icommandlistener == null) return VCMDWrapper.compatResponse(dsender)
var args = cmdstr.split(" ")
args = util.Arrays.copyOfRange(args, 1, args.length)
try vcmd.dispatchVanillaCommand(sender, icommandlistener, args)
catch {
case commandexception: CommandException =>
// Taken from CommandHandler
val chatmessage = new ChatMessage(commandexception.getMessage, commandexception.getArgs)
chatmessage.getChatModifier.setColor(EnumChatFormat.RED)
icommandlistener.sendMessage(chatmessage)
}
true
}
}
class VanillaCommandListener[T <: DiscordSenderBase with IMCPlayer[T]] extends ICommandListener {
def getPlayer: T = this.player
@Getter private var player: T = null.asInstanceOf
private var bukkitplayer: Player = null
/**
* This constructor will only send raw vanilla messages to the sender in plain text.
*
* @param player The Discord sender player (the wrapper)
*/
def this(player: T) {
this()
this.player = player
this.bukkitplayer = null
}
/**
* This constructor will send both raw vanilla messages to the sender in plain text and forward the raw message to the provided player.
*
* @param player The Discord sender player (the wrapper)
* @param bukkitplayer The Bukkit player to send the raw message to
*/
def this(player: T, bukkitplayer: Player) {
this()
this.player = player
this.bukkitplayer = bukkitplayer
if (bukkitplayer != null && !bukkitplayer.isInstanceOf[CraftPlayer])
throw new ClassCastException("bukkitplayer must be a Bukkit player!")
}
override def C_(): MinecraftServer = Bukkit.getServer.asInstanceOf[CraftServer].getServer
override def a(oplevel: Int, cmd: String): Boolean = { //return oplevel <= 2; // Value from CommandBlockListenerAbstract, found what it is in EntityPlayer - Wait, that'd always allow OP commands
oplevel == 0 || player.isOp
}
override def getName: String = player.getName
override def getWorld: World = player.getWorld.asInstanceOf[CraftWorld].getHandle
override def sendMessage(arg0: IChatBaseComponent): Unit = {
player.sendMessage(arg0.toPlainText)
if (bukkitplayer != null) bukkitplayer.asInstanceOf[CraftPlayer].getHandle.sendMessage(arg0)
}
}

View file

@ -1,108 +0,0 @@
package buttondevteam.discordplugin.playerfaker;
import buttondevteam.discordplugin.DiscordSenderBase;
import buttondevteam.discordplugin.IMCPlayer;
import lombok.Getter;
import lombok.val;
import net.minecraft.server.v1_14_R1.*;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.craftbukkit.v1_14_R1.CraftServer;
import org.bukkit.craftbukkit.v1_14_R1.CraftWorld;
import org.bukkit.craftbukkit.v1_14_R1.command.ProxiedNativeCommandSender;
import org.bukkit.craftbukkit.v1_14_R1.command.VanillaCommandWrapper;
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import java.util.Arrays;
public class VanillaCommandListener14<T extends DiscordSenderBase & IMCPlayer<T>> implements ICommandListener {
private @Getter T player;
private Player bukkitplayer;
/**
* This constructor will only send raw vanilla messages to the sender in plain text.
*
* @param player The Discord sender player (the wrapper)
*/
public VanillaCommandListener14(T player) {
this.player = player;
this.bukkitplayer = null;
}
/**
* This constructor will send both raw vanilla messages to the sender in plain text and forward the raw message to the provided player.
*
* @param player The Discord sender player (the wrapper)
* @param bukkitplayer The Bukkit player to send the raw message to
*/
public VanillaCommandListener14(T player, Player bukkitplayer) {
this.player = player;
this.bukkitplayer = bukkitplayer;
if (bukkitplayer != null && !(bukkitplayer instanceof CraftPlayer))
throw new ClassCastException("bukkitplayer must be a Bukkit player!");
}
@Override
public void sendMessage(IChatBaseComponent arg0) {
player.sendMessage(arg0.getString());
if (bukkitplayer != null)
((CraftPlayer) bukkitplayer).getHandle().sendMessage(arg0);
}
@Override
public boolean shouldSendSuccess() {
return true;
}
@Override
public boolean shouldSendFailure() {
return true;
}
@Override
public boolean shouldBroadcastCommands() {
return true; //Broadcast to in-game admins
}
@Override
public CommandSender getBukkitSender(CommandListenerWrapper commandListenerWrapper) {
return player;
}
public static boolean runBukkitOrVanillaCommand(DiscordSenderBase dsender, String cmdstr) {
val cmd = ((CraftServer) Bukkit.getServer()).getCommandMap().getCommand(cmdstr.split(" ")[0].toLowerCase());
if (!(dsender instanceof Player) || !(cmd instanceof VanillaCommandWrapper))
return Bukkit.dispatchCommand(dsender, cmdstr); // Unconnected users are treated well in vanilla cmds
if (!(dsender instanceof IMCPlayer))
throw new ClassCastException(
"dsender needs to implement IMCPlayer to use vanilla commands as it implements Player.");
IMCPlayer<?> sender = (IMCPlayer<?>) dsender; // Don't use val on recursive interfaces :P
val vcmd = (VanillaCommandWrapper) cmd;
if (!vcmd.testPermission(sender))
return true;
val world = ((CraftWorld) Bukkit.getWorlds().get(0)).getHandle();
ICommandListener icommandlistener = (ICommandListener) sender.getVanillaCmdListener().getListener();
if (icommandlistener == null)
return VCMDWrapper.compatResponse(dsender);
val wrapper = new CommandListenerWrapper(icommandlistener, new Vec3D(0, 0, 0),
new Vec2F(0, 0), world, 0, sender.getName(),
new ChatComponentText(sender.getName()), world.getMinecraftServer(), null);
val pncs = new ProxiedNativeCommandSender(wrapper, sender, sender);
String[] args = cmdstr.split(" ");
args = Arrays.copyOfRange(args, 1, args.length);
try {
return vcmd.execute(pncs, cmd.getLabel(), args);
} catch (CommandException commandexception) {
// Taken from CommandHandler
ChatMessage chatmessage = new ChatMessage(commandexception.getMessage(), commandexception.a());
chatmessage.getChatModifier().setColor(EnumChatFormat.RED);
icommandlistener.sendMessage(chatmessage);
}
return true;
}
}

View file

@ -0,0 +1,85 @@
package buttondevteam.discordplugin.playerfaker
import buttondevteam.discordplugin.{DiscordSenderBase, IMCPlayer}
import lombok.Getter
import net.minecraft.server.v1_14_R1._
import org.bukkit.Bukkit
import org.bukkit.command.CommandSender
import org.bukkit.craftbukkit.v1_14_R1.command.{ProxiedNativeCommandSender, VanillaCommandWrapper}
import org.bukkit.craftbukkit.v1_14_R1.entity.CraftPlayer
import org.bukkit.craftbukkit.v1_14_R1.{CraftServer, CraftWorld}
import org.bukkit.entity.Player
import java.util
object VanillaCommandListener14 {
def runBukkitOrVanillaCommand(dsender: DiscordSenderBase, cmdstr: String): Boolean = {
val cmd = Bukkit.getServer.asInstanceOf[CraftServer].getCommandMap.getCommand(cmdstr.split(" ")(0).toLowerCase)
if (!dsender.isInstanceOf[Player] || !cmd.isInstanceOf[VanillaCommandWrapper])
return Bukkit.dispatchCommand(dsender, cmdstr) // Unconnected users are treated well in vanilla cmds
if (!dsender.isInstanceOf[IMCPlayer[_]])
throw new ClassCastException("dsender needs to implement IMCPlayer to use vanilla commands as it implements Player.")
val sender = dsender.asInstanceOf[IMCPlayer[_]] // Don't use val on recursive interfaces :P
val vcmd = cmd.asInstanceOf[VanillaCommandWrapper]
if (!vcmd.testPermission(sender)) return true
val world = Bukkit.getWorlds.get(0).asInstanceOf[CraftWorld].getHandle
val icommandlistener = sender.getVanillaCmdListener.getListener.asInstanceOf[ICommandListener]
if (icommandlistener == null) return VCMDWrapper.compatResponse(dsender)
val wrapper = new CommandListenerWrapper(icommandlistener, new Vec3D(0, 0, 0), new Vec2F(0, 0), world, 0, sender.getName, new ChatComponentText(sender.getName), world.getMinecraftServer, null)
val pncs = new ProxiedNativeCommandSender(wrapper, sender, sender)
var args = cmdstr.split(" ")
args = util.Arrays.copyOfRange(args, 1, args.length)
try return vcmd.execute(pncs, cmd.getLabel, args)
catch {
case commandexception: CommandException =>
// Taken from CommandHandler
val chatmessage = new ChatMessage(commandexception.getMessage, commandexception.a)
chatmessage.getChatModifier.setColor(EnumChatFormat.RED)
icommandlistener.sendMessage(chatmessage)
}
true
}
}
class VanillaCommandListener14[T <: DiscordSenderBase with IMCPlayer[T]] extends ICommandListener {
def getPlayer: T = this.player
@Getter private var player: T = null.asInstanceOf
private var bukkitplayer: Player = null
/**
* This constructor will only send raw vanilla messages to the sender in plain text.
*
* @param player The Discord sender player (the wrapper)
*/
def this(player: T) {
this()
this.player = player
this.bukkitplayer = null
}
/**
* This constructor will send both raw vanilla messages to the sender in plain text and forward the raw message to the provided player.
*
* @param player The Discord sender player (the wrapper)
* @param bukkitplayer The Bukkit player to send the raw message to
*/
def this(player: T, bukkitplayer: Player) {
this()
this.player = player
this.bukkitplayer = bukkitplayer
if (bukkitplayer != null && !bukkitplayer.isInstanceOf[CraftPlayer]) throw new ClassCastException("bukkitplayer must be a Bukkit player!")
}
override def sendMessage(arg0: IChatBaseComponent): Unit = {
player.sendMessage(arg0.getString)
if (bukkitplayer != null) bukkitplayer.asInstanceOf[CraftPlayer].getHandle.sendMessage(arg0)
}
override def shouldSendSuccess = true
override def shouldSendFailure = true
override def shouldBroadcastCommands = true //Broadcast to in-game admins
override def getBukkitSender(commandListenerWrapper: CommandListenerWrapper): CommandSender = player
}

View file

@ -1,138 +0,0 @@
package buttondevteam.discordplugin.playerfaker;
import buttondevteam.discordplugin.DiscordSenderBase;
import buttondevteam.discordplugin.IMCPlayer;
import lombok.Getter;
import lombok.val;
import org.bukkit.Bukkit;
import org.bukkit.command.CommandSender;
import org.bukkit.command.SimpleCommandMap;
import org.bukkit.entity.Player;
import org.mockito.Answers;
import org.mockito.Mockito;
import java.lang.reflect.Modifier;
import java.util.Arrays;
/**
* Same as {@link VanillaCommandListener14} but with reflection
*/
public class VanillaCommandListener15<T extends DiscordSenderBase & IMCPlayer<T>> {
private @Getter T player;
private static Class<?> vcwcl;
private static String nms;
protected VanillaCommandListener15(T player, Player bukkitplayer) {
this.player = player;
if (bukkitplayer != null && !bukkitplayer.getClass().getSimpleName().endsWith("CraftPlayer"))
throw new ClassCastException("bukkitplayer must be a Bukkit player!");
}
/**
* This method will only send raw vanilla messages to the sender in plain text.
*
* @param player The Discord sender player (the wrapper)
*/
public static <T extends DiscordSenderBase & IMCPlayer<T>> VanillaCommandListener15<T> create(T player) throws Exception {
return create(player, null);
}
/**
* This method will send both raw vanilla messages to the sender in plain text and forward the raw message to the provided player.
*
* @param player The Discord sender player (the wrapper)
* @param bukkitplayer The Bukkit player to send the raw message to
*/
@SuppressWarnings("unchecked")
public static <T extends DiscordSenderBase & IMCPlayer<T>> VanillaCommandListener15<T> create(T player, Player bukkitplayer) throws Exception {
if (vcwcl == null) {
String pkg = Bukkit.getServer().getClass().getPackage().getName();
vcwcl = Class.forName(pkg + ".command.VanillaCommandWrapper");
}
if (nms == null) {
var server = Bukkit.getServer();
nms = server.getClass().getMethod("getServer").invoke(server).getClass().getPackage().getName(); //org.mockito.codegen
}
var iclcl = Class.forName(nms + ".ICommandListener");
return Mockito.mock(VanillaCommandListener15.class, Mockito.withSettings().stubOnly()
.useConstructor(player, bukkitplayer).extraInterfaces(iclcl).defaultAnswer(invocation -> {
if (invocation.getMethod().getName().equals("sendMessage")) {
var icbc = invocation.getArgument(0);
player.sendMessage((String) icbc.getClass().getMethod("getString").invoke(icbc));
if (bukkitplayer != null) {
var handle = bukkitplayer.getClass().getMethod("getHandle").invoke(bukkitplayer);
handle.getClass().getMethod("sendMessage", icbc.getClass()).invoke(handle, icbc);
}
return null;
}
if (!Modifier.isAbstract(invocation.getMethod().getModifiers()))
return invocation.callRealMethod();
if (invocation.getMethod().getReturnType() == boolean.class)
return true; //shouldSend... shouldBroadcast...
if (invocation.getMethod().getReturnType() == CommandSender.class)
return player;
return Answers.RETURNS_DEFAULTS.answer(invocation);
}));
}
public static boolean runBukkitOrVanillaCommand(DiscordSenderBase dsender, String cmdstr) throws Exception {
var server = Bukkit.getServer();
var cmap = (SimpleCommandMap) server.getClass().getMethod("getCommandMap").invoke(server);
val cmd = cmap.getCommand(cmdstr.split(" ")[0].toLowerCase());
if (!(dsender instanceof Player) || cmd == null || !vcwcl.isAssignableFrom(cmd.getClass()))
return Bukkit.dispatchCommand(dsender, cmdstr); // Unconnected users are treated well in vanilla cmds
if (!(dsender instanceof IMCPlayer))
throw new ClassCastException(
"dsender needs to implement IMCPlayer to use vanilla commands as it implements Player.");
IMCPlayer<?> sender = (IMCPlayer<?>) dsender; // Don't use val on recursive interfaces :P
if (!(Boolean) vcwcl.getMethod("testPermission", CommandSender.class).invoke(cmd, sender))
return true;
var cworld = Bukkit.getWorlds().get(0);
val world = cworld.getClass().getMethod("getHandle").invoke(cworld);
var icommandlistener = sender.getVanillaCmdListener().getListener();
if (icommandlistener == null)
return VCMDWrapper.compatResponse(dsender);
var clwcl = Class.forName(nms + ".CommandListenerWrapper");
var v3dcl = Class.forName(nms + ".Vec3D");
var v2fcl = Class.forName(nms + ".Vec2F");
var icbcl = Class.forName(nms + ".IChatBaseComponent");
var mcscl = Class.forName(nms + ".MinecraftServer");
var ecl = Class.forName(nms + ".Entity");
var cctcl = Class.forName(nms + ".ChatComponentText");
var iclcl = Class.forName(nms + ".ICommandListener");
Object wrapper = clwcl.getConstructor(iclcl, v3dcl, v2fcl, world.getClass(), int.class, String.class, icbcl, mcscl, ecl)
.newInstance(icommandlistener,
v3dcl.getConstructor(double.class, double.class, double.class).newInstance(0, 0, 0),
v2fcl.getConstructor(float.class, float.class).newInstance(0, 0),
world, 0, sender.getName(), cctcl.getConstructor(String.class).newInstance(sender.getName()),
world.getClass().getMethod("getMinecraftServer").invoke(world), null);
/*val wrapper = new CommandListenerWrapper(icommandlistener, new Vec3D(0, 0, 0),
new Vec2F(0, 0), world, 0, sender.getName(),
new ChatComponentText(sender.getName()), world.getMinecraftServer(), null);*/
var pncscl = Class.forName(vcwcl.getPackage().getName() + ".ProxiedNativeCommandSender");
Object pncs = pncscl.getConstructor(clwcl, CommandSender.class, CommandSender.class)
.newInstance(wrapper, sender, sender);
String[] args = cmdstr.split(" ");
args = Arrays.copyOfRange(args, 1, args.length);
try {
return cmd.execute((CommandSender) pncs, cmd.getLabel(), args);
} catch (Exception commandexception) {
if (!commandexception.getClass().getSimpleName().equals("CommandException"))
throw commandexception;
// Taken from CommandHandler
var cmcl = Class.forName(nms + ".ChatMessage");
var chatmessage = cmcl.getConstructor(String.class, Object[].class)
.newInstance(commandexception.getMessage(),
new Object[]{commandexception.getClass().getMethod("a").invoke(commandexception)});
var modifier = cmcl.getMethod("getChatModifier").invoke(chatmessage);
var ecfcl = Class.forName(nms + ".EnumChatFormat");
modifier.getClass().getMethod("setColor", ecfcl).invoke(modifier, ecfcl.getField("RED").get(null));
icommandlistener.getClass().getMethod("sendMessage", icbcl).invoke(icommandlistener, chatmessage);
}
return true;
}
}

View file

@ -0,0 +1,123 @@
package buttondevteam.discordplugin.playerfaker
import buttondevteam.discordplugin.{DiscordSenderBase, IMCPlayer}
import org.bukkit.Bukkit
import org.bukkit.command.{CommandSender, SimpleCommandMap}
import org.bukkit.entity.Player
import org.mockito.{Answers, Mockito}
import java.lang.reflect.Modifier
import java.util
/**
* Same as {@link VanillaCommandListener14} but with reflection
*/
object VanillaCommandListener15 {
private var vcwcl: Class[_] = null
private var nms: String = null
/**
* This method will only send raw vanilla messages to the sender in plain text.
*
* @param player The Discord sender player (the wrapper)
*/
@throws[Exception]
def create[T <: DiscordSenderBase with IMCPlayer[T]](player: T): VanillaCommandListener15[T] = create(player, null)
/**
* This method will send both raw vanilla messages to the sender in plain text and forward the raw message to the provided player.
*
* @param player The Discord sender player (the wrapper)
* @param bukkitplayer The Bukkit player to send the raw message to
*/
@SuppressWarnings(Array("unchecked"))
@throws[Exception]
def create[T <: DiscordSenderBase with IMCPlayer[T]](player: T, bukkitplayer: Player): VanillaCommandListener15[T] = {
if (vcwcl == null) {
val pkg = Bukkit.getServer.getClass.getPackage.getName
vcwcl = Class.forName(pkg + ".command.VanillaCommandWrapper")
}
if (nms == null) {
val server = Bukkit.getServer
nms = server.getClass.getMethod("getServer").invoke(server).getClass.getPackage.getName //org.mockito.codegen
}
val iclcl = Class.forName(nms + ".ICommandListener")
Mockito.mock(classOf[VanillaCommandListener15[T]],
Mockito.withSettings.stubOnly.useConstructor(player, bukkitplayer)
.extraInterfaces(iclcl).defaultAnswer(invocation => {
if (invocation.getMethod.getName == "sendMessage") {
val icbc = invocation.getArgument(0)
player.sendMessage(icbc.getClass.getMethod("getString").invoke(icbc).asInstanceOf[String])
if (bukkitplayer != null) {
val handle = bukkitplayer.getClass.getMethod("getHandle").invoke(bukkitplayer)
handle.getClass.getMethod("sendMessage", icbc.getClass).invoke(handle, icbc)
}
null
}
else if (!Modifier.isAbstract(invocation.getMethod.getModifiers)) invocation.callRealMethod
else if (invocation.getMethod.getReturnType eq classOf[Boolean]) true //shouldSend... shouldBroadcast...
else if (invocation.getMethod.getReturnType eq classOf[CommandSender]) player
else Answers.RETURNS_DEFAULTS.answer(invocation)
}))
}
@throws[Exception]
def runBukkitOrVanillaCommand(dsender: DiscordSenderBase, cmdstr: String): Boolean = {
val server = Bukkit.getServer
val cmap = server.getClass.getMethod("getCommandMap").invoke(server).asInstanceOf[SimpleCommandMap]
val cmd = cmap.getCommand(cmdstr.split(" ")(0).toLowerCase)
if (!dsender.isInstanceOf[Player] || cmd == null || !vcwcl.isAssignableFrom(cmd.getClass))
return Bukkit.dispatchCommand(dsender, cmdstr) // Unconnected users are treated well in vanilla cmds
if (!dsender.isInstanceOf[IMCPlayer[_]])
throw new ClassCastException("dsender needs to implement IMCPlayer to use vanilla commands as it implements Player.")
val sender = dsender.asInstanceOf[IMCPlayer[_]] // Don't use val on recursive interfaces :P
if (!vcwcl.getMethod("testPermission", classOf[CommandSender]).invoke(cmd, sender).asInstanceOf[Boolean])
return true
val cworld = Bukkit.getWorlds.get(0)
val world = cworld.getClass.getMethod("getHandle").invoke(cworld)
val icommandlistener = sender.getVanillaCmdListener.getListener
if (icommandlistener == null) return VCMDWrapper.compatResponse(dsender)
val clwcl = Class.forName(nms + ".CommandListenerWrapper")
val v3dcl = Class.forName(nms + ".Vec3D")
val v2fcl = Class.forName(nms + ".Vec2F")
val icbcl = Class.forName(nms + ".IChatBaseComponent")
val mcscl = Class.forName(nms + ".MinecraftServer")
val ecl = Class.forName(nms + ".Entity")
val cctcl = Class.forName(nms + ".ChatComponentText")
val iclcl = Class.forName(nms + ".ICommandListener")
val wrapper = clwcl.getConstructor(iclcl, v3dcl, v2fcl, world.getClass, classOf[Int], classOf[String], icbcl, mcscl, ecl)
.newInstance(icommandlistener, v3dcl.getConstructor(classOf[Double], classOf[Double], classOf[Double])
.newInstance(0, 0, 0), v2fcl.getConstructor(classOf[Float], classOf[Float])
.newInstance(0, 0), world, 0, sender.getName, cctcl.getConstructor(classOf[String])
.newInstance(sender.getName), world.getClass.getMethod("getMinecraftServer").invoke(world), null)
/*val wrapper = new CommandListenerWrapper(icommandlistener, new Vec3D(0, 0, 0),
new Vec2F(0, 0), world, 0, sender.getName(),
new ChatComponentText(sender.getName()), world.getMinecraftServer(), null);*/
val pncscl = Class.forName(vcwcl.getPackage.getName + ".ProxiedNativeCommandSender")
val pncs = pncscl.getConstructor(clwcl, classOf[CommandSender], classOf[CommandSender])
.newInstance(wrapper, sender, sender)
var args = cmdstr.split(" ")
args = util.Arrays.copyOfRange(args, 1, args.length)
try return cmd.execute(pncs.asInstanceOf[CommandSender], cmd.getLabel, args)
catch {
case commandexception: Exception =>
if (!(commandexception.getClass.getSimpleName == "CommandException")) throw commandexception
// Taken from CommandHandler
val cmcl = Class.forName(nms + ".ChatMessage")
val chatmessage = cmcl.getConstructor(classOf[String], classOf[Array[AnyRef]])
.newInstance(commandexception.getMessage, Array[AnyRef](commandexception.getClass.getMethod("a").invoke(commandexception)))
val modifier = cmcl.getMethod("getChatModifier").invoke(chatmessage)
val ecfcl = Class.forName(nms + ".EnumChatFormat")
modifier.getClass.getMethod("setColor", ecfcl).invoke(modifier, ecfcl.getField("RED").get(null))
icommandlistener.getClass.getMethod("sendMessage", icbcl).invoke(icommandlistener, chatmessage)
}
true
}
}
class VanillaCommandListener15[T <: DiscordSenderBase with IMCPlayer[T]] protected(var player: T, val bukkitplayer: Player) {
if (bukkitplayer != null && !bukkitplayer.getClass.getSimpleName.endsWith("CraftPlayer"))
throw new ClassCastException("bukkitplayer must be a Bukkit player!")
def getPlayer: T = this.player
}

View file

@ -1,40 +1,9 @@
package buttondevteam.discordplugin.playerfaker.perm;
import buttondevteam.discordplugin.DiscordConnectedPlayer;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.mcchat.MCChatUtils;
import buttondevteam.lib.TBMCCoreAPI;
import me.lucko.luckperms.bukkit.LPBukkitBootstrap;
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
import me.lucko.luckperms.bukkit.inject.permissible.DummyPermissibleBase;
import me.lucko.luckperms.bukkit.inject.permissible.LuckPermsPermissible;
import me.lucko.luckperms.bukkit.listeners.BukkitConnectionListener;
import me.lucko.luckperms.common.config.ConfigKeys;
import me.lucko.luckperms.common.locale.Message;
import me.lucko.luckperms.common.locale.TranslationManager;
import me.lucko.luckperms.common.model.User;
import net.kyori.adventure.text.Component;
import net.kyori.adventure.text.serializer.legacy.LegacyComponentSerializer;
import org.bukkit.Bukkit;
import org.bukkit.event.EventHandler;
import org.bukkit.event.EventPriority;
import org.bukkit.event.Listener;
import org.bukkit.event.player.PlayerLoginEvent;
import org.bukkit.event.player.PlayerQuitEvent;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.PermissionAttachment;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.Collection;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import java.util.concurrent.atomic.AtomicBoolean;
public final class LPInjector implements Listener { //Disable login event for LuckPerms
private final LPBukkitPlugin plugin;
/*private final LPBukkitPlugin plugin;
private final BukkitConnectionListener connectionListener;
private final Set<UUID> deniedLogin;
private final Field detectedCraftBukkitOfflineMode;
@ -86,11 +55,11 @@ public final class LPInjector implements Listener { //Disable login event for Lu
//Code copied from LuckPerms - me.lucko.luckperms.bukkit.listeners.BukkitConnectionListener
@EventHandler(priority = EventPriority.LOWEST)
public void onPlayerLogin(PlayerLoginEvent e) {
public void onPlayerLogin(PlayerLoginEvent e) {*/
/* Called when the player starts logging into the server.
At this point, the users data should be present and loaded. */
if (!(e.getPlayer() instanceof DiscordConnectedPlayer))
/*if (!(e.getPlayer() instanceof DiscordConnectedPlayer))
return; //Normal players must be handled by the plugin
final DiscordConnectedPlayer player = (DiscordConnectedPlayer) e.getPlayer();
@ -102,7 +71,7 @@ public final class LPInjector implements Listener { //Disable login event for Lu
final User user = plugin.getUserManager().getIfLoaded(player.getUniqueId());
/* User instance is null for whatever reason. Could be that it was unloaded between asyncpre and now. */
if (user == null) {
/*if (user == null) {
deniedLogin.add(player.getUniqueId());
if (!plugin.getConnectionListener().getUniqueConnections().contains(player.getUniqueId())) {
@ -234,5 +203,5 @@ public final class LPInjector implements Listener { //Disable login event for Lu
player.setPerm(DummyPermissibleBase.INSTANCE);
}
}
}*/
}