Merge pull request #39 from TBMCPlugins/dev

Added private Minecraft chat, Discord login, show message pinning, Maven project check, some of #12
This commit is contained in:
Norbi Peti 2017-07-04 18:14:01 +02:00 committed by GitHub
commit 38ccf5d52f
16 changed files with 3663 additions and 1174 deletions

View file

@ -1 +1,4 @@
language: java language: java
jdk:
- oraclejdk8

28
pom.xml
View file

@ -11,6 +11,8 @@
<url>http://maven.apache.org</url> <url>http://maven.apache.org</url>
<build> <build>
<!-- <sourceDirectory>target/generated-sources/delombok</sourceDirectory>
<testSourceDirectory>target/generated-test-sources/delombok</testSourceDirectory> -->
<sourceDirectory>src/main/java</sourceDirectory> <sourceDirectory>src/main/java</sourceDirectory>
<resources> <resources>
<resource> <resource>
@ -89,6 +91,14 @@
</execution> </execution>
</executions> </executions>
</plugin> </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> -->
</plugins> </plugins>
</build> </build>
@ -117,6 +127,10 @@
<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>
<id>projectlombok.org</id>
<url>http://projectlombok.org/mavenrepo</url>
</repository>
</repositories> </repositories>
<dependencies> <dependencies>
@ -129,7 +143,7 @@
<dependency> <dependency>
<groupId>org.spigotmc</groupId> <groupId>org.spigotmc</groupId>
<artifactId>spigot-api</artifactId> <artifactId>spigot-api</artifactId>
<version>1.11-R0.1-SNAPSHOT</version> <version>1.12-R0.1-SNAPSHOT</version>
<scope>provided</scope> <scope>provided</scope>
</dependency> </dependency>
<dependency> <dependency>
@ -162,5 +176,17 @@
<artifactId>Essentials</artifactId> <artifactId>Essentials</artifactId>
<version>2.13.1</version> <version>2.13.1</version>
</dependency> </dependency>
<dependency>
<groupId>com.github.xaanit</groupId>
<artifactId>D4J-OAuth</artifactId>
<version>master-SNAPSHOT</version>
</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>
</dependencies> </dependencies>
</project> </project>

File diff suppressed because it is too large Load diff

View file

@ -1,6 +1,7 @@
package buttondevteam.discordplugin; package buttondevteam.discordplugin;
import buttondevteam.lib.player.ChromaGamerBase; import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.PlayerData;
import buttondevteam.lib.player.UserClass; import buttondevteam.lib.player.UserClass;
@UserClass(foldername = "discord") @UserClass(foldername = "discord")
@ -15,4 +16,8 @@ public class DiscordPlayer extends ChromaGamerBase {
did = plugindata.getString(getFolder() + "_id"); did = plugindata.getString(getFolder() + "_id");
return did; return did;
} }
public PlayerData<Boolean> minecraftChat() {
return data(false);
}
} }

View file

@ -4,7 +4,10 @@ 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.Calendar;
import java.util.List; import java.util.List;
import java.util.Random;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.plugin.RegisteredServiceProvider; import org.bukkit.plugin.RegisteredServiceProvider;
import org.bukkit.plugin.java.JavaPlugin; import org.bukkit.plugin.java.JavaPlugin;
@ -23,10 +26,9 @@ import sx.blah.discord.api.events.IListener;
import sx.blah.discord.api.internal.json.objects.EmbedObject; import sx.blah.discord.api.internal.json.objects.EmbedObject;
import sx.blah.discord.handle.impl.events.ReadyEvent; import sx.blah.discord.handle.impl.events.ReadyEvent;
import sx.blah.discord.handle.obj.*; import sx.blah.discord.handle.obj.*;
import sx.blah.discord.util.DiscordException; import sx.blah.discord.util.*;
import sx.blah.discord.util.EmbedBuilder; import sx.blah.discord.util.RequestBuffer.IRequest;
import sx.blah.discord.util.MissingPermissionsException; import sx.blah.discord.util.RequestBuffer.IVoidRequest;
import sx.blah.discord.util.RateLimitException;
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";
@ -126,15 +128,34 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
MCChatListener mcchat = new MCChatListener(); MCChatListener mcchat = new MCChatListener();
dc.getDispatcher().registerListener(mcchat); dc.getDispatcher().registerListener(mcchat);
TBMCCoreAPI.RegisterEventsForExceptions(mcchat, this); TBMCCoreAPI.RegisterEventsForExceptions(mcchat, this);
dc.getDispatcher().registerListener(new AutoUpdaterListener()); TBMCCoreAPI.RegisterEventsForExceptions(new AutoUpdaterListener(), this);
Bukkit.getPluginManager().registerEvents(new ExceptionListener(), this); Bukkit.getPluginManager().registerEvents(new ExceptionListener(), this);
TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this); TBMCCoreAPI.RegisterEventsForExceptions(new MCListener(), this);
TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class); TBMCChatAPI.AddCommands(this, DiscordMCCommandBase.class);
TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class); TBMCCoreAPI.RegisterUserClass(DiscordPlayer.class);
new Thread(() -> AnnouncementGetterThreadMethod()).start(); new Thread(this::AnnouncementGetterThreadMethod).start();
setupProviders(); setupProviders();
TBMCCoreAPI.SendUnsentExceptions(); TBMCCoreAPI.SendUnsentExceptions();
TBMCCoreAPI.SendUnsentDebugMessages(); TBMCCoreAPI.SendUnsentDebugMessages();
if (!TBMCCoreAPI.IsTestServer()) {
final Calendar currentCal = Calendar.getInstance();
final Calendar newCal = Calendar.getInstance();
currentCal.set(currentCal.get(Calendar.YEAR), currentCal.get(Calendar.MONTH),
currentCal.get(Calendar.DAY_OF_MONTH), 4, 10);
if (currentCal.get(Calendar.DAY_OF_MONTH) % 9 == 0 && currentCal.before(newCal)) {
Random rand = new Random();
sendMessageToChannel(dc.getChannels().get(rand.nextInt(dc.getChannels().size())),
"You could make a religion out of this");
}
}
/*
* IDiscordOAuth doa = new DiscordOAuthBuilder(dc).withClientID("226443037893591041") .withClientSecret(getConfig().getString("appsecret")) .withRedirectUrl("https://" +
* (TBMCCoreAPI.IsTestServer() ? "localhost" : "server.figytuna.com") + ":8081/callback") .withScopes(Scope.IDENTIFY).withHttpServerOptions(new HttpServerOptions().setPort(8081))
* .withSuccessHandler((rc, user) -> { rc.response().headers().add("Location", "https://" + (TBMCCoreAPI.IsTestServer() ? "localhost" : "server.figytuna.com") + ":8080/login?type=discord&"
* + rc.request().query()); rc.response().setStatusCode(303); rc.response().end("Redirecting"); rc.response().close(); }).withFailureHandler(rc -> { rc.response().headers().add("Location",
* "https://" + (TBMCCoreAPI.IsTestServer() ? "localhost" : "server.figytuna.com") + ":8080/login?type=discord&" + rc.request().query()); rc.response().setStatusCode(303);
* rc.response().end("Redirecting"); rc.response().close(); }).build(); getLogger().info("Auth URL: " + doa.buildAuthUrl());
*/
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while enabling DiscordPlugin!", e); TBMCCoreAPI.SendException("An error occured while enabling DiscordPlugin!", e);
} }
@ -234,7 +255,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
try { try {
if (channel == chatchannel) if (channel == chatchannel)
MCChatListener.resetLastMessage(); // If this is a chat message, it'll be set again MCChatListener.resetLastMessage(); // If this is a chat message, it'll be set again
final String content = TBMCCoreAPI.IsTestServer() && channel != chatchannel final String content = TBMCCoreAPI.IsTestServer() && channel != chatchannel || channel == botroomchannel // Both are the same for testing
? "*The following message is from a test server*\n" + message : message; ? "*The following message is from a test server*\n" + message : message;
return perform( return perform(
() -> embed == null ? channel.sendMessage(content) : channel.sendMessage(content, embed, false)); () -> embed == null ? channel.sendMessage(content) : channel.sendMessage(content, embed, false));
@ -283,39 +304,23 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
/** /**
* Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode. * Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode.
*/ */
public static <T extends IDiscordObject<T>> T perform(DiscordSupplier<T> action) public static <T> T perform(IRequest<T> action) {
throws DiscordException, MissingPermissionsException {
for (int i = 0; i < 20; i++)
try {
if (SafeMode) if (SafeMode)
return null; return null;
return action.get(); return RequestBuffer.request(action).get(); // Let the pros handle this
} catch (RateLimitException e) {
try {
Thread.sleep(e.getRetryDelay() > 0 ? e.getRetryDelay() : 10);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
}
return null;
} }
/** /**
* Performs Discord actions, retrying when ratelimited. * Performs Discord actions, retrying when ratelimited.
*/ */
public static void perform(DiscordRunnable action) throws DiscordException, MissingPermissionsException { public static Void perform(IVoidRequest action) {
for (int i = 0; i < 20; i++)
try {
if (SafeMode) if (SafeMode)
return; return null;
action.run(); return RequestBuffer.request(action).get(); // Let the pros handle this
return; // Gotta escape that loop
} catch (RateLimitException e) {
try {
Thread.sleep(e.getRetryDelay() > 0 ? e.getRetryDelay() : 10);
} catch (InterruptedException e1) {
e1.printStackTrace();
}
} }
public static boolean checkIfSomeoneIsTestingWhileWeArent() {
return !TBMCCoreAPI.IsTestServer()
&& dc.getOurUser().getPresence().getPlayingText().orElse("").equals("testing");
} }
} }

View file

@ -97,9 +97,12 @@ public class DiscordSender extends DiscordSenderBase implements CommandSender {
@Override @Override
public String getName() { public String getName() {
if (user == null) return name == null ? user == null ? "Discord user" : user.getDisplayName(DiscordPlugin.mainServer) : name;
return "Discord user"; }
return name == null ? user.getDisplayName(DiscordPlugin.mainServer) : name;
@Override
public Spigot spigot() {
return new CommandSender.Spigot();
} }
} }

View file

@ -20,13 +20,16 @@ public abstract class DiscordCommandBase {
commands.put("userinfo", new UserinfoCommand()); commands.put("userinfo", new UserinfoCommand());
commands.put("help", new HelpCommand()); commands.put("help", new HelpCommand());
commands.put("role", new RoleCommand()); commands.put("role", new RoleCommand());
commands.put("mcchat", new MCChatCommand());
} }
public static void runCommand(String cmd, String args, IMessage message) { public static void runCommand(String cmd, String args, IMessage message) {
DiscordCommandBase command = commands.get(cmd); DiscordCommandBase command = commands.get(cmd);
if (command == null) { if (command == null) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Unknown command: " + cmd + " with args: " + args + "\nDo @ChromaBot help for help"); "Unknown command: " + cmd + " with args: " + args + "\nDo '"
+ (message.getChannel().isPrivate() ? "" : message.getClient().getOurUser().mention() + " ")
+ "help' for help");
return; return;
} }
try { try {

View file

@ -0,0 +1,43 @@
package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.player.PlayerData;
import sx.blah.discord.handle.obj.IMessage;
public class MCChatCommand extends DiscordCommandBase {
@Override
public String getCommandName() {
return "mcchat";
}
@Override
public void run(IMessage message, String args) {
if (!message.getChannel().isPrivate()) {
message.reply("This command can only be issued while DMing the bot.");
return;
}
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) {
PlayerData<Boolean> mcchat = user.minecraftChat();
mcchat.set(!mcchat.get());
MCChatListener.privateMCChat(message.getChannel(), mcchat.get());
message.reply("Minecraft chat " + (mcchat.get() //
? "enabled. Use '" + message.getClient().getOurUser().mention()
+ " mcchat' (with the mention) to disable." //
: "disabled."));
} catch (Exception e) {
TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e);
}
}
@Override
public String[] getHelpText() {
return new String[] { //
"mcchat enables or disables the Minecraft chat in private messages.", //
"It can be useful if you don't want your messages to be visible, for example when talking a private channel." //
}; // TODO: Pin channel switching to indicate the current channel
}
}

View file

@ -1,63 +1,22 @@
package buttondevteam.discordplugin.listeners; package buttondevteam.discordplugin.listeners;
import java.awt.Color; import org.bukkit.event.EventHandler;
import java.util.function.Supplier; import org.bukkit.event.Listener;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.DiscordSender; import buttondevteam.lib.PluginUpdater;
import buttondevteam.lib.TBMCCoreAPI; import buttondevteam.lib.TBMCCoreAPI;
import sx.blah.discord.api.events.IListener;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
import sx.blah.discord.handle.obj.IEmbed;
import sx.blah.discord.util.EmbedBuilder;
public class AutoUpdaterListener implements IListener<MessageReceivedEvent> { public class AutoUpdaterListener implements Listener {
@Override @EventHandler
public void handle(MessageReceivedEvent event) { public void handle(PluginUpdater.UpdatedEvent event) {
if (DiscordPlugin.SafeMode) if (DiscordPlugin.SafeMode)
return; return;
if (!event.getMessage().getChannel().getStringID().equals(DiscordPlugin.officechannel.getStringID()))
return;
if (239123781401051138L != event.getMessage().getWebhookLongID())
return;
if (event.getMessage().getEmbeds().size() == 0)
return;
final IEmbed embed = event.getMessage().getEmbeds().get(0);
final String title = embed.getTitle();
if (!title.contains("new commit"))
return;
String branch = title.substring(title.indexOf(':') + 1, title.indexOf(']'));
String project = title.substring(title.indexOf('[') + 1, title.indexOf(':'));
if ((branch.equals("master") || (TBMCCoreAPI.IsTestServer() && branch.equals("dev")))
&& TBMCCoreAPI.UpdatePlugin(project,
new DiscordSender(null,
TBMCCoreAPI.IsTestServer() //
? DiscordPlugin.chatchannel //
: DiscordPlugin.botroomchannel),
branch)
&& ((Supplier<Boolean>) () -> { // Best looking code I've ever written
try { try {
int hi, ei, prnum; DiscordPlugin.perform(() -> DiscordPlugin.officechannel.getMessageHistory(10).stream()
if ((hi = embed.getDescription().indexOf('#')) > -1 .filter(m -> m.getWebhookLongID() == 239123781401051138L && m.getEmbeds().get(0).getTitle()
&& ((ei = embed.getDescription().indexOf(' ', hi + 1)) > -1 .contains(event.getData().get("repository").getAsJsonObject().get("name").getAsString()))
|| (ei = embed.getDescription().indexOf(".", hi + 1)) > -1 .findFirst().get().addReaction(DiscordPlugin.DELIVERED_REACTION));
|| (ei = embed.getDescription().length()) > -1)
&& (prnum = Integer.parseInt(embed.getDescription().substring(hi + 1, ei))) > -1)
DiscordPlugin.sendMessageToChannel(DiscordPlugin.updatechannel, "",
new EmbedBuilder().withColor(Color.WHITE).withTitle("Update details")
.withUrl("https://github.com/TBMCPlugins/" + project + "/pull/" + prnum)
.build());
else
throw new Exception("No PR found");
} catch (Exception e) {
DiscordPlugin.sendMessageToChannel(DiscordPlugin.updatechannel, "",
new EmbedBuilder().withColor(Color.WHITE).withTitle("Update details:")
.withDescription(embed.getDescription() + " (" + e.getMessage() + ")").build());
}
return true;
}).get() && (!TBMCCoreAPI.IsTestServer() || !branch.equals("master")))
try {
DiscordPlugin.perform(() -> event.getMessage().addReaction(DiscordPlugin.DELIVERED_REACTION));
} catch (Exception e) { } catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while reacting to plugin update!", e); TBMCCoreAPI.SendException("An error occured while reacting to plugin update!", e);
} }

View file

@ -1,10 +1,13 @@
package buttondevteam.discordplugin.listeners; package buttondevteam.discordplugin.listeners;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays;
import java.util.Random; import java.util.Random;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin; import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.DiscordCommandBase; import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.lib.TBMCCoreAPI;
import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.events.IListener;
import sx.blah.discord.handle.impl.events.guild.channel.message.MentionEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MentionEvent;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
@ -17,15 +20,23 @@ public class CommandListener {
"Between now and the heat-death of the universe.", // Ghostise "Between now and the heat-death of the universe.", // Ghostise
"Soon™", "Ask again this time next month", // Ghostise "Soon™", "Ask again this time next month", // Ghostise
"In about 3 seconds", // Nicolai "In about 3 seconds", // Nicolai
"Right after we finish coding 7 plugins",//Ali "After we finish 8 plugins", // Ali
"It'll be done tomorrow.",//Ali "Tomorrow.", // Ali
"We just need to complete one tiiiny feature",//Ali "After one tiiiny feature", // Ali
"In 18 commits",//Ali "Next commit", // Ali
"After we finish strangling Towny",//Ali "After we finish strangling Towny", // Ali
"When we kill every bug in the system",//Ali "When we kill every *fucking* bug", // Ali
"Once the server stops screaming error messages.",//Ali "Once the server stops screaming.", // Ali
"After HL3 comes out", // Ali
"Next time you ask", // Ali
"When will *you* be open?" // Ali
}; };
private static final String[] serverReadyQuestions = new String[] { "when will the server be open",
"when will the server be ready", "when will the server be done", "when will the server be complete",
"when will the server be finished", "when's the server ready", "when's the server open",
"Vhen vill ze server be open?" };
private static final Random serverReadyRandom = new Random(); private static final Random serverReadyRandom = new Random();
private static final ArrayList<Short> usableServerReadyStrings = new ArrayList<Short>(serverReadyStrings.length) { private static final ArrayList<Short> usableServerReadyStrings = new ArrayList<Short>(serverReadyStrings.length) {
private static final long serialVersionUID = 2213771460909848770L; private static final long serialVersionUID = 2213771460909848770L;
@ -48,10 +59,14 @@ public class CommandListener {
if (event.getMessage().getAuthor().isBot()) if (event.getMessage().getAuthor().isBot())
return; return;
final IChannel channel = event.getMessage().getChannel(); final IChannel channel = event.getMessage().getChannel();
if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID()) && !channel.isPrivate()) if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID())
&& (!channel.isPrivate() || DiscordPlugin.checkIfSomeoneIsTestingWhileWeArent()))
return; return;
if (channel.getStringID().equals(DiscordPlugin.chatchannel.getStringID())) if (channel.getStringID().equals(DiscordPlugin.chatchannel.getStringID()))
return; // The chat code already handles this - Right now while testing botchannel is the same as chatchannel return; // The chat code already handles this - Right now while testing botchannel is the same as chatchannel
if (DiscordPlayer.getUser(event.getAuthor().getStringID(), DiscordPlayer.class).minecraftChat().get()) // Let the MCChatListener handle it
return;
event.getMessage().getChannel().setTypingStatus(true); // Fun
runCommand(event.getMessage(), true); runCommand(event.getMessage(), true);
} }
}, new IListener<MessageReceivedEvent>() { }, new IListener<MessageReceivedEvent>() {
@ -59,19 +74,19 @@ public class CommandListener {
public void handle(MessageReceivedEvent event) { public void handle(MessageReceivedEvent event) {
if (DiscordPlugin.SafeMode) if (DiscordPlugin.SafeMode)
return; return;
if (event.getMessage().getContent().toLowerCase().contains("when will the server be open?")) { final String msglowercase = event.getMessage().getContent().toLowerCase();
if (!TBMCCoreAPI.IsTestServer()
&& Arrays.stream(serverReadyQuestions).anyMatch(s -> msglowercase.contains(s))) {
int next; int next;
/*
* if (serverReadyStrings.length <= lastServerReadyStrings.size()) { next = lastServerReadyStrings.get(0); lastServerReadyStrings.clear(); } else { next = (short) serverReadyRandom
* .nextInt(serverReadyStrings.length - lastServerReadyStrings.size()); for (short i = 0; i < lastServerReadyStrings.size(); i++) { short j = lastServerReadyStrings.get(i); if
* (next == j) next++; if (next >= serverReadyStrings.length) next = 0; } lastServerReadyStrings.add(next); }
*/
if (usableServerReadyStrings.size() == 0) if (usableServerReadyStrings.size() == 0)
createUsableServerReadyStrings(usableServerReadyStrings); createUsableServerReadyStrings(usableServerReadyStrings);
next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size())); next = usableServerReadyStrings.remove(serverReadyRandom.nextInt(usableServerReadyStrings.size()));
DiscordPlugin.sendMessageToChannel(event.getMessage().getChannel(), serverReadyStrings[next]); DiscordPlugin.sendMessageToChannel(event.getMessage().getChannel(), serverReadyStrings[next]);
} }
if (!event.getMessage().getChannel().isPrivate()) if (!event.getMessage().getChannel().isPrivate() //
|| DiscordPlayer.getUser(event.getAuthor().getStringID(), DiscordPlayer.class).minecraftChat()
.get()
|| DiscordPlugin.checkIfSomeoneIsTestingWhileWeArent())
return; return;
if (event.getMessage().getAuthor().isBot()) if (event.getMessage().getAuthor().isBot())
return; return;
@ -92,7 +107,6 @@ public class CommandListener {
public static boolean runCommand(IMessage message, boolean mentionedonly) { public static boolean runCommand(IMessage message, boolean mentionedonly) {
if (DiscordPlugin.SafeMode) if (DiscordPlugin.SafeMode)
return true; return true;
message.getChannel().setTypingStatus(true);
final StringBuilder cmdwithargs = new StringBuilder(message.getContent()); final StringBuilder cmdwithargs = new StringBuilder(message.getContent());
final String mention = DiscordPlugin.dc.getOurUser().mention(false); final String mention = DiscordPlugin.dc.getOurUser().mention(false);
final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true); final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true);
@ -104,6 +118,7 @@ public class CommandListener {
message.getChannel().setTypingStatus(false); message.getChannel().setTypingStatus(false);
return false; return false;
} }
message.getChannel().setTypingStatus(true);
int index = cmdwithargs.indexOf(" "); int index = cmdwithargs.indexOf(" ");
String cmd; String cmd;
String args; String args;

View file

@ -1,8 +1,11 @@
package buttondevteam.discordplugin.listeners; package buttondevteam.discordplugin.listeners;
import java.awt.Color;
import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap; import java.util.HashMap;
import java.util.UUID; import java.util.UUID;
import java.util.function.Consumer;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import org.bukkit.Bukkit; import org.bukkit.Bukkit;
import org.bukkit.entity.Player; import org.bukkit.entity.Player;
@ -13,8 +16,8 @@ import buttondevteam.discordplugin.*;
import buttondevteam.lib.*; import buttondevteam.lib.*;
import buttondevteam.lib.chat.Channel; import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.TBMCChatAPI; import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer; import buttondevteam.lib.player.TBMCPlayer;
import lombok.val;
import sx.blah.discord.api.events.IListener; import sx.blah.discord.api.events.IListener;
import sx.blah.discord.api.internal.json.objects.EmbedObject; import sx.blah.discord.api.internal.json.objects.EmbedObject;
import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent; import sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent;
@ -28,52 +31,75 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
return; return;
if (e.getSender() instanceof DiscordSender || e.getSender() instanceof DiscordPlayerSender) if (e.getSender() instanceof DiscordSender || e.getSender() instanceof DiscordPlayerSender)
return; return;
if (!e.getChannel().equals(Channel.GlobalChat))
return;
synchronized (this) { synchronized (this) {
final String authorPlayer = DiscordPlugin.sanitizeString(e.getSender() instanceof Player // final String authorPlayer = DiscordPlugin.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).withDescription(e.getMessage()); final EmbedBuilder embed = new EmbedBuilder().withAuthorName(authorPlayer).withDescription(e.getMessage())
final EmbedObject embedObject = e.getSender() instanceof Player .withColor(new Color(e.getChannel().color.getRed(), e.getChannel().color.getGreen(),
? embed.withAuthorIcon( e.getChannel().color.getBlue()));
"https://minotar.net/avatar/" + ((Player) e.getSender()).getName() + "/32.png").build() if (e.getSender() instanceof Player)
: embed.build(); embed.withAuthorIcon("https://minotar.net/avatar/" + ((Player) e.getSender()).getName() + "/32.png");
final long nanoTime = System.nanoTime(); final long nanoTime = System.nanoTime();
if (lastmessage == null || lastmessage.isDeleted() Consumer<LastMsgData> doit = lastmsgdata -> {
|| !authorPlayer.equals(lastmessage.getEmbeds().get(0).getAuthor().getName()) final EmbedObject embedObject = embed.build();
|| lastmsgtime / 1000000000f < nanoTime / 1000000000f - 120) { String msg = lastmsgdata.channel.isPrivate() ? DiscordPlugin.sanitizeString(e.getChannel().DisplayName)
lastmessage = DiscordPlugin.sendMessageToChannel(DiscordPlugin.chatchannel, "", embedObject); : "";
lastmsgtime = nanoTime; if (lastmsgdata.message == null || lastmsgdata.message.isDeleted()
lastmsg = e.getMessage(); || !authorPlayer.equals(lastmsgdata.message.getEmbeds().get(0).getAuthor().getName())
|| lastmsgdata.time / 1000000000f < nanoTime / 1000000000f - 120
|| !lastmsgdata.mcchannel.ID.equals(e.getChannel().ID)) {
lastmsgdata.message = DiscordPlugin.sendMessageToChannel(lastmsgdata.channel, msg, embedObject);
lastmsgdata.time = nanoTime;
lastmsgdata.mcchannel = e.getChannel();
} else } else
try { try {
lastmsg = embedObject.description = lastmsg + "\n" + embedObject.description; lastmsgdata.content = embedObject.description = lastmsgdata.content + "\n"
DiscordPlugin.perform(() -> lastmessage.edit("", embedObject)); + embedObject.description;// The message object doesn't get updated
final LastMsgData _lastmsgdata = lastmsgdata;
DiscordPlugin.perform(() -> _lastmsgdata.message.edit(msg, 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);
} }
};
if (e.getChannel().equals(Channel.GlobalChat))
doit.accept(
lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel) : lastmsgdata);
for (LastMsgData data : lastmsgPerUser) {
final IUser iUser = data.channel.getUsersHere().stream()
.filter(u -> u.getLongID() != u.getClient().getOurUser().getLongID()).findFirst().get(); // Doesn't support group DMs
final DiscordPlayer user = DiscordPlayer.getUser(iUser.getStringID(), DiscordPlayer.class);
if (user.minecraftChat().get() && e.shouldSendTo(getSender(data.channel, iUser, user)))
doit.accept(data);
}
} // TODO: Author URL } // TODO: Author URL
} }
private static class LastMsgData {
public IMessage message;
public long time;
public String content;
public IChannel channel;
public Channel mcchannel;
public LastMsgData(IChannel channel) {
this.channel = channel;
}
}
@EventHandler @EventHandler
public void onChatPreprocess(TBMCChatPreprocessEvent event) { public void onChatPreprocess(TBMCChatPreprocessEvent event) {
int start = -1; int start = -1;
// System.out.println("A");
while ((start = event.getMessage().indexOf('@', start + 1)) != -1) { while ((start = event.getMessage().indexOf('@', start + 1)) != -1) {
// System.out.println("Start: " + start);
int mid = event.getMessage().indexOf('#', start + 1); int mid = event.getMessage().indexOf('#', start + 1);
// System.out.println("Mid: " + mid);
if (mid == -1) if (mid == -1)
return; return;
int end_ = event.getMessage().indexOf(' ', mid + 1); int end_ = event.getMessage().indexOf(' ', mid + 1);
// System.out.println("End: " + end_);
if (end_ == -1) if (end_ == -1)
end_ = event.getMessage().length(); end_ = event.getMessage().length();
final int end = end_; final int end = end_;
final int startF = start; final int startF = start;
// System.out.println("Name: " + event.getMessage().substring(start, mid));
// System.out.println("Disc: " + event.getMessage().substring(mid, end));
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()
@ -86,27 +112,36 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
private static final String[] UnconnectedCmds = new String[] { "list", "u", "shrug", "tableflip", "unflip", "mwiki", private static final String[] UnconnectedCmds = new String[] { "list", "u", "shrug", "tableflip", "unflip", "mwiki",
"yeehaw" }; "yeehaw" };
private static IMessage lastmessage = null; private static LastMsgData lastmsgdata;
private static long lastmsgtime = 0;
private static String lastmsg;
private static short lastlist = 0; private static short lastlist = 0;
private static short lastlistp = 0; private static short lastlistp = 0;
/**
* Used for messages in PMs (mcchat).
*/
private static ArrayList<LastMsgData> lastmsgPerUser = new ArrayList<LastMsgData>();
public static boolean privateMCChat(IChannel channel, boolean start) {
return start ? lastmsgPerUser.add(new LastMsgData(channel))
: lastmsgPerUser.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
public static final HashMap<String, DiscordSender> UnconnectedSenders = new HashMap<>(); public static final HashMap<String, DiscordSender> UnconnectedSenders = new HashMap<>();
public static final HashMap<String, DiscordPlayerSender> ConnectedSenders = new HashMap<>(); public static final HashMap<String, DiscordPlayerSender> ConnectedSenders = new HashMap<>();
public static short ListC = 0; public static short ListC = 0;
public static void resetLastMessage() { public static void resetLastMessage() {
lastmessage = null; (lastmsgdata == null ? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel) : lastmsgdata).message = null; // Don't set the whole object to null, the player and channel information should
} } // be preserved
@Override // Discord @Override // Discord
public void handle(sx.blah.discord.handle.impl.events.guild.channel.message.MessageReceivedEvent event) { public void handle(MessageReceivedEvent event) {
final IUser author = event.getMessage().getAuthor(); val author = event.getMessage().getAuthor();
val user = DiscordPlayer.getUser(author.getStringID(), DiscordPlayer.class);
if (!event.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID()) if (!event.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID())
/* && !(event.getMessage().getChannel().isPrivate() && privatechat) */) && !(event.getMessage().getChannel().isPrivate() && user.minecraftChat().get()
&& !DiscordPlugin.checkIfSomeoneIsTestingWhileWeArent()))
return; return;
lastmessage = null; resetLastMessage();
lastlist++; lastlist++;
if (author.isBot()) if (author.isBot())
return; return;
@ -115,23 +150,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
String dmessage = event.getMessage().getContent(); String dmessage = event.getMessage().getContent();
synchronized (this) { synchronized (this) {
try { try {
DiscordPlayer dp = ChromaGamerBase.getUser(author.getStringID(), DiscordPlayer.class); final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), author, user);
final DiscordSenderBase dsender;
Player mcp = null; // Offline players can't really run commands, or can they?
final String cid;
if ((cid = dp.getConnectedID(TBMCPlayer.class)) != null // Connected?
&& (mcp = Bukkit.getPlayer(UUID.fromString(cid))) != null) { // Execute as ingame player
if (!ConnectedSenders.containsKey(author.getStringID()))
ConnectedSenders.put(author.getStringID(),
new DiscordPlayerSender(author, event.getMessage().getChannel(), mcp));
dsender = ConnectedSenders.get(author.getStringID());
} else {
TBMCPlayer p = dp.getAs(TBMCPlayer.class);
if (!UnconnectedSenders.containsKey(author.getStringID()))
UnconnectedSenders.put(author.getStringID(), new DiscordSender(author,
event.getMessage().getChannel(), p == null ? null : p.PlayerName().get())); // Display the playername, if found
dsender = UnconnectedSenders.get(author.getStringID());
}
for (IUser u : event.getMessage().getMentions()) { for (IUser u : event.getMessage().getMentions()) {
dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting
@ -140,11 +159,15 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
} }
if (dmessage.startsWith("/")) { if (dmessage.startsWith("/")) {
DiscordPlugin.perform(() -> {
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
event.getMessage().delete();
});
final String cmd = dmessage.substring(1).toLowerCase(); final String cmd = dmessage.substring(1).toLowerCase();
if (mcp == null && !Arrays.stream(UnconnectedCmds) if (dsender instanceof DiscordSender && !Arrays.stream(UnconnectedCmds)
.anyMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) { .anyMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) {
// Command not whitelisted // Command not whitelisted
DiscordPlugin.sendMessageToChannel(event.getMessage().getChannel(), // TODO dsender.sendMessage( // TODO
"Sorry, you need to be online on the server and have your accounts connected, you can only access these commands:\n" "Sorry, you need to be online on the server and have your accounts connected, you can only access these commands:\n"
+ Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc) + Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc)
.collect(Collectors.joining(", ")) .collect(Collectors.joining(", "))
@ -163,12 +186,16 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
} else } else
Bukkit.dispatchCommand(dsender, cmd); Bukkit.dispatchCommand(dsender, cmd);
lastlistp = (short) Bukkit.getOnlinePlayers().size(); lastlistp = (short) Bukkit.getOnlinePlayers().size();
if (!event.getMessage().isDeleted())
event.getMessage().delete();
} else { } else {
TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0)
dmessage + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage() TBMCChatAPI.SendChatMessage(Channel.GlobalChat, dsender, "pinned a message on Discord."); // TODO: Not chat message
.getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n")) else
TBMCChatAPI
.SendChatMessage(Channel.GlobalChat,
dsender, dmessage
+ (event.getMessage().getAttachments().size() > 0
? "\n" + event.getMessage().getAttachments().stream()
.map(a -> a.getUrl()).collect(Collectors.joining("\n"))
: "")); : ""));
event.getMessage().getChannel().getMessageHistory().stream().forEach(m -> { event.getMessage().getChannel().getMessageHistory().stream().forEach(m -> {
try { try {
@ -187,4 +214,23 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
} }
} }
} }
private DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) {
final DiscordSenderBase dsender;
Player mcp = null; // Offline players can't really run commands, or can they? No, they can't, really.
final String cid;
if ((cid = dp.getConnectedID(TBMCPlayer.class)) != null // Connected?
&& (mcp = Bukkit.getPlayer(UUID.fromString(cid))) != null) { // Execute as ingame player
if (!ConnectedSenders.containsKey(author.getStringID()))
ConnectedSenders.put(author.getStringID(), new DiscordPlayerSender(author, channel, mcp));
dsender = ConnectedSenders.get(author.getStringID());
} else {
TBMCPlayer p = dp.getAs(TBMCPlayer.class);
if (!UnconnectedSenders.containsKey(author.getStringID()))
UnconnectedSenders.put(author.getStringID(),
new DiscordSender(author, channel, p == null ? null : p.PlayerName().get())); // Display the playername, if found
dsender = UnconnectedSenders.get(author.getStringID());
}
return dsender;
}
} }

View file

@ -0,0 +1,317 @@
package buttondevteam.discordplugin.playerfaker;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Bukkit;
import org.bukkit.EntityEffect;
import org.bukkit.Location;
import org.bukkit.Server;
import org.bukkit.World;
import org.bukkit.block.PistonMoveReaction;
import org.bukkit.entity.Entity;
import org.bukkit.event.entity.EntityDamageEvent;
import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.ServerOperator;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import buttondevteam.discordplugin.DiscordSenderBase;
import lombok.Getter;
import lombok.Setter;
import lombok.experimental.Delegate;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
@Getter
@Setter
public abstract class DiscordEntity extends DiscordSenderBase implements Entity {
protected DiscordEntity(IUser user, IChannel channel, int entityId, UUID uuid) {
super(user, channel);
this.entityId = entityId;
uniqueId = uuid;
}
private HashMap<String, MetadataValue> metadata = new HashMap<String, MetadataValue>();
@Delegate
private PermissibleBase perm = new PermissibleBase(new ServerOperator() {
private @Getter @Setter boolean op;
});
private Location location;
private Vector velocity;
private final int entityId;
private EntityDamageEvent lastDamageCause;
private final Set<String> scoreboardTags = new HashSet<String>();
private final UUID uniqueId;
@Override
public void setMetadata(String metadataKey, MetadataValue newMetadataValue) {
metadata.put(metadataKey, newMetadataValue);
}
@Override
public List<MetadataValue> getMetadata(String metadataKey) {
return Arrays.asList(metadata.get(metadataKey)); // Who needs multiple data anyways
}
@Override
public boolean hasMetadata(String metadataKey) {
return metadata.containsKey(metadataKey);
}
@Override
public void removeMetadata(String metadataKey, Plugin owningPlugin) {
metadata.remove(metadataKey);
}
@Override
public Location getLocation(Location loc) {
if (loc != null) {
loc.setWorld(getWorld());
loc.setX(location.getX());
loc.setY(location.getY());
loc.setZ(location.getZ());
loc.setYaw(location.getYaw());
loc.setPitch(location.getPitch());
}
return loc;
}
@Override
public double getHeight() {
return 0;
}
@Override
public double getWidth() {
return 0;
}
@Override
public boolean isOnGround() {
return false;
}
@Override
public World getWorld() {
return location.getWorld();
}
@Override
public boolean teleport(Location location) {
this.location = location;
return true;
}
@Override
public boolean teleport(Location location, TeleportCause cause) {
this.location = location;
return true;
}
@Override
public boolean teleport(Entity destination) {
this.location = destination.getLocation();
return true;
}
@Override
public boolean teleport(Entity destination, TeleportCause cause) {
this.location = destination.getLocation();
return true;
}
@Override
public List<Entity> getNearbyEntities(double x, double y, double z) {
return Arrays.asList();
}
@Override
public int getFireTicks() {
return 0;
}
@Override
public int getMaxFireTicks() {
return 0;
}
@Override
public void setFireTicks(int ticks) {
}
@Override
public void remove() {
}
@Override
public boolean isDead() { // Impossible to kill
return false;
}
@Override
public boolean isValid() {
return true;
}
@Override
public Server getServer() {
return Bukkit.getServer();
}
@Override
public Entity getPassenger() {
return null;
}
@Override
public boolean setPassenger(Entity passenger) {
return false;
}
@Override
public List<Entity> getPassengers() {
return Arrays.asList();
}
@Override
public boolean addPassenger(Entity passenger) {
return false;
}
@Override
public boolean removePassenger(Entity passenger) { // Don't support passengers
return false;
}
@Override
public boolean isEmpty() {
return true;
}
@Override
public boolean eject() {
return false;
}
@Override
public float getFallDistance() {
return 0;
}
@Override
public void setFallDistance(float distance) {
}
@Override
public int getTicksLived() {
return 1;
}
@Override
public void setTicksLived(int value) {
}
@Override
public void playEffect(EntityEffect type) {
}
@Override
public boolean isInsideVehicle() {
return false;
}
@Override
public boolean leaveVehicle() {
return false;
}
@Override
public Entity getVehicle() { // Don't support vehicles
return null;
}
@Override
public void setCustomNameVisible(boolean flag) {
}
@Override
public boolean isCustomNameVisible() {
return true;
}
@Override
public void setGlowing(boolean flag) {
}
@Override
public boolean isGlowing() {
return false;
}
@Override
public void setInvulnerable(boolean flag) {
}
@Override
public boolean isInvulnerable() {
return true;
}
@Override
public boolean isSilent() {
return true;
}
@Override
public void setSilent(boolean flag) {
}
@Override
public boolean hasGravity() {
return false;
}
@Override
public void setGravity(boolean gravity) {
}
@Override
public int getPortalCooldown() {
return 0;
}
@Override
public void setPortalCooldown(int cooldown) {
}
@Override
public boolean addScoreboardTag(String tag) {
return scoreboardTags.add(tag);
}
@Override
public boolean removeScoreboardTag(String tag) {
return scoreboardTags.remove(tag);
}
@Override
public PistonMoveReaction getPistonMoveReaction() {
return PistonMoveReaction.IGNORE;
}
@Override
public Entity.Spigot spigot() {
return new Entity.Spigot();
}
}

View file

@ -0,0 +1,205 @@
package buttondevteam.discordplugin.playerfaker;
import java.util.UUID;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.InventoryView;
import org.bukkit.inventory.InventoryView.Property;
import org.bukkit.inventory.ItemStack;
import org.bukkit.inventory.MainHand;
import org.bukkit.inventory.Merchant;
import org.bukkit.inventory.PlayerInventory;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
public abstract class DiscordHumanEntity extends DiscordLivingEntity implements HumanEntity {
protected DiscordHumanEntity(IUser user, IChannel channel, int entityId, UUID uuid) {
super(user, channel, entityId, uuid);
}
@Override
public PlayerInventory getInventory() { // TODO
return null;
}
@Override
public Inventory getEnderChest() {
// TODO Auto-generated method stub
return null;
}
@Override
public MainHand getMainHand() {
return MainHand.RIGHT;
}
@Override
public boolean setWindowProperty(Property prop, int value) {
return false;
}
@Override
public InventoryView getOpenInventory() {
// TODO Auto-generated method stub
return null;
}
@Override
public InventoryView openInventory(Inventory inventory) {
// TODO Auto-generated method stub
return null;
}
@Override
public InventoryView openWorkbench(Location location, boolean force) {
// TODO Auto-generated method stub
return null;
}
@Override
public InventoryView openEnchanting(Location location, boolean force) {
// TODO Auto-generated method stub
return null;
}
@Override
public void openInventory(InventoryView inventory) {
// TODO Auto-generated method stub
}
@Override
public InventoryView openMerchant(Villager trader, boolean force) {
// TODO Auto-generated method stub
return null;
}
@Override
public InventoryView openMerchant(Merchant merchant, boolean force) {
// TODO Auto-generated method stub
return null;
}
@Override
public void closeInventory() {
// TODO Auto-generated method stub
}
@Override
public ItemStack getItemInHand() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setItemInHand(ItemStack item) {
// TODO Auto-generated method stub
}
@Override
public ItemStack getItemOnCursor() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setItemOnCursor(ItemStack item) {
// TODO Auto-generated method stub
}
@Override
public boolean hasCooldown(Material material) {
// TODO Auto-generated method stub
return false;
}
@Override
public int getCooldown(Material material) {
// TODO Auto-generated method stub
return 0;
}
@Override
public void setCooldown(Material material, int ticks) {
// TODO Auto-generated method stub
}
@Override
public boolean isSleeping() {
// TODO Auto-generated method stub
return false;
}
@Override
public int getSleepTicks() {
// TODO Auto-generated method stub
return 0;
}
@Override
public GameMode getGameMode() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setGameMode(GameMode mode) {
// TODO Auto-generated method stub
}
@Override
public boolean isBlocking() {
// TODO Auto-generated method stub
return false;
}
@Override
public boolean isHandRaised() {
// TODO Auto-generated method stub
return false;
}
@Override
public int getExpToLevel() {
// TODO Auto-generated method stub
return 0;
}
@Override
public Entity getShoulderEntityLeft() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setShoulderEntityLeft(Entity entity) {
// TODO Auto-generated method stub
}
@Override
public Entity getShoulderEntityRight() {
// TODO Auto-generated method stub
return null;
}
@Override
public void setShoulderEntityRight(Entity entity) {
// TODO Auto-generated method stub
}
}

View file

@ -0,0 +1,303 @@
package buttondevteam.discordplugin.playerfaker;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
import org.bukkit.attribute.AttributeInstance;
import org.bukkit.block.Block;
import org.bukkit.entity.Entity;
import org.bukkit.entity.LivingEntity;
import org.bukkit.entity.Player;
import org.bukkit.entity.Projectile;
import org.bukkit.inventory.EntityEquipment;
import org.bukkit.inventory.ItemStack;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.util.Vector;
import lombok.Getter;
import lombok.Setter;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
public abstract class DiscordLivingEntity extends DiscordEntity implements LivingEntity {
protected DiscordLivingEntity(IUser user, IChannel channel, int entityId, UUID uuid) {
super(user, channel, entityId, uuid);
}
private @Getter EntityEquipment equipment = new DiscordEntityEquipment(this);
@Getter
@Setter
private static class DiscordEntityEquipment implements EntityEquipment {
private float leggingsDropChance;
private ItemStack leggings;
private float itemInOffHandDropChance;
private ItemStack itemInOffHand;
private float itemInMainHandDropChance;
private ItemStack itemInMainHand;
private float itemInHandDropChance;
private ItemStack itemInHand;
private float helmetDropChance;
private ItemStack helmet;
private float chestplateDropChance;
private ItemStack chestplate;
private float bootsDropChance;
private ItemStack boots;
private ItemStack[] armorContents = new ItemStack[0]; // TODO
private final Entity holder;
public DiscordEntityEquipment(Entity holder) {
this.holder = holder;
}
@Override
public void clear() {
armorContents = new ItemStack[0];
}
}
@Override
public AttributeInstance getAttribute(Attribute attribute) { // We don't support any attribute
return null;
}
@Override
public void damage(double amount) {
}
@Override
public void damage(double amount, Entity source) {
}
@Override
public double getHealth() {
return getMaxHealth();
}
@Override
public void setHealth(double health) {
}
@Override
public double getMaxHealth() {
return 100;
}
@Override
public void setMaxHealth(double health) {
}
@Override
public void resetMaxHealth() {
}
@Override
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile) {
return null;
}
@Override
public <T extends Projectile> T launchProjectile(Class<? extends T> projectile, Vector velocity) {
return null;
}
@Override
public double getEyeHeight() {
return 0;
}
@Override
public double getEyeHeight(boolean ignoreSneaking) {
return 0;
}
@Override
public Location getEyeLocation() {
return getLocation();
}
@Override
public List<Block> getLineOfSight(Set<Material> transparent, int maxDistance) {
return Arrays.asList();
}
@Override
public Block getTargetBlock(HashSet<Byte> transparent, int maxDistance) {
return null;
}
@Override
public Block getTargetBlock(Set<Material> transparent, int maxDistance) {
return null;
}
@Override
public List<Block> getLastTwoTargetBlocks(HashSet<Byte> transparent, int maxDistance) {
return Arrays.asList();
}
@Override
public List<Block> getLastTwoTargetBlocks(Set<Material> transparent, int maxDistance) {
return Arrays.asList();
}
@Override
public int getRemainingAir() {
return 100;
}
@Override
public void setRemainingAir(int ticks) {
}
@Override
public int getMaximumAir() {
return 100;
}
@Override
public void setMaximumAir(int ticks) {
}
@Override
public int getMaximumNoDamageTicks() {
return 100;
}
@Override
public void setMaximumNoDamageTicks(int ticks) {
}
@Override
public double getLastDamage() {
return 0;
}
@Override
public void setLastDamage(double damage) {
}
@Override
public int getNoDamageTicks() {
return 100;
}
@Override
public void setNoDamageTicks(int ticks) {
}
@Override
public Player getKiller() {
return null;
}
@Override
public boolean addPotionEffect(PotionEffect effect) {
return false;
}
@Override
public boolean addPotionEffect(PotionEffect effect, boolean force) {
return false;
}
@Override
public boolean addPotionEffects(Collection<PotionEffect> effects) {
return false;
}
@Override
public boolean hasPotionEffect(PotionEffectType type) {
return false;
}
@Override
public PotionEffect getPotionEffect(PotionEffectType type) {
return null;
}
@Override
public void removePotionEffect(PotionEffectType type) {
}
@Override
public Collection<PotionEffect> getActivePotionEffects() {
return Arrays.asList();
}
@Override
public boolean hasLineOfSight(Entity other) {
return false;
}
@Override
public boolean getRemoveWhenFarAway() {
return false;
}
@Override
public void setRemoveWhenFarAway(boolean remove) {
}
@Override
public void setCanPickupItems(boolean pickup) {
}
@Override
public boolean getCanPickupItems() {
return false;
}
@Override
public boolean isLeashed() {
return false;
}
@Override
public Entity getLeashHolder() throws IllegalStateException {
throw new IllegalStateException();
}
@Override
public boolean setLeashHolder(Entity holder) {
return false;
}
@Override
public boolean isGliding() {
return false;
}
@Override
public void setGliding(boolean gliding) {
}
@Override
public void setAI(boolean ai) {
}
@Override
public boolean hasAI() {
return false;
}
@Override
public void setCollidable(boolean collidable) {
}
@Override
public boolean isCollidable() {
return false;
}
}

View file

@ -1,11 +1,5 @@
package buttondevteam.DiscordPlugin; package buttondevteam.DiscordPlugin;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.apache.commons.lang.exception.ExceptionUtils;
import buttondevteam.lib.TBMCCoreAPI;
import junit.framework.Test; import junit.framework.Test;
import junit.framework.TestCase; import junit.framework.TestCase;
import junit.framework.TestSuite; import junit.framework.TestSuite;
@ -35,26 +29,6 @@ public class AppTest extends TestCase {
* Rigourous Test :-) * Rigourous Test :-)
*/ */
public void testApp() { public void testApp() {
/*String sourcemessage = "Test message";
Exception e = new Exception("Test exception");
StringBuilder sb = TBMCCoreAPI.IsTestServer() ? new StringBuilder()
: new StringBuilder("Coder role").append("\n");
sb.append(sourcemessage).append("\n");
sb.append("```").append("\n");
String stackTrace = Arrays.stream(ExceptionUtils.getStackTrace(e).split("\\n"))
.filter(s -> !(s.contains("\tat ") && ( //
s.contains("java.util") //
|| s.contains("java.lang") //
|| s.contains("net.minecraft.server") //
|| s.contains("sun.reflect") //
|| s.contains("org.bukkit") //
))).collect(Collectors.joining("\n"));
if (stackTrace.length() > 1800)
stackTrace = stackTrace.substring(0, 1800);
sb.append(stackTrace).append("\n");
sb.append("```");
System.out.println(sb.toString());
assertTrue(sb.toString().contains("Coder role"));*/
assertTrue(true); assertTrue(true);
} }
} }