Merge pull request #44 from TBMCPlugins/dev
Catching all vanilla broadcasts in Minecraft
This commit is contained in:
commit
faa1c96a4b
11 changed files with 670 additions and 113 deletions
|
@ -2,10 +2,10 @@ cache:
|
||||||
directories:
|
directories:
|
||||||
- $HOME/.m2/repository/org/
|
- $HOME/.m2/repository/org/
|
||||||
before_install: | # Wget BuildTools and run if cached folder not found
|
before_install: | # Wget BuildTools and run if cached folder not found
|
||||||
if [ ! -d "$HOME/.m2/repository/org/spigotmc/spigot/1.12-R0.1-SNAPSHOT" ]; then
|
if [ ! -d "$HOME/.m2/repository/org/spigotmc/spigot/1.12.2-R0.1-SNAPSHOT" ]; then
|
||||||
wget -O BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
|
wget -O BuildTools.jar https://hub.spigotmc.org/jenkins/job/BuildTools/lastSuccessfulBuild/artifact/target/BuildTools.jar
|
||||||
# grep so that download counts don't appear in log files
|
# grep so that download counts don't appear in log files
|
||||||
java -jar BuildTools.jar --rev 1.12 | grep -vE "[^/ ]*/[^/ ]*\s*KB\s*$" | grep -v "^\s*$"
|
java -jar BuildTools.jar --rev 1.12.2 | grep -vE "[^/ ]*/[^/ ]*\s*KB\s*$" | grep -v "^\s*$"
|
||||||
fi
|
fi
|
||||||
language: java
|
language: java
|
||||||
jdk:
|
jdk:
|
||||||
|
|
10
pom.xml
10
pom.xml
|
@ -153,7 +153,7 @@
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>org.spigotmc</groupId>
|
<groupId>org.spigotmc</groupId>
|
||||||
<artifactId>spigot</artifactId>
|
<artifactId>spigot</artifactId>
|
||||||
<version>1.12-R0.1-SNAPSHOT</version>
|
<version>1.12.2-R0.1-SNAPSHOT</version>
|
||||||
<scope>provided</scope>
|
<scope>provided</scope>
|
||||||
</dependency>
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
|
@ -210,5 +210,13 @@
|
||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<!-- https://mvnrepository.com/artifact/org.objenesis/objenesis -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.objenesis</groupId>
|
||||||
|
<artifactId>objenesis</artifactId>
|
||||||
|
<version>2.6</version>
|
||||||
|
<scope>test</scope>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
</dependencies>
|
</dependencies>
|
||||||
</project>
|
</project>
|
||||||
|
|
147
src/main/java/buttondevteam/discordplugin/ChromaBot.java
Normal file
147
src/main/java/buttondevteam/discordplugin/ChromaBot.java
Normal file
|
@ -0,0 +1,147 @@
|
||||||
|
package buttondevteam.discordplugin;
|
||||||
|
|
||||||
|
import java.awt.Color;
|
||||||
|
import java.util.Arrays;
|
||||||
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.entity.Player;
|
||||||
|
import org.bukkit.scheduler.BukkitScheduler;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||||
|
import lombok.Getter;
|
||||||
|
import sx.blah.discord.api.internal.json.objects.EmbedObject;
|
||||||
|
import sx.blah.discord.handle.obj.IChannel;
|
||||||
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
|
|
||||||
|
public class ChromaBot {
|
||||||
|
/**
|
||||||
|
* May be null if it's not initialized. Initialization happens after the server is done loading (using {@link BukkitScheduler#runTaskAsynchronously(org.bukkit.plugin.Plugin, Runnable)})
|
||||||
|
*/
|
||||||
|
private static @Getter ChromaBot instance;
|
||||||
|
private DiscordPlugin dp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This will set the instance field.
|
||||||
|
*
|
||||||
|
* @param dp
|
||||||
|
* The Discord plugin
|
||||||
|
*/
|
||||||
|
ChromaBot(DiscordPlugin dp) {
|
||||||
|
instance = this;
|
||||||
|
this.dp = dp;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void delete() {
|
||||||
|
instance = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to the chat channel and private chats.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* The message to send, duh
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message) {
|
||||||
|
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to the chat channel and private chats.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* The message to send, duh
|
||||||
|
* @param embed
|
||||||
|
* Custom fancy stuff, use {@link EmbedBuilder} to create one
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message, EmbedObject embed) {
|
||||||
|
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, embed));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to an arbitrary channel. This will not send it to the private chats.
|
||||||
|
*
|
||||||
|
* @param channel
|
||||||
|
* The channel to send to, use the channel variables in {@link DiscordPlugin}
|
||||||
|
* @param message
|
||||||
|
* The message to send, duh
|
||||||
|
* @param embed
|
||||||
|
* Custom fancy stuff, use {@link EmbedBuilder} to create one
|
||||||
|
*/
|
||||||
|
public void sendMessage(IChannel channel, String message, EmbedObject embed) {
|
||||||
|
DiscordPlugin.sendMessageToChannel(channel, message, embed);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a fancy message to the chat channel. This will show a bold text with a colored line.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* The message to send, duh
|
||||||
|
* @param color
|
||||||
|
* The color of the line before the text
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message, Color color) {
|
||||||
|
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
|
||||||
|
new EmbedBuilder().withTitle(message).withColor(color).build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a fancy message to the chat channel. This will show a bold text with a colored line.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* The message to send, duh
|
||||||
|
* @param color
|
||||||
|
* The color of the line before the text
|
||||||
|
* @param mcauthor
|
||||||
|
* The name of the Minecraft player who is the author of this message
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message, Color color, String mcauthor) {
|
||||||
|
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message,
|
||||||
|
DPUtils.embedWithHead(new EmbedBuilder().withTitle(message).withColor(color), mcauthor).build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a fancy message to the chat channel. This will show a bold text with a colored line.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* The message to send, duh
|
||||||
|
* @param color
|
||||||
|
* The color of the line before the text
|
||||||
|
* @param authorname
|
||||||
|
* The name of the author of this message
|
||||||
|
* @param authorimg
|
||||||
|
* The URL of the avatar image for this message's author
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message, Color color, String authorname, String authorimg) {
|
||||||
|
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, new EmbedBuilder()
|
||||||
|
.withTitle(message).withColor(color).withAuthorName(authorname).withAuthorIcon(authorimg).build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Send a message to the chat channel. This will show a bold text with a colored line.
|
||||||
|
*
|
||||||
|
* @param message
|
||||||
|
* The message to send, duh
|
||||||
|
* @param color
|
||||||
|
* The color of the line before the text
|
||||||
|
* @param sender
|
||||||
|
* The player who sends this message
|
||||||
|
*/
|
||||||
|
public void sendMessage(String message, Color color, Player sender) {
|
||||||
|
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, message, DPUtils
|
||||||
|
.embedWithHead(new EmbedBuilder().withTitle(message).withColor(color), sender.getName()).build()));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updatePlayerList() {
|
||||||
|
DPUtils.performNoWait(() -> {
|
||||||
|
String[] s = DiscordPlugin.chatchannel.getTopic().split("\\n----\\n");
|
||||||
|
if (s.length < 3)
|
||||||
|
return;
|
||||||
|
s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "")
|
||||||
|
+ " online";
|
||||||
|
s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream()
|
||||||
|
.map(p -> DPUtils.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", "));
|
||||||
|
DiscordPlugin.chatchannel.changeTopic(Arrays.stream(s).collect(Collectors.joining("\n----\n")));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
67
src/main/java/buttondevteam/discordplugin/DPUtils.java
Normal file
67
src/main/java/buttondevteam/discordplugin/DPUtils.java
Normal file
|
@ -0,0 +1,67 @@
|
||||||
|
package buttondevteam.discordplugin;
|
||||||
|
|
||||||
|
import sx.blah.discord.util.EmbedBuilder;
|
||||||
|
import sx.blah.discord.util.RequestBuffer;
|
||||||
|
import sx.blah.discord.util.RequestBuffer.IRequest;
|
||||||
|
import sx.blah.discord.util.RequestBuffer.IVoidRequest;
|
||||||
|
|
||||||
|
public final class DPUtils {
|
||||||
|
|
||||||
|
public static EmbedBuilder embedWithHead(EmbedBuilder builder, String playername) {
|
||||||
|
return builder.withAuthorIcon("https://minotar.net/avatar/" + playername + "/32.png");
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Removes §[char] colour codes from strings */
|
||||||
|
public static String sanitizeString(String string) {
|
||||||
|
String sanitizedString = "";
|
||||||
|
boolean random = false;
|
||||||
|
for (int i = 0; i < string.length(); i++) {
|
||||||
|
if (string.charAt(i) == '§') {
|
||||||
|
i++;// Skips the data value, the 4 in "§4Alisolarflare"
|
||||||
|
if (string.charAt(i) == 'k')
|
||||||
|
random = true;
|
||||||
|
else
|
||||||
|
random = false;
|
||||||
|
} else {
|
||||||
|
if (!random) // Skip random/obfuscated characters
|
||||||
|
sanitizedString += string.charAt(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return sanitizedString;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode.
|
||||||
|
*/
|
||||||
|
public static <T> T perform(IRequest<T> action) {
|
||||||
|
if (DiscordPlugin.SafeMode)
|
||||||
|
return null;
|
||||||
|
if (Thread.currentThread() == DiscordPlugin.mainThread)
|
||||||
|
throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
||||||
|
return RequestBuffer.request(action).get(); // Let the pros handle this
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs Discord actions, retrying when ratelimited.
|
||||||
|
*/
|
||||||
|
public static Void perform(IVoidRequest action) {
|
||||||
|
if (DiscordPlugin.SafeMode)
|
||||||
|
return null;
|
||||||
|
if (Thread.currentThread() == DiscordPlugin.mainThread)
|
||||||
|
throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
|
||||||
|
return RequestBuffer.request(action).get(); // Let the pros handle this
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void performNoWait(IVoidRequest action) {
|
||||||
|
if (DiscordPlugin.SafeMode)
|
||||||
|
return;
|
||||||
|
RequestBuffer.request(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static <T> void performNoWait(IRequest<T> action) {
|
||||||
|
if (DiscordPlugin.SafeMode)
|
||||||
|
return;
|
||||||
|
RequestBuffer.request(action);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -4,11 +4,9 @@ import java.awt.Color;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.nio.charset.StandardCharsets;
|
import java.nio.charset.StandardCharsets;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
|
||||||
import java.util.Calendar;
|
import java.util.Calendar;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Random;
|
import java.util.Random;
|
||||||
import java.util.stream.Collectors;
|
|
||||||
|
|
||||||
import org.bukkit.Bukkit;
|
import org.bukkit.Bukkit;
|
||||||
import org.bukkit.event.player.PlayerQuitEvent;
|
import org.bukkit.event.player.PlayerQuitEvent;
|
||||||
|
@ -33,22 +31,30 @@ import sx.blah.discord.handle.impl.events.ReadyEvent;
|
||||||
import sx.blah.discord.handle.impl.obj.ReactionEmoji;
|
import sx.blah.discord.handle.impl.obj.ReactionEmoji;
|
||||||
import sx.blah.discord.handle.obj.*;
|
import sx.blah.discord.handle.obj.*;
|
||||||
import sx.blah.discord.util.*;
|
import sx.blah.discord.util.*;
|
||||||
import sx.blah.discord.util.RequestBuffer.IRequest;
|
|
||||||
import sx.blah.discord.util.RequestBuffer.IVoidRequest;
|
|
||||||
|
|
||||||
public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
private static final String SubredditURL = "https://www.reddit.com/r/ChromaGamers";
|
private static final String SubredditURL = "https://www.reddit.com/r/ChromaGamers";
|
||||||
private static boolean stop = false;
|
private static boolean stop = false;
|
||||||
|
static Thread mainThread;
|
||||||
public static IDiscordClient dc;
|
public static IDiscordClient dc;
|
||||||
public static DiscordPlugin plugin;
|
public static DiscordPlugin plugin;
|
||||||
public static boolean SafeMode = true;
|
public static boolean SafeMode = true;
|
||||||
public static List<String> GameRoles;
|
public static List<String> GameRoles;
|
||||||
|
public static boolean hooked = false;
|
||||||
|
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
@Override
|
@Override
|
||||||
public void onEnable() {
|
public void onEnable() {
|
||||||
try {
|
try {
|
||||||
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
Bukkit.getLogger().info("Initializing DiscordPlugin...");
|
||||||
|
try {
|
||||||
|
PlayerListWatcher.hookUp();
|
||||||
|
hooked = true;
|
||||||
|
Bukkit.getLogger().info("Finished hooking into the player list");
|
||||||
|
} catch (Throwable e) {
|
||||||
|
e.printStackTrace();
|
||||||
|
Bukkit.getLogger().warning("Couldn't hook into the player list!");
|
||||||
|
}
|
||||||
plugin = this;
|
plugin = this;
|
||||||
lastannouncementtime = getConfig().getLong("lastannouncementtime");
|
lastannouncementtime = getConfig().getLong("lastannouncementtime");
|
||||||
lastseentime = getConfig().getLong("lastseentime");
|
lastseentime = getConfig().getLong("lastseentime");
|
||||||
|
@ -57,6 +63,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
|
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
|
||||||
dc = cb.login();
|
dc = cb.login();
|
||||||
dc.getDispatcher().registerListener(this);
|
dc.getDispatcher().registerListener(this);
|
||||||
|
mainThread = Thread.currentThread();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
e.printStackTrace();
|
e.printStackTrace();
|
||||||
Bukkit.getPluginManager().disablePlugin(this);
|
Bukkit.getPluginManager().disablePlugin(this);
|
||||||
|
@ -121,14 +128,16 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
if (getConfig().getBoolean("serverup", false)) {
|
if (getConfig().getBoolean("serverup", false)) {
|
||||||
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.YELLOW)
|
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.YELLOW)
|
||||||
.withTitle("Server recovered from a crash - chat connected.").build());
|
.withTitle("Server recovered from a crash - chat connected.").build());
|
||||||
TBMCCoreAPI.SendException("The server crashed!", new Throwable(
|
val thr = new Throwable(
|
||||||
"The server shut down unexpectedly. See the log of the previous run for more details."));
|
"The server shut down unexpectedly. See the log of the previous run for more details.");
|
||||||
|
thr.setStackTrace(new StackTraceElement[0]);
|
||||||
|
TBMCCoreAPI.SendException("The server crashed!", thr);
|
||||||
} else
|
} else
|
||||||
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.GREEN)
|
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Color.GREEN)
|
||||||
.withTitle("Server started - chat connected.").build());
|
.withTitle("Server started - chat connected.").build());
|
||||||
getConfig().set("serverup", true);
|
getConfig().set("serverup", true);
|
||||||
saveConfig();
|
saveConfig();
|
||||||
performNoWait(() -> {
|
DPUtils.performNoWait(() -> {
|
||||||
try {
|
try {
|
||||||
List<IMessage> msgs = genchannel.getPinnedMessages();
|
List<IMessage> msgs = genchannel.getPinnedMessages();
|
||||||
for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10
|
for (int i = msgs.size() - 1; i >= 10; i--) { // Unpin all pinned messages except the newest 10
|
||||||
|
@ -159,7 +168,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
"You could make a religion out of this");
|
"You could make a religion out of this");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
updatePlayerList();
|
new ChromaBot(this).updatePlayerList();
|
||||||
}
|
}
|
||||||
}, 0, 10);
|
}, 0, 10);
|
||||||
for (IListener<?> listener : CommandListener.getListeners())
|
for (IListener<?> listener : CommandListener.getListeners())
|
||||||
|
@ -205,6 +214,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
|
sendMessageToChannel(chatchannel, "", new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
|
||||||
.withTitle(Restart ? "Server restarting" : "Server stopping").build());
|
.withTitle(Restart ? "Server restarting" : "Server stopping").build());
|
||||||
try {
|
try {
|
||||||
|
ChromaBot.delete();
|
||||||
dc.online("on TBMC");
|
dc.online("on TBMC");
|
||||||
dc.logout();
|
dc.logout();
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -313,9 +323,9 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
RequestBuffer.IRequest<IMessage> r = () -> embed == null ? channel.sendMessage(content)
|
RequestBuffer.IRequest<IMessage> r = () -> embed == null ? channel.sendMessage(content)
|
||||||
: channel.sendMessage(content, embed, false);
|
: channel.sendMessage(content, embed, false);
|
||||||
if (wait)
|
if (wait)
|
||||||
return perform(r);
|
return DPUtils.perform(r);
|
||||||
else {
|
else {
|
||||||
performNoWait(r);
|
DPUtils.performNoWait(r);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
|
@ -325,10 +335,6 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static EmbedBuilder embedWithHead(EmbedBuilder builder, String playername) {
|
|
||||||
return builder.withAuthorIcon("https://minotar.net/avatar/" + playername + "/32.png");
|
|
||||||
}
|
|
||||||
|
|
||||||
public static Permission perms;
|
public static Permission perms;
|
||||||
|
|
||||||
public boolean setupProviders() {
|
public boolean setupProviders() {
|
||||||
|
@ -344,66 +350,4 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
|
||||||
perms = permsProvider.getProvider();
|
perms = permsProvider.getProvider();
|
||||||
return perms != null;
|
return perms != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Removes §[char] colour codes from strings */
|
|
||||||
public static String sanitizeString(String string) {
|
|
||||||
String sanitizedString = "";
|
|
||||||
boolean random = false;
|
|
||||||
for (int i = 0; i < string.length(); i++) {
|
|
||||||
if (string.charAt(i) == '§') {
|
|
||||||
i++;// Skips the data value, the 4 in "§4Alisolarflare"
|
|
||||||
if (string.charAt(i) == 'k')
|
|
||||||
random = true;
|
|
||||||
else
|
|
||||||
random = false;
|
|
||||||
} else {
|
|
||||||
if (!random) // Skip random/obfuscated characters
|
|
||||||
sanitizedString += string.charAt(i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return sanitizedString;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode.
|
|
||||||
*/
|
|
||||||
public static <T> T perform(IRequest<T> action) {
|
|
||||||
if (SafeMode)
|
|
||||||
return null;
|
|
||||||
return RequestBuffer.request(action).get(); // Let the pros handle this
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Performs Discord actions, retrying when ratelimited.
|
|
||||||
*/
|
|
||||||
public static Void perform(IVoidRequest action) {
|
|
||||||
if (SafeMode)
|
|
||||||
return null;
|
|
||||||
return RequestBuffer.request(action).get(); // Let the pros handle this
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void performNoWait(IVoidRequest action) {
|
|
||||||
if (SafeMode)
|
|
||||||
return;
|
|
||||||
RequestBuffer.request(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static <T> void performNoWait(IRequest<T> action) {
|
|
||||||
if (SafeMode)
|
|
||||||
return;
|
|
||||||
RequestBuffer.request(action);
|
|
||||||
}
|
|
||||||
|
|
||||||
public static void updatePlayerList() {
|
|
||||||
performNoWait(() -> {
|
|
||||||
String[] s = chatchannel.getTopic().split("\\n----\\n");
|
|
||||||
if (s.length < 3)
|
|
||||||
return;
|
|
||||||
s[0] = Bukkit.getOnlinePlayers().size() + " player" + (Bukkit.getOnlinePlayers().size() != 1 ? "s" : "")
|
|
||||||
+ " online";
|
|
||||||
s[s.length - 1] = "Players: " + Bukkit.getOnlinePlayers().stream()
|
|
||||||
.map(p -> DiscordPlugin.sanitizeString(p.getDisplayName())).collect(Collectors.joining(", "));
|
|
||||||
chatchannel.changeTopic(Arrays.stream(s).collect(Collectors.joining("\n----\n")));
|
|
||||||
});
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -50,7 +50,7 @@ public abstract class DiscordSenderBase implements IDiscordSender {
|
||||||
final boolean broadcast = new Exception().getStackTrace()[2].getMethodName().contains("broadcast");
|
final boolean broadcast = new Exception().getStackTrace()[2].getMethodName().contains("broadcast");
|
||||||
if (broadcast)
|
if (broadcast)
|
||||||
return;
|
return;
|
||||||
final String sendmsg = DiscordPlugin.sanitizeString(message);
|
final String sendmsg = DPUtils.sanitizeString(message);
|
||||||
msgtosend += "\n" + sendmsg;
|
msgtosend += "\n" + sendmsg;
|
||||||
if (sendtask == null)
|
if (sendtask == null)
|
||||||
sendtask = Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
sendtask = Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
|
||||||
|
|
375
src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java
Normal file
375
src/main/java/buttondevteam/discordplugin/PlayerListWatcher.java
Normal file
|
@ -0,0 +1,375 @@
|
||||||
|
package buttondevteam.discordplugin;
|
||||||
|
|
||||||
|
import java.lang.reflect.Field;
|
||||||
|
import java.lang.reflect.Modifier;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.UUID;
|
||||||
|
|
||||||
|
import org.bukkit.Bukkit;
|
||||||
|
import org.bukkit.Location;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
|
||||||
|
import org.bukkit.craftbukkit.v1_12_R1.util.CraftChatMessage;
|
||||||
|
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
|
||||||
|
import org.objenesis.ObjenesisStd;
|
||||||
|
|
||||||
|
import com.mojang.authlib.GameProfile;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.listeners.MCChatListener;
|
||||||
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
import lombok.val;
|
||||||
|
import net.minecraft.server.v1_12_R1.AdvancementDataPlayer;
|
||||||
|
import net.minecraft.server.v1_12_R1.ChatMessageType;
|
||||||
|
import net.minecraft.server.v1_12_R1.DedicatedPlayerList;
|
||||||
|
import net.minecraft.server.v1_12_R1.DedicatedServer;
|
||||||
|
import net.minecraft.server.v1_12_R1.Entity;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityHuman;
|
||||||
|
import net.minecraft.server.v1_12_R1.EntityPlayer;
|
||||||
|
import net.minecraft.server.v1_12_R1.GameProfileBanList;
|
||||||
|
import net.minecraft.server.v1_12_R1.IChatBaseComponent;
|
||||||
|
import net.minecraft.server.v1_12_R1.IpBanList;
|
||||||
|
import net.minecraft.server.v1_12_R1.LoginListener;
|
||||||
|
import net.minecraft.server.v1_12_R1.MinecraftServer;
|
||||||
|
import net.minecraft.server.v1_12_R1.NBTTagCompound;
|
||||||
|
import net.minecraft.server.v1_12_R1.NetworkManager;
|
||||||
|
import net.minecraft.server.v1_12_R1.OpList;
|
||||||
|
import net.minecraft.server.v1_12_R1.Packet;
|
||||||
|
import net.minecraft.server.v1_12_R1.PacketPlayOutChat;
|
||||||
|
import net.minecraft.server.v1_12_R1.ScoreboardServer;
|
||||||
|
import net.minecraft.server.v1_12_R1.ServerStatisticManager;
|
||||||
|
import net.minecraft.server.v1_12_R1.WhiteList;
|
||||||
|
import net.minecraft.server.v1_12_R1.World;
|
||||||
|
import net.minecraft.server.v1_12_R1.WorldServer;
|
||||||
|
|
||||||
|
public class PlayerListWatcher extends DedicatedPlayerList {
|
||||||
|
private DedicatedPlayerList plist;
|
||||||
|
|
||||||
|
public PlayerListWatcher(DedicatedServer minecraftserver) {
|
||||||
|
super(minecraftserver); // <-- Does some init stuff and calls Bukkit.setServer() so we have to use Objenesis
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendAll(Packet<?> packet) {
|
||||||
|
plist.sendAll(packet);
|
||||||
|
try { // Some messages get sent by directly constructing a packet
|
||||||
|
if (packet instanceof PacketPlayOutChat) {
|
||||||
|
Field msgf = PacketPlayOutChat.class.getDeclaredField("a");
|
||||||
|
msgf.setAccessible(true);
|
||||||
|
MCChatListener.sendSystemMessageToChat(((IChatBaseComponent) msgf.get(packet)).toPlainText());
|
||||||
|
}
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("Failed to broadcast message sent to all players - hacking failed.", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(IChatBaseComponent ichatbasecomponent, boolean flag) { // Needed so it calls the overriden method
|
||||||
|
plist.getServer().sendMessage(ichatbasecomponent);
|
||||||
|
ChatMessageType chatmessagetype = flag ? ChatMessageType.SYSTEM : ChatMessageType.CHAT;
|
||||||
|
|
||||||
|
// CraftBukkit start - we run this through our processor first so we can get web links etc
|
||||||
|
this.sendAll(new PacketPlayOutChat(CraftChatMessage.fixComponent(ichatbasecomponent), chatmessagetype));
|
||||||
|
// CraftBukkit end
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(IChatBaseComponent ichatbasecomponent) { // Needed so it calls the overriden method
|
||||||
|
this.sendMessage(ichatbasecomponent, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void sendMessage(IChatBaseComponent[] iChatBaseComponents) { // Needed so it calls the overriden method
|
||||||
|
for (IChatBaseComponent component : iChatBaseComponents) {
|
||||||
|
sendMessage(component, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void hookUp() {
|
||||||
|
try {
|
||||||
|
Field conf = CraftServer.class.getDeclaredField("console");
|
||||||
|
conf.setAccessible(true);
|
||||||
|
val server = (MinecraftServer) conf.get(Bukkit.getServer());
|
||||||
|
val plw = new ObjenesisStd().newInstance(PlayerListWatcher.class); // Cannot call super constructor
|
||||||
|
plw.plist = (DedicatedPlayerList) server.getPlayerList();
|
||||||
|
plw.maxPlayers = plw.plist.getMaxPlayers();
|
||||||
|
Field plf = plw.getClass().getField("players");
|
||||||
|
plf.setAccessible(true);
|
||||||
|
Field modf = plf.getClass().getDeclaredField("modifiers");
|
||||||
|
modf.setAccessible(true);
|
||||||
|
modf.set(plf, plf.getModifiers() & ~Modifier.FINAL);
|
||||||
|
plf.set(plw, plw.plist.players);
|
||||||
|
server.a(plw);
|
||||||
|
Field pllf = CraftServer.class.getDeclaredField("playerList");
|
||||||
|
pllf.setAccessible(true);
|
||||||
|
pllf.set(Bukkit.getServer(), plw);
|
||||||
|
} catch (Exception e) {
|
||||||
|
TBMCCoreAPI.SendException("Error while hacking the player list!", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) {
|
||||||
|
plist.a(entityhuman, ichatbasecomponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(EntityPlayer entityplayer, int i) {
|
||||||
|
plist.a(entityplayer, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(EntityPlayer entityplayer, WorldServer worldserver) {
|
||||||
|
plist.a(entityplayer, worldserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NBTTagCompound a(EntityPlayer entityplayer) {
|
||||||
|
return plist.a(entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(int i) {
|
||||||
|
plist.a(i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(NetworkManager networkmanager, EntityPlayer entityplayer) {
|
||||||
|
plist.a(networkmanager, entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void a(Packet<?> packet, int i) {
|
||||||
|
plist.a(packet, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayer a(UUID uuid) {
|
||||||
|
return plist.a(uuid);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addOp(GameProfile gameprofile) {
|
||||||
|
plist.addOp(gameprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void addWhitelist(GameProfile gameprofile) {
|
||||||
|
plist.addWhitelist(gameprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayer attemptLogin(LoginListener loginlistener, GameProfile gameprofile, String hostname) {
|
||||||
|
return plist.attemptLogin(loginlistener, gameprofile, hostname);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String b(boolean flag) {
|
||||||
|
return plist.b(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(EntityHuman entityhuman, IChatBaseComponent ichatbasecomponent) {
|
||||||
|
plist.b(entityhuman, ichatbasecomponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void b(EntityPlayer entityplayer, WorldServer worldserver) {
|
||||||
|
plist.b(entityplayer, worldserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EntityPlayer> b(String s) {
|
||||||
|
return plist.b(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Location calculateTarget(Location enter, World target) {
|
||||||
|
return plist.calculateTarget(enter, target);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeDimension(EntityPlayer entityplayer, int i, TeleportCause cause) {
|
||||||
|
plist.changeDimension(entityplayer, i, cause);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void changeWorld(Entity entity, int i, WorldServer worldserver, WorldServer worldserver1) {
|
||||||
|
plist.changeWorld(entity, i, worldserver, worldserver1);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int d() {
|
||||||
|
return plist.d();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void d(EntityPlayer entityplayer) {
|
||||||
|
plist.d(entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String disconnect(EntityPlayer entityplayer) {
|
||||||
|
return plist.disconnect(entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return plist.equals(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] f() {
|
||||||
|
return plist.f();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void f(EntityPlayer entityplayer) {
|
||||||
|
plist.f(entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean f(GameProfile gameprofile) {
|
||||||
|
return plist.f(gameprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameProfile[] g() {
|
||||||
|
return plist.g();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean getHasWhitelist() {
|
||||||
|
return plist.getHasWhitelist();
|
||||||
|
}
|
||||||
|
|
||||||
|
public IpBanList getIPBans() {
|
||||||
|
return plist.getIPBans();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getMaxPlayers() {
|
||||||
|
return plist.getMaxPlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public OpList getOPs() {
|
||||||
|
return plist.getOPs();
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayer getPlayer(String s) {
|
||||||
|
return plist.getPlayer(s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getPlayerCount() {
|
||||||
|
return plist.getPlayerCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
public GameProfileBanList getProfileBans() {
|
||||||
|
return plist.getProfileBans();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getSeenPlayers() {
|
||||||
|
return plist.getSeenPlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
public DedicatedServer getServer() {
|
||||||
|
return plist.getServer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public WhiteList getWhitelist() {
|
||||||
|
return plist.getWhitelist();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getWhitelisted() {
|
||||||
|
return plist.getWhitelisted();
|
||||||
|
}
|
||||||
|
|
||||||
|
public AdvancementDataPlayer h(EntityPlayer entityplayer) {
|
||||||
|
return plist.h(entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return plist.hashCode();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isOp(GameProfile gameprofile) {
|
||||||
|
return plist.isOp(gameprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isWhitelisted(GameProfile gameprofile) {
|
||||||
|
return plist.isWhitelisted(gameprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag, Location location,
|
||||||
|
boolean avoidSuffocation) {
|
||||||
|
return plist.moveToWorld(entityplayer, i, flag, location, avoidSuffocation);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayer moveToWorld(EntityPlayer entityplayer, int i, boolean flag) {
|
||||||
|
return plist.moveToWorld(entityplayer, i, flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] n() {
|
||||||
|
return plist.n();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void onPlayerJoin(EntityPlayer entityplayer, String joinMessage) {
|
||||||
|
plist.onPlayerJoin(entityplayer, joinMessage);
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityPlayer processLogin(GameProfile gameprofile, EntityPlayer player) {
|
||||||
|
return plist.processLogin(gameprofile, player);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reload() {
|
||||||
|
plist.reload();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void reloadWhitelist() {
|
||||||
|
plist.reloadWhitelist();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeOp(GameProfile gameprofile) {
|
||||||
|
plist.removeOp(gameprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void removeWhitelist(GameProfile gameprofile) {
|
||||||
|
plist.removeWhitelist(gameprofile);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void repositionEntity(Entity entity, Location exit, boolean portal) {
|
||||||
|
plist.repositionEntity(entity, exit, portal);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int s() {
|
||||||
|
return plist.s();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void savePlayers() {
|
||||||
|
plist.savePlayers();
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public void sendAll(Packet packet, EntityHuman entityhuman) {
|
||||||
|
plist.sendAll(packet, entityhuman);
|
||||||
|
}
|
||||||
|
|
||||||
|
@SuppressWarnings("rawtypes")
|
||||||
|
public void sendAll(Packet packet, World world) {
|
||||||
|
plist.sendAll(packet, world);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendPacketNearby(EntityHuman entityhuman, double d0, double d1, double d2, double d3, int i,
|
||||||
|
Packet<?> packet) {
|
||||||
|
plist.sendPacketNearby(entityhuman, d0, d1, d2, d3, i, packet);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void sendScoreboard(ScoreboardServer scoreboardserver, EntityPlayer entityplayer) {
|
||||||
|
plist.sendScoreboard(scoreboardserver, entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setHasWhitelist(boolean flag) {
|
||||||
|
plist.setHasWhitelist(flag);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPlayerFileData(WorldServer[] aworldserver) {
|
||||||
|
plist.setPlayerFileData(aworldserver);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NBTTagCompound t() {
|
||||||
|
return plist.t();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void tick() {
|
||||||
|
plist.tick();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
return plist.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void u() {
|
||||||
|
plist.u();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void updateClient(EntityPlayer entityplayer) {
|
||||||
|
plist.updateClient(entityplayer);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<EntityPlayer> v() {
|
||||||
|
return plist.v();
|
||||||
|
}
|
||||||
|
|
||||||
|
public ServerStatisticManager getStatisticManager(EntityPlayer entityhuman) {
|
||||||
|
return plist.getStatisticManager(entityhuman);
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,7 @@ package buttondevteam.discordplugin.commands;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
import sx.blah.discord.handle.obj.IMessage;
|
import sx.blah.discord.handle.obj.IMessage;
|
||||||
|
@ -28,7 +29,7 @@ public class RoleCommand extends DiscordCommandBase {
|
||||||
if (role == null)
|
if (role == null)
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
DiscordPlugin.perform(() -> message.getAuthor().addRole(role));
|
DPUtils.perform(() -> message.getAuthor().addRole(role));
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added game role.");
|
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added game role.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Error while adding role!", e);
|
TBMCCoreAPI.SendException("Error while adding role!", e);
|
||||||
|
@ -39,7 +40,7 @@ public class RoleCommand extends DiscordCommandBase {
|
||||||
if (role == null)
|
if (role == null)
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
DiscordPlugin.perform(() -> message.getAuthor().removeRole(role));
|
DPUtils.perform(() -> message.getAuthor().removeRole(role));
|
||||||
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed game role.");
|
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed game role.");
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("Error while removing role!", e);
|
TBMCCoreAPI.SendException("Error while removing role!", e);
|
||||||
|
|
|
@ -3,6 +3,7 @@ package buttondevteam.discordplugin.listeners;
|
||||||
import org.bukkit.event.EventHandler;
|
import org.bukkit.event.EventHandler;
|
||||||
import org.bukkit.event.Listener;
|
import org.bukkit.event.Listener;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
import buttondevteam.discordplugin.DiscordPlugin;
|
import buttondevteam.discordplugin.DiscordPlugin;
|
||||||
import buttondevteam.lib.PluginUpdater;
|
import buttondevteam.lib.PluginUpdater;
|
||||||
import buttondevteam.lib.TBMCCoreAPI;
|
import buttondevteam.lib.TBMCCoreAPI;
|
||||||
|
@ -13,7 +14,7 @@ public class AutoUpdaterListener implements Listener {
|
||||||
if (DiscordPlugin.SafeMode)
|
if (DiscordPlugin.SafeMode)
|
||||||
return;
|
return;
|
||||||
try {
|
try {
|
||||||
DiscordPlugin.performNoWait(() -> DiscordPlugin.officechannel.getMessageHistory(10).stream()
|
DPUtils.performNoWait(() -> DiscordPlugin.officechannel.getMessageHistory(10).stream()
|
||||||
.filter(m -> m.getWebhookLongID() == 239123781401051138L && m.getEmbeds().get(0).getTitle()
|
.filter(m -> m.getWebhookLongID() == 239123781401051138L && m.getEmbeds().get(0).getTitle()
|
||||||
.contains(event.getData().get("repository").getAsJsonObject().get("name").getAsString()))
|
.contains(event.getData().get("repository").getAsJsonObject().get("name").getAsString()))
|
||||||
.findFirst().get().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
.findFirst().get().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
||||||
|
|
|
@ -35,7 +35,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
return;
|
return;
|
||||||
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
|
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
|
||||||
synchronized (this) {
|
synchronized (this) {
|
||||||
final String authorPlayer = DiscordPlugin.sanitizeString(e.getSender() instanceof Player //
|
final String authorPlayer = DPUtils.sanitizeString(e.getSender() instanceof Player //
|
||||||
? ((Player) e.getSender()).getDisplayName() //
|
? ((Player) e.getSender()).getDisplayName() //
|
||||||
: e.getSender().getName());
|
: e.getSender().getName());
|
||||||
final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer)
|
final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer)
|
||||||
|
@ -44,11 +44,10 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
// embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "")
|
// embed.appendField("Channel", ((e.getSender() instanceof DiscordSenderBase ? "d|" : "")
|
||||||
// + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false);
|
// + DiscordPlugin.sanitizeString(e.getChannel().DisplayName)), false);
|
||||||
if (e.getSender() instanceof Player)
|
if (e.getSender() instanceof Player)
|
||||||
DiscordPlugin
|
DPUtils.embedWithHead(
|
||||||
.embedWithHead(
|
embed.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id="
|
||||||
embed.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=minecraft&id="
|
+ ((Player) e.getSender()).getUniqueId()),
|
||||||
+ ((Player) e.getSender()).getUniqueId()),
|
((Player) e.getSender()).getName());
|
||||||
((Player) e.getSender()).getName());
|
|
||||||
else if (e.getSender() instanceof DiscordSenderBase)
|
else if (e.getSender() instanceof DiscordSenderBase)
|
||||||
embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL())
|
embed.withAuthorIcon(((DiscordSenderBase) e.getSender()).getUser().getAvatarURL())
|
||||||
.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id="
|
.withAuthorUrl("https://tbmcplugins.github.io/profile.html?type=discord&id="
|
||||||
|
@ -59,13 +58,14 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
Consumer<LastMsgData> doit = lastmsgdata -> {
|
Consumer<LastMsgData> doit = lastmsgdata -> {
|
||||||
final EmbedObject embedObject = embed.build();
|
final EmbedObject embedObject = embed.build();
|
||||||
final String dmsg = lastmsgdata.channel.isPrivate()
|
final String dmsg = lastmsgdata.channel.isPrivate()
|
||||||
? DiscordPlugin.sanitizeString(e.getChannel().DisplayName) : "";
|
? DPUtils.sanitizeString(e.getChannel().DisplayName)
|
||||||
|
: "";
|
||||||
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|
if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
|
||||||
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|
|| !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|
||||||
|| lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
|
|| lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
|
||||||
|| !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) {
|
|| !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) {
|
||||||
lastmsgdata.message = DiscordPlugin.sendMessageToChannelWait(lastmsgdata.channel, dmsg,
|
lastmsgdata.message = DiscordPlugin.sendMessageToChannelWait(lastmsgdata.channel, dmsg,
|
||||||
embedObject);
|
embedObject); // TODO Use ChromaBot API
|
||||||
lastmsgdata.time = nanoTime;
|
lastmsgdata.time = nanoTime;
|
||||||
lastmsgdata.mcchannel = e.getChannel();
|
lastmsgdata.mcchannel = e.getChannel();
|
||||||
lastmsgdata.content = embedObject.description;
|
lastmsgdata.content = embedObject.description;
|
||||||
|
@ -74,7 +74,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n"
|
lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n"
|
||||||
+ embedObject.description;// The message object doesn't get updated
|
+ embedObject.description;// The message object doesn't get updated
|
||||||
final LastMsgData _lastmsgdata = lastmsgdata;
|
final LastMsgData _lastmsgdata = lastmsgdata;
|
||||||
DiscordPlugin.perform(() -> _lastmsgdata.message.edit(dmsg, embedObject));
|
DPUtils.perform(() -> _lastmsgdata.message.edit(dmsg, embedObject));
|
||||||
} catch (MissingPermissionsException | DiscordException e1) {
|
} catch (MissingPermissionsException | DiscordException e1) {
|
||||||
TBMCCoreAPI.SendException("An error occured while editing chat message!", e1);
|
TBMCCoreAPI.SendException("An error occured while editing chat message!", e1);
|
||||||
}
|
}
|
||||||
|
@ -85,8 +85,9 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
|
|
||||||
if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp"))
|
if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp"))
|
||||||
&& isdifferentchannel.test(DiscordPlugin.chatchannel))
|
&& isdifferentchannel.test(DiscordPlugin.chatchannel))
|
||||||
doit.accept(lastmsgdata == null
|
doit.accept(
|
||||||
? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null) : lastmsgdata);
|
lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null)
|
||||||
|
: lastmsgdata);
|
||||||
|
|
||||||
for (LastMsgData data : lastmsgPerUser) {
|
for (LastMsgData data : lastmsgPerUser) {
|
||||||
if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel)
|
if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel)
|
||||||
|
@ -123,8 +124,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
DiscordPlugin.dc.getUsersByName(event.getMessage().substring(start + 1, mid)).stream()
|
DiscordPlugin.dc.getUsersByName(event.getMessage().substring(start + 1, mid)).stream()
|
||||||
.filter(u -> u.getDiscriminator().equals(event.getMessage().substring(mid + 1, end))).findAny()
|
.filter(u -> u.getDiscriminator().equals(event.getMessage().substring(mid + 1, end))).findAny()
|
||||||
.ifPresent(user -> event.setMessage(event.getMessage().substring(0, startF) + "@" + user.getName()
|
.ifPresent(user -> event.setMessage(event.getMessage().substring(0, startF) + "@" + user.getName()
|
||||||
+ (event.getMessage().length() > end ? event.getMessage().substring(end)
|
+ (event.getMessage().length() > end ? event.getMessage().substring(end) : ""))); // TODO: Add formatting
|
||||||
: ""))); // TODO: Add formatting
|
|
||||||
start = end; // Skip any @s inside the mention
|
start = end; // Skip any @s inside the mention
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -203,18 +203,26 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
* This overload sends it to the global chat.
|
* This overload sends it to the global chat.
|
||||||
*/
|
*/
|
||||||
public static void sendSystemMessageToChat(String msg) {
|
public static void sendSystemMessageToChat(String msg) {
|
||||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel, DiscordPlugin.sanitizeString(msg));
|
forAllMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(msg)));
|
||||||
for (LastMsgData data : lastmsgPerUser)
|
|
||||||
DiscordPlugin.sendMessageToChannel(data.channel, DiscordPlugin.sanitizeString(msg));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void sendSystemMessageToChat(TBMCSystemChatEvent event) {
|
public static void sendSystemMessageToChat(TBMCSystemChatEvent event) {
|
||||||
|
forAllowedMCChat(ch -> DiscordPlugin.sendMessageToChannel(ch, DPUtils.sanitizeString(event.getMessage())),
|
||||||
|
event);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void forAllMCChat(Consumer<IChannel> action) {
|
||||||
|
action.accept(DiscordPlugin.chatchannel);
|
||||||
|
for (LastMsgData data : lastmsgPerUser)
|
||||||
|
action.accept(data.channel);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) {
|
||||||
if (Channel.GlobalChat.ID.equals(event.getChannel().ID))
|
if (Channel.GlobalChat.ID.equals(event.getChannel().ID))
|
||||||
DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel,
|
action.accept(DiscordPlugin.chatchannel);
|
||||||
DiscordPlugin.sanitizeString(event.getMessage()));
|
|
||||||
for (LastMsgData data : lastmsgPerUser)
|
for (LastMsgData data : lastmsgPerUser)
|
||||||
if (event.shouldSendTo(getSender(data.channel, data.user, data.dp)))
|
if (event.shouldSendTo(getSender(data.channel, data.user, data.dp)))
|
||||||
DiscordPlugin.sendMessageToChannel(data.channel, DiscordPlugin.sanitizeString(event.getMessage()));
|
action.accept(data.channel);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override // Discord
|
@Override // Discord
|
||||||
|
@ -257,7 +265,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
boolean react = false;
|
boolean react = false;
|
||||||
|
|
||||||
if (dmessage.startsWith("/")) { // Ingame command
|
if (dmessage.startsWith("/")) { // Ingame command
|
||||||
DiscordPlugin.perform(() -> {
|
DPUtils.perform(() -> {
|
||||||
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
|
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
|
||||||
event.getMessage().delete();
|
event.getMessage().delete();
|
||||||
});
|
});
|
||||||
|
@ -308,7 +316,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
} else
|
} else
|
||||||
dsender.setMcchannel(Channel.GlobalChat);
|
dsender.setMcchannel(Channel.GlobalChat);
|
||||||
dsender.sendMessage("You're now talking in: "
|
dsender.sendMessage("You're now talking in: "
|
||||||
+ DiscordPlugin.sanitizeString(dsender.getMcchannel().DisplayName));
|
+ DPUtils.sanitizeString(dsender.getMcchannel().DisplayName));
|
||||||
} else { // Send single message
|
} else { // Send single message
|
||||||
sendChatMessage.accept(chc, cmd.substring(spi + 1));
|
sendChatMessage.accept(chc, cmd.substring(spi + 1));
|
||||||
react = true;
|
react = true;
|
||||||
|
@ -333,12 +341,12 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
|
||||||
try {
|
try {
|
||||||
final IReaction reaction = m.getReactionByEmoji(DiscordPlugin.DELIVERED_REACTION);
|
final IReaction reaction = m.getReactionByEmoji(DiscordPlugin.DELIVERED_REACTION);
|
||||||
if (reaction != null)
|
if (reaction != null)
|
||||||
DiscordPlugin.perform(() -> m.removeReaction(DiscordPlugin.dc.getOurUser(), reaction));
|
DPUtils.perform(() -> m.removeReaction(DiscordPlugin.dc.getOurUser(), reaction));
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
TBMCCoreAPI.SendException("An error occured while removing reactions from chat!", e);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
DiscordPlugin.performNoWait(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
DPUtils.performNoWait(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
|
||||||
}
|
}
|
||||||
} catch (Exception e) {
|
} catch (Exception e) {
|
||||||
TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e);
|
TBMCCoreAPI.SendException("An error occured while handling message \"" + dmessage + "\"!", e);
|
||||||
|
|
|
@ -23,6 +23,8 @@ import org.bukkit.plugin.RegisteredListener;
|
||||||
|
|
||||||
import com.earth2me.essentials.CommandSource;
|
import com.earth2me.essentials.CommandSource;
|
||||||
|
|
||||||
|
import buttondevteam.discordplugin.ChromaBot;
|
||||||
|
import buttondevteam.discordplugin.DPUtils;
|
||||||
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
import buttondevteam.discordplugin.DiscordConnectedPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlayer;
|
import buttondevteam.discordplugin.DiscordPlayer;
|
||||||
import buttondevteam.discordplugin.DiscordPlayerSender;
|
import buttondevteam.discordplugin.DiscordPlayerSender;
|
||||||
|
@ -68,9 +70,10 @@ public class MCListener implements Listener {
|
||||||
+ " do /discord accept");
|
+ " do /discord accept");
|
||||||
p.sendMessage("§bIf it wasn't you, do /discord decline");
|
p.sendMessage("§bIf it wasn't you, do /discord decline");
|
||||||
}
|
}
|
||||||
MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " joined the game");
|
if (!DiscordPlugin.hooked)
|
||||||
|
MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " joined the game");
|
||||||
MCChatListener.ListC = 0;
|
MCChatListener.ListC = 0;
|
||||||
DiscordPlugin.updatePlayerList();
|
ChromaBot.getInstance().updatePlayerList();
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.HIGHEST)
|
@EventHandler(priority = EventPriority.HIGHEST)
|
||||||
|
@ -83,8 +86,10 @@ public class MCListener implements Listener {
|
||||||
() -> MCChatListener.ConnectedSenders.values().stream()
|
() -> MCChatListener.ConnectedSenders.values().stream()
|
||||||
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
.filter(s -> s.getUniqueId().equals(e.getPlayer().getUniqueId())).findAny()
|
||||||
.ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
|
.ifPresent(dcp -> callEventExcludingSome(new PlayerJoinEvent(dcp, ""))));
|
||||||
MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " left the game");
|
if (!DiscordPlugin.hooked)
|
||||||
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, DiscordPlugin::updatePlayerList, 5);
|
MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " left the game");
|
||||||
|
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin,
|
||||||
|
ChromaBot.getInstance()::updatePlayerList, 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
|
@ -105,14 +110,15 @@ public class MCListener implements Listener {
|
||||||
|
|
||||||
@EventHandler(priority = EventPriority.LOW)
|
@EventHandler(priority = EventPriority.LOW)
|
||||||
public void onPlayerDeath(PlayerDeathEvent e) {
|
public void onPlayerDeath(PlayerDeathEvent e) {
|
||||||
MCChatListener.sendSystemMessageToChat(e.getDeathMessage());
|
if (!DiscordPlugin.hooked)
|
||||||
|
MCChatListener.sendSystemMessageToChat(e.getDeathMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerAFK(AfkStatusChangeEvent e) {
|
public void onPlayerAFK(AfkStatusChangeEvent e) {
|
||||||
if (e.isCancelled() || !e.getAffected().getBase().isOnline())
|
if (e.isCancelled() || !e.getAffected().getBase().isOnline())
|
||||||
return;
|
return;
|
||||||
MCChatListener.sendSystemMessageToChat(DiscordPlugin.sanitizeString(e.getAffected().getBase().getDisplayName())
|
MCChatListener.sendSystemMessageToChat(DPUtils.sanitizeString(e.getAffected().getBase().getDisplayName())
|
||||||
+ " is " + (e.getValue() ? "now" : "no longer") + " AFK.");
|
+ " is " + (e.getValue() ? "now" : "no longer") + " AFK.");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -124,7 +130,7 @@ public class MCListener implements Listener {
|
||||||
@EventHandler
|
@EventHandler
|
||||||
public void onPlayerMute(MuteStatusChangeEvent e) {
|
public void onPlayerMute(MuteStatusChangeEvent e) {
|
||||||
try {
|
try {
|
||||||
DiscordPlugin.performNoWait(() -> {
|
DPUtils.performNoWait(() -> {
|
||||||
final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L);
|
final IRole role = DiscordPlugin.dc.getRoleByID(164090010461667328L);
|
||||||
final CommandSource source = e.getAffected().getSource();
|
final CommandSource source = e.getAffected().getSource();
|
||||||
if (!source.isPlayer())
|
if (!source.isPlayer())
|
||||||
|
|
Loading…
Reference in a new issue