LP injecting, fake player fixes
#96 LuckPerms Added support for excluding plugins from certain events from code Also might have fixed some message timeouts by relocating netty
This commit is contained in:
parent
2bdba0af22
commit
bf538d9bd0
8 changed files with 1114 additions and 787 deletions
422
pom.xml
422
pom.xml
|
@ -1,45 +1,45 @@
|
||||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||||
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||||
<modelVersion>4.0.0</modelVersion>
|
<modelVersion>4.0.0</modelVersion>
|
||||||
|
|
||||||
<groupId>com.github.TBMCPlugins</groupId>
|
<groupId>com.github.TBMCPlugins</groupId>
|
||||||
<artifactId>DiscordPlugin</artifactId>
|
<artifactId>DiscordPlugin</artifactId>
|
||||||
<version>master-SNAPSHOT</version>
|
<version>master-SNAPSHOT</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>DiscordPlugin</name>
|
<name>DiscordPlugin</name>
|
||||||
<url>http://maven.apache.org</url>
|
<url>http://maven.apache.org</url>
|
||||||
|
|
||||||
<build>
|
<build>
|
||||||
<!-- <sourceDirectory>target/generated-sources/delombok</sourceDirectory>
|
<!-- <sourceDirectory>target/generated-sources/delombok</sourceDirectory>
|
||||||
<testSourceDirectory>target/generated-test-sources/delombok</testSourceDirectory> -->
|
<testSourceDirectory>target/generated-test-sources/delombok</testSourceDirectory> -->
|
||||||
<sourceDirectory>src/main/java</sourceDirectory>
|
<sourceDirectory>src/main/java</sourceDirectory>
|
||||||
<resources>
|
<resources>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src</directory>
|
<directory>src</directory>
|
||||||
<excludes>
|
<excludes>
|
||||||
<exclude>**/*.java</exclude>
|
<exclude>**/*.java</exclude>
|
||||||
</excludes>
|
</excludes>
|
||||||
</resource>
|
</resource>
|
||||||
<resource>
|
<resource>
|
||||||
<directory>src/main/resources</directory>
|
<directory>src/main/resources</directory>
|
||||||
<includes>
|
<includes>
|
||||||
<include>*.properties</include>
|
<include>*.properties</include>
|
||||||
<include>*.yml</include>
|
<include>*.yml</include>
|
||||||
<include>*.csv</include>
|
<include>*.csv</include>
|
||||||
<include>*.txt</include>
|
<include>*.txt</include>
|
||||||
</includes>
|
</includes>
|
||||||
<filtering>true</filtering>
|
<filtering>true</filtering>
|
||||||
</resource>
|
</resource>
|
||||||
</resources>
|
</resources>
|
||||||
<finalName>DiscordPlugin</finalName>
|
<finalName>DiscordPlugin</finalName>
|
||||||
<plugins>
|
<plugins>
|
||||||
<plugin>
|
<plugin>
|
||||||
<artifactId>maven-compiler-plugin</artifactId>
|
<artifactId>maven-compiler-plugin</artifactId>
|
||||||
<version>3.6.2</version>
|
<version>3.6.2</version>
|
||||||
<configuration>
|
<configuration>
|
||||||
<source>1.8</source>
|
<source>1.8</source>
|
||||||
<target>1.8</target>
|
<target>1.8</target>
|
||||||
<!-- <compilerArgs>
|
<!-- <compilerArgs>
|
||||||
<arg>-processor</arg>
|
<arg>-processor</arg>
|
||||||
<arg>buttondevteam.buttonproc.ButtonProcessor, lombok.core.AnnotationProcessor</arg>
|
<arg>buttondevteam.buttonproc.ButtonProcessor, lombok.core.AnnotationProcessor</arg>
|
||||||
|
@ -48,104 +48,112 @@
|
||||||
<annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
|
<annotationProcessor>lombok.launch.AnnotationProcessorHider$AnnotationProcessor</annotationProcessor>
|
||||||
<annotationProcessor>buttondevteam.buttonproc.ButtonProcessor</annotationProcessor>
|
<annotationProcessor>buttondevteam.buttonproc.ButtonProcessor</annotationProcessor>
|
||||||
</annotationProcessors> -->
|
</annotationProcessors> -->
|
||||||
</configuration>
|
</configuration>
|
||||||
</plugin>
|
</plugin>
|
||||||
<plugin>
|
<plugin>
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
<artifactId>maven-shade-plugin</artifactId>
|
<artifactId>maven-shade-plugin</artifactId>
|
||||||
<version>2.4.2</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<phase>package</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>shade</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<artifactSet>
|
|
||||||
<excludes>
|
|
||||||
<exclude>org.spigotmc:spigot-api</exclude>
|
|
||||||
<exclude>com.github.TBMCPlugins.ButtonCore:ButtonCore</exclude>
|
|
||||||
<exclude>net.ess3:Essentials</exclude>
|
|
||||||
</excludes> <!-- http://stackoverflow.com/questions/28458058/maven-shade-plugin-exclude-a-dependency-and-all-its-transitive-dependencies -->
|
|
||||||
</artifactSet>
|
|
||||||
<minimizeJar>true</minimizeJar>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<plugin>
|
|
||||||
<groupId>org.apache.maven.plugins</groupId>
|
|
||||||
<artifactId>maven-resources-plugin</artifactId>
|
|
||||||
<version>3.0.1</version>
|
|
||||||
<executions>
|
|
||||||
<execution>
|
|
||||||
<id>copy</id>
|
|
||||||
<phase>compile</phase>
|
|
||||||
<goals>
|
|
||||||
<goal>copy-resources</goal>
|
|
||||||
</goals>
|
|
||||||
<configuration>
|
|
||||||
<outputDirectory>target</outputDirectory>
|
|
||||||
<resources>
|
|
||||||
<resource>
|
|
||||||
<directory>resources</directory>
|
|
||||||
</resource>
|
|
||||||
</resources>
|
|
||||||
</configuration>
|
|
||||||
</execution>
|
|
||||||
</executions>
|
|
||||||
</plugin>
|
|
||||||
<!-- <plugin> <groupId>org.projectlombok</groupId> <artifactId>lombok-maven-plugin</artifactId>
|
|
||||||
<version>1.16.16.0</version> <executions> <execution> <id>delombok</id> <phase>generate-sources</phase>
|
|
||||||
<goals> <goal>delombok</goal> </goals> <configuration> <addOutputDirectory>false</addOutputDirectory>
|
|
||||||
<sourceDirectory>src/main/java</sourceDirectory> <verbose>true</verbose>
|
|
||||||
</configuration> </execution> <execution> <id>test-delombok</id> <phase>generate-test-sources</phase>
|
|
||||||
<goals> <goal>testDelombok</goal> </goals> <configuration> <addOutputDirectory>false</addOutputDirectory>
|
|
||||||
<sourceDirectory>src/test/java</sourceDirectory> </configuration> </execution>
|
|
||||||
</executions> </plugin> -->
|
|
||||||
<plugin>
|
|
||||||
<artifactId>maven-surefire-plugin</artifactId>
|
|
||||||
<version>2.4.2</version>
|
<version>2.4.2</version>
|
||||||
<configuration>
|
<executions>
|
||||||
<useSystemClassLoader>false
|
<execution>
|
||||||
</useSystemClassLoader> <!-- https://stackoverflow.com/a/53012553/2703239 -->
|
<phase>package</phase>
|
||||||
</configuration>
|
<goals>
|
||||||
</plugin>
|
<goal>shade</goal>
|
||||||
</plugins>
|
</goals>
|
||||||
</build>
|
<configuration>
|
||||||
|
<artifactSet>
|
||||||
|
<excludes>
|
||||||
|
<exclude>org.spigotmc:spigot-api</exclude>
|
||||||
|
<exclude>com.github.TBMCPlugins.ButtonCore:ButtonCore</exclude>
|
||||||
|
<exclude>net.ess3:Essentials</exclude>
|
||||||
|
</excludes> <!-- http://stackoverflow.com/questions/28458058/maven-shade-plugin-exclude-a-dependency-and-all-its-transitive-dependencies -->
|
||||||
|
</artifactSet>
|
||||||
|
<minimizeJar>true</minimizeJar>
|
||||||
|
<relocations>
|
||||||
|
<relocation>
|
||||||
|
<pattern>io.netty</pattern>
|
||||||
|
<shadedPattern>buttondevteam.discordplugin.io.netty</shadedPattern>
|
||||||
|
<excludes>
|
||||||
|
</excludes>
|
||||||
|
</relocation>
|
||||||
|
</relocations>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<plugin>
|
||||||
|
<groupId>org.apache.maven.plugins</groupId>
|
||||||
|
<artifactId>maven-resources-plugin</artifactId>
|
||||||
|
<version>3.0.1</version>
|
||||||
|
<executions>
|
||||||
|
<execution>
|
||||||
|
<id>copy</id>
|
||||||
|
<phase>compile</phase>
|
||||||
|
<goals>
|
||||||
|
<goal>copy-resources</goal>
|
||||||
|
</goals>
|
||||||
|
<configuration>
|
||||||
|
<outputDirectory>target</outputDirectory>
|
||||||
|
<resources>
|
||||||
|
<resource>
|
||||||
|
<directory>resources</directory>
|
||||||
|
</resource>
|
||||||
|
</resources>
|
||||||
|
</configuration>
|
||||||
|
</execution>
|
||||||
|
</executions>
|
||||||
|
</plugin>
|
||||||
|
<!-- <plugin> <groupId>org.projectlombok</groupId> <artifactId>lombok-maven-plugin</artifactId>
|
||||||
|
<version>1.16.16.0</version> <executions> <execution> <id>delombok</id> <phase>generate-sources</phase>
|
||||||
|
<goals> <goal>delombok</goal> </goals> <configuration> <addOutputDirectory>false</addOutputDirectory>
|
||||||
|
<sourceDirectory>src/main/java</sourceDirectory> <verbose>true</verbose>
|
||||||
|
</configuration> </execution> <execution> <id>test-delombok</id> <phase>generate-test-sources</phase>
|
||||||
|
<goals> <goal>testDelombok</goal> </goals> <configuration> <addOutputDirectory>false</addOutputDirectory>
|
||||||
|
<sourceDirectory>src/test/java</sourceDirectory> </configuration> </execution>
|
||||||
|
</executions> </plugin> -->
|
||||||
|
<plugin>
|
||||||
|
<artifactId>maven-surefire-plugin</artifactId>
|
||||||
|
<version>2.4.2</version>
|
||||||
|
<configuration>
|
||||||
|
<useSystemClassLoader>false
|
||||||
|
</useSystemClassLoader> <!-- https://stackoverflow.com/a/53012553/2703239 -->
|
||||||
|
</configuration>
|
||||||
|
</plugin>
|
||||||
|
</plugins>
|
||||||
|
</build>
|
||||||
|
|
||||||
<properties>
|
<properties>
|
||||||
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
|
||||||
<branch>
|
<branch>
|
||||||
master
|
master
|
||||||
</branch> <!-- Should be master if building ButtonCore locally - the CI will overwrite it (see below) -->
|
</branch> <!-- Should be master if building ButtonCore locally - the CI will overwrite it (see below) -->
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
<repositories>
|
<repositories>
|
||||||
<repository>
|
<repository>
|
||||||
<id>spigot-repo</id>
|
<id>spigot-repo</id>
|
||||||
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
<url>https://hub.spigotmc.org/nexus/content/repositories/snapshots/</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository> <!-- This repo fixes issues with transitive dependencies -->
|
<repository> <!-- This repo fixes issues with transitive dependencies -->
|
||||||
<id>jcenter</id>
|
<id>jcenter</id>
|
||||||
<url>http://jcenter.bintray.com</url>
|
<url>http://jcenter.bintray.com</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>jitpack.io</id>
|
<id>jitpack.io</id>
|
||||||
<url>https://jitpack.io</url>
|
<url>https://jitpack.io</url>
|
||||||
</repository>
|
</repository>
|
||||||
<!-- <repository>
|
<!-- <repository>
|
||||||
<id>vault-repo</id>
|
<id>vault-repo</id>
|
||||||
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
<url>http://nexus.hc.to/content/repositories/pub_releases</url>
|
||||||
</repository> -->
|
</repository> -->
|
||||||
<repository>
|
<repository>
|
||||||
<id>Essentials</id>
|
<id>Essentials</id>
|
||||||
<url>http://repo.ess3.net/content/repositories/essrel/</url>
|
<url>http://repo.ess3.net/content/repositories/essrel/</url>
|
||||||
</repository>
|
</repository>
|
||||||
<repository>
|
<repository>
|
||||||
<id>projectlombok.org</id>
|
<id>projectlombok.org</id>
|
||||||
<url>http://projectlombok.org/mavenrepo</url>
|
<url>http://projectlombok.org/mavenrepo</url>
|
||||||
</repository>
|
</repository>
|
||||||
<!-- <repository>
|
<!-- <repository>
|
||||||
<id>pex-repo</id>
|
<id>pex-repo</id>
|
||||||
<url>http://pex-repo.aoeu.xyz</url>
|
<url>http://pex-repo.aoeu.xyz</url>
|
||||||
|
@ -154,64 +162,64 @@
|
||||||
<id>Reactor-Tools</id>
|
<id>Reactor-Tools</id>
|
||||||
<url>https://repo.spring.io/milestone</url>
|
<url>https://repo.spring.io/milestone</url>
|
||||||
</repository> -->
|
</repository> -->
|
||||||
</repositories>
|
</repositories>
|
||||||
|
|
||||||
<dependencies>
|
<dependencies>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>junit</groupId>
|
<groupId>junit</groupId>
|
||||||
<artifactId>junit</artifactId>
|
<artifactId>junit</artifactId>
|
||||||
<version>3.8.1</version>
|
<version>3.8.1</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot-api</artifactId>
|
<artifactId>spigot-api</artifactId>
|
||||||
<version>1.12-R0.1-SNAPSHOT</version>
|
<version>1.12-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>spigot</artifactId>
|
||||||
<version>1.12.2-R0.1-SNAPSHOT</version>
|
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</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>
|
||||||
<artifactId>discord4j-core</artifactId>
|
<artifactId>discord4j-core</artifactId>
|
||||||
<version>3.0.5</version>
|
<version>3.0.5</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-jdk14 -->
|
<!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-jdk14 -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.slf4j</groupId>
|
<groupId>org.slf4j</groupId>
|
||||||
<artifactId>slf4j-jdk14</artifactId>
|
<artifactId>slf4j-jdk14</artifactId>
|
||||||
<version>1.7.21</version>
|
<version>1.7.21</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.github.TBMCPlugins.ButtonCore</groupId>
|
<groupId>com.github.TBMCPlugins.ButtonCore</groupId>
|
||||||
<artifactId>ButtonCore</artifactId>
|
<artifactId>ButtonCore</artifactId>
|
||||||
<version>${branch}-SNAPSHOT</version>
|
<version>${branch}-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>com.github.milkbowl</groupId> <!-- net.milkbowl.vault -->
|
|
||||||
<artifactId>VaultAPI</artifactId>
|
|
||||||
<version>master-SNAPSHOT</version> <!-- 1.6 -->
|
|
||||||
<scope>provided</scope>
|
|
||||||
</dependency>
|
|
||||||
<dependency>
|
|
||||||
<groupId>net.ess3</groupId>
|
|
||||||
<artifactId>Essentials</artifactId>
|
|
||||||
<version>2.13.1</version>
|
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
<dependency>
|
||||||
<dependency>
|
<groupId>com.github.milkbowl</groupId> <!-- net.milkbowl.vault -->
|
||||||
<groupId>org.projectlombok</groupId>
|
<artifactId>VaultAPI</artifactId>
|
||||||
<artifactId>lombok</artifactId>
|
<version>master-SNAPSHOT</version> <!-- 1.6 -->
|
||||||
<version>1.16.16</version>
|
<scope>provided</scope>
|
||||||
<scope>provided</scope>
|
</dependency>
|
||||||
</dependency>
|
<dependency>
|
||||||
|
<groupId>net.ess3</groupId>
|
||||||
|
<artifactId>Essentials</artifactId>
|
||||||
|
<version>2.13.1</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.projectlombok/lombok -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.projectlombok</groupId>
|
||||||
|
<artifactId>lombok</artifactId>
|
||||||
|
<version>1.16.16</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
<!-- <dependency>
|
<!-- <dependency>
|
||||||
<groupId>ru.tehkode</groupId>
|
<groupId>ru.tehkode</groupId>
|
||||||
<artifactId>PermissionsEx</artifactId>
|
<artifactId>PermissionsEx</artifactId>
|
||||||
|
@ -224,38 +232,44 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency> -->
|
</dependency> -->
|
||||||
<!-- https://mvnrepository.com/artifact/org.objenesis/objenesis -->
|
<!-- https://mvnrepository.com/artifact/org.objenesis/objenesis -->
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.objenesis</groupId>
|
<groupId>org.objenesis</groupId>
|
||||||
<artifactId>objenesis</artifactId>
|
<artifactId>objenesis</artifactId>
|
||||||
<version>2.6</version>
|
<version>2.6</version>
|
||||||
<scope>test</scope>
|
<scope>test</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>com.vdurmont</groupId>
|
<groupId>com.vdurmont</groupId>
|
||||||
<artifactId>emoji-java</artifactId>
|
<artifactId>emoji-java</artifactId>
|
||||||
<version>4.0.0</version>
|
<version>4.0.0</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
<!-- https://mvnrepository.com/artifact/io.projectreactor.tools/blockhound -->
|
<!-- https://mvnrepository.com/artifact/io.projectreactor.tools/blockhound -->
|
||||||
<!-- <dependency>
|
<!-- <dependency>
|
||||||
<groupId>io.projectreactor.tools</groupId>
|
<groupId>io.projectreactor.tools</groupId>
|
||||||
<artifactId>blockhound</artifactId>
|
<artifactId>blockhound</artifactId>
|
||||||
<version>1.0.0.M3</version>
|
<version>1.0.0.M3</version>
|
||||||
</dependency> -->
|
</dependency> -->
|
||||||
</dependencies>
|
<dependency>
|
||||||
|
<groupId>com.github.lucko</groupId>
|
||||||
|
<artifactId>LuckPerms</artifactId>
|
||||||
|
<version>v4.4</version>
|
||||||
|
<scope>provided</scope>
|
||||||
|
</dependency>
|
||||||
|
</dependencies>
|
||||||
|
|
||||||
<profiles>
|
<profiles>
|
||||||
<profile>
|
<profile>
|
||||||
<id>ci</id>
|
<id>ci</id>
|
||||||
<activation>
|
<activation>
|
||||||
<property>
|
<property>
|
||||||
<name>env.TRAVIS_BRANCH</name>
|
<name>env.TRAVIS_BRANCH</name>
|
||||||
</property>
|
</property>
|
||||||
</activation>
|
</activation>
|
||||||
<properties>
|
<properties>
|
||||||
<!-- Override only if necessary -->
|
<!-- Override only if necessary -->
|
||||||
<branch>${env.TRAVIS_BRANCH}</branch>
|
<branch>${env.TRAVIS_BRANCH}</branch>
|
||||||
</properties>
|
</properties>
|
||||||
</profile>
|
</profile>
|
||||||
</profiles>
|
</profiles>
|
||||||
</project>
|
</project>
|
||||||
|
|
|
@ -6,15 +6,19 @@ import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
|
||||||
import discord4j.core.object.entity.MessageChannel;
|
import discord4j.core.object.entity.MessageChannel;
|
||||||
import discord4j.core.object.entity.User;
|
import discord4j.core.object.entity.User;
|
||||||
import lombok.Getter;
|
import lombok.Getter;
|
||||||
|
import lombok.Setter;
|
||||||
|
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
|
|
||||||
public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlayer<DiscordConnectedPlayer> {
|
public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlayer<DiscordConnectedPlayer> {
|
||||||
private static int nextEntityId = 10000;
|
private static int nextEntityId = 10000;
|
||||||
private @Getter VanillaCommandListener<DiscordConnectedPlayer> vanillaCmdListener;
|
private @Getter VanillaCommandListener<DiscordConnectedPlayer> vanillaCmdListener;
|
||||||
|
@Getter
|
||||||
|
@Setter
|
||||||
|
private boolean loggedIn = false;
|
||||||
|
|
||||||
public DiscordConnectedPlayer(User user, MessageChannel channel, UUID uuid, String mcname, MinecraftChatModule module) {
|
public DiscordConnectedPlayer(User user, MessageChannel channel, UUID uuid, String mcname, MinecraftChatModule module) {
|
||||||
super(user, channel, nextEntityId++, uuid, mcname ,module);
|
super(user, channel, nextEntityId++, uuid, mcname, module);
|
||||||
vanillaCmdListener = new VanillaCommandListener<>(this);
|
vanillaCmdListener = new VanillaCommandListener<>(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,12 @@ package buttondevteam.discordplugin.mcchat;
|
||||||
import buttondevteam.core.ComponentManager;
|
import buttondevteam.core.ComponentManager;
|
||||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlayer;
|
import buttondevteam.discordplugin.DiscordPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
|
||||||
import buttondevteam.lib.player.TBMCPlayer;
|
import buttondevteam.lib.player.TBMCPlayer;
|
||||||
import discord4j.core.object.entity.MessageChannel;
|
import discord4j.core.object.entity.MessageChannel;
|
||||||
import discord4j.core.object.entity.PrivateChannel;
|
import discord4j.core.object.entity.PrivateChannel;
|
||||||
import discord4j.core.object.entity.User;
|
import discord4j.core.object.entity.User;
|
||||||
import lombok.val;
|
import lombok.val;
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.Event;
|
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
|
||||||
|
@ -32,11 +29,14 @@ public class MCChatPrivate {
|
||||||
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName(), mcm);
|
val sender = new DiscordConnectedPlayer(user, channel, mcp.getUUID(), op.getName(), mcm);
|
||||||
MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender);
|
MCChatUtils.addSender(MCChatUtils.ConnectedSenders, user, sender);
|
||||||
if (p == null)// Player is offline - If the player is online, that takes precedence
|
if (p == null)// Player is offline - If the player is online, that takes precedence
|
||||||
MCListener.callLoginEvents(sender);
|
MCChatUtils.callLoginEvents(sender);
|
||||||
} else {
|
} else {
|
||||||
val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel.getId(), user);
|
val sender = MCChatUtils.removeSender(MCChatUtils.ConnectedSenders, channel.getId(), user);
|
||||||
if (p == null)// Player is offline - If the player is online, that takes precedence
|
assert sender != null;
|
||||||
callEventSync(new PlayerQuitEvent(sender, ""));
|
if (p == null // Player is offline - If the player is online, that takes precedence
|
||||||
|
&& sender.isLoggedIn()) //Don't call the quit event if login failed
|
||||||
|
MCChatUtils.callLogoutEvent(sender, true);
|
||||||
|
sender.setLoggedIn(false);
|
||||||
}
|
}
|
||||||
} // ---- PermissionsEx warning is normal on logout ----
|
} // ---- PermissionsEx warning is normal on logout ----
|
||||||
if (!start)
|
if (!start)
|
||||||
|
@ -60,11 +60,8 @@ public class MCChatPrivate {
|
||||||
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
|
for (val entry : MCChatUtils.ConnectedSenders.entrySet())
|
||||||
for (val valueEntry : entry.getValue().entrySet())
|
for (val valueEntry : entry.getValue().entrySet())
|
||||||
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey(), valueEntry.getValue().getUser()) == null) //If the player is online then the fake player was already logged out
|
if (MCChatUtils.getSender(MCChatUtils.OnlineSenders, valueEntry.getKey(), valueEntry.getValue().getUser()) == null) //If the player is online then the fake player was already logged out
|
||||||
MCChatUtils.callEventExcludingSome(new PlayerQuitEvent(valueEntry.getValue(), "")); //This is sync
|
MCChatUtils.callLogoutEvent(valueEntry.getValue(), false); //This is sync
|
||||||
MCChatUtils.ConnectedSenders.clear();
|
MCChatUtils.ConnectedSenders.clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void callEventSync(Event event) {
|
|
||||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> MCChatUtils.callEventExcludingSome(event));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import buttondevteam.discordplugin.*;
|
||||||
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
import buttondevteam.discordplugin.broadcaster.GeneralEventBroadcasterModule;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
|
import com.google.common.collect.Sets;
|
||||||
import discord4j.core.object.entity.*;
|
import discord4j.core.object.entity.*;
|
||||||
import discord4j.core.object.util.Snowflake;
|
import discord4j.core.object.util.Snowflake;
|
||||||
import io.netty.util.collection.LongObjectHashMap;
|
import io.netty.util.collection.LongObjectHashMap;
|
||||||
|
@ -15,14 +16,20 @@ import org.bukkit.Bukkit;
|
||||||
import org.bukkit.command.CommandSender;
|
import org.bukkit.command.CommandSender;
|
||||||
import org.bukkit.event.Event;
|
import org.bukkit.event.Event;
|
||||||
import org.bukkit.event.HandlerList;
|
import org.bukkit.event.HandlerList;
|
||||||
|
import org.bukkit.event.player.AsyncPlayerPreLoginEvent;
|
||||||
|
import org.bukkit.event.player.PlayerJoinEvent;
|
||||||
|
import org.bukkit.event.player.PlayerLoginEvent;
|
||||||
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
import org.bukkit.plugin.AuthorNagException;
|
import org.bukkit.plugin.AuthorNagException;
|
||||||
import org.bukkit.plugin.Plugin;
|
import org.bukkit.plugin.Plugin;
|
||||||
import org.bukkit.plugin.RegisteredListener;
|
import org.bukkit.plugin.RegisteredListener;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import javax.annotation.Nullable;
|
import javax.annotation.Nullable;
|
||||||
|
import java.net.InetAddress;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.HashMap;
|
import java.util.HashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
import java.util.function.Consumer;
|
import java.util.function.Consumer;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
@ -43,6 +50,7 @@ public class MCChatUtils {
|
||||||
static @Nullable LastMsgData lastmsgdata;
|
static @Nullable LastMsgData lastmsgdata;
|
||||||
static LongObjectHashMap<Message> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
|
static LongObjectHashMap<Message> lastmsgfromd = new LongObjectHashMap<>(); // Last message sent by a Discord user, used for clearing checkmarks
|
||||||
private static MinecraftChatModule module;
|
private static MinecraftChatModule module;
|
||||||
|
private static HashMap<Class<? extends Event>, HashSet<String>> staticExcludedPlugins = new HashMap<>();
|
||||||
|
|
||||||
public static void updatePlayerList() {
|
public static void updatePlayerList() {
|
||||||
if (notEnabled()) return;
|
if (notEnabled()) return;
|
||||||
|
@ -74,19 +82,19 @@ public class MCChatUtils {
|
||||||
if (s.length < 3)
|
if (s.length < 3)
|
||||||
return;
|
return;
|
||||||
s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "")
|
s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "")
|
||||||
+ " online";
|
+ " online";
|
||||||
s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream()
|
s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream()
|
||||||
.map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", "));
|
.map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", "));
|
||||||
((TextChannel) lmd.channel).edit(tce -> tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe(); //Don't wait
|
((TextChannel) lmd.channel).edit(tce -> tce.setTopic(String.join("\n----\n", s)).setReason("Player list update")).subscribe(); //Don't wait
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
||||||
User user, T sender) {
|
User user, T sender) {
|
||||||
return addSender(senders, user.getId().asString(), sender);
|
return addSender(senders, user.getId().asString(), sender);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
public static <T extends DiscordSenderBase> T addSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
||||||
String did, T sender) {
|
String did, T sender) {
|
||||||
var map = senders.get(did);
|
var map = senders.get(did);
|
||||||
if (map == null)
|
if (map == null)
|
||||||
map = new HashMap<>();
|
map = new HashMap<>();
|
||||||
|
@ -96,7 +104,7 @@ public class MCChatUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends DiscordSenderBase> T getSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
public static <T extends DiscordSenderBase> T getSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
||||||
Snowflake channel, User user) {
|
Snowflake channel, User user) {
|
||||||
var map = senders.get(user.getId().asString());
|
var map = senders.get(user.getId().asString());
|
||||||
if (map != null)
|
if (map != null)
|
||||||
return map.get(channel);
|
return map.get(channel);
|
||||||
|
@ -104,7 +112,7 @@ public class MCChatUtils {
|
||||||
}
|
}
|
||||||
|
|
||||||
public static <T extends DiscordSenderBase> T removeSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
public static <T extends DiscordSenderBase> T removeSender(HashMap<String, HashMap<Snowflake, T>> senders,
|
||||||
Snowflake channel, User user) {
|
Snowflake channel, User user) {
|
||||||
var map = senders.get(user.getId().asString());
|
var map = senders.get(user.getId().asString());
|
||||||
if (map != null)
|
if (map != null)
|
||||||
return map.remove(channel);
|
return map.remove(channel);
|
||||||
|
@ -195,11 +203,11 @@ public class MCChatUtils {
|
||||||
static DiscordSenderBase getSender(Snowflake channel, final User author) {
|
static DiscordSenderBase getSender(Snowflake channel, final User author) {
|
||||||
//noinspection OptionalGetWithoutIsPresent
|
//noinspection OptionalGetWithoutIsPresent
|
||||||
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
|
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
|
||||||
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null
|
() -> Optional.ofNullable(getSender(OnlineSenders, channel, author)), // Find first non-null
|
||||||
() -> Optional.ofNullable(getSender(ConnectedSenders, channel, author)), // This doesn't support the public chat, but it'll always return null for it
|
() -> Optional.ofNullable(getSender(ConnectedSenders, channel, author)), // This doesn't support the public chat, but it'll always return null for it
|
||||||
() -> Optional.ofNullable(getSender(UnconnectedSenders, channel, author)), //
|
() -> Optional.ofNullable(getSender(UnconnectedSenders, channel, author)), //
|
||||||
() -> Optional.of(addSender(UnconnectedSenders, author,
|
() -> Optional.of(addSender(UnconnectedSenders, author,
|
||||||
new DiscordSender(author, (MessageChannel) DiscordPlugin.dc.getChannelById(channel).block())))).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
new DiscordSender(author, (MessageChannel) DiscordPlugin.dc.getChannelById(channel).block())))).map(Supplier::get).filter(Optional::isPresent).map(Optional::get).findFirst().get();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -213,7 +221,7 @@ public class MCChatUtils {
|
||||||
System.out.println("Reset last message");
|
System.out.println("Reset last message");
|
||||||
if (channel.getId().asLong() == module.chatChannel().get().asLong()) {
|
if (channel.getId().asLong() == module.chatChannel().get().asLong()) {
|
||||||
(lastmsgdata == null ? lastmsgdata = new LastMsgData(module.chatChannelMono().block(), null)
|
(lastmsgdata == null ? lastmsgdata = new LastMsgData(module.chatChannelMono().block(), null)
|
||||||
: lastmsgdata).message = null;
|
: lastmsgdata).message = null;
|
||||||
System.out.println("Reset done: public chat");
|
System.out.println("Reset done: public chat");
|
||||||
return;
|
return;
|
||||||
} // Don't set the whole object to null, the player and channel information should be preserved
|
} // Don't set the whole object to null, the player and channel information should be preserved
|
||||||
|
@ -227,9 +235,23 @@ public class MCChatUtils {
|
||||||
//If it gets here, it's sending a message to a non-chat channel
|
//If it gets here, it's sending a message to a non-chat channel
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static void addStaticExcludedPlugin(Class<? extends Event> event, String plugin) {
|
||||||
|
staticExcludedPlugins.compute(event, (e, hs) -> hs == null
|
||||||
|
? Sets.newHashSet(plugin)
|
||||||
|
: (hs.add(plugin) ? hs : hs));
|
||||||
|
}
|
||||||
|
|
||||||
public static void callEventExcludingSome(Event event) {
|
public static void callEventExcludingSome(Event event) {
|
||||||
if (notEnabled()) return;
|
if (notEnabled()) return;
|
||||||
callEventExcluding(event, false, module.excludedPlugins().get());
|
val second = staticExcludedPlugins.get(event.getClass());
|
||||||
|
String[] first = module.excludedPlugins().get();
|
||||||
|
String[] both = second == null ? first
|
||||||
|
: Arrays.copyOf(first, first.length + second.size());
|
||||||
|
int i = first.length;
|
||||||
|
if (second != null)
|
||||||
|
for (String plugin : second)
|
||||||
|
both[i++] = plugin;
|
||||||
|
callEventExcluding(event, false, both);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -290,6 +312,50 @@ public class MCChatUtils {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Call it from an async thread.
|
||||||
|
*/
|
||||||
|
public static void callLoginEvents(DiscordConnectedPlayer dcp) {
|
||||||
|
Consumer<Supplier<String>> loginFail = kickMsg -> {
|
||||||
|
dcp.sendMessage("Minecraft chat disabled, as the login failed: " + kickMsg.get());
|
||||||
|
MCChatPrivate.privateMCChat(dcp.getChannel(), false, dcp.getUser(), dcp.getChromaUser());
|
||||||
|
}; //Probably also happens if the user is banned or so
|
||||||
|
val event = new AsyncPlayerPreLoginEvent(dcp.getName(), InetAddress.getLoopbackAddress(), dcp.getUniqueId());
|
||||||
|
callEventExcludingSome(event);
|
||||||
|
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED) {
|
||||||
|
loginFail.accept(event::getKickMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> {
|
||||||
|
val ev = new PlayerLoginEvent(dcp, "localhost", InetAddress.getLoopbackAddress());
|
||||||
|
callEventExcludingSome(ev);
|
||||||
|
if (ev.getResult() != PlayerLoginEvent.Result.ALLOWED) {
|
||||||
|
loginFail.accept(ev::getKickMessage);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
callEventExcludingSome(new PlayerJoinEvent(dcp, ""));
|
||||||
|
dcp.setLoggedIn(true);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Only calls the events if the player is actually logged in
|
||||||
|
*
|
||||||
|
* @param dcp The player
|
||||||
|
* @param needsSync Whether we're in an async thread
|
||||||
|
*/
|
||||||
|
public static void callLogoutEvent(DiscordConnectedPlayer dcp, boolean needsSync) {
|
||||||
|
if (!dcp.isLoggedIn()) return;
|
||||||
|
val event = new PlayerQuitEvent(dcp, "");
|
||||||
|
if (needsSync) callEventSync(event);
|
||||||
|
else callEventExcludingSome(event);
|
||||||
|
dcp.setLoggedIn(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void callEventSync(Event event) {
|
||||||
|
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> callEventExcludingSome(event));
|
||||||
|
}
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
public static class LastMsgData {
|
public static class LastMsgData {
|
||||||
public Message message;
|
public Message message;
|
||||||
|
|
|
@ -18,12 +18,12 @@ import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.EventPriority;
|
import org.bukkit.event.EventPriority;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
import org.bukkit.event.entity.PlayerDeathEvent;
|
import org.bukkit.event.entity.PlayerDeathEvent;
|
||||||
import org.bukkit.event.player.*;
|
import org.bukkit.event.player.PlayerKickEvent;
|
||||||
|
import org.bukkit.event.player.PlayerLoginEvent;
|
||||||
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
import org.bukkit.event.player.PlayerLoginEvent.Result;
|
||||||
import org.bukkit.event.server.BroadcastMessageEvent;
|
import org.bukkit.event.server.BroadcastMessageEvent;
|
||||||
import reactor.core.publisher.Mono;
|
import reactor.core.publisher.Mono;
|
||||||
|
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.util.Objects;
|
import java.util.Objects;
|
||||||
|
|
||||||
@RequiredArgsConstructor
|
@RequiredArgsConstructor
|
||||||
|
@ -38,7 +38,7 @@ class MCListener implements Listener {
|
||||||
return;
|
return;
|
||||||
MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders
|
MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream()) //Only private mcchat should be in ConnectedSenders
|
||||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||||
.ifPresent(dcp -> MCChatUtils.callEventExcludingSome(new PlayerQuitEvent(dcp, "")));
|
.ifPresent(dcp -> MCChatUtils.callLogoutEvent(dcp, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOWEST)
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
@ -70,30 +70,13 @@ class MCListener implements Listener {
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin,
|
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin,
|
||||||
() -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
|
() -> MCChatUtils.ConnectedSenders.values().stream().flatMap(v -> v.values().stream())
|
||||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||||
.ifPresent(MCListener::callLoginEvents));
|
.ifPresent(MCChatUtils::callLoginEvents));
|
||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
|
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
|
||||||
ChromaBot.getInstance()::updatePlayerList, 5);
|
ChromaBot.getInstance()::updatePlayerList, 5);
|
||||||
final String message = e.GetPlayer().PlayerName().get() + " left the game";
|
final String message = e.GetPlayer().PlayerName().get() + " left the game";
|
||||||
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
MCChatUtils.forAllowedCustomAndAllMCChat(MCChatUtils.send(message), e.getPlayer(), ChannelconBroadcast.JOINLEAVE, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Call it from an async thread.
|
|
||||||
*/
|
|
||||||
public static void callLoginEvents(DiscordConnectedPlayer dcp) {
|
|
||||||
val event = new AsyncPlayerPreLoginEvent(dcp.getName(), InetAddress.getLoopbackAddress(), dcp.getUniqueId());
|
|
||||||
MCChatUtils.callEventExcludingSome(event);
|
|
||||||
if (event.getLoginResult() != AsyncPlayerPreLoginEvent.Result.ALLOWED)
|
|
||||||
return;
|
|
||||||
Bukkit.getScheduler().runTask(DiscordPlugin.plugin, () -> {
|
|
||||||
val ev = new PlayerLoginEvent(dcp, "localhost", InetAddress.getLoopbackAddress());
|
|
||||||
MCChatUtils.callEventExcludingSome(ev);
|
|
||||||
if (ev.getResult() != Result.ALLOWED)
|
|
||||||
return;
|
|
||||||
MCChatUtils.callEventExcludingSome(new PlayerJoinEvent(dcp, ""));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
public void onPlayerKick(PlayerKickEvent e) {
|
public void onPlayerKick(PlayerKickEvent e) {
|
||||||
/*if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting")
|
/*if (!DiscordPlugin.hooked && !e.getReason().equals("The server is restarting")
|
||||||
|
|
|
@ -1,9 +1,11 @@
|
||||||
package buttondevteam.discordplugin.mcchat;
|
package buttondevteam.discordplugin.mcchat;
|
||||||
|
|
||||||
|
import buttondevteam.core.MainPlugin;
|
||||||
import buttondevteam.core.component.channel.Channel;
|
import buttondevteam.core.component.channel.Channel;
|
||||||
import buttondevteam.discordplugin.DPUtils;
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
|
import buttondevteam.discordplugin.playerfaker.perm.LPInjector;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import buttondevteam.lib.TBMCSystemChatEvent;
|
import buttondevteam.lib.TBMCSystemChatEvent;
|
||||||
import buttondevteam.lib.architecture.Component;
|
import buttondevteam.lib.architecture.Component;
|
||||||
|
@ -106,6 +108,12 @@ public class MinecraftChatModule extends Component<DiscordPlugin> {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try {
|
||||||
|
new LPInjector(MainPlugin.Instance);
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("Failed to init LuckPerms injector", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,240 @@
|
||||||
|
package buttondevteam.discordplugin.playerfaker.perm;
|
||||||
|
|
||||||
|
import buttondevteam.core.MainPlugin;
|
||||||
|
import buttondevteam.discordplugin.mcchat.MCChatUtils;
|
||||||
|
import buttondevteam.discordplugin.playerfaker.DiscordFakePlayer;
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import me.lucko.luckperms.bukkit.LPBukkitBootstrap;
|
||||||
|
import me.lucko.luckperms.bukkit.LPBukkitPlugin;
|
||||||
|
import me.lucko.luckperms.bukkit.inject.dummy.DummyPermissibleBase;
|
||||||
|
import me.lucko.luckperms.bukkit.inject.permissible.LPPermissible;
|
||||||
|
import me.lucko.luckperms.bukkit.listeners.BukkitConnectionListener;
|
||||||
|
import me.lucko.luckperms.common.config.ConfigKeys;
|
||||||
|
import me.lucko.luckperms.common.locale.message.Message;
|
||||||
|
import me.lucko.luckperms.common.model.User;
|
||||||
|
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 LPBukkitPlugin plugin;
|
||||||
|
private BukkitConnectionListener connectionListener;
|
||||||
|
private Set<UUID> deniedLogin;
|
||||||
|
private Field detectedCraftBukkitOfflineMode;
|
||||||
|
private Method printCraftBukkitOfflineModeError;
|
||||||
|
private Field PERMISSIBLE_BASE_ATTACHMENTS_FIELD;
|
||||||
|
private Method convertAndAddAttachments;
|
||||||
|
private Method getActive;
|
||||||
|
private Method setOldPermissible;
|
||||||
|
private Method getOldPermissible;
|
||||||
|
|
||||||
|
public LPInjector(MainPlugin mp) throws NoSuchFieldException, IllegalAccessException, NoSuchMethodException {
|
||||||
|
LPBukkitBootstrap bs = (LPBukkitBootstrap) Bukkit.getPluginManager().getPlugin("LuckPerms");
|
||||||
|
Field field = LPBukkitBootstrap.class.getDeclaredField("plugin");
|
||||||
|
field.setAccessible(true);
|
||||||
|
plugin = (LPBukkitPlugin) field.get(bs);
|
||||||
|
MCChatUtils.addStaticExcludedPlugin(PlayerLoginEvent.class, "LuckPerms");
|
||||||
|
MCChatUtils.addStaticExcludedPlugin(PlayerQuitEvent.class, "LuckPerms");
|
||||||
|
|
||||||
|
field = LPBukkitPlugin.class.getDeclaredField("connectionListener");
|
||||||
|
field.setAccessible(true);
|
||||||
|
connectionListener = (BukkitConnectionListener) field.get(plugin);
|
||||||
|
field = connectionListener.getClass().getDeclaredField("deniedLogin");
|
||||||
|
field.setAccessible(true);
|
||||||
|
//noinspection unchecked
|
||||||
|
deniedLogin = (Set<UUID>) field.get(connectionListener);
|
||||||
|
field = connectionListener.getClass().getDeclaredField("detectedCraftBukkitOfflineMode");
|
||||||
|
field.setAccessible(true);
|
||||||
|
detectedCraftBukkitOfflineMode = field;
|
||||||
|
printCraftBukkitOfflineModeError = connectionListener.getClass().getDeclaredMethod("printCraftBukkitOfflineModeError");
|
||||||
|
printCraftBukkitOfflineModeError.setAccessible(true);
|
||||||
|
|
||||||
|
//PERMISSIBLE_FIELD = DiscordFakePlayer.class.getDeclaredField("perm");
|
||||||
|
//PERMISSIBLE_FIELD.setAccessible(true); //Hacking my own plugin, while we're at it
|
||||||
|
PERMISSIBLE_BASE_ATTACHMENTS_FIELD = PermissibleBase.class.getDeclaredField("attachments");
|
||||||
|
PERMISSIBLE_BASE_ATTACHMENTS_FIELD.setAccessible(true);
|
||||||
|
|
||||||
|
convertAndAddAttachments = LPPermissible.class.getDeclaredMethod("convertAndAddAttachments", Collection.class);
|
||||||
|
convertAndAddAttachments.setAccessible(true);
|
||||||
|
getActive = LPPermissible.class.getDeclaredMethod("getActive");
|
||||||
|
getActive.setAccessible(true);
|
||||||
|
setOldPermissible = LPPermissible.class.getDeclaredMethod("setOldPermissible", PermissibleBase.class);
|
||||||
|
setOldPermissible.setAccessible(true);
|
||||||
|
getOldPermissible = LPPermissible.class.getDeclaredMethod("getOldPermissible");
|
||||||
|
getOldPermissible.setAccessible(true);
|
||||||
|
|
||||||
|
TBMCCoreAPI.RegisterEventsForExceptions(this, mp);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//Code copied from LuckPerms - me.lucko.luckperms.bukkit.listeners.BukkitConnectionListener
|
||||||
|
@EventHandler(priority = EventPriority.LOWEST)
|
||||||
|
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 DiscordFakePlayer))
|
||||||
|
return; //Normal players must be handled by the plugin
|
||||||
|
|
||||||
|
final DiscordFakePlayer player = (DiscordFakePlayer) e.getPlayer();
|
||||||
|
|
||||||
|
if (plugin.getConfiguration().get(ConfigKeys.DEBUG_LOGINS)) {
|
||||||
|
plugin.getLogger().info("Processing login for " + player.getUniqueId() + " - " + player.getName());
|
||||||
|
}
|
||||||
|
|
||||||
|
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) {
|
||||||
|
deniedLogin.add(player.getUniqueId());
|
||||||
|
|
||||||
|
if (!connectionListener.getUniqueConnections().contains(player.getUniqueId())) {
|
||||||
|
|
||||||
|
plugin.getLogger().warn("User " + player.getUniqueId() + " - " + player.getName() +
|
||||||
|
" doesn't have data pre-loaded, they have never been processed during pre-login in this session." +
|
||||||
|
" - denying login.");
|
||||||
|
|
||||||
|
try {
|
||||||
|
if ((Boolean) detectedCraftBukkitOfflineMode.get(connectionListener)) {
|
||||||
|
printCraftBukkitOfflineModeError.invoke(connectionListener);
|
||||||
|
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_STATE_ERROR_CB_OFFLINE_MODE.asString(plugin.getLocaleManager()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
} catch (IllegalAccessException | InvocationTargetException ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
plugin.getLogger().warn("User " + player.getUniqueId() + " - " + player.getName() +
|
||||||
|
" doesn't currently have data pre-loaded, but they have been processed before in this session." +
|
||||||
|
" - denying login.");
|
||||||
|
}
|
||||||
|
|
||||||
|
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_STATE_ERROR.asString(plugin.getLocaleManager()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
// User instance is there, now we can inject our custom Permissible into the player.
|
||||||
|
// Care should be taken at this stage to ensure that async tasks which manipulate bukkit data check that the player is still online.
|
||||||
|
try {
|
||||||
|
// get the existing PermissibleBase held by the player
|
||||||
|
PermissibleBase oldPermissible = player.getPerm();
|
||||||
|
|
||||||
|
// Make a new permissible for the user
|
||||||
|
LPPermissible lpPermissible = new LPPermissible(player, user, plugin);
|
||||||
|
|
||||||
|
// Inject into the player
|
||||||
|
inject(player, lpPermissible, oldPermissible);
|
||||||
|
|
||||||
|
} catch (Throwable t) {
|
||||||
|
plugin.getLogger().warn("Exception thrown when setting up permissions for " +
|
||||||
|
player.getUniqueId() + " - " + player.getName() + " - denying login.");
|
||||||
|
t.printStackTrace();
|
||||||
|
|
||||||
|
e.disallow(PlayerLoginEvent.Result.KICK_OTHER, Message.LOADING_SETUP_ERROR.asString(plugin.getLocaleManager()));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
plugin.refreshAutoOp(player, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Wait until the last priority to unload, so plugins can still perform permission checks on this event
|
||||||
|
@EventHandler(priority = EventPriority.MONITOR)
|
||||||
|
public void onPlayerQuit(PlayerQuitEvent e) {
|
||||||
|
if (!(e.getPlayer() instanceof DiscordFakePlayer))
|
||||||
|
return;
|
||||||
|
|
||||||
|
final DiscordFakePlayer player = (DiscordFakePlayer) e.getPlayer();
|
||||||
|
|
||||||
|
connectionListener.handleDisconnect(player.getUniqueId());
|
||||||
|
|
||||||
|
// perform unhooking from bukkit objects 1 tick later.
|
||||||
|
// this allows plugins listening after us on MONITOR to still have intact permissions data
|
||||||
|
this.plugin.getBootstrap().getServer().getScheduler().runTaskLaterAsynchronously(this.plugin.getBootstrap(), () -> {
|
||||||
|
// Remove the custom permissible
|
||||||
|
try {
|
||||||
|
uninject(player, true);
|
||||||
|
} catch (Exception ex) {
|
||||||
|
ex.printStackTrace();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Handle auto op
|
||||||
|
if (this.plugin.getConfiguration().get(ConfigKeys.AUTO_OP)) {
|
||||||
|
player.setOp(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
// remove their contexts cache
|
||||||
|
this.plugin.getContextManager().onPlayerQuit(player);
|
||||||
|
}, 1L);
|
||||||
|
}
|
||||||
|
|
||||||
|
//me.lucko.luckperms.bukkit.inject.permissible.PermissibleInjector
|
||||||
|
private void inject(DiscordFakePlayer player, LPPermissible newPermissible, PermissibleBase oldPermissible) throws IllegalAccessException, InvocationTargetException {
|
||||||
|
|
||||||
|
// seems we have already injected into this player.
|
||||||
|
if (oldPermissible instanceof LPPermissible) {
|
||||||
|
throw new IllegalStateException("LPPermissible already injected into player " + player.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move attachments over from the old permissible
|
||||||
|
|
||||||
|
//noinspection unchecked
|
||||||
|
List<PermissionAttachment> attachments = (List<PermissionAttachment>) PERMISSIBLE_BASE_ATTACHMENTS_FIELD.get(oldPermissible);
|
||||||
|
|
||||||
|
convertAndAddAttachments.invoke(newPermissible, attachments);
|
||||||
|
attachments.clear();
|
||||||
|
oldPermissible.clearPermissions();
|
||||||
|
|
||||||
|
// Setup the new permissible
|
||||||
|
((AtomicBoolean) getActive.invoke(newPermissible)).set(true);
|
||||||
|
setOldPermissible.invoke(newPermissible, oldPermissible);
|
||||||
|
|
||||||
|
// inject the new instance
|
||||||
|
player.setPerm(newPermissible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void uninject(DiscordFakePlayer player, boolean dummy) throws Exception {
|
||||||
|
|
||||||
|
// gets the players current permissible.
|
||||||
|
PermissibleBase permissible = player.getPerm();
|
||||||
|
|
||||||
|
// only uninject if the permissible was a luckperms one.
|
||||||
|
if (permissible instanceof LPPermissible) {
|
||||||
|
LPPermissible lpPermissible = ((LPPermissible) permissible);
|
||||||
|
|
||||||
|
// clear all permissions
|
||||||
|
lpPermissible.clearPermissions();
|
||||||
|
|
||||||
|
// set to inactive
|
||||||
|
((AtomicBoolean) getActive.invoke(lpPermissible)).set(false);
|
||||||
|
|
||||||
|
// handle the replacement permissible.
|
||||||
|
if (dummy) {
|
||||||
|
// just inject a dummy class. this is used when we know the player is about to quit the server.
|
||||||
|
player.setPerm(DummyPermissibleBase.INSTANCE);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
PermissibleBase newPb = (PermissibleBase) getOldPermissible.invoke(lpPermissible);
|
||||||
|
if (newPb == null) {
|
||||||
|
newPb = new PermissibleBase(player);
|
||||||
|
}
|
||||||
|
|
||||||
|
player.setPerm(newPb);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue