Merge branch 'dev' (#54)

# Conflicts:
#	pom.xml
This commit is contained in:
Norbi Peti 2018-06-15 18:49:21 +02:00
commit b3259239e5
No known key found for this signature in database
GPG key ID: DBA4C4549A927E56
44 changed files with 820 additions and 501 deletions

2
.gitignore vendored Normal file → Executable file
View file

@ -131,7 +131,7 @@ publish/
*.publishproj
# NuGet Packages Directory
## TODO: If you have NuGet Package Restore enabled, uncomment the next line
## TO!DO: If you have NuGet Package Restore enabled, uncomment the next line
#packages/
# Windows Azure Build Output

0
.travis.yml Normal file → Executable file
View file

0
License.md Normal file → Executable file
View file

0
README.md Normal file → Executable file
View file

2
deploy.sh Normal file → Executable file
View file

@ -6,5 +6,5 @@ if [ $1 = 'production' ]; then
echo Production mode
echo $UPLOAD_KEY > upload_key
chmod 400 upload_key
yes | scp -B -i upload_key -o StrictHostKeyChecking=no $FILENAME travis@server.figytuna.com:/minecraft/main/plugins
yes | scp -B -i upload_key -o StrictHostKeyChecking=no $FILENAME travis@server.figytuna.com:/minecraft/main/pluginupdates
fi

9
pom.xml Normal file → Executable file
View file

@ -58,7 +58,7 @@
<exclude>org.spigotmc:spigot-api</exclude>
<exclude>com.github.TBMCPlugins.ButtonCore:ButtonCore</exclude>
<exclude>net.ess3:Essentials</exclude>
</excludes> <!-- TODO: http://stackoverflow.com/questions/28458058/maven-shade-plugin-exclude-a-dependency-and-all-its-transitive-dependencies -->
</excludes> <!-- http://stackoverflow.com/questions/28458058/maven-shade-plugin-exclude-a-dependency-and-all-its-transitive-dependencies -->
</artifactSet>
</configuration>
</execution>
@ -179,6 +179,7 @@
<groupId>net.ess3</groupId>
<artifactId>Essentials</artifactId>
<version>2.13.1</version>
<scope>provided</scope>
</dependency>
<dependency>
<groupId>com.github.xaanit</groupId>
@ -211,6 +212,10 @@
<version>2.6</version>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.vdurmont</groupId>
<artifactId>emoji-java</artifactId>
<version>4.0.0</version>
</dependency>
</dependencies>
</project>

View file

@ -1,19 +1,18 @@
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 org.bukkit.Bukkit;
import org.bukkit.entity.Player;
import org.bukkit.scheduler.BukkitScheduler;
import sx.blah.discord.api.internal.json.objects.EmbedObject;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.util.EmbedBuilder;
import java.awt.*;
import java.util.Arrays;
import java.util.stream.Collectors;
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)})
@ -47,7 +46,7 @@ public class ChromaBot {
}
/**
* Send a message to the chat channel and private chats.
* Send a message to the chat channels and private chats.
*
* @param message
* The message to send, duh
@ -73,7 +72,7 @@ public class ChromaBot {
}
/**
* Send a fancy message to the chat channel. This will show a bold text with a colored line.
* Send a fancy message to the chat channels. This will show a bold text with a colored line.
*
* @param message
* The message to send, duh
@ -86,7 +85,7 @@ public class ChromaBot {
}
/**
* Send a fancy message to the chat channel. This will show a bold text with a colored line.
* Send a fancy message to the chat channels. This will show a bold text with a colored line.
*
* @param message
* The message to send, duh
@ -101,7 +100,7 @@ public class ChromaBot {
}
/**
* Send a fancy message to the chat channel. This will show a bold text with a colored line.
* Send a fancy message to the chat channels. This will show a bold text with a colored line.
*
* @param message
* The message to send, duh
@ -118,7 +117,7 @@ public class ChromaBot {
}
/**
* Send a message to the chat channel. This will show a bold text with a colored line.
* Send a message to the chat channels. This will show a bold text with a colored line.
*
* @param message
* The message to send, duh

27
src/main/java/buttondevteam/discordplugin/DPUtils.java Normal file → Executable file
View file

@ -1,10 +1,15 @@
package buttondevteam.discordplugin;
import buttondevteam.lib.TBMCCoreAPI;
import org.bukkit.Bukkit;
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;
import javax.annotation.Nullable;
import java.util.concurrent.TimeUnit;
public final class DPUtils {
public static EmbedBuilder embedWithHead(EmbedBuilder builder, String playername) {
@ -33,11 +38,31 @@ public final class DPUtils {
/**
* Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode.
*/
@Nullable
public static <T> T perform(IRequest<T> action, long timeout, TimeUnit unit) {
if (DiscordPlugin.SafeMode)
return null;
if (Thread.currentThread() == DiscordPlugin.mainThread) // TODO: Ignore shutdown message <--
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
try {
return RequestBuffer.request(action).get(timeout, unit); // Let the pros handle this
} catch (Exception e) {
TBMCCoreAPI.SendException("Couldn't perform Discord action!", e);
return null;
}
}
/**
* Performs Discord actions, retrying when ratelimited. May return null if action fails too many times or in safe mode.
*/
@Nullable
public static <T> T perform(IRequest<T> action) {
if (DiscordPlugin.SafeMode)
return null;
// if (Thread.currentThread() == DiscordPlugin.mainThread) - TODO: Ignore shutdown message <--
if (Thread.currentThread() == DiscordPlugin.mainThread) // TODO: Ignore shutdown message <--
// throw new RuntimeException("Tried to wait for a Discord request on the main thread. This could cause lag.");
Bukkit.getLogger().warning("Waiting for a Discord request on the main thread!");
return RequestBuffer.request(action).get(); // Let the pros handle this
}

View file

