Auto stash before merge of "master" and "origin/master"
This commit is contained in:
@@ -20,7 +20,7 @@ public class CommandBetBeans extends Command
|
||||
{
|
||||
String call = "";
|
||||
|
||||
int min = 50;
|
||||
int min = 20;
|
||||
int bet = 0;
|
||||
int win = 0;
|
||||
|
||||
|
||||
@@ -1,72 +1,72 @@
|
||||
package commands.general;
|
||||
|
||||
import core.Command;
|
||||
import core.LocStrings;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyEmbed;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyRating;
|
||||
import dataStructures.KittyRole;
|
||||
import dataStructures.KittyUser;
|
||||
import dataStructures.Response;
|
||||
import dataStructures.UserInput;
|
||||
import network.NetworkDerpi;
|
||||
|
||||
public class CommandDerpi extends Command
|
||||
{
|
||||
NetworkDerpi searcher = new NetworkDerpi();
|
||||
KittyEmbed response;
|
||||
|
||||
// Required constructor
|
||||
public CommandDerpi(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||
|
||||
@Override
|
||||
public String getHelpText() { return "Will search derpibooru for the tags entered, if KittyBot's content filter allows it"; }
|
||||
|
||||
@Override
|
||||
public void onRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res)
|
||||
{
|
||||
if(guild.contentRating == KittyRating.Filtered)
|
||||
{
|
||||
try
|
||||
{
|
||||
response = searcher.getDerpi(input.args.replace(',', ' ') + " safe").output();
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("DerpiError"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(input.args == null || input.args.length() == 0)
|
||||
res.send("DerpiNoSearchError");
|
||||
else
|
||||
{
|
||||
response = searcher.getDerpi(input.args).output();
|
||||
try
|
||||
{
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("DerpiError"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(input.args.startsWith("ID:"))
|
||||
{
|
||||
response = searcher.getDerpiByID(input.args.substring(input.args.indexOf(':'))).output();
|
||||
try
|
||||
{
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("DerpiError"));
|
||||
}
|
||||
}
|
||||
}
|
||||
package commands.general;
|
||||
|
||||
import core.Command;
|
||||
import core.LocStrings;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyEmbed;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyRating;
|
||||
import dataStructures.KittyRole;
|
||||
import dataStructures.KittyUser;
|
||||
import dataStructures.Response;
|
||||
import dataStructures.UserInput;
|
||||
import network.NetworkDerpi;
|
||||
|
||||
public class CommandDerpi extends Command
|
||||
{
|
||||
NetworkDerpi searcher = new NetworkDerpi();
|
||||
KittyEmbed response;
|
||||
|
||||
// Required constructor
|
||||
public CommandDerpi(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||
|
||||
@Override
|
||||
public String getHelpText() { return "Will search derpibooru for the tags entered, if KittyBot's content filter allows it"; }
|
||||
|
||||
@Override
|
||||
public void onRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res)
|
||||
{
|
||||
if(guild.contentRating == KittyRating.Filtered)
|
||||
{
|
||||
try
|
||||
{
|
||||
response = searcher.getDerpi(input.args.replace(',', ' ') + " safe").output();
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("DerpiError"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(input.args == null || input.args.length() == 0)
|
||||
res.send("DerpiNoSearchError");
|
||||
else
|
||||
{
|
||||
response = searcher.getDerpi(input.args).output();
|
||||
try
|
||||
{
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("DerpiError"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(input.args.startsWith("ID:"))
|
||||
{
|
||||
response = searcher.getDerpiByID(input.args.substring(input.args.indexOf(':'))).output();
|
||||
try
|
||||
{
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("DerpiError"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,60 +1,76 @@
|
||||
package commands.general;
|
||||
|
||||
import core.Command;
|
||||
import core.LocStrings;
|
||||
import dataStructures.*;
|
||||
import network.NetworkE6;
|
||||
|
||||
public class CommandE6 extends Command
|
||||
{
|
||||
NetworkE6 searcher = new NetworkE6();
|
||||
KittyEmbed response;
|
||||
|
||||
public CommandE6(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||
|
||||
@Override
|
||||
public String getHelpText()
|
||||
{
|
||||
String toRet = "Will search e6";
|
||||
toRet += "21 for the tags entered, if KittyBot's content filter allows it";
|
||||
return toRet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res)
|
||||
{
|
||||
if(guild.contentRating == KittyRating.Filtered || !guild.channels.get(Long.getLong(channel.uniqueID)).mature)
|
||||
{
|
||||
if(!guild.channels.get(Long.getLong(channel.uniqueID)).mature)
|
||||
{
|
||||
res.send("This channel is SFW only! Have some (probably) wholesome content ^^~");
|
||||
}
|
||||
response = searcher.getE6(input.args + " rating:safe").output();
|
||||
try
|
||||
{
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("E6Blacklisted"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(input.args == null || input.args.length() == 0)
|
||||
res.send("E6NoSearchError");
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
response = searcher.getE6(input.args).output();
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("E6Blacklisted"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
package commands.general;
|
||||
|
||||
import core.Command;
|
||||
import core.LocStrings;
|
||||
import dataStructures.*;
|
||||
import network.NetworkE6;
|
||||
|
||||
public class CommandE6 extends Command
|
||||
{
|
||||
NetworkE6 searcher = new NetworkE6();
|
||||
KittyEmbed response;
|
||||
GenericImage image;
|
||||
|
||||
public CommandE6(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||
|
||||
@Override
|
||||
public String getHelpText()
|
||||
{
|
||||
String toRet = "Will search e6";
|
||||
toRet += "21 for the tags entered, if KittyBot's content filter allows it";
|
||||
return toRet;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response res)
|
||||
{
|
||||
if(guild.contentRating == KittyRating.Filtered || !guild.channels.get(Long.getLong(channel.uniqueID)).mature)
|
||||
{
|
||||
if(!guild.channels.get(Long.getLong(channel.uniqueID)).mature)
|
||||
{
|
||||
res.send("This channel is SFW only! Have some (probably) wholesome content ^^~");
|
||||
}
|
||||
|
||||
image = searcher.getE6(input.args + " rating:safe");
|
||||
try
|
||||
{
|
||||
response = image.output();
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("E6Blacklisted"));
|
||||
return;
|
||||
}
|
||||
try
|
||||
{
|
||||
if(response.authorText == null)
|
||||
{
|
||||
Exception e = new Exception();
|
||||
throw e;
|
||||
}
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("E6Blacklisted"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(input.args == null || input.args.length() == 0)
|
||||
res.send("E6NoSearchError");
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
response = searcher.getE6(input.args).output();
|
||||
res.send(response);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
res.send(LocStrings.stub("E6Blacklisted"));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -18,6 +18,7 @@ public class CommandMusicMain extends Command
|
||||
framework.addCommand("skip", new SubCommandSkip(KittyRole.General, KittyRating.Safe));
|
||||
framework.addCommand("stop", new SubCommandStop(KittyRole.General, KittyRating.Safe));
|
||||
framework.addCommand("playlist", new SubCommandPlaylist(KittyRole.General, KittyRating.Safe));
|
||||
framework.addCommand("volume", new SubCommandVolume(KittyRole.General, KittyRating.Safe));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
package commands.music;
|
||||
|
||||
import core.LocStrings;
|
||||
import core.SubCommand;
|
||||
import core.SubCommandFormattable;
|
||||
import dataStructures.KittyChannel;
|
||||
@@ -27,6 +28,6 @@ public class SubCommandAddTrack extends SubCommand
|
||||
video = YT.getYT(video);
|
||||
}
|
||||
guild.audio.playVideo(video);
|
||||
return new SubCommandFormattable(video);
|
||||
return new SubCommandFormattable(String.format(LocStrings.stub("MusicAddTrack"), video));
|
||||
}
|
||||
}
|
||||
@@ -1,23 +1,23 @@
|
||||
package commands.music;
|
||||
|
||||
import core.SubCommand;
|
||||
import core.SubCommandFormattable;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyRating;
|
||||
import dataStructures.KittyRole;
|
||||
import dataStructures.KittyUser;
|
||||
import dataStructures.UserInput;
|
||||
|
||||
public class SubCommandSkip extends SubCommand
|
||||
{
|
||||
public SubCommandSkip(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||
{
|
||||
|
||||
}
|
||||
@Override
|
||||
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
||||
{
|
||||
return new SubCommandFormattable(guild.audio.skipVideo(guild.audio.player));
|
||||
}
|
||||
}
|
||||
package commands.music;
|
||||
|
||||
import core.SubCommand;
|
||||
import core.SubCommandFormattable;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyRating;
|
||||
import dataStructures.KittyRole;
|
||||
import dataStructures.KittyUser;
|
||||
import dataStructures.UserInput;
|
||||
|
||||
public class SubCommandSkip extends SubCommand
|
||||
{
|
||||
public SubCommandSkip(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||
{
|
||||
|
||||
}
|
||||
@Override
|
||||
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
||||
{
|
||||
return new SubCommandFormattable(guild.audio.skipVideo(guild.audio.player));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package commands.music;
|
||||
|
||||
import core.LocStrings;
|
||||
import core.SubCommand;
|
||||
import core.SubCommandFormattable;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyRating;
|
||||
import dataStructures.KittyRole;
|
||||
import dataStructures.KittyUser;
|
||||
import dataStructures.UserInput;
|
||||
|
||||
public class SubCommandVolume extends SubCommand
|
||||
{
|
||||
public SubCommandVolume(KittyRole level, KittyRating rating) { super(level, rating); }
|
||||
{
|
||||
|
||||
}
|
||||
@Override
|
||||
public SubCommandFormattable OnRun(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input)
|
||||
{
|
||||
int newVol = guild.audio.getVolume(guild.audio.player);
|
||||
if(input.args != null)
|
||||
{
|
||||
try
|
||||
{
|
||||
newVol = Integer.parseInt(input.args);
|
||||
if(newVol > 100 || newVol <1)
|
||||
{
|
||||
return new SubCommandFormattable(String.format(LocStrings.stub("MusicVolOOB")));
|
||||
}
|
||||
guild.audio.changeVolume(guild.audio.player, newVol);
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
return new SubCommandFormattable(String.format(LocStrings.stub("MusicVolCurrent"), newVol));
|
||||
}
|
||||
|
||||
}
|
||||
return new SubCommandFormattable(String.format(LocStrings.stub("MusicVolChanged"), newVol));
|
||||
}
|
||||
}
|
||||
+235
-234
@@ -1,234 +1,235 @@
|
||||
package core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import commands.characters.CommandCharacterMain;
|
||||
import commands.general.*;
|
||||
import commands.guildrole.CommandGuildRoleMain;
|
||||
import commands.mod.CommandModMain;
|
||||
import commands.music.CommandMusicMain;
|
||||
import commands.poll.CommandPollMain;
|
||||
import commands.raffle.CommandRaffleMain;
|
||||
import dataStructures.*;
|
||||
import utils.GlobalLog;
|
||||
import utils.LogFilter;
|
||||
|
||||
public class CommandManager
|
||||
{
|
||||
// Variables
|
||||
private HashMap<String, Command> commands;
|
||||
private ArrayList<CommandThread> threadAccumulator;
|
||||
private CommandEnabler commandEnabler;
|
||||
private long invokeCount;
|
||||
|
||||
// Singleton
|
||||
public static CommandManager instance;
|
||||
|
||||
// Default Constructor
|
||||
public CommandManager(CommandEnabler commandEnabler)
|
||||
{
|
||||
GlobalLog.log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName());
|
||||
|
||||
if(instance == null)
|
||||
{
|
||||
this.commands = new HashMap<String, Command>();
|
||||
this.threadAccumulator = new ArrayList<CommandThread>();
|
||||
this.invokeCount = 0;
|
||||
this.commandEnabler = commandEnabler;
|
||||
|
||||
registerAllCommands();
|
||||
|
||||
instance = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalLog.error(LogFilter.Core, "You can't have two of the following: " + this.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
// Registers all the commands for the instance
|
||||
public void registerAllCommands()
|
||||
{
|
||||
this.commands.clear();
|
||||
|
||||
// Dev
|
||||
this.register(LocCommands.stub("work"), new CommandDoWork(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("shutdown"), new CommandShutdown(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("stats"), new CommandStats(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("invite"), new CommandInvite(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("buildHelp"), new CommandHelpBuilder(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("tweet"), new CommandTweet(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("dbflush"), new CommandDBFlush(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("dbstats"), new CommandDBStats(KittyRole.Dev, KittyRating.Safe));
|
||||
|
||||
// Admin
|
||||
this.register(LocCommands.stub("rating"), new CommandRating(KittyRole.Admin, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("indicator"), new CommandChangeIndicator(KittyRole.Admin, KittyRating.Safe));
|
||||
|
||||
// Mod
|
||||
this.register(LocCommands.stub("givebeans"), new CommandGiveBeans(KittyRole.Mod, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("mod"), new CommandModMain(KittyRole.Mod, KittyRating.Safe));
|
||||
|
||||
// General
|
||||
this.register(LocCommands.stub("fetch"), new CommandFetch(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("teey"), new CommandTeey(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("perish, thenperish"), new CommandPerish(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("yeet"), new CommandYeet(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("ping"), new CommandPing(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("boop"), new CommandBoop(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("roll"), new CommandRoll(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("choose"), new CommandChoose(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("help"), new CommandHelp(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("info, about"), new CommandInfo(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("wolfram"), new CommandWolfram(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("c++, g++, cplus, cpp"), new CommandColiru(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("java, jdoodle"), new CommandJDoodle(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("beans"), new CommandBeansShow(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("kittyrole"), new CommandRole(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("bet"), new CommandBetBeans(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("map"), new CommandMap(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("rpstart"), new CommandRPStart(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("rpend"), new CommandRPEnd(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("tony, stark, dontfeelgood, dontfeelsogood"), new CommandStark(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("blur"), new CommandBlurry(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("eightball, 8ball"), new CommandEightBall(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("catch"), new CommandCatch(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("bethistory"), new CommandBetHistory(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("crouton"), new CommandCrouton(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("benchmark, bench"), new CommandBenchmark(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("leaderboard"), new CommandLeaderboard(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("color, colour"), new CommandColor(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("remind"), new CommandRemind(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("role"), new CommandGuildRoleMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("character"), new CommandCharacterMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("raffle"), new CommandRaffleMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("poll"), new CommandPollMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("music"), new CommandMusicMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("defaultdance"), new CommandDefaultDance(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("getsauce"), new CommandGetSauce(KittyRole.General, KittyRating.Safe));
|
||||
|
||||
this.register(LocCommands.stub("e6"), new CommandE6(KittyRole.General, KittyRating.Filtered));
|
||||
this.register(LocCommands.stub("derpi"), new CommandDerpi(KittyRole.General, KittyRating.Filtered));
|
||||
}
|
||||
|
||||
// Allows the command manager to keep track of a command. Takes a pair (the un-localized and localzied commands)
|
||||
// and the command associated with the localized commands.
|
||||
public void register(Pair<String, String> pair, Command command)
|
||||
{
|
||||
if(pair == null || pair.Second == null)
|
||||
return;
|
||||
|
||||
String[] keys = pair.Second.split(",");
|
||||
|
||||
for(int i = 0; i < keys.length; ++i)
|
||||
{
|
||||
String key = keys[i].trim().toLowerCase();
|
||||
|
||||
command.registeredNames.add(key);
|
||||
Command old = commands.put(key, command);
|
||||
|
||||
if(old != null)
|
||||
{
|
||||
GlobalLog.warn(LogFilter.Core, "Writing over a command with the key " + key);
|
||||
return;
|
||||
}
|
||||
|
||||
GlobalLog.log(LogFilter.Core, "Command registered under key " + key);
|
||||
}
|
||||
}
|
||||
|
||||
// Calls the command but on a whole new thread!
|
||||
public boolean invokeOnNewThread(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
||||
{
|
||||
// This is here to prevent spinning up a thread if this wasn't even a command.
|
||||
if(input == null || !input.isValid())
|
||||
return false;
|
||||
|
||||
// At this point, verify that the command is enabled. If we don't have any info
|
||||
// on if it's enabled or not, we assume it's enabled to prevent broken functionality due
|
||||
// to formatting or casing issues.
|
||||
if(input.key != null && !commandEnabler.isEnabled(input.key))
|
||||
return false;
|
||||
|
||||
Command command = commands.get(input.key);
|
||||
if(command != null)
|
||||
{
|
||||
// Spin up a thread and begin it. The thread carries the info needed to invoke the command.
|
||||
CommandThread newThread = new CommandThread(this, input, guild, channel, user, responseContext);
|
||||
threadAccumulator.add(newThread);
|
||||
newThread.start();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalLog.warn(LogFilter.Command, "User " + user.name + " tried to invoke command that doesn't exist: " + input.key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Calls the command specified with the key, providing user information arguments, etc.
|
||||
void invoke(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
||||
{
|
||||
if(input == null || !input.isValid())
|
||||
return;
|
||||
|
||||
Command command = commands.get(input.key);
|
||||
if(command != null)
|
||||
{
|
||||
++invokeCount;
|
||||
command.invoke(guild, channel, user, input, responseContext);
|
||||
}
|
||||
}
|
||||
|
||||
// Looks up command by name. If it exists, dumps help text, otherwise returns null.
|
||||
public String getCommandHelpText(String key)
|
||||
{
|
||||
Command command = commands.get(key);
|
||||
|
||||
if(command != null)
|
||||
return "`" + key + "`: " + command.getHelpText();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns the number of commands sent so far during this program run
|
||||
public long getInvokeCount()
|
||||
{
|
||||
return invokeCount;
|
||||
}
|
||||
|
||||
// Returns all commands by name
|
||||
public ArrayList<Command> getAllRegisteredCommands()
|
||||
{
|
||||
ArrayList<Command> cmds = new ArrayList<Command>();
|
||||
for(Entry<String, Command> entry : commands.entrySet())
|
||||
cmds.add(entry.getValue());
|
||||
|
||||
return cmds;
|
||||
}
|
||||
|
||||
// Info about threads running packaged into an object
|
||||
public class ThreadData
|
||||
{
|
||||
public HashMap<Thread.State, Integer> states = new HashMap<Thread.State, Integer>();
|
||||
}
|
||||
public ThreadData dumpThreadData()
|
||||
{
|
||||
ThreadData data = new ThreadData();
|
||||
|
||||
for(int i = 0; i < threadAccumulator.size(); ++i)
|
||||
{
|
||||
Thread.State state = threadAccumulator.get(i).getState();
|
||||
Integer num = data.states.get(state);
|
||||
|
||||
if(num == null)
|
||||
num = 0;
|
||||
|
||||
data.states.put(state, num + 1);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
package core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import commands.characters.CommandCharacterMain;
|
||||
import commands.general.*;
|
||||
import commands.guildrole.CommandGuildRoleMain;
|
||||
import commands.mod.CommandModMain;
|
||||
import commands.music.CommandMusicMain;
|
||||
import commands.poll.CommandPollMain;
|
||||
import commands.raffle.CommandRaffleMain;
|
||||
import dataStructures.*;
|
||||
import utils.GlobalLog;
|
||||
import utils.LogFilter;
|
||||
|
||||
public class CommandManager
|
||||
{
|
||||
// Variables
|
||||
private HashMap<String, Command> commands;
|
||||
private ArrayList<CommandThread> threadAccumulator;
|
||||
private CommandEnabler commandEnabler;
|
||||
private long invokeCount;
|
||||
|
||||
// Singleton
|
||||
public static CommandManager instance;
|
||||
|
||||
// Default Constructor
|
||||
public CommandManager(CommandEnabler commandEnabler)
|
||||
{
|
||||
GlobalLog.log(LogFilter.Core, "Initializing " + this.getClass().getSimpleName());
|
||||
|
||||
if(instance == null)
|
||||
{
|
||||
this.commands = new HashMap<String, Command>();
|
||||
this.threadAccumulator = new ArrayList<CommandThread>();
|
||||
this.invokeCount = 0;
|
||||
this.commandEnabler = commandEnabler;
|
||||
|
||||
registerAllCommands();
|
||||
|
||||
instance = this;
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalLog.error(LogFilter.Core, "You can't have two of the following: " + this.getClass().getSimpleName());
|
||||
}
|
||||
}
|
||||
|
||||
// Registers all the commands for the instance
|
||||
public void registerAllCommands()
|
||||
{
|
||||
this.commands.clear();
|
||||
|
||||
// Dev
|
||||
this.register(LocCommands.stub("work"), new CommandDoWork(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("shutdown"), new CommandShutdown(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("stats"), new CommandStats(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("invite"), new CommandInvite(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("buildHelp"), new CommandHelpBuilder(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("tweet"), new CommandTweet(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("dbflush"), new CommandDBFlush(KittyRole.Dev, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("dbstats"), new CommandDBStats(KittyRole.Dev, KittyRating.Safe));
|
||||
|
||||
// Admin
|
||||
this.register(LocCommands.stub("rating"), new CommandRating(KittyRole.Admin, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("indicator"), new CommandChangeIndicator(KittyRole.Admin, KittyRating.Safe));
|
||||
|
||||
// Mod
|
||||
this.register(LocCommands.stub("givebeans"), new CommandGiveBeans(KittyRole.Mod, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("mod"), new CommandModMain(KittyRole.Mod, KittyRating.Safe));
|
||||
|
||||
// General
|
||||
this.register(LocCommands.stub("fetch"), new CommandFetch(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("teey"), new CommandTeey(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("perish, thenperish"), new CommandPerish(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("yeet"), new CommandYeet(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("ping"), new CommandPing(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("boop"), new CommandBoop(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("roll"), new CommandRoll(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("choose"), new CommandChoose(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("help"), new CommandHelp(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("info, about"), new CommandInfo(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("wolfram"), new CommandWolfram(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("c++, g++, cplus, cpp"), new CommandColiru(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("java, jdoodle"), new CommandJDoodle(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("beans"), new CommandBeansShow(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("kittyrole"), new CommandRole(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("bet"), new CommandBetBeans(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("map"), new CommandMap(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("rpstart"), new CommandRPStart(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("rpend"), new CommandRPEnd(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("tony, stark, dontfeelgood, dontfeelsogood"), new CommandStark(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("blur"), new CommandBlurry(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("eightball, 8ball"), new CommandEightBall(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("catch"), new CommandCatch(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("bethistory"), new CommandBetHistory(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("crouton"), new CommandCrouton(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("benchmark, bench"), new CommandBenchmark(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("leaderboard"), new CommandLeaderboard(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("color, colour"), new CommandColor(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("remind"), new CommandRemind(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("role"), new CommandGuildRoleMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("character"), new CommandCharacterMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("raffle"), new CommandRaffleMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("poll"), new CommandPollMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("music"), new CommandMusicMain(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("defaultdance"), new CommandDefaultDance(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("getsauce"), new CommandGetSauce(KittyRole.General, KittyRating.Safe));
|
||||
this.register(LocCommands.stub("tradebeans"), new CommandTradeBeans(KittyRole.General, KittyRating.Safe));
|
||||
|
||||
this.register(LocCommands.stub("e6"), new CommandE6(KittyRole.General, KittyRating.Filtered));
|
||||
this.register(LocCommands.stub("derpi"), new CommandDerpi(KittyRole.General, KittyRating.Filtered));
|
||||
}
|
||||
|
||||
// Allows the command manager to keep track of a command. Takes a pair (the un-localized and localzied commands)
|
||||
// and the command associated with the localized commands.
|
||||
public void register(Pair<String, String> pair, Command command)
|
||||
{
|
||||
if(pair == null || pair.Second == null)
|
||||
return;
|
||||
|
||||
String[] keys = pair.Second.split(",");
|
||||
|
||||
for(int i = 0; i < keys.length; ++i)
|
||||
{
|
||||
String key = keys[i].trim().toLowerCase();
|
||||
|
||||
command.registeredNames.add(key);
|
||||
Command old = commands.put(key, command);
|
||||
|
||||
if(old != null)
|
||||
{
|
||||
GlobalLog.warn(LogFilter.Core, "Writing over a command with the key " + key);
|
||||
return;
|
||||
}
|
||||
|
||||
GlobalLog.log(LogFilter.Core, "Command registered under key " + key);
|
||||
}
|
||||
}
|
||||
|
||||
// Calls the command but on a whole new thread!
|
||||
public boolean invokeOnNewThread(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
||||
{
|
||||
// This is here to prevent spinning up a thread if this wasn't even a command.
|
||||
if(input == null || !input.isValid())
|
||||
return false;
|
||||
|
||||
// At this point, verify that the command is enabled. If we don't have any info
|
||||
// on if it's enabled or not, we assume it's enabled to prevent broken functionality due
|
||||
// to formatting or casing issues.
|
||||
if(input.key != null && !commandEnabler.isEnabled(input.key))
|
||||
return false;
|
||||
|
||||
Command command = commands.get(input.key);
|
||||
if(command != null)
|
||||
{
|
||||
// Spin up a thread and begin it. The thread carries the info needed to invoke the command.
|
||||
CommandThread newThread = new CommandThread(this, input, guild, channel, user, responseContext);
|
||||
threadAccumulator.add(newThread);
|
||||
newThread.start();
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
GlobalLog.warn(LogFilter.Command, "User " + user.name + " tried to invoke command that doesn't exist: " + input.key);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
// Calls the command specified with the key, providing user information arguments, etc.
|
||||
void invoke(KittyGuild guild, KittyChannel channel, KittyUser user, UserInput input, Response responseContext)
|
||||
{
|
||||
if(input == null || !input.isValid())
|
||||
return;
|
||||
|
||||
Command command = commands.get(input.key);
|
||||
if(command != null)
|
||||
{
|
||||
++invokeCount;
|
||||
command.invoke(guild, channel, user, input, responseContext);
|
||||
}
|
||||
}
|
||||
|
||||
// Looks up command by name. If it exists, dumps help text, otherwise returns null.
|
||||
public String getCommandHelpText(String key)
|
||||
{
|
||||
Command command = commands.get(key);
|
||||
|
||||
if(command != null)
|
||||
return "`" + key + "`: " + command.getHelpText();
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
// Returns the number of commands sent so far during this program run
|
||||
public long getInvokeCount()
|
||||
{
|
||||
return invokeCount;
|
||||
}
|
||||
|
||||
// Returns all commands by name
|
||||
public ArrayList<Command> getAllRegisteredCommands()
|
||||
{
|
||||
ArrayList<Command> cmds = new ArrayList<Command>();
|
||||
for(Entry<String, Command> entry : commands.entrySet())
|
||||
cmds.add(entry.getValue());
|
||||
|
||||
return cmds;
|
||||
}
|
||||
|
||||
// Info about threads running packaged into an object
|
||||
public class ThreadData
|
||||
{
|
||||
public HashMap<Thread.State, Integer> states = new HashMap<Thread.State, Integer>();
|
||||
}
|
||||
public ThreadData dumpThreadData()
|
||||
{
|
||||
ThreadData data = new ThreadData();
|
||||
|
||||
for(int i = 0; i < threadAccumulator.size(); ++i)
|
||||
{
|
||||
Thread.State state = threadAccumulator.get(i).getState();
|
||||
Integer num = data.states.get(state);
|
||||
|
||||
if(num == null)
|
||||
num = 0;
|
||||
|
||||
data.states.put(state, num + 1);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
}
|
||||
|
||||
+478
-478
@@ -1,479 +1,479 @@
|
||||
package core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||
|
||||
//import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
//import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
|
||||
import core.lua.PluginManager;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyCore;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyRating;
|
||||
import dataStructures.KittyRole;
|
||||
import dataStructures.KittyStartupMode;
|
||||
import dataStructures.KittyUser;
|
||||
import main.Main;
|
||||
import net.dv8tion.jda.core.AccountType;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.JDABuilder;
|
||||
import net.dv8tion.jda.core.entities.Emote;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Member;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
|
||||
import offline.Ref;
|
||||
import utils.AdminControl;
|
||||
//import utils.AudioUtils;
|
||||
import utils.GlobalLog;
|
||||
import utils.LogFilter;
|
||||
import utils.audio.AudioUtils;
|
||||
|
||||
// NOTE(wisp): Isolated factory to assist with storage and caching if needed.
|
||||
// This also minimizes the number of places JDA interacts with our codebase.
|
||||
// As it stands, if the object name begins with Kitty, it's constructed here.
|
||||
// TODO: Make all methods ID based instead of event based
|
||||
public class ObjectBuilderFactory
|
||||
{
|
||||
// Key: guild string id, Value: guild information
|
||||
private static HashMap<String, KittyGuild> guildCache;
|
||||
|
||||
// Key: channel string id, Value: channel information
|
||||
private static HashMap<String, KittyChannel> channelCache;
|
||||
|
||||
// Key: guild string id + user string id, Value: user information
|
||||
private static HashMap<String, KittyUser> userCache;
|
||||
|
||||
// For tracking and managing object sync
|
||||
private static DatabaseManager database;
|
||||
|
||||
// Stats tracking and whatnot... for setting stats too internally potentially
|
||||
private static Stats stats;
|
||||
|
||||
// RPManger for tracking RP system
|
||||
private static RPManager rpManager;
|
||||
|
||||
// Plugin manager
|
||||
private static PluginManager pluginManager;
|
||||
|
||||
// Command manager
|
||||
private static CommandManager commandManager;
|
||||
|
||||
//Audio track manager
|
||||
private static AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
|
||||
|
||||
// Localization classes - these are singletons, but should be initialized before almost all other
|
||||
// things so their inclusion in the factory is to ensure they're started at the correct time.
|
||||
@SuppressWarnings("unused") private static LocStrings locStrings;
|
||||
@SuppressWarnings("unused") private static LocCommands locCommands;
|
||||
|
||||
// Config
|
||||
@SuppressWarnings("unused") private static Config config;
|
||||
|
||||
// Lazy initialization multithreaded mutex stuff to prevent explosions.
|
||||
// TODO: Investigate using 'synchronized' instead potentially
|
||||
private static boolean hasInitialized;
|
||||
private static Semaphore initMutex = new Semaphore(1);
|
||||
private static JDA kitty;
|
||||
|
||||
// This is it, this is how the lazy init starts!
|
||||
private static void lazyInit()
|
||||
{
|
||||
if(hasInitialized)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
initMutex.acquire();
|
||||
try
|
||||
{
|
||||
// structure initialization
|
||||
// Construct necessary data structures.
|
||||
guildCache = new HashMap<String, KittyGuild>();
|
||||
userCache = new HashMap<String, KittyUser>();
|
||||
channelCache = new HashMap<String, KittyChannel>();
|
||||
database = null;
|
||||
stats = null;
|
||||
|
||||
AudioSourceManagers.registerRemoteSources(playerManager);
|
||||
AudioSourceManagers.registerLocalSource(playerManager);
|
||||
|
||||
// Start by reading from things that are external. Because
|
||||
// we require these things to be resolved before the rest of the application,
|
||||
// we place them here.
|
||||
config = new Config();
|
||||
}
|
||||
finally
|
||||
{
|
||||
initMutex.release();
|
||||
hasInitialized = true;
|
||||
}
|
||||
}
|
||||
catch(InterruptedException ie)
|
||||
{
|
||||
GlobalLog.error(LogFilter.Core, "Issue during object builder lazy initialization."
|
||||
+ " The factory was not initialized, and kitty will not be able to continue functionally.");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// Extraction Methods //
|
||||
////////////////////////
|
||||
|
||||
// Explicitly locks: guildCache
|
||||
public static KittyGuild extractGuild(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Look up the guild. This process can only happen in a single-threaded way
|
||||
// because of the nature of the cache. We wait until the last second to
|
||||
// look up the guild.
|
||||
String uid = event.getGuild().getId();
|
||||
|
||||
List<Emote> emotes = event.getGuild().getEmotes();
|
||||
ArrayList<String> emotesString = new ArrayList<String>();
|
||||
HashMap<Long, KittyChannel> channels = new HashMap<Long, KittyChannel>();
|
||||
String emote;
|
||||
String emoteFix;
|
||||
channels.put(Long.getLong(uid), extractChannel(event));
|
||||
for(int i = 0; i < emotes.size(); i++)
|
||||
{
|
||||
emote = emotes.get(i).toString();
|
||||
emoteFix = "<:" + emote.substring(2, emote.indexOf("("));
|
||||
emoteFix += ":" + emote.substring(emote.indexOf("(")+1, emote.length()-1) + ">";
|
||||
emotesString.add(emoteFix);
|
||||
}
|
||||
|
||||
// once we're lazily initialized, we can synchronize w/ the
|
||||
// guildCache object now instead of having to use a mutex.
|
||||
KittyGuild guild = null;
|
||||
synchronized (guildCache)
|
||||
{
|
||||
KittyGuild cachedGuild = guildCache.get(uid);
|
||||
if(cachedGuild != null)
|
||||
{
|
||||
guild = cachedGuild;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct a new guild with defaults
|
||||
guild = new KittyGuild(uid, new AdminControl(event.getGuild()), emotesString, new AudioUtils(event.getGuild(), playerManager), channels);
|
||||
DatabaseManager.instance.globalRegister(guild);
|
||||
guildCache.put(uid, guild);
|
||||
}
|
||||
}
|
||||
|
||||
return guild;
|
||||
}
|
||||
|
||||
// Explicitly locks: guildCache
|
||||
public static KittyRole extractRole(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Looks up the user role. If none is found we check to see if they own
|
||||
// the guild if not, they're assumed to be
|
||||
// allowed to use the bot at a general level.
|
||||
KittyRole role = KittyRole.General;
|
||||
|
||||
if(event.getAuthor().getId() == event.getGuild().getOwner().getUser().getId())
|
||||
{
|
||||
role = KittyRole.Admin;
|
||||
}
|
||||
|
||||
String uid = event.getGuild().getId() + event.getAuthor().getId();
|
||||
synchronized(userCache)
|
||||
{
|
||||
KittyUser cachedUser = userCache.get(uid);
|
||||
if(cachedUser != null)
|
||||
role = cachedUser.getRole();
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
// Explicitly locks: guildCache
|
||||
// Extracts the content rating information it can from the provided event.
|
||||
public static KittyRating extractContentRating(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Look up content rating of the guild, returns a safe content rating.
|
||||
KittyRating contentRating = KittyRating.Safe;
|
||||
String uid = event.getGuild().getId();
|
||||
synchronized(guildCache)
|
||||
{
|
||||
KittyGuild cachedGuild = guildCache.get(uid);
|
||||
if(cachedGuild != null)
|
||||
contentRating = cachedGuild.contentRating;
|
||||
}
|
||||
|
||||
return contentRating;
|
||||
}
|
||||
|
||||
// Implicitly locks guild cache by calling ExtractGuild
|
||||
public static KittyChannel extractChannel(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
String channelID = event.getChannel().getId();
|
||||
KittyChannel channel = null;
|
||||
|
||||
synchronized(channelCache)
|
||||
{
|
||||
KittyChannel cachedChannel = channelCache.get(channelID);
|
||||
boolean mature;
|
||||
|
||||
if(cachedChannel != null)
|
||||
{
|
||||
channel = cachedChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
mature = event.getChannel().isNSFW();
|
||||
channel = new KittyChannel(channelID, mature);
|
||||
channelCache.put(channelID, channel);
|
||||
}
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
// Implicitly locks guild cache by calling ExtractRole and ExtractGuild
|
||||
public static KittyUser extractUser(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
String uid = event.getGuild().getId() + event.getAuthor().getId();
|
||||
KittyUser user = null;
|
||||
synchronized(userCache)
|
||||
{
|
||||
KittyUser cachedUser = userCache.get(uid);
|
||||
if(cachedUser != null)
|
||||
{
|
||||
updateUser(cachedUser, event.getMember());
|
||||
user = cachedUser;
|
||||
}
|
||||
else
|
||||
{
|
||||
KittyRole role = extractRole(event);
|
||||
KittyGuild guild = extractGuild(event);
|
||||
|
||||
String name;
|
||||
if(event.getMember().getNickname() == null)
|
||||
name = event.getAuthor().getName();
|
||||
else
|
||||
name = event.getMember().getNickname();
|
||||
|
||||
String discordID = event.getMember().getUser().getId();
|
||||
String avatarID = event.getAuthor().getAvatarUrl();
|
||||
user = new KittyUser(name, guild, role, uid, avatarID, discordID);
|
||||
DatabaseManager.instance.globalRegister(user);
|
||||
userCache.put(uid, user);
|
||||
}
|
||||
}
|
||||
|
||||
if(event.getMessage().getMentionedMembers().isEmpty())
|
||||
return user;
|
||||
|
||||
Member mentioned;
|
||||
for(int i = 0; i < event.getMessage().getMentionedMembers().size(); i++)
|
||||
{
|
||||
mentioned = event.getMessage().getMentionedMembers().get(i);
|
||||
if(mentioned.getNickname() != null)
|
||||
extractUserByJDAUser(event.getGuild().getId(), mentioned.getNickname(),
|
||||
mentioned.getUser().getId(), mentioned.getUser().getAvatarUrl(), mentioned.getUser().getId());
|
||||
else
|
||||
extractUserByJDAUser(event.getGuild().getId(), mentioned.getUser().getName(),
|
||||
mentioned.getUser().getId(), mentioned.getUser().getAvatarUrl(), mentioned.getUser().getId());
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
// TODO: Clean up
|
||||
public static KittyUser extractUserByJDAUser(String guildID, String name, String userID, String avatarID, String discordID)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
String uid = guildID + userID;
|
||||
KittyUser user = null;
|
||||
synchronized(userCache)
|
||||
{
|
||||
KittyUser cachedUser = userCache.get(uid);
|
||||
if(cachedUser != null)
|
||||
{
|
||||
if(name != null)
|
||||
cachedUser.name = name;
|
||||
|
||||
cachedUser.avatarID = avatarID;
|
||||
user = cachedUser;
|
||||
}
|
||||
else
|
||||
{
|
||||
KittyRole role = KittyRole.General;
|
||||
KittyGuild guild = guildCache.get(guildID);
|
||||
user = new KittyUser(name, guild, role, uid, avatarID, discordID);
|
||||
DatabaseManager.instance.globalRegister(user);
|
||||
userCache.put(uid, user);
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
// There is some redundant lookup occurring. If the user isn't cached yet, then we construct them and cache them.
|
||||
// The assumption is made that the user does, in fact, exist.
|
||||
public static KittyUser getKittyUser(String guildID, String userID)
|
||||
{
|
||||
String uid = guildID + userID;
|
||||
KittyUser user = null;
|
||||
synchronized(userCache)
|
||||
{
|
||||
user = userCache.get(uid);
|
||||
}
|
||||
|
||||
if(user == null)
|
||||
{
|
||||
Guild jdaGuild = kitty.getGuildById(guildID);
|
||||
if(jdaGuild == null) return null;
|
||||
|
||||
Member jdaMember = jdaGuild.getMemberById(userID);
|
||||
if(jdaMember == null) return null;
|
||||
|
||||
User jdaUser = jdaMember.getUser();
|
||||
if(jdaUser == null) return null;
|
||||
|
||||
user = extractUserByJDAUser(guildID, jdaMember.getNickname(), jdaUser.getId(), jdaUser.getAvatarUrl(), jdaUser.getId());
|
||||
updateUser(user, jdaMember);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
// Updates a user's name appropriately based on nickname if available
|
||||
public static void updateUser(KittyUser user, Member member)
|
||||
{
|
||||
if(member.getNickname() == null)
|
||||
{
|
||||
user.name = member.getUser().getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
user.name = member.getNickname();
|
||||
}
|
||||
|
||||
user.avatarID = member.getUser().getAvatarUrl();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// Construction Methods //
|
||||
//////////////////////////
|
||||
// Builds the core of the bot
|
||||
public static KittyCore constructKittyCore() throws LoginException, InterruptedException
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Determine token based on config. Default to test token.
|
||||
String tokenToUse = Ref.TestToken;
|
||||
if(ConfigGlobals.getStartupMode() == KittyStartupMode.Release)
|
||||
tokenToUse = Ref.Token;
|
||||
|
||||
// Construct bot based on token
|
||||
kitty = new JDABuilder(AccountType.BOT)
|
||||
.setToken(tokenToUse).buildBlocking();
|
||||
kitty.getPresence().setGame(Game.playing("with a laser pointer"));
|
||||
kitty.addEventListener(new Main());
|
||||
|
||||
return new KittyCore(kitty);
|
||||
}
|
||||
|
||||
// Default construction of the command manager. In order to remotely resolve command enabling
|
||||
// and disabling, what we do is construct the commands with a localized pair that is checked against
|
||||
// the CommandEnabler object passed in. In theory, we could have multiple CommandManagers, tho we can
|
||||
// only have one CommandEnabler.
|
||||
public static CommandManager constructCommandManager(CommandEnabler commandEnabler)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(commandManager == null)
|
||||
commandManager = new CommandManager(commandEnabler);
|
||||
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
// Default database manager construction. It can be constructed
|
||||
// in different ways, and so we construct it outside of the constructor for
|
||||
// the factory since it doesn't have to be present / can be elsewhere.
|
||||
// Effectively we cache the database here.
|
||||
public static DatabaseManager constructDatabaseManager()
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(database == null)
|
||||
database = new DatabaseManager();
|
||||
|
||||
return database;
|
||||
}
|
||||
|
||||
public static Stats constructStats(CommandManager manager)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(stats == null)
|
||||
stats = new Stats(manager);
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
public static RPManager constructRPManager()
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(rpManager == null)
|
||||
rpManager = new RPManager();
|
||||
|
||||
return rpManager;
|
||||
}
|
||||
|
||||
public static PluginManager constructPluginManager()
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(pluginManager == null)
|
||||
pluginManager = new PluginManager(Constants.AssetDirectory + "plugins/");
|
||||
|
||||
return pluginManager;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Utility Methods //
|
||||
/////////////////////
|
||||
|
||||
// Returns number of cached guilds (does not equal total users in the database, only what's in memory)
|
||||
public static Integer getGuildCount()
|
||||
{ synchronized(guildCache)
|
||||
{
|
||||
return guildCache.size();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns number of cached users (does not equal total users in the database, only what's in memory)
|
||||
public static Integer getUserCount()
|
||||
{ synchronized(userCache)
|
||||
{
|
||||
return userCache.size();
|
||||
}
|
||||
}
|
||||
package core;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.Semaphore;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||
|
||||
//import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
//import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
|
||||
import core.lua.PluginManager;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyCore;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyRating;
|
||||
import dataStructures.KittyRole;
|
||||
import dataStructures.KittyStartupMode;
|
||||
import dataStructures.KittyUser;
|
||||
import main.Main;
|
||||
import net.dv8tion.jda.core.AccountType;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.JDABuilder;
|
||||
import net.dv8tion.jda.core.entities.Emote;
|
||||
import net.dv8tion.jda.core.entities.Game;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.Member;
|
||||
import net.dv8tion.jda.core.entities.User;
|
||||
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
|
||||
import offline.Ref;
|
||||
import utils.AdminControl;
|
||||
//import utils.AudioUtils;
|
||||
import utils.GlobalLog;
|
||||
import utils.LogFilter;
|
||||
import utils.audio.AudioUtils;
|
||||
|
||||
// NOTE(wisp): Isolated factory to assist with storage and caching if needed.
|
||||
// This also minimizes the number of places JDA interacts with our codebase.
|
||||
// As it stands, if the object name begins with Kitty, it's constructed here.
|
||||
// TODO: Make all methods ID based instead of event based
|
||||
public class ObjectBuilderFactory
|
||||
{
|
||||
// Key: guild string id, Value: guild information
|
||||
private static HashMap<String, KittyGuild> guildCache;
|
||||
|
||||
// Key: channel string id, Value: channel information
|
||||
private static HashMap<String, KittyChannel> channelCache;
|
||||
|
||||
// Key: guild string id + user string id, Value: user information
|
||||
private static HashMap<String, KittyUser> userCache;
|
||||
|
||||
// For tracking and managing object sync
|
||||
private static DatabaseManager database;
|
||||
|
||||
// Stats tracking and whatnot... for setting stats too internally potentially
|
||||
private static Stats stats;
|
||||
|
||||
// RPManger for tracking RP system
|
||||
private static RPManager rpManager;
|
||||
|
||||
// Plugin manager
|
||||
private static PluginManager pluginManager;
|
||||
|
||||
// Command manager
|
||||
private static CommandManager commandManager;
|
||||
|
||||
//Audio track manager
|
||||
private static AudioPlayerManager playerManager = new DefaultAudioPlayerManager();
|
||||
|
||||
// Localization classes - these are singletons, but should be initialized before almost all other
|
||||
// things so their inclusion in the factory is to ensure they're started at the correct time.
|
||||
@SuppressWarnings("unused") private static LocStrings locStrings;
|
||||
@SuppressWarnings("unused") private static LocCommands locCommands;
|
||||
|
||||
// Config
|
||||
@SuppressWarnings("unused") private static Config config;
|
||||
|
||||
// Lazy initialization multithreaded mutex stuff to prevent explosions.
|
||||
// TODO: Investigate using 'synchronized' instead potentially
|
||||
private static boolean hasInitialized;
|
||||
private static Semaphore initMutex = new Semaphore(1);
|
||||
private static JDA kitty;
|
||||
|
||||
// This is it, this is how the lazy init starts!
|
||||
private static void lazyInit()
|
||||
{
|
||||
if(hasInitialized)
|
||||
return;
|
||||
|
||||
try
|
||||
{
|
||||
initMutex.acquire();
|
||||
try
|
||||
{
|
||||
// structure initialization
|
||||
// Construct necessary data structures.
|
||||
guildCache = new HashMap<String, KittyGuild>();
|
||||
userCache = new HashMap<String, KittyUser>();
|
||||
channelCache = new HashMap<String, KittyChannel>();
|
||||
database = null;
|
||||
stats = null;
|
||||
|
||||
AudioSourceManagers.registerRemoteSources(playerManager);
|
||||
AudioSourceManagers.registerLocalSource(playerManager);
|
||||
|
||||
// Start by reading from things that are external. Because
|
||||
// we require these things to be resolved before the rest of the application,
|
||||
// we place them here.
|
||||
config = new Config();
|
||||
}
|
||||
finally
|
||||
{
|
||||
initMutex.release();
|
||||
hasInitialized = true;
|
||||
}
|
||||
}
|
||||
catch(InterruptedException ie)
|
||||
{
|
||||
GlobalLog.error(LogFilter.Core, "Issue during object builder lazy initialization."
|
||||
+ " The factory was not initialized, and kitty will not be able to continue functionally.");
|
||||
}
|
||||
}
|
||||
|
||||
////////////////////////
|
||||
// Extraction Methods //
|
||||
////////////////////////
|
||||
|
||||
// Explicitly locks: guildCache
|
||||
public static KittyGuild extractGuild(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Look up the guild. This process can only happen in a single-threaded way
|
||||
// because of the nature of the cache. We wait until the last second to
|
||||
// look up the guild.
|
||||
String uid = event.getGuild().getId();
|
||||
|
||||
List<Emote> emotes = event.getGuild().getEmotes();
|
||||
ArrayList<String> emotesString = new ArrayList<String>();
|
||||
HashMap<Long, KittyChannel> channels = new HashMap<Long, KittyChannel>();
|
||||
String emote;
|
||||
String emoteFix;
|
||||
channels.put(Long.getLong(uid), extractChannel(event));
|
||||
for(int i = 0; i < emotes.size(); i++)
|
||||
{
|
||||
emote = emotes.get(i).toString();
|
||||
emoteFix = "<:" + emote.substring(2, emote.indexOf("("));
|
||||
emoteFix += ":" + emote.substring(emote.indexOf("(")+1, emote.length()-1) + ">";
|
||||
emotesString.add(emoteFix);
|
||||
}
|
||||
|
||||
// once we're lazily initialized, we can synchronize w/ the
|
||||
// guildCache object now instead of having to use a mutex.
|
||||
KittyGuild guild = null;
|
||||
synchronized (guildCache)
|
||||
{
|
||||
KittyGuild cachedGuild = guildCache.get(uid);
|
||||
if(cachedGuild != null)
|
||||
{
|
||||
guild = cachedGuild;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Construct a new guild with defaults
|
||||
guild = new KittyGuild(uid, new AdminControl(event.getGuild()), emotesString, new AudioUtils(event.getGuild(), playerManager), channels);
|
||||
DatabaseManager.instance.globalRegister(guild);
|
||||
guildCache.put(uid, guild);
|
||||
}
|
||||
}
|
||||
|
||||
return guild;
|
||||
}
|
||||
|
||||
// Explicitly locks: guildCache
|
||||
public static KittyRole extractRole(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Looks up the user role. If none is found we check to see if they own
|
||||
// the guild if not, they're assumed to be
|
||||
// allowed to use the bot at a general level.
|
||||
KittyRole role = KittyRole.General;
|
||||
|
||||
if(event.getAuthor().getId() == event.getGuild().getOwner().getUser().getId())
|
||||
{
|
||||
role = KittyRole.Admin;
|
||||
}
|
||||
|
||||
String uid = event.getGuild().getId() + event.getAuthor().getId();
|
||||
synchronized(userCache)
|
||||
{
|
||||
KittyUser cachedUser = userCache.get(uid);
|
||||
if(cachedUser != null)
|
||||
role = cachedUser.getRole();
|
||||
}
|
||||
|
||||
return role;
|
||||
}
|
||||
|
||||
// Explicitly locks: guildCache
|
||||
// Extracts the content rating information it can from the provided event.
|
||||
public static KittyRating extractContentRating(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Look up content rating of the guild, returns a safe content rating.
|
||||
KittyRating contentRating = KittyRating.Safe;
|
||||
String uid = event.getGuild().getId();
|
||||
synchronized(guildCache)
|
||||
{
|
||||
KittyGuild cachedGuild = guildCache.get(uid);
|
||||
if(cachedGuild != null)
|
||||
contentRating = cachedGuild.contentRating;
|
||||
}
|
||||
|
||||
return contentRating;
|
||||
}
|
||||
|
||||
// Implicitly locks guild cache by calling ExtractGuild
|
||||
public static KittyChannel extractChannel(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
String channelID = event.getChannel().getId();
|
||||
KittyChannel channel = null;
|
||||
|
||||
synchronized(channelCache)
|
||||
{
|
||||
KittyChannel cachedChannel = channelCache.get(channelID);
|
||||
boolean mature;
|
||||
|
||||
if(cachedChannel != null)
|
||||
{
|
||||
channel = cachedChannel;
|
||||
}
|
||||
else
|
||||
{
|
||||
mature = event.getChannel().isNSFW();
|
||||
channel = new KittyChannel(channelID, mature);
|
||||
channelCache.put(channelID, channel);
|
||||
}
|
||||
}
|
||||
|
||||
return channel;
|
||||
}
|
||||
|
||||
// Implicitly locks guild cache by calling ExtractRole and ExtractGuild
|
||||
public static KittyUser extractUser(GuildMessageReceivedEvent event)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
String uid = event.getGuild().getId() + event.getAuthor().getId();
|
||||
KittyUser user = null;
|
||||
synchronized(userCache)
|
||||
{
|
||||
KittyUser cachedUser = userCache.get(uid);
|
||||
if(cachedUser != null)
|
||||
{
|
||||
updateUser(cachedUser, event.getMember());
|
||||
user = cachedUser;
|
||||
}
|
||||
else
|
||||
{
|
||||
KittyRole role = extractRole(event);
|
||||
KittyGuild guild = extractGuild(event);
|
||||
|
||||
String name;
|
||||
if(event.getMember().getNickname() == null)
|
||||
name = event.getAuthor().getName();
|
||||
else
|
||||
name = event.getMember().getNickname();
|
||||
|
||||
String discordID = event.getMember().getUser().getId();
|
||||
String avatarID = event.getAuthor().getAvatarUrl();
|
||||
user = new KittyUser(name, guild, role, uid, avatarID, discordID);
|
||||
DatabaseManager.instance.globalRegister(user);
|
||||
userCache.put(uid, user);
|
||||
}
|
||||
}
|
||||
|
||||
if(event.getMessage().getMentionedMembers().isEmpty())
|
||||
return user;
|
||||
|
||||
Member mentioned;
|
||||
for(int i = 0; i < event.getMessage().getMentionedMembers().size(); i++)
|
||||
{
|
||||
mentioned = event.getMessage().getMentionedMembers().get(i);
|
||||
if(mentioned.getNickname() != null)
|
||||
extractUserByJDAUser(event.getGuild().getId(), mentioned.getNickname(),
|
||||
mentioned.getUser().getId(), mentioned.getUser().getAvatarUrl(), mentioned.getUser().getId());
|
||||
else
|
||||
extractUserByJDAUser(event.getGuild().getId(), mentioned.getUser().getName(),
|
||||
mentioned.getUser().getId(), mentioned.getUser().getAvatarUrl(), mentioned.getUser().getId());
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
// TODO: Clean up
|
||||
public static KittyUser extractUserByJDAUser(String guildID, String name, String userID, String avatarID, String discordID)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
String uid = guildID + userID;
|
||||
KittyUser user = null;
|
||||
synchronized(userCache)
|
||||
{
|
||||
KittyUser cachedUser = userCache.get(uid);
|
||||
if(cachedUser != null)
|
||||
{
|
||||
if(name != null)
|
||||
cachedUser.name = name;
|
||||
|
||||
cachedUser.avatarID = avatarID;
|
||||
user = cachedUser;
|
||||
}
|
||||
else
|
||||
{
|
||||
KittyRole role = KittyRole.General;
|
||||
KittyGuild guild = guildCache.get(guildID);
|
||||
user = new KittyUser(name, guild, role, uid, avatarID, discordID);
|
||||
DatabaseManager.instance.globalRegister(user);
|
||||
userCache.put(uid, user);
|
||||
}
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
// There is some redundant lookup occurring. If the user isn't cached yet, then we construct them and cache them.
|
||||
// The assumption is made that the user does, in fact, exist.
|
||||
public static KittyUser getKittyUser(String guildID, String userID)
|
||||
{
|
||||
String uid = guildID + userID;
|
||||
KittyUser user = null;
|
||||
synchronized(userCache)
|
||||
{
|
||||
user = userCache.get(uid);
|
||||
}
|
||||
|
||||
if(user == null)
|
||||
{
|
||||
Guild jdaGuild = kitty.getGuildById(guildID);
|
||||
if(jdaGuild == null) return null;
|
||||
|
||||
Member jdaMember = jdaGuild.getMemberById(userID);
|
||||
if(jdaMember == null) return null;
|
||||
|
||||
User jdaUser = jdaMember.getUser();
|
||||
if(jdaUser == null) return null;
|
||||
|
||||
user = extractUserByJDAUser(guildID, jdaMember.getNickname(), jdaUser.getId(), jdaUser.getAvatarUrl(), jdaUser.getId());
|
||||
updateUser(user, jdaMember);
|
||||
}
|
||||
|
||||
return user;
|
||||
}
|
||||
|
||||
// Updates a user's name appropriately based on nickname if available
|
||||
public static void updateUser(KittyUser user, Member member)
|
||||
{
|
||||
if(member.getNickname() == null)
|
||||
{
|
||||
user.name = member.getUser().getName();
|
||||
}
|
||||
else
|
||||
{
|
||||
user.name = member.getNickname();
|
||||
}
|
||||
|
||||
user.avatarID = member.getUser().getAvatarUrl();
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////
|
||||
// Construction Methods //
|
||||
//////////////////////////
|
||||
// Builds the core of the bot
|
||||
public static KittyCore constructKittyCore() throws LoginException, InterruptedException
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
// Determine token based on config. Default to test token.
|
||||
String tokenToUse = Ref.TestToken;
|
||||
if(ConfigGlobals.getStartupMode() == KittyStartupMode.Release)
|
||||
tokenToUse = Ref.PoguToken;
|
||||
|
||||
// Construct bot based on token
|
||||
kitty = new JDABuilder(AccountType.BOT)
|
||||
.setToken(tokenToUse).buildBlocking();
|
||||
kitty.getPresence().setGame(Game.playing("with a laser pointer"));
|
||||
kitty.addEventListener(new Main());
|
||||
|
||||
return new KittyCore(kitty);
|
||||
}
|
||||
|
||||
// Default construction of the command manager. In order to remotely resolve command enabling
|
||||
// and disabling, what we do is construct the commands with a localized pair that is checked against
|
||||
// the CommandEnabler object passed in. In theory, we could have multiple CommandManagers, tho we can
|
||||
// only have one CommandEnabler.
|
||||
public static CommandManager constructCommandManager(CommandEnabler commandEnabler)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(commandManager == null)
|
||||
commandManager = new CommandManager(commandEnabler);
|
||||
|
||||
return commandManager;
|
||||
}
|
||||
|
||||
// Default database manager construction. It can be constructed
|
||||
// in different ways, and so we construct it outside of the constructor for
|
||||
// the factory since it doesn't have to be present / can be elsewhere.
|
||||
// Effectively we cache the database here.
|
||||
public static DatabaseManager constructDatabaseManager()
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(database == null)
|
||||
database = new DatabaseManager();
|
||||
|
||||
return database;
|
||||
}
|
||||
|
||||
public static Stats constructStats(CommandManager manager)
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(stats == null)
|
||||
stats = new Stats(manager);
|
||||
|
||||
return stats;
|
||||
}
|
||||
|
||||
public static RPManager constructRPManager()
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(rpManager == null)
|
||||
rpManager = new RPManager();
|
||||
|
||||
return rpManager;
|
||||
}
|
||||
|
||||
public static PluginManager constructPluginManager()
|
||||
{
|
||||
lazyInit();
|
||||
|
||||
if(pluginManager == null)
|
||||
pluginManager = new PluginManager(Constants.AssetDirectory + "plugins/");
|
||||
|
||||
return pluginManager;
|
||||
}
|
||||
|
||||
|
||||
/////////////////////
|
||||
// Utility Methods //
|
||||
/////////////////////
|
||||
|
||||
// Returns number of cached guilds (does not equal total users in the database, only what's in memory)
|
||||
public static Integer getGuildCount()
|
||||
{ synchronized(guildCache)
|
||||
{
|
||||
return guildCache.size();
|
||||
}
|
||||
}
|
||||
|
||||
// Returns number of cached users (does not equal total users in the database, only what's in memory)
|
||||
public static Integer getUserCount()
|
||||
{ synchronized(userCache)
|
||||
{
|
||||
return userCache.size();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,15 @@
|
||||
package dataStructures;
|
||||
|
||||
|
||||
public class KittyChannel
|
||||
{
|
||||
public String uniqueID;
|
||||
public boolean mature;
|
||||
|
||||
public KittyChannel(String uniqueID, boolean mature)
|
||||
{
|
||||
//super(uniqueID);
|
||||
this.uniqueID = uniqueID;
|
||||
this.mature = false;
|
||||
}
|
||||
package dataStructures;
|
||||
|
||||
|
||||
public class KittyChannel
|
||||
{
|
||||
public String uniqueID;
|
||||
public boolean mature;
|
||||
|
||||
public KittyChannel(String uniqueID, boolean mature)
|
||||
{
|
||||
//super(uniqueID);
|
||||
this.uniqueID = uniqueID;
|
||||
this.mature = false;
|
||||
}
|
||||
}
|
||||
+180
-180
@@ -1,180 +1,180 @@
|
||||
package dataStructures;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import core.DatabaseManager;
|
||||
import core.DatabaseTrackedObject;
|
||||
import utils.AdminControl;
|
||||
import utils.audio.AudioUtils;
|
||||
|
||||
// Context for a given guild for kittybot. Primarily designed to hold guild-specific settings.
|
||||
public class KittyGuild extends DatabaseTrackedObject
|
||||
{
|
||||
// Variables
|
||||
public final String uniqueID;
|
||||
public KittyRating contentRating;
|
||||
public KittyUser guildOwner;
|
||||
public boolean polling;
|
||||
public String poll;
|
||||
public boolean raffling;
|
||||
public int raffleCost;
|
||||
public ArrayList<String> hasVoted = new ArrayList<String>();
|
||||
public ArrayList<String> emoji = new ArrayList<String>();
|
||||
public ArrayList <KittyPoll> choices = new ArrayList<KittyPoll>();
|
||||
public HashMap <Long, KittyChannel> channels;
|
||||
public AdminControl control;
|
||||
public AudioUtils audio;
|
||||
public ArrayList <KittyUser> raffleUsersUnchosen = new ArrayList<KittyUser>();
|
||||
public ArrayList <KittyUser> raffleUsersChosen = new ArrayList<KittyUser>();
|
||||
|
||||
// Database synced info
|
||||
private final String roleListName = "guildRoles";
|
||||
public final KittyTrackedVector roleList;
|
||||
|
||||
private final String beansName = "guildBeans";
|
||||
public final KittyTrackedLong beans;
|
||||
|
||||
private String commandIndicator;
|
||||
|
||||
private void registerTrackedObjects()
|
||||
{
|
||||
DatabaseManager.instance.globalRegister(roleList);
|
||||
DatabaseManager.instance.globalRegister(beans);
|
||||
}
|
||||
|
||||
// Default content for a guild
|
||||
public KittyGuild(String uniqueID, AdminControl adminControl, ArrayList <String> emoji, AudioUtils audio, HashMap<Long, KittyChannel> channels)
|
||||
{
|
||||
|
||||
super(uniqueID);
|
||||
this.uniqueID = uniqueID;
|
||||
roleList = new KittyTrackedVector(roleListName, uniqueID);
|
||||
beans = new KittyTrackedLong(beansName, uniqueID);
|
||||
registerTrackedObjects();
|
||||
|
||||
control = adminControl;
|
||||
this.contentRating = KittyRating.Safe;
|
||||
this.polling = false;
|
||||
this.emoji = emoji;
|
||||
this.audio = audio;
|
||||
this.channels = channels;
|
||||
setCommandIndicator("!");
|
||||
}
|
||||
|
||||
// Explicit constructor
|
||||
public KittyGuild(String commandIndicator, KittyRating contentRating, KittyUser guildOwner, String uniqueID, AudioUtils audio, HashMap<Long, KittyChannel> channels)
|
||||
{
|
||||
super(uniqueID);
|
||||
this.uniqueID = uniqueID;
|
||||
roleList = new KittyTrackedVector(roleListName, uniqueID);
|
||||
beans = new KittyTrackedLong(beansName, uniqueID);
|
||||
registerTrackedObjects();
|
||||
|
||||
setCommandIndicator(commandIndicator);
|
||||
this.contentRating = contentRating;
|
||||
this.polling = false;
|
||||
this.guildOwner = guildOwner;
|
||||
this.audio = audio;
|
||||
this.channels = channels;
|
||||
}
|
||||
|
||||
public String startPoll(String poll)
|
||||
{
|
||||
polling = true;
|
||||
this.poll = poll;
|
||||
return "Poll `" + poll + "` started! Don't forget to add choices with `!poll choice`~";
|
||||
}
|
||||
|
||||
public String addChoiceToPoll(String choice)
|
||||
{
|
||||
choices.add(new KittyPoll(choice));
|
||||
return "Added `" + choice + "` to poll!";
|
||||
}
|
||||
|
||||
public String endPoll()
|
||||
{
|
||||
choices.clear();
|
||||
hasVoted.clear();
|
||||
this.polling = false;
|
||||
poll = null;
|
||||
return "Poll ended!";
|
||||
}
|
||||
|
||||
//Raffle methods
|
||||
public boolean startRaffle(int beanCost)
|
||||
{
|
||||
if(raffling)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
raffleCost = beanCost;
|
||||
raffling = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean endRaffle()
|
||||
{
|
||||
if(raffling)
|
||||
{
|
||||
raffleCost = 0;
|
||||
raffling = false;
|
||||
raffleUsersChosen.removeAll(raffleUsersChosen);
|
||||
raffleUsersUnchosen.removeAll(raffleUsersUnchosen);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean joinRaffle(KittyUser user)
|
||||
{
|
||||
if(!raffleUsersChosen.contains(user) && !raffleUsersUnchosen.contains(user) && user.getBeans() > raffleCost && raffling)
|
||||
{
|
||||
user.changeBeans(raffleCost);
|
||||
raffleUsersUnchosen.add(user);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public KittyUser chooseRaffleWinner()
|
||||
{
|
||||
if(!raffleUsersUnchosen.isEmpty())
|
||||
{
|
||||
KittyUser chosen = raffleUsersUnchosen.get((int) (Math.random() * raffleUsersUnchosen.size()));
|
||||
raffleUsersUnchosen.remove(chosen);
|
||||
raffleUsersChosen.add(chosen);
|
||||
return chosen;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialize()
|
||||
{
|
||||
return commandIndicator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deSerialzie(String string)
|
||||
{
|
||||
if(string == null || string.length() == 0)
|
||||
setCommandIndicator("!");
|
||||
else
|
||||
setCommandIndicator(string);
|
||||
}
|
||||
|
||||
public String getCommandIndicator()
|
||||
{
|
||||
return commandIndicator;
|
||||
}
|
||||
|
||||
public void setCommandIndicator(String newIndicator)
|
||||
{
|
||||
if(newIndicator != commandIndicator)
|
||||
{
|
||||
commandIndicator = newIndicator;
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
package dataStructures;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import core.DatabaseManager;
|
||||
import core.DatabaseTrackedObject;
|
||||
import utils.AdminControl;
|
||||
import utils.audio.AudioUtils;
|
||||
|
||||
// Context for a given guild for kittybot. Primarily designed to hold guild-specific settings.
|
||||
public class KittyGuild extends DatabaseTrackedObject
|
||||
{
|
||||
// Variables
|
||||
public final String uniqueID;
|
||||
public KittyRating contentRating;
|
||||
public KittyUser guildOwner;
|
||||
public boolean polling;
|
||||
public String poll;
|
||||
public boolean raffling;
|
||||
public int raffleCost;
|
||||
public ArrayList<String> hasVoted = new ArrayList<String>();
|
||||
public ArrayList<String> emoji = new ArrayList<String>();
|
||||
public ArrayList <KittyPoll> choices = new ArrayList<KittyPoll>();
|
||||
public HashMap <Long, KittyChannel> channels;
|
||||
public AdminControl control;
|
||||
public AudioUtils audio;
|
||||
public ArrayList <KittyUser> raffleUsersUnchosen = new ArrayList<KittyUser>();
|
||||
public ArrayList <KittyUser> raffleUsersChosen = new ArrayList<KittyUser>();
|
||||
|
||||
// Database synced info
|
||||
private final String roleListName = "guildRoles";
|
||||
public final KittyTrackedVector roleList;
|
||||
|
||||
private final String beansName = "guildBeans";
|
||||
public final KittyTrackedLong beans;
|
||||
|
||||
private String commandIndicator;
|
||||
|
||||
private void registerTrackedObjects()
|
||||
{
|
||||
DatabaseManager.instance.globalRegister(roleList);
|
||||
DatabaseManager.instance.globalRegister(beans);
|
||||
}
|
||||
|
||||
// Default content for a guild
|
||||
public KittyGuild(String uniqueID, AdminControl adminControl, ArrayList <String> emoji, AudioUtils audio, HashMap<Long, KittyChannel> channels)
|
||||
{
|
||||
|
||||
super(uniqueID);
|
||||
this.uniqueID = uniqueID;
|
||||
roleList = new KittyTrackedVector(roleListName, uniqueID);
|
||||
beans = new KittyTrackedLong(beansName, uniqueID);
|
||||
registerTrackedObjects();
|
||||
|
||||
control = adminControl;
|
||||
this.contentRating = KittyRating.Safe;
|
||||
this.polling = false;
|
||||
this.emoji = emoji;
|
||||
this.audio = audio;
|
||||
this.channels = channels;
|
||||
setCommandIndicator("!");
|
||||
}
|
||||
|
||||
// Explicit constructor
|
||||
public KittyGuild(String commandIndicator, KittyRating contentRating, KittyUser guildOwner, String uniqueID, AudioUtils audio, HashMap<Long, KittyChannel> channels)
|
||||
{
|
||||
super(uniqueID);
|
||||
this.uniqueID = uniqueID;
|
||||
roleList = new KittyTrackedVector(roleListName, uniqueID);
|
||||
beans = new KittyTrackedLong(beansName, uniqueID);
|
||||
registerTrackedObjects();
|
||||
|
||||
setCommandIndicator(commandIndicator);
|
||||
this.contentRating = contentRating;
|
||||
this.polling = false;
|
||||
this.guildOwner = guildOwner;
|
||||
this.audio = audio;
|
||||
this.channels = channels;
|
||||
}
|
||||
|
||||
public String startPoll(String poll)
|
||||
{
|
||||
polling = true;
|
||||
this.poll = poll;
|
||||
return "Poll `" + poll + "` started! Don't forget to add choices with `!poll choice`~";
|
||||
}
|
||||
|
||||
public String addChoiceToPoll(String choice)
|
||||
{
|
||||
choices.add(new KittyPoll(choice));
|
||||
return "Added `" + choice + "` to poll!";
|
||||
}
|
||||
|
||||
public String endPoll()
|
||||
{
|
||||
choices.clear();
|
||||
hasVoted.clear();
|
||||
this.polling = false;
|
||||
poll = null;
|
||||
return "Poll ended!";
|
||||
}
|
||||
|
||||
//Raffle methods
|
||||
public boolean startRaffle(int beanCost)
|
||||
{
|
||||
if(raffling)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
raffleCost = beanCost;
|
||||
raffling = true;
|
||||
return true;
|
||||
}
|
||||
|
||||
public boolean endRaffle()
|
||||
{
|
||||
if(raffling)
|
||||
{
|
||||
raffleCost = 0;
|
||||
raffling = false;
|
||||
raffleUsersChosen.removeAll(raffleUsersChosen);
|
||||
raffleUsersUnchosen.removeAll(raffleUsersUnchosen);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean joinRaffle(KittyUser user)
|
||||
{
|
||||
if(!raffleUsersChosen.contains(user) && !raffleUsersUnchosen.contains(user) && user.getBeans() > raffleCost && raffling)
|
||||
{
|
||||
user.changeBeans(-raffleCost);
|
||||
raffleUsersUnchosen.add(user);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public KittyUser chooseRaffleWinner()
|
||||
{
|
||||
if(!raffleUsersUnchosen.isEmpty())
|
||||
{
|
||||
KittyUser chosen = raffleUsersUnchosen.get((int) (Math.random() * raffleUsersUnchosen.size()));
|
||||
raffleUsersUnchosen.remove(chosen);
|
||||
raffleUsersChosen.add(chosen);
|
||||
return chosen;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String serialize()
|
||||
{
|
||||
return commandIndicator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void deSerialzie(String string)
|
||||
{
|
||||
if(string == null || string.length() == 0)
|
||||
setCommandIndicator("!");
|
||||
else
|
||||
setCommandIndicator(string);
|
||||
}
|
||||
|
||||
public String getCommandIndicator()
|
||||
{
|
||||
return commandIndicator;
|
||||
}
|
||||
|
||||
public void setCommandIndicator(String newIndicator)
|
||||
{
|
||||
if(newIndicator != commandIndicator)
|
||||
{
|
||||
commandIndicator = newIndicator;
|
||||
markDirty();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+134
-134
@@ -1,135 +1,135 @@
|
||||
package main;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
|
||||
|
||||
import core.CharacterManager;
|
||||
import core.CommandEnabler;
|
||||
import core.CommandManager;
|
||||
import core.DatabaseManager;
|
||||
import core.ObjectBuilderFactory;
|
||||
import core.RPManager;
|
||||
import core.Stats;
|
||||
import core.lua.PluginManager;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyCore;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyUser;
|
||||
import dataStructures.Response;
|
||||
import dataStructures.UserInput;
|
||||
import net.dv8tion.jda.core.AccountType;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.JDABuilder;
|
||||
import net.dv8tion.jda.core.audio.AudioSendHandler;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.core.hooks.ListenerAdapter;
|
||||
import net.dv8tion.jda.core.managers.AudioManager;
|
||||
import offline.Ref;
|
||||
import utils.GlobalLog;
|
||||
|
||||
// http://www.slf4j.org/ - this JDA logging tool has been disabled by specifying NOP implementation.
|
||||
// This is the application entry point, and bot startup location!
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class Main extends ListenerAdapter
|
||||
{
|
||||
// Variables and bot specific objects
|
||||
private static KittyCore kittyCore;
|
||||
private static DatabaseManager databaseManager;
|
||||
private static CommandManager commandManager;
|
||||
private static Stats stats;
|
||||
private static RPManager rpManager;
|
||||
private static PluginManager pluginManager;
|
||||
private static CharacterManager charManager;
|
||||
|
||||
|
||||
// Initialization and setup
|
||||
public static void main(String[] args) throws InterruptedException, LoginException, Exception
|
||||
{
|
||||
// Factory startup. The ordering is intentional.
|
||||
GlobalLog.initialize();
|
||||
databaseManager = ObjectBuilderFactory.constructDatabaseManager();
|
||||
commandManager = ObjectBuilderFactory.constructCommandManager(CommandEnabler.instance); // TODO: Untangle this singleton
|
||||
stats = ObjectBuilderFactory.constructStats(commandManager);
|
||||
charManager = new CharacterManager();
|
||||
rpManager = ObjectBuilderFactory.constructRPManager();
|
||||
pluginManager = ObjectBuilderFactory.constructPluginManager();
|
||||
|
||||
// Bot startup
|
||||
kittyCore = ObjectBuilderFactory.constructKittyCore();
|
||||
}
|
||||
|
||||
// When a message is sent in a server that kitty is in, this is what's called.
|
||||
@Override
|
||||
public void onGuildMessageReceived(GuildMessageReceivedEvent event)
|
||||
{
|
||||
// Tweak the event as necessary
|
||||
if(!Superintendent.preProcessSetup(event, stats))
|
||||
return;
|
||||
|
||||
// Factory objects
|
||||
KittyUser user = ObjectBuilderFactory.extractUser(event);
|
||||
KittyGuild guild = ObjectBuilderFactory.extractGuild(event);
|
||||
KittyChannel channel = ObjectBuilderFactory.extractChannel(event);
|
||||
|
||||
// Specialized uncached objects
|
||||
Response response = new Response(event, kittyCore);
|
||||
UserInput input = new UserInput(event, guild);
|
||||
|
||||
// Tweak object construction as necessary
|
||||
if(!Superintendent.postProcessSetup(event, user, guild, channel, response, input))
|
||||
return;
|
||||
|
||||
// Track beans!
|
||||
user.changeBeans(1);
|
||||
|
||||
// RP logging system
|
||||
RPManager.instance.addLine(channel, user, input);
|
||||
|
||||
// Run any pre-emptive upkeep we need to
|
||||
if(!Superintendent.perCommandUpkeepPre(pluginManager))
|
||||
return;
|
||||
|
||||
// Attempt to spin up a command. If the command doesn't exist.
|
||||
// Run plugins right before invoking the commands but after all other setup.
|
||||
if(commandManager.invokeOnNewThread(guild, channel, user, input, response) == false)
|
||||
{
|
||||
List<String> pluginOutput = pluginManager.runAll(input.message, user);
|
||||
|
||||
if(pluginOutput != null && pluginOutput.size() > 0)
|
||||
{
|
||||
for(int i = 0; i < pluginOutput.size(); ++i)
|
||||
{
|
||||
if(pluginOutput.get(i).startsWith("!"))
|
||||
{
|
||||
commandManager.invokeOnNewThread(guild, channel, user, new UserInput(pluginOutput.get(i).substring(1), guild), response);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.send(pluginOutput.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run any upkeep in post we need to
|
||||
if(!Superintendent.perCommandUpkeepPost(kittyCore, databaseManager))
|
||||
return;
|
||||
}
|
||||
package main;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import javax.security.auth.login.LoginException;
|
||||
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioLoadResultHandler;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayer;
|
||||
import com.sedmelluq.discord.lavaplayer.player.AudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.player.DefaultAudioPlayerManager;
|
||||
import com.sedmelluq.discord.lavaplayer.source.AudioSourceManagers;
|
||||
import com.sedmelluq.discord.lavaplayer.tools.FriendlyException;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioPlaylist;
|
||||
import com.sedmelluq.discord.lavaplayer.track.AudioTrack;
|
||||
import com.sedmelluq.discord.lavaplayer.track.playback.AudioFrame;
|
||||
|
||||
import core.CharacterManager;
|
||||
import core.CommandEnabler;
|
||||
import core.CommandManager;
|
||||
import core.DatabaseManager;
|
||||
import core.ObjectBuilderFactory;
|
||||
import core.RPManager;
|
||||
import core.Stats;
|
||||
import core.lua.PluginManager;
|
||||
import dataStructures.KittyChannel;
|
||||
import dataStructures.KittyCore;
|
||||
import dataStructures.KittyGuild;
|
||||
import dataStructures.KittyUser;
|
||||
import dataStructures.Response;
|
||||
import dataStructures.UserInput;
|
||||
import net.dv8tion.jda.core.AccountType;
|
||||
import net.dv8tion.jda.core.JDA;
|
||||
import net.dv8tion.jda.core.JDABuilder;
|
||||
import net.dv8tion.jda.core.audio.AudioSendHandler;
|
||||
import net.dv8tion.jda.core.entities.Guild;
|
||||
import net.dv8tion.jda.core.entities.TextChannel;
|
||||
import net.dv8tion.jda.core.entities.VoiceChannel;
|
||||
import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent;
|
||||
import net.dv8tion.jda.core.hooks.ListenerAdapter;
|
||||
import net.dv8tion.jda.core.managers.AudioManager;
|
||||
import offline.Ref;
|
||||
import utils.GlobalLog;
|
||||
|
||||
// http://www.slf4j.org/ - this JDA logging tool has been disabled by specifying NOP implementation.
|
||||
// This is the application entry point, and bot startup location!
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class Main extends ListenerAdapter
|
||||
{
|
||||
// Variables and bot specific objects
|
||||
private static KittyCore kittyCore;
|
||||
private static DatabaseManager databaseManager;
|
||||
private static CommandManager commandManager;
|
||||
private static Stats stats;
|
||||
private static RPManager rpManager;
|
||||
private static PluginManager pluginManager;
|
||||
private static CharacterManager charManager;
|
||||
|
||||
|
||||
// Initialization and setup
|
||||
public static void main(String[] args) throws InterruptedException, LoginException, Exception
|
||||
{
|
||||
// Factory startup. The ordering is intentional.
|
||||
GlobalLog.initialize();
|
||||
databaseManager = ObjectBuilderFactory.constructDatabaseManager();
|
||||
commandManager = ObjectBuilderFactory.constructCommandManager(CommandEnabler.instance); // TODO: Untangle this singleton
|
||||
stats = ObjectBuilderFactory.constructStats(commandManager);
|
||||
charManager = new CharacterManager();
|
||||
rpManager = ObjectBuilderFactory.constructRPManager();
|
||||
pluginManager = ObjectBuilderFactory.constructPluginManager();
|
||||
|
||||
// Bot startup
|
||||
kittyCore = ObjectBuilderFactory.constructKittyCore();
|
||||
}
|
||||
|
||||
// When a message is sent in a server that kitty is in, this is what's called.
|
||||
@Override
|
||||
public void onGuildMessageReceived(GuildMessageReceivedEvent event)
|
||||
{
|
||||
// Tweak the event as necessary
|
||||
if(!Superintendent.preProcessSetup(event, stats))
|
||||
return;
|
||||
|
||||
// Factory objects
|
||||
KittyUser user = ObjectBuilderFactory.extractUser(event);
|
||||
KittyGuild guild = ObjectBuilderFactory.extractGuild(event);
|
||||
KittyChannel channel = ObjectBuilderFactory.extractChannel(event);
|
||||
|
||||
// Specialized uncached objects
|
||||
Response response = new Response(event, kittyCore);
|
||||
UserInput input = new UserInput(event, guild);
|
||||
|
||||
// Tweak object construction as necessary
|
||||
if(!Superintendent.postProcessSetup(event, user, guild, channel, response, input))
|
||||
return;
|
||||
|
||||
// Track beans!
|
||||
user.changeBeans(1);
|
||||
|
||||
// RP logging system
|
||||
RPManager.instance.addLine(channel, user, input);
|
||||
|
||||
// Run any pre-emptive upkeep we need to
|
||||
if(!Superintendent.perCommandUpkeepPre(pluginManager))
|
||||
return;
|
||||
|
||||
// Attempt to spin up a command. If the command doesn't exist.
|
||||
// Run plugins right before invoking the commands but after all other setup.
|
||||
if(commandManager.invokeOnNewThread(guild, channel, user, input, response) == false)
|
||||
{
|
||||
List<String> pluginOutput = pluginManager.runAll(input.message, user);
|
||||
|
||||
if(pluginOutput != null && pluginOutput.size() > 0)
|
||||
{
|
||||
for(int i = 0; i < pluginOutput.size(); ++i)
|
||||
{
|
||||
if(pluginOutput.get(i).startsWith("!"))
|
||||
{
|
||||
commandManager.invokeOnNewThread(guild, channel, user, new UserInput(pluginOutput.get(i).substring(1), guild), response);
|
||||
}
|
||||
else
|
||||
{
|
||||
response.send(pluginOutput.get(i));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Run any upkeep in post we need to
|
||||
if(!Superintendent.perCommandUpkeepPost(kittyCore, databaseManager))
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -1,48 +1,48 @@
|
||||
package network;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import offline.Ref;
|
||||
import utils.HTTPUtils;
|
||||
|
||||
public class NetworkSauceNAO
|
||||
{
|
||||
private static final Gson jsonParser_ = new Gson();
|
||||
private static final String API_ROOT = "https://saucenao.com/search.php?db=999&output_type=2&numres=10&api_key=" + Ref.SauceNAOKey +"&url=";
|
||||
NetworkE6 e6Sauce = new NetworkE6();
|
||||
private class SauceNAOResponseObject
|
||||
{
|
||||
List<SauceNAOResult> results;
|
||||
}
|
||||
|
||||
private class SauceNAOResult
|
||||
{
|
||||
SauceNAOData data;
|
||||
}
|
||||
|
||||
private class SauceNAOData
|
||||
{
|
||||
String [] ext_urls;
|
||||
}
|
||||
|
||||
public String getSauce(String input)
|
||||
{
|
||||
input = input.trim();
|
||||
input = input.replace("+", "%2B");
|
||||
input = input.replace(" ", "%20");
|
||||
|
||||
String res = HTTPUtils.sendGETRequest(API_ROOT + input);
|
||||
|
||||
SauceNAOResponseObject sauce = jsonParser_.fromJson(res, SauceNAOResponseObject.class);
|
||||
String sauceUrl = sauce.results.get(0).data.ext_urls[0];
|
||||
if(sauceUrl.startsWith("https://e621.net/post/show/"))
|
||||
{
|
||||
System.out.println("id:" + sauceUrl.substring(26));
|
||||
return e6Sauce.getE6("id:" + sauceUrl.substring(27)).toString();
|
||||
}
|
||||
return sauce.results.get(0).data.ext_urls[0];
|
||||
}
|
||||
|
||||
}
|
||||
package network;
|
||||
|
||||
import java.util.List;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
|
||||
import offline.Ref;
|
||||
import utils.HTTPUtils;
|
||||
|
||||
public class NetworkSauceNAO
|
||||
{
|
||||
private static final Gson jsonParser_ = new Gson();
|
||||
private static final String API_ROOT = "https://saucenao.com/search.php?db=999&output_type=2&numres=10&api_key=" + Ref.SauceNAOKey +"&url=";
|
||||
NetworkE6 e6Sauce = new NetworkE6();
|
||||
private class SauceNAOResponseObject
|
||||
{
|
||||
List<SauceNAOResult> results;
|
||||
}
|
||||
|
||||
private class SauceNAOResult
|
||||
{
|
||||
SauceNAOData data;
|
||||
}
|
||||
|
||||
private class SauceNAOData
|
||||
{
|
||||
String [] ext_urls;
|
||||
}
|
||||
|
||||
public String getSauce(String input)
|
||||
{
|
||||
input = input.trim();
|
||||
input = input.replace("+", "%2B");
|
||||
input = input.replace(" ", "%20");
|
||||
|
||||
String res = HTTPUtils.sendGETRequest(API_ROOT + input);
|
||||
|
||||
SauceNAOResponseObject sauce = jsonParser_.fromJson(res, SauceNAOResponseObject.class);
|
||||
String sauceUrl = sauce.results.get(0).data.ext_urls[0];
|
||||
if(sauceUrl.startsWith("https://e621.net/post/show/"))
|
||||
{
|
||||
System.out.println("id:" + sauceUrl.substring(26));
|
||||
return e6Sauce.getE6("id:" + sauceUrl.substring(27)).toString();
|
||||
}
|
||||
return sauce.results.get(0).data.ext_urls[0];
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@@ -119,6 +119,16 @@ public class AudioUtils
|
||||
return null;
|
||||
}
|
||||
|
||||
public int getVolume(AudioPlayer player)
|
||||
{
|
||||
return player.getVolume();
|
||||
}
|
||||
|
||||
public void changeVolume(AudioPlayer player, int newVol)
|
||||
{
|
||||
player.setVolume(newVol);
|
||||
}
|
||||
|
||||
public String skipVideo(AudioPlayer player)
|
||||
{
|
||||
player.stopTrack();
|
||||
@@ -152,6 +162,9 @@ class MusicController extends Thread
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
try {
|
||||
Thread.sleep(5000);
|
||||
} catch (InterruptedException e) {}
|
||||
AudioTrack nowPlaying = null;
|
||||
do
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user