@ -1,13 +1,13 @@
package buttondevteam.discordplugin;
import java.util.UUID;
import buttondevteam.discordplugin.playerfaker.DiscordFakePlayer;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
import lombok.Getter;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import java.util.UUID;
public class DiscordConnectedPlayer extends DiscordFakePlayer implements IMCPlayer<DiscordConnectedPlayer> {
private static int nextEntityId = 10000;
private @Getter VanillaCommandListener<DiscordConnectedPlayer> vanillaCmdListener;

View file

View file

@ -1,13 +1,7 @@
package buttondevteam.discordplugin;
import java.net.InetSocketAddress;
import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.UUID;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
import lombok.Getter;
import org.bukkit.*;
import org.bukkit.advancement.Advancement;
import org.bukkit.advancement.AdvancementProgress;
@ -24,18 +18,20 @@ import org.bukkit.inventory.*;
import org.bukkit.inventory.InventoryView.Property;
import org.bukkit.map.MapView;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.permissions.*;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import org.bukkit.potion.PotionEffect;
import org.bukkit.potion.PotionEffectType;
import org.bukkit.scoreboard.Scoreboard;
import org.bukkit.util.Vector;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
import lombok.Getter;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import java.net.InetSocketAddress;
import java.util.*;
@SuppressWarnings("deprecation")
public class DiscordPlayerSender extends DiscordSenderBase implements IMCPlayer<DiscordPlayerSender> {

View file

@ -1,8 +1,10 @@
package buttondevteam.discordplugin;
import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.discordplugin.listeners.*;
import buttondevteam.discordplugin.mccommands.DiscordMCCommandBase;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.ChromaGamerBase;
import com.google.common.io.Files;
@ -30,8 +32,9 @@ import sx.blah.discord.util.RequestBuffer;
import java.awt.*;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;
public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
@ -60,7 +63,6 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
plugin = this;
lastannouncementtime = getConfig().getLong("lastannouncementtime");
lastseentime = getConfig().getLong("lastseentime");
GameRoles = (List<String>) getConfig().getList("gameroles", new ArrayList<String>());
ClientBuilder cb = new ClientBuilder();
cb.withToken(Files.readFirstLine(new File("TBMC", "Token.txt"), StandardCharsets.UTF_8));
dc = cb.login();
@ -77,6 +79,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
public static IChannel genchannel;
public static IChannel chatchannel;
public static IChannel botroomchannel;
public static IChannel modlogchannel;
/**
* Don't send messages, just receive, the same channel is used when testing
*/
@ -109,6 +112,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
updatechannel = devServer.getChannelByID(233724163519414272L); // server-updates
devofficechannel = officechannel; // developers-office
modlogchannel = mainServer.getChannelByID(283840717275791360L); // modlog
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "Chromacraft");
} else {
botchannel = devServer.getChannelByID(239519012529111040L); // bot-room
@ -119,6 +123,7 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
officechannel = devServer.getChannelByID(219626707458457603L); // developers-office
updatechannel = botchannel;
devofficechannel = botchannel;// bot-room
modlogchannel = botchannel; // bot-room
dc.changePresence(StatusType.ONLINE, ActivityType.PLAYING, "testing");
}
if (botchannel == null || annchannel == null || genchannel == null || botroomchannel == null
@ -129,6 +134,27 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
task.cancel();
if (!sent) {
new ChromaBot(this).updatePlayerList();
GameRoles = mainServer.getRoles().stream().filter(this::isGameRole).map(IRole::getName).collect(Collectors.toList());
val chcons = getConfig().getConfigurationSection("chcons");
if (chcons != null) {
val chconkeys = chcons.getKeys(false);
for (val chconkey : chconkeys) {
val chcon = chcons.getConfigurationSection(chconkey);
val mcch = Channel.getChannels().stream().filter(ch -> ch.ID.equals(chcon.getString("mcchid"))).findAny();
val ch = dc.getChannelByID(chcon.getLong("chid"));
val did = chcon.getLong("did");
val dp = DiscordPlayer.getUser(Long.toString(did), DiscordPlayer.class);
val user = dc.fetchUser(did);
val dcp = new DiscordConnectedPlayer(user, ch, UUID.fromString(chcon.getString("mcuid")), chcon.getString("mcname"));
val groupid = chcon.getString("groupid");
if (!mcch.isPresent() || ch == null || user == null || groupid == null)
continue;
MCChatListener.addCustomChat(ch, groupid, mcch.get(), dp, user, dcp);
}
}
DiscordCommandBase.registerCommands();
if (getConfig().getBoolean("serverup", false)) {
ChromaBot.getInstance().sendMessage("", new EmbedBuilder().withColor(Color.YELLOW)
.withTitle("Server recovered from a crash - chat connected.").build());
@ -199,6 +225,14 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
}
}
public boolean isGameRole(IRole r) {
if (r.getGuild().getLongID() != mainServer.getLongID())
return false; //Only allow on the main server
val rc = new Color(149, 165, 166, 0);
return r.getColor().equals(rc)
&& r.getPosition() < mainServer.getRoleByID(234343495735836672L).getPosition(); //Below the ChromaBot role
}
/**
* Always true, except when running "stop" from console
*/
@ -211,8 +245,20 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
MCListener.callEventExcludingSome(new PlayerQuitEvent(entry.getValue(), ""));
getConfig().set("lastannouncementtime", lastannouncementtime);
getConfig().set("lastseentime", lastseentime);
getConfig().set("gameroles", GameRoles);
getConfig().set("serverup", false);
val chcons = MCChatListener.getCustomChats();
val chconsc = getConfig().createSection("chcons");
for (val chcon : chcons) {
val chconc = chconsc.createSection(chcon.channel.getStringID());
chconc.set("mcchid", chcon.mcchannel.ID);
chconc.set("chid", chcon.channel.getLongID());
chconc.set("did", chcon.user.getLongID());
chconc.set("mcuid", chcon.dcp.getUniqueId().toString());
chconc.set("mcname", chcon.dcp.getName());
chconc.set("groupid", chcon.groupID);
}
saveConfig();
MCChatListener.forAllMCChat(ch -> DiscordPlugin.sendMessageToChannelWait(ch, "",
new EmbedBuilder().withColor(Restart ? Color.ORANGE : Color.RED)
@ -225,10 +271,11 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
+ (Bukkit.getOnlinePlayers().size() == 1 ? " was " : " were ")
+ "asked *politely* to leave the server for a bit.")
: "")
.build()));
.build(), 5, TimeUnit.SECONDS));
ChromaBot.getInstance().updatePlayerList();
try {
SafeMode = true; // Stop interacting with Discord
MCChatListener.stop();
ChromaBot.delete();
dc.changePresence(StatusType.IDLE, ActivityType.PLAYING, "Chromacraft"); //No longer using the same account for testing
dc.logout();
@ -323,7 +370,15 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
return sendMessageToChannel(channel, message, embed, true);
}
public static IMessage sendMessageToChannelWait(IChannel channel, String message, EmbedObject embed, long timeout, TimeUnit unit) {
return sendMessageToChannel(channel, message, embed, true, timeout, unit);
}
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait) {
return sendMessageToChannel(channel, message, embed, wait, -1, null);
}
private static IMessage sendMessageToChannel(IChannel channel, String message, EmbedObject embed, boolean wait, long timeout, TimeUnit unit) {
if (message.length() > 1980) {
message = message.substring(0, 1980);
Bukkit.getLogger()
@ -337,9 +392,15 @@ public class DiscordPlugin extends JavaPlugin implements IListener<ReadyEvent> {
final String content = message;
RequestBuffer.IRequest<IMessage> r = () -> embed == null ? channel.sendMessage(content)
: channel.sendMessage(content, embed, false);
if (wait)
if (wait) {
if (unit != null)
return DPUtils.perform(r, timeout, unit);
else
return DPUtils.perform(r);
else {
} else {
if (unit != null)
plugin.getLogger().warning("Tried to set timeout for non-waiting call.");
else
DPUtils.performNoWait(r);
return null;
}

View file

View file

@ -1,15 +1,18 @@
package buttondevteam.discordplugin;
import java.util.Set;
import org.bukkit.Bukkit;
import org.bukkit.Server;
import org.bukkit.command.CommandSender;
import org.bukkit.permissions.*;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.permissions.Permission;
import org.bukkit.permissions.PermissionAttachment;
import org.bukkit.permissions.PermissionAttachmentInfo;
import org.bukkit.plugin.Plugin;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import java.util.Set;
public class DiscordSender extends DiscordSenderBase implements CommandSender {
private PermissibleBase perm = new PermissibleBase(this);

View file

@ -1,20 +1,19 @@
package buttondevteam.discordplugin;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.IDiscordSender;
import lombok.Getter;
import lombok.NonNull;
import lombok.Setter;
import org.bukkit.Bukkit;
import org.bukkit.scheduler.BukkitTask;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import java.util.Arrays;
import java.util.stream.Collectors;
public abstract class DiscordSenderBase implements IDiscordSender {
/**
* May be null.

View file

View file

@ -1,8 +1,7 @@
package buttondevteam.discordplugin;
import org.bukkit.entity.Player;
import buttondevteam.discordplugin.playerfaker.VanillaCommandListener;
import org.bukkit.entity.Player;
public interface IMCPlayer<T extends DiscordSenderBase & IMCPlayer<T>> extends Player {
VanillaCommandListener<T> getVanillaCmdListener();

View file

@ -1,10 +1,10 @@
package buttondevteam.discordplugin;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.UUID;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.lib.TBMCCoreAPI;
import com.mojang.authlib.GameProfile;
import lombok.val;
import net.minecraft.server.v1_12_R1.*;
import org.bukkit.Bukkit;
import org.bukkit.Location;
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
@ -12,33 +12,10 @@ 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;
import java.lang.reflect.Field;
import java.lang.reflect.Modifier;
import java.util.List;
import java.util.UUID;
public class PlayerListWatcher extends DedicatedPlayerList {
private DedicatedPlayerList plist;

View file

@ -0,0 +1,83 @@
package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.DiscordConnectedPlayer;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.listeners.MCChatListener;
import buttondevteam.lib.TBMCChannelConnectFakeEvent;
import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.player.TBMCPlayer;
import lombok.val;
import org.bukkit.Bukkit;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.Permissions;
import sx.blah.discord.util.PermissionUtils;
import java.util.Arrays;
public class ChannelconCommand extends DiscordCommandBase {
@Override
public String getCommandName() {
return "channelcon";
}
@Override
public boolean run(IMessage message, String args) {
if (args.length() == 0)
return false;
if (!PermissionUtils.hasPermissions(message.getChannel(), message.getAuthor(), Permissions.MANAGE_CHANNEL)) {
message.reply("you need to have manage permissions for this channel!");
return true;
}
if (MCChatListener.hasCustomChat(message.getChannel())) {
if (args.equalsIgnoreCase("remove")) {
if (MCChatListener.removeCustomChat(message.getChannel()))
message.reply("channel connection removed.");
else
message.reply("wait what, couldn't remove channel connection.");
return true;
}
message.reply("this channel is already connected to a Minecraft channel. Use `@ChromaBot channelcon remove` to remove it.");
return true;
}
val chan = Channel.getChannels().stream().filter(ch -> ch.ID.equalsIgnoreCase(args) || (ch.IDs != null && Arrays.stream(ch.IDs).anyMatch(cid -> cid.equalsIgnoreCase(args)))).findAny();
if (!chan.isPresent()) { //TODO: Red embed that disappears over time (kinda like the highlight messages in OW)
message.reply("MC channel with ID '" + args + "' not found! The ID is the command for it without the /.");
return true;
}
val dp = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class);
val chp = dp.getAs(TBMCPlayer.class);
if (chp == null) {
message.reply("you need to connect your Minecraft account. On our server in #bot do /connect <MCname>");
return true;
}
DiscordConnectedPlayer dcp = new DiscordConnectedPlayer(message.getAuthor(), message.getChannel(), chp.getUUID(), Bukkit.getOfflinePlayer(chp.getUUID()).getName());
val ev = new TBMCChannelConnectFakeEvent(dcp, chan.get());
//Using a fake player with no login/logout, should be fine for this event
String groupid = ev.getGroupID(ev.getSender()); //We're not trying to send in a specific group, we want to know which group the user belongs to (so not getGroupID())
if (groupid == null) {
message.reply("sorry, that didn't work. You cannot use that Minecraft channel.");
return true;
}
if (MCChatListener.getCustomChats().stream().anyMatch(cc -> cc.groupID.equals(groupid) && cc.mcchannel.ID.equals(chan.get().ID))) {
message.reply("sorry, this MC chat is already connected to a different channel, multiple channels are not supported atm.");
return true;
}
MCChatListener.addCustomChat(message.getChannel(), groupid, ev.getChannel(), dp, message.getAuthor(), dcp);
message.reply("alright, connection made to group `" + groupid + "`!");
return true;
}
@Override
public String[] getHelpText() {
return new String[]{ //
"---- Channel connect ---", //
"This command allows you to connect a Minecraft channel to a Discord channel (just like how the global chat is connected to #minecraft-chat).", //
"You need to have access to the MC channel and have manage permissions on the Discord channel.", //
"You also need to have your Minecraft account connected. In #bot use /connect <mcname>.", //
"Call this command from the channel you want to use. Usage: @ChromaBot channelcon <mcchannel>", //
"To remove a connection use @ChromaBot channelcon remove in the channel.", //
"Mentioning the bot is needed in this case because the / prefix only works in #bot.", //
"Invite link: <https://discordapp.com/oauth2/authorize?client_id=226443037893591041&scope=bot&permissions=268509264>" //
};
}
}

View file

@ -1,16 +1,14 @@
package buttondevteam.discordplugin.commands;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import com.google.common.collect.HashBiMap;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCCoreAPI;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import com.google.common.collect.HashBiMap;
import org.bukkit.Bukkit;
import org.bukkit.OfflinePlayer;
import org.bukkit.entity.Player;
import sx.blah.discord.handle.obj.IMessage;
public class ConnectCommand extends DiscordCommandBase {
@ -27,15 +25,13 @@ public class ConnectCommand extends DiscordCommandBase {
public static HashBiMap<String, String> WaitingToConnect = HashBiMap.create();
@Override
public void run(IMessage message, String args) {
if (args.length() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Usage: connect <Minecraftname>");
return;
}
public boolean run(IMessage message, String args) {
if (args.length() == 0)
return true;
if (args.contains(" ")) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Too many arguments.\nUsage: connect <Minecraftname>");
return;
return true;
}
if (WaitingToConnect.inverse().containsKey(message.getAuthor().getStringID())) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
@ -46,13 +42,13 @@ public class ConnectCommand extends DiscordCommandBase {
OfflinePlayer p = Bukkit.getOfflinePlayer(args);
if (p == null) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "The specified Minecraft player cannot be found");
return;
return true;
}
try (TBMCPlayer pl = TBMCPlayerBase.getPlayer(p.getUniqueId(), TBMCPlayer.class)) {
DiscordPlayer dp = pl.getAs(DiscordPlayer.class);
if (dp != null && message.getAuthor().getStringID().equals(dp.getDiscordID())) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "You already have this account connected.");
return;
return true;
}
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while connecting a Discord account!", e);
@ -60,11 +56,12 @@ public class ConnectCommand extends DiscordCommandBase {
}
WaitingToConnect.put(p.getName(), message.getAuthor().getStringID());
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Pending connection - accept connection in Minecraft from the account " + args
+ " before the server gets restarted. You can also adjust the Minecraft name you want to connect to with the same command.");
"Alright! Now accept the connection in Minecraft from the account " + args
+ " before the next server restart. You can also adjust the Minecraft name you want to connect to with the same command.");
if (p.isOnline())
((Player) p).sendMessage("§bTo connect with the Discord account " + message.getAuthor().getName() + "#"
+ message.getAuthor().getDiscriminator() + " do /discord accept");
return true;
}
@Override

View file

@ -0,0 +1,26 @@
package buttondevteam.discordplugin.commands;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.listeners.CommandListener;
import sx.blah.discord.handle.obj.IMessage;
public class DebugCommand extends DiscordCommandBase {
@Override
public String getCommandName() {
return "debug";
}
@Override
public boolean run(IMessage message, String args) {
if (message.getAuthor().hasRole(DiscordPlugin.mainServer.getRoleByID(126030201472811008L)))
message.reply("Debug " + (CommandListener.debug() ? "enabled" : "disabled"));
else
message.reply("You need to be a moderator to use this command.");
return true;
}
@Override
public String[] getHelpText() {
return new String[]{"Switches debug mode."};
}
}

View file

@ -1,29 +1,36 @@
package buttondevteam.discordplugin.commands;
import java.util.HashMap;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCCoreAPI;
import sx.blah.discord.handle.obj.IMessage;
import java.util.Arrays;
import java.util.HashMap;
import java.util.stream.Collectors;
import static buttondevteam.discordplugin.listeners.CommandListener.debug;
public abstract class DiscordCommandBase {
public abstract String getCommandName();
public abstract void run(IMessage message, String args);
public abstract boolean run(IMessage message, String args);
public abstract String[] getHelpText();
static final HashMap<String, DiscordCommandBase> commands = new HashMap<String, DiscordCommandBase>();
static {
public static void registerCommands() {
commands.put("connect", new ConnectCommand()); // TODO: API for adding commands?
commands.put("userinfo", new UserinfoCommand());
commands.put("help", new HelpCommand());
commands.put("role", new RoleCommand());
commands.put("mcchat", new MCChatCommand());
commands.put("channelcon", new ChannelconCommand());
commands.put("debug", new DebugCommand());
}
public static void runCommand(String cmd, String args, IMessage message) {
debug("F"); //Not sure if needed
DiscordCommandBase command = commands.get(cmd);
if (command == null) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
@ -32,12 +39,19 @@ public abstract class DiscordCommandBase {
+ "help' for help");
return;
}
debug("G");
try {
command.run(message, args);
if (!command.run(message, args))
DiscordPlugin.sendMessageToChannel(message.getChannel(), Arrays.stream(command.getHelpText()).collect(Collectors.joining("\n")));
} catch (Exception e) {
TBMCCoreAPI.SendException("An error occured while executing command " + cmd + "!", e);
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"An internal error occured while executing this command. For more technical details see the server-issues channel on the dev Discord.");
}
debug("H");
}
protected String[] splitargs(String args) {
return args.split("\\s+");
}
}

View file

@ -1,11 +1,11 @@
package buttondevteam.discordplugin.commands;
import java.util.Arrays;
import java.util.stream.Collectors;
import buttondevteam.discordplugin.DiscordPlugin;
import sx.blah.discord.handle.obj.IMessage;
import java.util.Arrays;
import java.util.stream.Collectors;
public class HelpCommand extends DiscordCommandBase {
@Override
@ -14,7 +14,7 @@ public class HelpCommand extends DiscordCommandBase {
}
@Override
public void run(IMessage message, String args) {
public boolean run(IMessage message, String args) {
DiscordCommandBase argdc;
if (args.length() == 0)
DiscordPlugin.sendMessageToChannel(message.getChannel(),
@ -24,6 +24,7 @@ public class HelpCommand extends DiscordCommandBase {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
(argdc = DiscordCommandBase.commands.get(args)) == null ? "Command not found: " + args
: Arrays.stream(argdc.getHelpText()).collect(Collectors.joining("\n")));
return true;
}
@Override

View file

@ -14,23 +14,23 @@ public class MCChatCommand extends DiscordCommandBase {
}
@Override
public void run(IMessage message, String args) {
public boolean run(IMessage message, String args) {
if (!message.getChannel().isPrivate()) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"This command can only be issued in a direct message with the bot.");
return;
return true;
}
try (final DiscordPlayer user = DiscordPlayer.getUser(message.getAuthor().getStringID(), DiscordPlayer.class)) {
boolean mcchat = !user.isMinecraftChatEnabled();
MCChatListener.privateMCChat(message.getChannel(), mcchat, message.getAuthor(), user);
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Minecraft chat " + (mcchat //
? "enabled. Use '" + message.getClient().getOurUser().mention()
+ " mcchat' (with the mention) to disable." //
? "enabled. Use '/mcchat' again to turn it off." //
: "disabled."));
} catch (Exception e) {
TBMCCoreAPI.SendException("Error while setting mcchat for user" + message.getAuthor().getName(), e);
}
return true;
}
@Override

View file

@ -6,7 +6,6 @@ import buttondevteam.lib.TBMCCoreAPI;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IRole;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
@ -18,17 +17,14 @@ public class RoleCommand extends DiscordCommandBase {
}
@Override
public void run(IMessage message, String args) {
final String usagemsg = "Subcommands: add, remove, list";
if (args.length() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), usagemsg);
return;
}
String[] argsa = args.split(" ");
public boolean run(IMessage message, String args) {
if (args.length() == 0)
return false;
String[] argsa = splitargs(args);
if (argsa[0].equalsIgnoreCase("add")) {
final IRole role = checkAndGetRole(message, argsa, "This command adds a game role to your account.");
if (role == null)
return;
return true;
try {
DPUtils.perform(() -> message.getAuthor().addRole(role));
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Added game role.");
@ -39,7 +35,7 @@ public class RoleCommand extends DiscordCommandBase {
} else if (argsa[0].equalsIgnoreCase("remove")) {
final IRole role = checkAndGetRole(message, argsa, "This command removes a game role from your account.");
if (role == null)
return;
return true;
try {
DPUtils.perform(() -> message.getAuthor().removeRole(role));
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Removed game role.");
@ -48,35 +44,14 @@ public class RoleCommand extends DiscordCommandBase {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while removing the role.");
}
} else if (argsa[0].equalsIgnoreCase("list")) {
listRoles(message);
} else return false;
return true;
}
private void listRoles(IMessage message) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"List of game roles:\n" + DiscordPlugin.GameRoles.stream().collect(Collectors.joining("\n")));
} else if (argsa[0].equalsIgnoreCase("admin") && argsa.length > 1 && argsa[1].equalsIgnoreCase("addrole")) {
if (message.getAuthor().getRolesForGuild(DiscordPlugin.mainServer).stream()
.noneMatch(r -> r.getLongID() == 126030201472811008L)) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"You need to be a moderator to use this command.");
return;
}
if (argsa.length < 3) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Add a role to the game role list.\nUsage: " + argsa[0] + " <rolename>");
return;
}
String rolename = Arrays.stream(argsa).skip(2).collect(Collectors.joining(" "));
final List<IRole> roles = (TBMCCoreAPI.IsTestServer() ? DiscordPlugin.devServer : DiscordPlugin.mainServer)
.getRolesByName(rolename);
if (roles.size() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "That role cannot be found on Discord.");
return;
}
if (roles.size() > 1) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"There are more roles with this name. Why are there more roles with this name?");
return;
}
DiscordPlugin.GameRoles.add(roles.get(0).getName());
DiscordPlugin.sendMessageToChannel(message.getChannel(), "Game role added.");
}
"List of game roles:\n" + DiscordPlugin.GameRoles.stream().sorted().collect(Collectors.joining("\n")));
}
private IRole checkAndGetRole(IMessage message, String[] argsa, String usage) {
@ -88,13 +63,11 @@ public class RoleCommand extends DiscordCommandBase {
for (int i = 2; i < argsa.length; i++)
rolename += " " + argsa[i];
if (!DiscordPlugin.GameRoles.contains(rolename)) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"That game role cannot be found.\nList of game roles:\n"
+ DiscordPlugin.GameRoles.stream().collect(Collectors.joining("\n")));
DiscordPlugin.sendMessageToChannel(message.getChannel(), "That game role cannot be found.");
listRoles(message);
return null;
}
final List<IRole> roles = (TBMCCoreAPI.IsTestServer() ? DiscordPlugin.devServer : DiscordPlugin.mainServer)
.getRolesByName(rolename);
final List<IRole> roles = DiscordPlugin.mainServer.getRolesByName(rolename);
if (roles.size() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"The specified role cannot be found on Discord! Removing from the list.");
@ -114,7 +87,7 @@ public class RoleCommand extends DiscordCommandBase {
return new String[]{ //
"Add or remove game roles from yourself.", //
"Usage: role add|remove <name> or role list", //
"Mods can use role addrole <name> to add a role as a game role" };
};
}
}

View file

@ -1,8 +1,5 @@
package buttondevteam.discordplugin.commands;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCCoreAPI;
@ -11,6 +8,10 @@ import buttondevteam.lib.player.ChromaGamerBase.InfoTarget;
import sx.blah.discord.handle.obj.IMessage;
import sx.blah.discord.handle.obj.IUser;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
public class UserinfoCommand extends DiscordCommandBase {
@Override
@ -19,12 +20,7 @@ public class UserinfoCommand extends DiscordCommandBase {
}
@Override
public void run(IMessage message, String args) {
if (args.contains(" ")) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Too many arguments.\nUsage: userinfo [username/nickname[#tag]/ping]\nExamples:\nuserinfo ChromaBot\nuserinfo ChromaBot#6338\nuserinfo @ChromaBot#6338");
return;
}
public boolean run(IMessage message, String args) {
IUser target = null;
if (args.length() == 0)
target = message.getAuthor();
@ -39,7 +35,7 @@ public class UserinfoCommand extends DiscordCommandBase {
if (targets.size() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"The user cannot be found (by name): " + args);
return;
return true;
}
for (IUser ptarget : targets) {
if (ptarget.getDiscriminator().equalsIgnoreCase(targettag[1])) {
@ -51,19 +47,19 @@ public class UserinfoCommand extends DiscordCommandBase {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"The user cannot be found (by discriminator): " + args + "(Found " + targets.size()
+ " users with the name.)");
return;
return true;
}
} else {
final List<IUser> targets = getUsers(message, args);
if (targets.size() == 0) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"The user cannot be found on Discord: " + args);
return;
return true;
}
if (targets.size() > 1) {
DiscordPlugin.sendMessageToChannel(message.getChannel(),
"Multiple users found with that (nick)name. Please specify the whole tag, like ChromaBot#6338 or use a ping.");
return;
return true;
}
target = targets.get(0);
}
@ -76,6 +72,7 @@ public class UserinfoCommand extends DiscordCommandBase {
DiscordPlugin.sendMessageToChannel(message.getChannel(), "An error occured while getting the user!");
TBMCCoreAPI.SendException("Error while getting info about " + target.getName() + "!", e);
}
return true;
}
private List<IUser> getUsers(IMessage message, String args) {
@ -93,7 +90,8 @@ public class UserinfoCommand extends DiscordCommandBase {
return new String[] { //
"---- User information ----", //
"Shows some information about users, from Discord, from Minecraft or from Reddit if they have these accounts connected.", //
"Usage: userinfo <Discordname>" //
"If used without args, shows your info.", //
"Usage: userinfo [username/nickname[#tag]/ping]\nExamples:\nuserinfo ChromaBot\nuserinfo ChromaBot#6338\nuserinfo @ChromaBot#6338" //
};
}

View file

@ -1,12 +1,11 @@
package buttondevteam.discordplugin.listeners;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import buttondevteam.discordplugin.DPUtils;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.PluginUpdater;
import buttondevteam.lib.TBMCCoreAPI;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class AutoUpdaterListener implements Listener {
@EventHandler

View file

@ -5,9 +5,13 @@ import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.discordplugin.commands.DiscordCommandBase;
import buttondevteam.lib.TBMCCoreAPI;
import lombok.val;
import org.bukkit.Bukkit;
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.MessageReceivedEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleCreateEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleDeleteEvent;
import sx.blah.discord.handle.impl.events.guild.role.RoleUpdateEvent;
import sx.blah.discord.handle.impl.events.user.PresenceUpdateEvent;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IMessage;
@ -46,6 +50,7 @@ public class CommandListener {
private static final Random serverReadyRandom = new Random();
private static final ArrayList<Short> usableServerReadyStrings = new ArrayList<Short>(serverReadyStrings.length) {
private static final long serialVersionUID = 2213771460909848770L;
{
createUsableServerReadyStrings(this);
}
@ -67,7 +72,8 @@ public class CommandListener {
if (event.getMessage().getAuthor().isBot())
return;
final IChannel channel = event.getMessage().getChannel();
if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID()))
if (!channel.getStringID().equals(DiscordPlugin.botchannel.getStringID())
&& (!event.getMessage().getContent().contains("channelcon") || MCChatListener.hasCustomChat(channel))) //Allow channelcon in other servers but avoid double handling when it's enabled
return;
if (channel.getStringID().equals(DiscordPlugin.chatchannel.getStringID()))
return; // The chat code already handles this - Right now while testing botchannel is the same as chatchannel
@ -89,7 +95,9 @@ public class CommandListener {
DiscordPlugin.sendMessageToChannel(event.getMessage().getChannel(), serverReadyStrings[next]);
return;
}
if (!event.getMessage().getChannel().isPrivate()) //
if (!event.getMessage().getChannel().isPrivate()
&& !(event.getMessage().getContent().startsWith("/")
&& event.getChannel().getStringID().equals(DiscordPlugin.botchannel.getStringID()))) //
return;
if (DiscordPlayer.getUser(event.getAuthor().getStringID(), DiscordPlayer.class)
.isMinecraftChatEnabled())
@ -121,21 +129,43 @@ public class CommandListener {
lasttime = TimeUnit.NANOSECONDS.toHours(System.nanoTime());
}
}
}, (IListener<RoleCreateEvent>) event -> {
Bukkit.getScheduler().runTaskLaterAsynchronously(DiscordPlugin.plugin, () -> {
if (event.getRole().isDeleted() || !DiscordPlugin.plugin.isGameRole(event.getRole()))
return; //Deleted or not a game role
DiscordPlugin.GameRoles.add(event.getRole().getName());
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getRole().getName() + " as game role. If you don't want this, change the role's color from the default.");
}, 100);
}, (IListener<RoleDeleteEvent>) event -> {
if (DiscordPlugin.GameRoles.remove(event.getRole().getName()))
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getRole().getName() + " as a game role.");
}, (IListener<RoleUpdateEvent>) event -> { //Role update event
if (!DiscordPlugin.plugin.isGameRole(event.getNewRole())) {
if (DiscordPlugin.GameRoles.remove(event.getOldRole().getName()))
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Removed " + event.getOldRole().getName() + " as a game role because it's color changed.");
} else {
boolean removed = DiscordPlugin.GameRoles.remove(event.getOldRole().getName()); //Regardless of whether it was a game role
DiscordPlugin.GameRoles.add(event.getNewRole().getName()); //Add it because it has no color
if (removed)
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Changed game role from " + event.getOldRole().getName() + " to " + event.getNewRole().getName() + ".");
else
DiscordPlugin.sendMessageToChannel(DiscordPlugin.modlogchannel, "Added " + event.getNewRole().getName() + " as game role because it has the default color.");
}
}};
}
/**
* Runs a ChromaBot command.
*
* @param message
* The Discord message
* @param mentionedonly
* Only run the command if ChromaBot is mentioned at the start of the message
* @param message The Discord message
* @param mentionedonly Only run the command if ChromaBot is mentioned at the start of the message
* @return Whether it ran the command (always true if mentionedonly is false)
*/
public static boolean runCommand(IMessage message, boolean mentionedonly) {
debug("A");
if (DiscordPlugin.SafeMode)
return true;
debug("B");
final StringBuilder cmdwithargs = new StringBuilder(message.getContent());
final String mention = DiscordPlugin.dc.getOurUser().mention(false);
final String mentionNick = DiscordPlugin.dc.getOurUser().mention(true);
@ -143,26 +173,41 @@ public class CommandListener {
gotmention = checkanddeletemention(cmdwithargs, mentionNick, message) || gotmention;
for (String mentionRole : (Iterable<String>) message.getRoleMentions().stream().filter(r -> DiscordPlugin.dc.getOurUser().hasRole(r)).map(r -> r.mention())::iterator)
gotmention = checkanddeletemention(cmdwithargs, mentionRole, message) || gotmention; // Delete all mentions
debug("C");
if (mentionedonly && !gotmention) {
message.getChannel().setTypingStatus(false);
return false;
}
debug("D");
message.getChannel().setTypingStatus(true);
int index = cmdwithargs.indexOf(" ");
String cmdwithargsString = cmdwithargs.toString().trim(); //Remove spaces between mention and command
int index = cmdwithargsString.indexOf(" ");
String cmd;
String args;
if (index == -1) {
cmd = cmdwithargs.toString();
cmd = cmdwithargsString;
args = "";
} else {
cmd = cmdwithargs.substring(0, index);
args = cmdwithargs.substring(index + 1);
cmd = cmdwithargsString.substring(0, index);
args = cmdwithargsString.substring(index + 1).trim(); //In case there are multiple spaces
}
debug("E");
DiscordCommandBase.runCommand(cmd.toLowerCase(), args, message);
message.getChannel().setTypingStatus(false);
return true;
}
private static boolean debug = false;
public static void debug(String debug) {
if (CommandListener.debug) //Debug
System.out.println(debug);
}
public static boolean debug() {
return debug = !debug;
}
private static boolean checkanddeletemention(StringBuilder cmdwithargs, String mention, IMessage message) {
if (message.getContent().startsWith(mention)) // TODO: Resolve mentions: Compound arguments, either a mention or text
if (cmdwithargs.length() > mention.length() + 1)
@ -170,8 +215,11 @@ public class CommandListener {
cmdwithargs.charAt(mention.length()) == ' ' ? mention.length() + 1 : mention.length());
else
cmdwithargs.replace(0, cmdwithargs.length(), "help");
else
else {
if (cmdwithargs.length() > 0 && cmdwithargs.charAt(0) == '/')
cmdwithargs.deleteCharAt(0); //Don't treat / as mention, mentions can be used in public mcchat
return false;
}
if (cmdwithargs.length() == 0)
cmdwithargs.replace(0, cmdwithargs.length(), "help");
return true;

View file

@ -1,9 +1,9 @@
package buttondevteam.discordplugin.listeners;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
import buttondevteam.discordplugin.DiscordPlugin;
import buttondevteam.lib.TBMCDebugMessageEvent;
import org.bukkit.event.EventHandler;
import org.bukkit.event.Listener;
public class DebugMessageListener implements Listener{
@EventHandler

View file

@ -23,8 +23,8 @@ public class ExceptionListener implements Listener {
return;
if (lastthrown.stream()
.anyMatch(ex -> Arrays.equals(e.getException().getStackTrace(), ex.getStackTrace())
&& e.getException().getMessage() == null ? ex.getMessage() == null
: e.getException().getMessage().equals(ex.getMessage())) // e.Exception.Message==ex.Message
&& (e.getException().getMessage() == null ? ex.getMessage() == null
: e.getException().getMessage().equals(ex.getMessage()))) // e.Exception.Message==ex.Message
&& lastsourcemsg.contains(e.getSourceMessage()))
return;
SendException(e.getException(), e.getSourceMessage());

View file

@ -10,6 +10,8 @@ import buttondevteam.lib.chat.Channel;
import buttondevteam.lib.chat.ChatRoom;
import buttondevteam.lib.chat.TBMCChatAPI;
import buttondevteam.lib.player.TBMCPlayer;
import com.vdurmont.emoji.EmojiParser;
import lombok.NonNull;
import lombok.RequiredArgsConstructor;
import lombok.val;
import org.bukkit.Bukkit;
@ -33,9 +35,10 @@ import sx.blah.discord.util.MissingPermissionsException;
import java.awt.*;
import java.time.Instant;
import java.util.*;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;
import java.util.stream.Collectors;
@ -45,6 +48,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
private BukkitTask sendtask;
private LinkedBlockingQueue<AbstractMap.SimpleEntry<TBMCChatEvent, Instant>> sendevents = new LinkedBlockingQueue<>();
private Runnable sendrunnable;
private static Thread sendthread;
@EventHandler // Minecraft
public void onMCChat(TBMCChatEvent ev) {
@ -54,7 +58,9 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
if (sendtask != null)
return;
sendrunnable = () -> {
sendthread = Thread.currentThread();
processMCToDiscord();
if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
};
sendtask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, sendrunnable);
@ -117,27 +123,41 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
}
};
// Checks if the given channel is different than where the message was sent from
// Or if it was from MC
Predicate<IChannel> isdifferentchannel = ch -> !(e.getSender() instanceof DiscordSenderBase)
|| ((DiscordSenderBase) e.getSender()).getChannel().getLongID() != ch.getLongID();
if ((e.getChannel() == Channel.GlobalChat || e.getChannel().ID.equals("rp"))
&& isdifferentchannel.test(DiscordPlugin.chatchannel))
&& (e.isFromcmd() || isdifferentchannel.test(DiscordPlugin.chatchannel)))
doit.accept(lastmsgdata == null
? lastmsgdata = new LastMsgData(DiscordPlugin.chatchannel, null, null)
: lastmsgdata);
for (LastMsgData data : lastmsgPerUser) {
if (data.dp.isMinecraftChatEnabled() && isdifferentchannel.test(data.channel)
&& e.shouldSendTo(getSender(data.channel, data.user, data.dp)))
if (data.dp.isMinecraftChatEnabled() && (e.isFromcmd() || isdifferentchannel.test(data.channel))
&& e.shouldSendTo(getSender(data.channel, data.user)))
doit.accept(data);
}
val iterator = lastmsgCustom.iterator();
while (iterator.hasNext()) { //TODO: Add cmd to fix mcchat
val lmd = iterator.next();
if ((e.isFromcmd() || isdifferentchannel.test(lmd.channel)) //Test if msg is from Discord
&& e.getChannel().ID.equals(lmd.mcchannel.ID)) //If it's from a command, the command msg has been deleted, so we need to send it
if (e.shouldSendTo(lmd.dcp) && e.getGroupID().equals(lmd.groupID)) //Check original user's permissions
doit.accept(lmd);
else {
iterator.remove(); //If the user no longer has permission, remove the connection
DiscordPlugin.sendMessageToChannel(lmd.channel, "The user no longer has permission to view the channel, connection removed.");
}
}
} catch (Exception ex) {
TBMCCoreAPI.SendException("Error while sending message to Discord!", ex);
}
}
@RequiredArgsConstructor
private static class LastMsgData {
public static class LastMsgData {
public IMessage message;
public long time;
public String content;
@ -147,6 +167,20 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
public final DiscordPlayer dp;
}
public static class CustomLMD extends LastMsgData {
public final String groupID;
public final Channel mcchannel;
public final DiscordConnectedPlayer dcp;
public CustomLMD(@NonNull IChannel channel, @NonNull IUser user, @NonNull DiscordPlayer dp,
@NonNull String groupid, @NonNull Channel mcchannel, @NonNull DiscordConnectedPlayer dcp) {
super(channel, user, dp);
groupID = groupid;
this.mcchannel = mcchannel;
this.dcp = dcp;
}
}
@EventHandler
public void onChatPreprocess(TBMCChatPreprocessEvent event) {
int start = -1;
@ -168,7 +202,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
}
private static final String[] UnconnectedCmds = new String[]{"list", "u", "shrug", "tableflip", "unflip", "mwiki",
"yeehaw"};
"yeehaw", "lenny", "rp", "plugins"};
private static LastMsgData lastmsgdata;
private static short lastlist = 0;
@ -177,6 +211,10 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
* Used for messages in PMs (mcchat).
*/
private static ArrayList<LastMsgData> lastmsgPerUser = new ArrayList<LastMsgData>();
/**
* Used for town or nation chats or anything else
*/
private static ArrayList<CustomLMD> lastmsgCustom = new ArrayList<>();
public static boolean privateMCChat(IChannel channel, boolean start, IUser user, DiscordPlayer dp) {
TBMCPlayer mcp = dp.getAs(TBMCPlayer.class);
@ -220,6 +258,27 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
.anyMatch(lmd -> ((IPrivateChannel) lmd.channel).getRecipient().getStringID().equals(did));
}
public static void addCustomChat(IChannel channel, String groupid, Channel mcchannel, DiscordPlayer dp, IUser user, DiscordConnectedPlayer dcp) {
val lmd = new CustomLMD(channel, user, dp, groupid, mcchannel, dcp);
lastmsgCustom.add(lmd);
}
public static boolean hasCustomChat(IChannel channel) {
return lastmsgCustom.stream().anyMatch(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
public static CustomLMD getCustomChat(IChannel channel) {
return lastmsgCustom.stream().filter(lmd -> lmd.channel.getLongID() == channel.getLongID()).findAny().orElse(null);
}
public static boolean removeCustomChat(IChannel channel) {
return lastmsgCustom.removeIf(lmd -> lmd.channel.getLongID() == channel.getLongID());
}
public static List<CustomLMD> getCustomChats() {
return Collections.unmodifiableList(lastmsgCustom);
}
/**
* May contain P&lt;DiscordID&gt; as key for public chat
*/
@ -242,6 +301,12 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
data.message = null; // Since only private channels are stored, only those will work anyways
}
public static void resetLastMessageCustom(IChannel channel) {
for (LastMsgData data : lastmsgCustom)
if (data.channel.getLongID() == channel.getLongID())
data.message = null;
}
/**
* This overload sends it to the global chat.
*/
@ -258,37 +323,50 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
action.accept(DiscordPlugin.chatchannel);
for (LastMsgData data : lastmsgPerUser)
action.accept(data.channel);
lastmsgCustom.forEach(cc -> action.accept(cc.channel));
}
private static void forAllowedMCChat(Consumer<IChannel> action, TBMCSystemChatEvent event) {
if (Channel.GlobalChat.ID.equals(event.getChannel().ID))
action.accept(DiscordPlugin.chatchannel);
for (LastMsgData data : lastmsgPerUser)
if (event.shouldSendTo(getSender(data.channel, data.user, data.dp)))
if (event.shouldSendTo(getSender(data.channel, data.user)))
action.accept(data.channel);
lastmsgCustom.stream().filter(data -> event.shouldSendTo(data.dcp))
.map(data -> data.channel).forEach(action);
}
public static void stop() {
if (sendthread != null) sendthread.interrupt();
if (recthread != null) recthread.interrupt();
}
private BukkitTask rectask;
private LinkedBlockingQueue<MessageReceivedEvent> recevents = new LinkedBlockingQueue<>();
private IMessage lastmsgfromd; // Last message sent by a Discord user, used for clearing checkmarks
private Runnable recrun;
private static Thread recthread;
@Override // Discord
public void handle(MessageReceivedEvent ev) {
if (DiscordPlugin.SafeMode)
return;
val author = ev.getMessage().getAuthor();
if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID())
&& !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID())))
return;
if (author.isBot())
return;
final boolean hasCustomChat = hasCustomChat(ev.getChannel());
if (!ev.getMessage().getChannel().getStringID().equals(DiscordPlugin.chatchannel.getStringID())
&& !(ev.getMessage().getChannel().isPrivate() && isMinecraftChatEnabled(author.getStringID()))
&& !hasCustomChat)
return;
if (ev.getMessage().getContent().equalsIgnoreCase("mcchat"))
return; // Race condition: If it gets here after it enabled mcchat it says it - I might as well allow disabling with this (CommandListener)
if (CommandListener.runCommand(ev.getMessage(), true))
return;
if (!ev.getMessage().getChannel().isPrivate())
resetLastMessage();
else if (hasCustomChat)
resetLastMessageCustom(ev.getChannel());
else
resetLastMessage(ev.getMessage().getChannel());
lastlist++;
@ -296,7 +374,9 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
if (rectask != null)
return;
recrun = () -> { //Don't return in a while loop next time
recthread = Thread.currentThread();
processDiscordToMC();
if (DiscordPlugin.plugin.isEnabled()) //Don't run again if shutting down
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Continue message processing
};
rectask = Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, recrun); //Start message processing
@ -315,7 +395,7 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
val user = DiscordPlayer.getUser(sender.getStringID(), DiscordPlayer.class);
String dmessage = event.getMessage().getContent();
try {
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender, user);
final DiscordSenderBase dsender = getSender(event.getMessage().getChannel(), sender);
for (IUser u : event.getMessage().getMentions()) {
dmessage = dmessage.replace(u.mention(false), "@" + u.getName()); // TODO: IG Formatting
@ -323,11 +403,15 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
dmessage = dmessage.replace(u.mention(true), "@" + (nick != null ? nick : u.getName()));
}
BiConsumer<Channel, String> sendChatMessage = (channel, msg) -> //
TBMCChatAPI.SendChatMessage(channel, dsender,
dmessage = EmojiParser.parseToAliases(dmessage, EmojiParser.FitzpatrickAction.PARSE); //Converts emoji to text- TODO: Add option to disable (resource pack?)
dmessage = dmessage.replaceAll(":(\\S+)\\|type_(?:(\\d)|(1)_2):", ":$1::skin-tone-$2:"); //Convert to Discord's format so it still shows up
Function<String, String> getChatMessage = msg -> //
msg + (event.getMessage().getAttachments().size() > 0 ? "\n" + event.getMessage()
.getAttachments().stream().map(a -> a.getUrl()).collect(Collectors.joining("\n"))
: ""));
: "");
CustomLMD clmd = getCustomChat(event.getChannel());
boolean react = false;
@ -336,40 +420,46 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
if (!event.getMessage().isDeleted() && !event.getChannel().isPrivate())
event.getMessage().delete();
});
final String cmd = dmessage.substring(1).toLowerCase();
//preprocessChat(dsender, dmessage); - Same is done below
final String cmdlowercased = dmessage.substring(1).toLowerCase();
if (dsender instanceof DiscordSender && Arrays.stream(UnconnectedCmds)
.noneMatch(s -> cmd.equals(s) || cmd.startsWith(s + " "))) {
.noneMatch(s -> cmdlowercased.equals(s) || cmdlowercased.startsWith(s + " "))) {
// Command not whitelisted
dsender.sendMessage("Sorry, you can only access these commands:\n"
+ Arrays.stream(UnconnectedCmds).map(uc -> "/" + uc)
.collect(Collectors.joining(", "))
+ (user.getConnectedID(TBMCPlayer.class) == null
? "\nTo access your commands, first please connect your accounts, using @ChromaBot connect in "
? "\nTo access your commands, first please connect your accounts, using /connect in "
+ DiscordPlugin.botchannel.mention()
+ "\nThen you can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"
: "\nYou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!"));
+ "\nThen y"
: "\nY")
+ "ou can access all of your regular commands (even offline) in private chat: DM me `mcchat`!");
return;
}
if (lastlist > 5) {
ListC = 0;
lastlist = 0;
}
if (cmd.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
if (cmdlowercased.equals("list") && Bukkit.getOnlinePlayers().size() == lastlistp && ListC++ > 2) // Lowered already
{
dsender.sendMessage("Stop it. You know the answer.");
lastlist = 0;
} else {
int spi = cmd.indexOf(' ');
final String topcmd = spi == -1 ? cmd : cmd.substring(0, spi);
int spi = cmdlowercased.indexOf(' ');
final String topcmd = spi == -1 ? cmdlowercased : cmdlowercased.substring(0, spi);
Optional<Channel> ch = Channel.getChannels().stream()
.filter(c -> c.ID.equalsIgnoreCase(topcmd)).findAny();
.filter(c -> c.ID.equalsIgnoreCase(topcmd)
|| (c.IDs != null && c.IDs.length > 0
&& Arrays.stream(c.IDs).anyMatch(id -> id.equalsIgnoreCase(topcmd)))).findAny();
if (!ch.isPresent())
Bukkit.getScheduler().runTask(DiscordPlugin.plugin,
() -> VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmd));
() -> {
VanillaCommandListener.runBukkitOrVanillaCommand(dsender, cmdlowercased);
Bukkit.getLogger().info(dsender.getName() + " issued command from Discord: /" + cmdlowercased);
});
else {
Channel chc = ch.get();
if (!chc.ID.equals(Channel.GlobalChat.ID)
&& !event.getMessage().getChannel().isPrivate())
if (!chc.ID.equals(Channel.GlobalChat.ID) && !chc.ID.equals("rp") && !event.getMessage().getChannel().isPrivate())
dsender.sendMessage(
"You can only talk in global in the public chat. DM `mcchat` to enable private chat to talk in the other channels.");
else {
@ -387,7 +477,11 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
dsender.sendMessage("You're now talking in: "
+ DPUtils.sanitizeString(dsender.getMcchannel().DisplayName));
} else { // Send single message
sendChatMessage.accept(chc, cmd.substring(spi + 1));
final String msg = event.getMessage().getContent().substring(spi + 2);
if (clmd == null)
TBMCChatAPI.SendChatMessage(chc, dsender, getChatMessage.apply(msg), true);
else
TBMCChatAPI.SendChatMessageDontCheckSender(chc, dsender, getChatMessage.apply(msg), true, clmd.dcp);
react = true;
}
}
@ -396,21 +490,20 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
lastlistp = (short) Bukkit.getOnlinePlayers().size();
} else {// Not a command
if (dmessage.length() == 0 && event.getMessage().getAttachments().size() == 0
&& !event.getChannel().isPrivate())
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0,
&& !event.getChannel().isPrivate() && event.getMessage().isSystemMessage())
TBMCChatAPI.SendSystemMessage(Channel.GlobalChat, 0, "everyone",
(dsender instanceof Player ? ((Player) dsender).getDisplayName()
: dsender.getName()) + " pinned a message on Discord.");
else {
sendChatMessage.accept(dsender.getMcchannel(), dmessage);
if (clmd != null)
TBMCChatAPI.SendChatMessageDontCheckSender(clmd.mcchannel, dsender, getChatMessage.apply(dmessage), false, clmd.dcp);
else
TBMCChatAPI.SendChatMessage(dsender.getMcchannel(), dsender, getChatMessage.apply(dmessage));
react = true;
}
}
if (react) {
try {
/*
* System.out.println("Got message: " + m.getContent() + " with embeds: " + m.getEmbeds().stream().map(e -> e.getTitle() + " " + e.getDescription())
* .collect(Collectors.joining("\n")));
*/
if (lastmsgfromd != null) {
DPUtils.perform(() -> lastmsgfromd.removeReaction(DiscordPlugin.dc.getOurUser(),
DiscordPlugin.DELIVERED_REACTION)); // Remove it no matter what, we know it's there 99.99% of the time
@ -426,10 +519,46 @@ public class MCChatListener implements Listener, IListener<MessageReceivedEvent>
}
}
private boolean preprocessChat(DiscordSenderBase dsender, String dmessage) {
if (dmessage.length() < 2)
return false;
int index = dmessage.indexOf(" ");
String cmd;
if (index == -1) { // Only the command is run
cmd = dmessage;
for (Channel channel : Channel.getChannels()) {
if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) {
Channel oldch = dsender.getMcchannel();
if (oldch instanceof ChatRoom)
((ChatRoom) oldch).leaveRoom(dsender);
if (oldch.equals(channel))
dsender.setMcchannel(Channel.GlobalChat);
else {
dsender.setMcchannel(channel);
if (channel instanceof ChatRoom)
((ChatRoom) channel).joinRoom(dsender);
}
dsender.sendMessage("You are now talking in: " + dsender.getMcchannel().DisplayName);
return true;
}
}
} else { // We have arguments
cmd = dmessage.substring(0, index);
for (Channel channel : Channel.getChannels()) {
if (cmd.equalsIgnoreCase(channel.ID) || (channel.IDs != null && Arrays.stream(channel.IDs).anyMatch(cmd::equalsIgnoreCase))) {
TBMCChatAPI.SendChatMessage(channel, dsender, dmessage.substring(index + 1));
return true;
}
}
// TODO: Target selectors
}
return false;
}
/**
* This method will find the best sender to use: if the player is online, use that, if not but connected then use that etc.
*/
private static DiscordSenderBase getSender(IChannel channel, final IUser author, DiscordPlayer dp) {
private static DiscordSenderBase getSender(IChannel channel, final IUser author) {
val key = (channel.isPrivate() ? "" : "P") + author.getStringID();
return Stream.<Supplier<Optional<DiscordSenderBase>>>of( // https://stackoverflow.com/a/28833677/2703239
() -> Optional.ofNullable(OnlineSenders.get(key)), // Find first non-null

View file

@ -45,6 +45,7 @@ public class MCListener implements Listener {
public void onPlayerJoin(TBMCPlayerJoinEvent e) {
if (e.getPlayer() instanceof DiscordConnectedPlayer)
return; // Don't show the joined message for the fake player
Bukkit.getScheduler().runTaskAsynchronously(DiscordPlugin.plugin, () -> {
final Player p = e.getPlayer();
DiscordPlayer dp = e.GetPlayer().getAs(DiscordPlayer.class);
if (dp != null) {
@ -65,6 +66,7 @@ public class MCListener implements Listener {
MCChatListener.sendSystemMessageToChat(e.GetPlayer().PlayerName().get() + " joined the game");
MCChatListener.ListC = 0;
ChromaBot.getInstance().updatePlayerList();
});
}
@EventHandler(priority = EventPriority.HIGHEST)
@ -93,7 +95,7 @@ public class MCListener implements Listener {
if (DiscordPlugin.SafeMode)
return;
DiscordPlayer dp = e.getPlayer().getAs(DiscordPlayer.class);
if (dp == null || dp.getDiscordID() == null || dp.getDiscordID() == "")
if (dp == null || dp.getDiscordID() == null || dp.getDiscordID().equals(""))
return;
IUser user = DiscordPlugin.dc.getUserByID(Long.parseLong(dp.getDiscordID()));
e.addInfo("Discord tag: " + user.getName() + "#" + user.getDiscriminator());

View file

@ -1,7 +1,5 @@
package buttondevteam.discordplugin.mccommands;
import org.bukkit.entity.Player;
import buttondevteam.discordplugin.DiscordPlayer;
import buttondevteam.discordplugin.commands.ConnectCommand;
import buttondevteam.discordplugin.listeners.MCChatListener;
@ -9,6 +7,7 @@ import buttondevteam.lib.chat.CommandClass;
import buttondevteam.lib.player.ChromaGamerBase;
import buttondevteam.lib.player.TBMCPlayer;
import buttondevteam.lib.player.TBMCPlayerBase;
import org.bukkit.entity.Player;
@CommandClass(modOnly = false, path = "accept")
public class AcceptMCCommand extends DiscordMCCommandBase {
@ -18,7 +17,7 @@ public class AcceptMCCommand extends DiscordMCCommandBase {
return new String[] { //
"§6---- Accept Discord connection ----", //
"Accept a pending connection between your Discord and Minecraft account.", //
"To start the connection process, do §b@ChromaBot connect <MCname>§r in the #bot channel on Discord", //
"To start the connection process, do §b/connect <MCname>§r in the #bot channel on Discord", //
"Usage: /" + alias + " accept" //
};
}

View file

@ -1,9 +1,8 @@
package buttondevteam.discordplugin.mccommands;
import org.bukkit.entity.Player;
import buttondevteam.discordplugin.commands.ConnectCommand;
import buttondevteam.lib.chat.CommandClass;
import org.bukkit.entity.Player;
@CommandClass(modOnly = false, path = "decline")
public class DeclineMCCommand extends DiscordMCCommandBase {
@ -13,7 +12,7 @@ public class DeclineMCCommand extends DiscordMCCommandBase {
return new String[] { //
"§6---- Decline Discord connection ----", //
"Decline a pending connection between your Discord and Minecraft account.", //
"To start the connection process, do §b@ChromaBot connect <MCname>§r in the #bot channel on Discord", //
"To start the connection process, do §b/connect <MCname>§r in the #bot channel on Discord", //
"Usage: /" + alias + " decline" //
};
}

View file

@ -1,7 +1,8 @@
package buttondevteam.discordplugin.playerfaker;
import java.util.*;
import buttondevteam.discordplugin.DiscordSenderBase;
import lombok.Getter;
import lombok.Setter;
import org.bukkit.*;
import org.bukkit.block.PistonMoveReaction;
import org.bukkit.entity.Entity;
@ -10,13 +11,11 @@ import org.bukkit.event.player.PlayerTeleportEvent.TeleportCause;
import org.bukkit.metadata.MetadataValue;
import org.bukkit.plugin.Plugin;
import org.bukkit.util.Vector;
import buttondevteam.discordplugin.DiscordSenderBase;
import lombok.Getter;
import lombok.Setter;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import java.util.*;
@Getter
@Setter
@SuppressWarnings("deprecated")

View file

@ -1,25 +1,27 @@
package buttondevteam.discordplugin.playerfaker;
import java.net.InetSocketAddress;
import java.util.*;
import buttondevteam.discordplugin.DiscordPlugin;
import lombok.Getter;
import lombok.experimental.Delegate;
import org.bukkit.*;
import org.bukkit.advancement.Advancement;
import org.bukkit.advancement.AdvancementProgress;
import org.bukkit.conversations.Conversation;
import org.bukkit.conversations.ConversationAbandonedEvent;
import org.bukkit.entity.*;
import org.bukkit.entity.Entity;
import org.bukkit.entity.EntityType;
import org.bukkit.entity.Player;
import org.bukkit.event.player.AsyncPlayerChatEvent;
import org.bukkit.map.MapView;
import org.bukkit.permissions.PermissibleBase;
import org.bukkit.plugin.Plugin;
import org.bukkit.scoreboard.Scoreboard;
import buttondevteam.discordplugin.DiscordPlugin;
import lombok.experimental.Delegate;
import lombok.Getter;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import java.net.InetSocketAddress;
import java.util.*;
public class DiscordFakePlayer extends DiscordHumanEntity implements Player {
protected DiscordFakePlayer(IUser user, IChannel channel, int entityId, UUID uuid, String mcname) {
super(user, channel, entityId, uuid);

View file

@ -1,7 +1,5 @@
package buttondevteam.discordplugin.playerfaker;
import java.util.UUID;
import org.bukkit.GameMode;
import org.bukkit.Location;
import org.bukkit.Material;
@ -10,10 +8,11 @@ import org.bukkit.entity.HumanEntity;
import org.bukkit.entity.Villager;
import org.bukkit.inventory.*;
import org.bukkit.inventory.InventoryView.Property;
import sx.blah.discord.handle.obj.IChannel;
import sx.blah.discord.handle.obj.IUser;
import java.util.UUID;
public abstract class DiscordHumanEntity extends DiscordLivingEntity implements HumanEntity {
protected DiscordHumanEntity(IUser user, IChannel channel, int entityId, UUID uuid) {
super(user, channel, entityId, uuid);

View file

@ -1,12 +1,5 @@
package buttondevteam.discordplugin.playerfaker;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.entity.HumanEntity;
@ -14,6 +7,13 @@ import org.bukkit.event.inventory.InventoryType;
import org.bukkit.inventory.Inventory;
import org.bukkit.inventory.ItemStack;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.ListIterator;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
public class DiscordInventory implements Inventory {
public DiscordInventory(DiscordHumanEntity holder) {
this.holder = holder;

View file

@ -1,12 +1,7 @@
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 lombok.Getter;
import lombok.Setter;
import org.bukkit.Location;
import org.bukkit.Material;
import org.bukkit.attribute.Attribute;
@ -21,12 +16,11 @@ 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;
import java.util.*;
public abstract class DiscordLivingEntity extends DiscordEntity implements LivingEntity {
protected DiscordLivingEntity(IUser user, IChannel channel, int entityId, UUID uuid) {

View file

@ -1,7 +1,10 @@
package buttondevteam.discordplugin.playerfaker;
import java.util.Arrays;
import buttondevteam.discordplugin.DiscordSenderBase;
import buttondevteam.discordplugin.IMCPlayer;
import lombok.Getter;
import lombok.val;
import net.minecraft.server.v1_12_R1.*;
import org.bukkit.Bukkit;
import org.bukkit.craftbukkit.v1_12_R1.CraftServer;
import org.bukkit.craftbukkit.v1_12_R1.CraftWorld;
@ -9,17 +12,7 @@ import org.bukkit.craftbukkit.v1_12_R1.command.VanillaCommandWrapper;
import org.bukkit.craftbukkit.v1_12_R1.entity.CraftPlayer;
import org.bukkit.entity.Player;
import buttondevteam.discordplugin.DiscordSenderBase;
import buttondevteam.discordplugin.IMCPlayer;
import lombok.Getter;
import lombok.val;
import net.minecraft.server.v1_12_R1.ChatMessage;
import net.minecraft.server.v1_12_R1.CommandException;
import net.minecraft.server.v1_12_R1.EnumChatFormat;
import net.minecraft.server.v1_12_R1.IChatBaseComponent;
import net.minecraft.server.v1_12_R1.ICommandListener;
import net.minecraft.server.v1_12_R1.MinecraftServer;
import net.minecraft.server.v1_12_R1.World;
import java.util.Arrays;
public class VanillaCommandListener<T extends DiscordSenderBase & IMCPlayer<T>> implements ICommandListener {
private @Getter T player;

0
src/main/resources/plugin.yml Normal file → Executable file
View file

0
src/test/java/buttondevteam/DiscordPlugin/AppTest.java Normal file → Executable file
View file