From e1fca7a08c81b545746590b86bf068489c1b3fb8 Mon Sep 17 00:00:00 2001 From: Ramid Khan Date: Tue, 21 Nov 2017 21:34:28 +1100 Subject: [PATCH 01/14] Update some stuff --- .../ml/duncte123/skybot/EventManager.java | 36 +++++++++++++++++++ src/main/java/ml/duncte123/skybot/SkyBot.java | 6 +++- .../commands/essentials/RestartCommand.kt | 2 +- .../commands/essentials/UpdateCommand.kt | 2 +- 4 files changed, 43 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ml/duncte123/skybot/EventManager.java diff --git a/src/main/java/ml/duncte123/skybot/EventManager.java b/src/main/java/ml/duncte123/skybot/EventManager.java new file mode 100644 index 000000000..8835b6174 --- /dev/null +++ b/src/main/java/ml/duncte123/skybot/EventManager.java @@ -0,0 +1,36 @@ +package ml.duncte123.skybot; + +import net.dv8tion.jda.core.events.Event; +import net.dv8tion.jda.core.hooks.IEventManager; + +import java.util.Arrays; +import java.util.List; + +/** + * A single event listener container + */ +class EventManager +implements IEventManager { + + private BotListener botListener = new BotListener(); + + @Override + public void register(Object listener) { + throw new IllegalArgumentException(); + } + + @Override + public void unregister(Object listener) { + throw new IllegalArgumentException(); + } + + @Override + public void handle(Event event) { + botListener.onEvent(event); + } + + @Override + public List getRegisteredListeners() { + return Arrays.asList(botListener); + } +} diff --git a/src/main/java/ml/duncte123/skybot/SkyBot.java b/src/main/java/ml/duncte123/skybot/SkyBot.java index 13999a801..4b1813146 100644 --- a/src/main/java/ml/duncte123/skybot/SkyBot.java +++ b/src/main/java/ml/duncte123/skybot/SkyBot.java @@ -27,10 +27,14 @@ import ml.duncte123.skybot.utils.Settings; import net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder; import net.dv8tion.jda.core.entities.Game; +import net.dv8tion.jda.core.events.Event; +import net.dv8tion.jda.core.hooks.IEventManager; import org.apache.commons.lang3.time.DateUtils; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; +import java.util.List; + /** * NOTE TO SELF String.format("%#s", userObject) */ @@ -90,7 +94,7 @@ public static void main(String... args) throws Exception { //Set up sharding for the bot new DefaultShardManagerBuilder() - .addEventListeners(new BotListener()) //event.getJDA().getRegisteredListeners().get(0) + .setEventManager(new EventManager()) .setAudioSendFactory(new NativeAudioSendFactory()) .setShardsTotal(TOTAL_SHARDS) .setGameProvider(shardId -> Game.watching("Danny Phantom on shard #" + (shardId + 1))) diff --git a/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt b/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt index 291f6304d..66876c68b 100644 --- a/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt +++ b/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt @@ -36,7 +36,7 @@ class RestartCommand : Command() { } override fun executeCommand(invoke: String?, args: Array?, event: GuildMessageReceivedEvent) { - if (!Arrays.asList(*Settings.wbkxwkZPaG4ni5lm8laY).contains(event.author.id)) return + if (!Settings.wbkxwkZPaG4ni5lm8laY.contains(event.author.id)) return val shardManager = event.jda.asBot().shardManager // val list = event.jda.registeredListeners.filter { t -> t is BotListener}.map {t -> t as BotListener} diff --git a/src/main/kotlin/ml/duncte123/skybot/commands/essentials/UpdateCommand.kt b/src/main/kotlin/ml/duncte123/skybot/commands/essentials/UpdateCommand.kt index 5f4c25588..3fdea8004 100644 --- a/src/main/kotlin/ml/duncte123/skybot/commands/essentials/UpdateCommand.kt +++ b/src/main/kotlin/ml/duncte123/skybot/commands/essentials/UpdateCommand.kt @@ -14,7 +14,7 @@ class UpdateCommand: Command() { } override fun executeCommand(invoke: String, args: Array?, event: GuildMessageReceivedEvent) { - if (!Arrays.asList(*Settings.wbkxwkZPaG4ni5lm8laY).contains(event.author.id) + if (!Settings.wbkxwkZPaG4ni5lm8laY.contains(event.author.id) && Settings.ownerId != event.author.id) { event.channel.sendMessage(":x: ***YOU ARE DEFINITELY THE OWNER OF THIS BOT***").queue() sendError(event.message) From 4767ac38fd848ba48d247b599add1b9d268a939b Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Tue, 21 Nov 2017 11:58:32 +0100 Subject: [PATCH 02/14] Remove clutter --- .../commands/essentials/RestartCommand.kt | 28 ------------------- 1 file changed, 28 deletions(-) diff --git a/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt b/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt index 291f6304d..7b6abf226 100644 --- a/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt +++ b/src/main/kotlin/ml/duncte123/skybot/commands/essentials/RestartCommand.kt @@ -39,36 +39,8 @@ class RestartCommand : Command() { if (!Arrays.asList(*Settings.wbkxwkZPaG4ni5lm8laY).contains(event.author.id)) return val shardManager = event.jda.asBot().shardManager -// val list = event.jda.registeredListeners.filter { t -> t is BotListener}.map {t -> t as BotListener} -// -// if(list.isEmpty()) { -// sendMsg(event, "There are no command listeners in here?") -// sendError(event.message) -// return -// } - -// val restart = list[0].restart - -// if(args!!.isEmpty()) { - // Stop all shards -// shardManager.shutdown() -// if (!restart) { - // Clean the variables -// AirUtils.reload() - // Re-run the main command -// SkyBot.main() -// } else - // Magic code, send the restart signal to the executing program -// System.exit(0x5454) -// } else try { -// shardManager.shutdown(args[0].toInt()) -// } catch (e: NumberFormatException) { -// sendMsg(event, "Invalid shard number") -// sendError(event.message) -// } if (args == null) { error("args is null?!") - return } when (args.size) { From c594765c29e9c8e70aa0351d26238fb8c804b2bc Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Tue, 21 Nov 2017 12:09:07 +0100 Subject: [PATCH 03/14] Update guild count when ready --- src/main/java/ml/duncte123/skybot/BotListener.java | 2 ++ src/main/java/ml/duncte123/skybot/SkyBot.java | 4 ---- 2 files changed, 2 insertions(+), 4 deletions(-) diff --git a/src/main/java/ml/duncte123/skybot/BotListener.java b/src/main/java/ml/duncte123/skybot/BotListener.java index b0c9a85d9..4faa14566 100644 --- a/src/main/java/ml/duncte123/skybot/BotListener.java +++ b/src/main/java/ml/duncte123/skybot/BotListener.java @@ -201,6 +201,8 @@ public void run() { settingsUpdateTimer.schedule(settingsTask, DateUtils.MILLIS_PER_HOUR, DateUtils.MILLIS_PER_HOUR); settingsUpdateTimerRunning = true; } + //Update guild count from then the bot was offline (should never die tho) + AirUtils.updateGuildCount(event.getJDA(), event.getJDA().asBot().getShardManager().getGuildCache().size()); } /** diff --git a/src/main/java/ml/duncte123/skybot/SkyBot.java b/src/main/java/ml/duncte123/skybot/SkyBot.java index 4b1813146..7dcc2ba0a 100644 --- a/src/main/java/ml/duncte123/skybot/SkyBot.java +++ b/src/main/java/ml/duncte123/skybot/SkyBot.java @@ -27,14 +27,10 @@ import ml.duncte123.skybot.utils.Settings; import net.dv8tion.jda.bot.sharding.DefaultShardManagerBuilder; import net.dv8tion.jda.core.entities.Game; -import net.dv8tion.jda.core.events.Event; -import net.dv8tion.jda.core.hooks.IEventManager; import org.apache.commons.lang3.time.DateUtils; import org.slf4j.LoggerFactory; import org.slf4j.event.Level; -import java.util.List; - /** * NOTE TO SELF String.format("%#s", userObject) */ From de33425112301818bda3c35701ef3383590004d5 Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Tue, 21 Nov 2017 15:35:42 +0100 Subject: [PATCH 04/14] Load the WA engine before loading the commands --- src/main/java/ml/duncte123/skybot/utils/AirUtils.java | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/java/ml/duncte123/skybot/utils/AirUtils.java b/src/main/java/ml/duncte123/skybot/utils/AirUtils.java index ea8321196..41c91f5f2 100644 --- a/src/main/java/ml/duncte123/skybot/utils/AirUtils.java +++ b/src/main/java/ml/duncte123/skybot/utils/AirUtils.java @@ -48,6 +48,10 @@ public class AirUtils { * This is our config file */ public static Config config = new ConfigUtils().loadConfig(); + /** + * The {@link WAEngine engine} to query Wolfram|Alpha + */ + public static final WAEngine alphaEngine = getWolframEngine(); /** * This will hold the command setup and the registered commands */ @@ -56,10 +60,6 @@ public class AirUtils { * We are using slf4j to log things to the console */ public static Logger logger = LoggerFactory.getLogger(Settings.defaultName); - /** - * The {@link WAEngine engine} to query Wolfram|Alpha - */ - public static final WAEngine alphaEngine = getWolframEngine(); /** * This holds the value if we should use a non-SQLite database */ From ee82c32cf9c54be2d9ff35c408e174bc196af04f Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Tue, 21 Nov 2017 17:37:23 +0100 Subject: [PATCH 05/14] Orginize imports (and don't tell anyone about the failure --- .../skybot/commands/essentials/eval/filter/EvalFilter.java | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java b/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java index 5d98f0206..d235851ea 100644 --- a/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java +++ b/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java @@ -24,17 +24,18 @@ import groovy.lang.Script; import ml.duncte123.skybot.entities.delegate.GuildDelegate; import ml.duncte123.skybot.entities.delegate.JDADelegate; -import ml.duncte123.skybot.entities.delegate.MemberDelegate; import ml.duncte123.skybot.entities.delegate.UserDelegate; import net.dv8tion.jda.core.JDA; import net.dv8tion.jda.core.entities.Guild; -import net.dv8tion.jda.core.entities.Member; import net.dv8tion.jda.core.entities.User; import org.kohsuke.groovy.sandbox.GroovyValueFilter; import java.math.BigDecimal; import java.math.BigInteger; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; import java.util.regex.Pattern; import java.util.stream.Collectors; From bf21664454939956ef0b3c1ff034e134fbba0d10 Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Tue, 21 Nov 2017 18:30:24 +0100 Subject: [PATCH 06/14] Allow java.lang.Math in eval --- .../essentials/eval/filter/EvalFilter.java | 7 +- .../objects/delegate/ScriptDelegate.java | 78 +++++++++++++++++++ 2 files changed, 82 insertions(+), 3 deletions(-) create mode 100644 src/main/java/ml/duncte123/skybot/objects/delegate/ScriptDelegate.java diff --git a/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java b/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java index d235851ea..5c0a1d730 100644 --- a/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java +++ b/src/main/java/ml/duncte123/skybot/commands/essentials/eval/filter/EvalFilter.java @@ -25,6 +25,7 @@ import ml.duncte123.skybot.entities.delegate.GuildDelegate; import ml.duncte123.skybot.entities.delegate.JDADelegate; import ml.duncte123.skybot.entities.delegate.UserDelegate; +import ml.duncte123.skybot.objects.delegate.ScriptDelegate; import net.dv8tion.jda.core.JDA; import net.dv8tion.jda.core.entities.Guild; import net.dv8tion.jda.core.entities.User; @@ -45,6 +46,7 @@ public class EvalFilter extends GroovyValueFilter { * This contains a list of all the allowed classes */ private static final Class[] ALLOWED_TYPES_LIST = { + Math.class, String.class, Boolean.class, @@ -113,9 +115,8 @@ public class EvalFilter extends GroovyValueFilter { */ @Override public final Object filter(Object o) { - if (o == null || ALLOWED_TYPES.contains(o.getClass())) + if (o==null || ALLOWED_TYPES.contains(o.getClass()) ) return o; - //Return delegates for the objects, if they get access to the actual classes in some way they will get blocked //because the class is not whitelisted if(o instanceof JDA) @@ -126,7 +127,7 @@ public final Object filter(Object o) { return new GuildDelegate((Guild) o); //////////////////////////////////////////// if(o instanceof Script) - return o; + return new ScriptDelegate((Script) o); if (o instanceof Closure) throw new SecurityException("Closures are not allowed."); throw new VRCubeException("Class not allowed: " + o.getClass().getName()); diff --git a/src/main/java/ml/duncte123/skybot/objects/delegate/ScriptDelegate.java b/src/main/java/ml/duncte123/skybot/objects/delegate/ScriptDelegate.java new file mode 100644 index 000000000..cc55edbf9 --- /dev/null +++ b/src/main/java/ml/duncte123/skybot/objects/delegate/ScriptDelegate.java @@ -0,0 +1,78 @@ +/* + * Skybot, a multipurpose discord bot + * Copyright (C) 2017 Duncan "duncte123" Sterken & Ramid "ramidzkh" Khan & Sanduhr32 + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as published + * by the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +package ml.duncte123.skybot.objects.delegate; + +import Java.lang.VRCubeException; +import groovy.lang.Script; +import org.codehaus.groovy.control.CompilationFailedException; + +import java.io.File; +import java.io.IOException; + +public class ScriptDelegate extends Script { + + public ScriptDelegate(Script s) { + super(s.getBinding()); + } + + @Override + public Object run() { + return "I'm a bot, I can't run."; + } + + @Override + public void println() { + throw new VRCubeException("Hey, i like to keep my console clean"); + } + + @Override + public void print(Object value) { + throw new VRCubeException("Hey, i like to keep my console clean"); + } + + @Override + public void println(Object value) { + throw new VRCubeException("Hey, i like to keep my console clean"); + } + + @Override + public void printf(String format, Object value) { + throw new VRCubeException("Hey, i like to keep my console clean"); + } + + @Override + public void printf(String format, Object[] values) { + throw new VRCubeException("Hey, i like to keep my console clean"); + } + + @Override + public Object evaluate(String expression) throws CompilationFailedException { + throw new VRCubeException("Erm, no?"); + } + + @Override + public Object evaluate(File file) throws CompilationFailedException, IOException { + throw new VRCubeException("Erm, no?"); + } + + @Override + public void run(File file, String[] arguments) throws CompilationFailedException, IOException { + throw new VRCubeException("Erm, no?"); + } +} From 4b2ffb1541e1f764d191938db4af523915f96af7 Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Tue, 21 Nov 2017 18:34:00 +0100 Subject: [PATCH 07/14] Erm, what about the owner? --- .../duncte123/skybot/commands/essentials/eval/EvalCommand.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ml/duncte123/skybot/commands/essentials/eval/EvalCommand.java b/src/main/java/ml/duncte123/skybot/commands/essentials/eval/EvalCommand.java index 00de35ef6..4c6f2d24a 100644 --- a/src/main/java/ml/duncte123/skybot/commands/essentials/eval/EvalCommand.java +++ b/src/main/java/ml/duncte123/skybot/commands/essentials/eval/EvalCommand.java @@ -87,7 +87,7 @@ public EvalCommand() { public void executeCommand(String invoke, String[] args, GuildMessageReceivedEvent event) { boolean isRanByBotOwner = Arrays.asList(Settings.wbkxwkZPaG4ni5lm8laY).contains( event.getAuthor().getId()) || - event.getAuthor().getId().equals(Settings.wbkxwkZPaG4ni5lm8laY[0]); + event.getAuthor().getId().equals(Settings.ownerId); if (!isRanByBotOwner && !hasUpvoted(event.getAuthor())) { sendError(event.getMessage()); From 5e53a24c0eb40ce379cb93089a44b6732eeb7387 Mon Sep 17 00:00:00 2001 From: duncte123 Date: Wed, 22 Nov 2017 10:21:46 +0100 Subject: [PATCH 08/14] Some stuff --- .gitignore | 2 ++ gradle/wrapper/gradle-wrapper.jar | Bin 54712 -> 54731 bytes 2 files changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 26ece123c..d2b029805 100644 --- a/.gitignore +++ b/.gitignore @@ -130,3 +130,5 @@ skybot-updater/\.idea/libraries/Gradle__org_hamcrest_hamcrest_core_1_3\.xml skybot-updater/\.idea/workspace\.xml skybot-updater/updater\.json + +*.db diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index ed88a042a287c140a32e1639edfc91b2a233da8c..6b6ea3ab4ff4f69d55c5fd9c0a6ac70f47d41008 100644 GIT binary patch delta 1771 zcmVlyNL@p1tGkQ%YJ9d8N?8pdv=1pol$4U>PO zAd`^I43i0P8h=nIgj*maK+>ck(4yF08T7A84n9Ntx;NiHFYg zPxObh{f?~2vSpV{Clj4Lt3A8l?tXjZKmPvpHvli=+bFhSO2r#dv|*|PTQS{%8N4Z_ zS^2mg!yInJa1(FI$J;7y#h_zeMOH;Fiq7gOA*FYulz*4ff_xYe+>YQ~sWc;4l&XR} zYsp7Z#T^y40@W&(4XaR6&^2~jzpG~|Wy8!&it@06j!7e5(90EDDA-;9_IPz`>Vx(SPj%wF;s}AzPWJPHvRz1f937N^!<0FDN+J2->pqnY^v%Op(c&MrOoXT+|D> zF{2!auj)I|NfH(uIsmsy8IZ3Wn9qmu9%1ra&WXhe) z|BRow8&>kIr*7C5rHaYSHU-|Et{7%cNCtG$cb&7t$)K-Qp^OvODbuv>`LVVq2RI&^ zy?YfB15E zIcZhwtT<;#_V)y=4oI&W_CvC^7U6#;d8nDfX1*&-xk@j!;$F~+|G+>%ODj(Q?pmj zvPZ$2K|#cD?=Tj+uJ^vXEgsbJ%R{=4i~EckDmY91>{KD~@Y*^G5Tl-x>`Vr2C4axe zda)=9G#G3;JguiMY>Gl&GMF_ORj@TV@?X}GvQ<^dh`AgminHx!>xgBV#3U){z_P`n zbyr{~zsB46=?^0=Sq3(WyEf|EB+^j%DOKf$QI=wU89iDj5r&QThr#Y?nE(P9`e{=C`ClS#gL1qX?b zsBj2FfFo_kVIn_5S>syO9QE>gmC`YKsb-boPTH)I&>lMm8K;O+xyK1wb$_zP4N!G* zoVwR=!gX?$s|2B@(y|hdy}Y81dVq&hj;o%knTJ(%J5$3dHT@pelTMh|`IKRfP$O+R zQtJ_03Do8bbb!Y*KFl3%AO)wII$7Jy$w3ESGbg7p;yU@$O;|ibC!5|i#_DxHhnAM> z64uRdjXy^+y@d7OA)4;)TYtianRI-kd?$_Kju7v0Z4(dC+i2VCm@Hva4d5~U&;(l< zVH3N!>t!Eyut0m+i9u#~hdV)m2*)2NLeRxz4&zQ#}|MbNh zr%yDQK3*$cQT&G!jg>H(9G2Z{Huq{{O6c2@4v=ZlwhP0OgZm&1C|vb(3*{Ba`dRF#?))lW~C~lg4%$ zlUvRz0x)`$ae*U~TzV3dyv`~DBz=={fg_VpeH)Wo&JdF}&l&+}lTpue0tSSWae*U~ z>CZ+1D3dVIX#y&blQEYmlU$D$lRncBlj_hK0v(c*F_$TmFVQ*zE0vQmmnoB7l@XIZ z(-4!j(Ha3LlhDy%0t=dxF_$lsVbVGR<(!jofg_W^(mMh?pObNcBaS}R001EVT{r*$ delta 1810 zcmYk6cTm&W7Jx%AYltWq1tpNMfIvi)zEqzOR;q#s0SUbeC_?ChL=hNC^y));|cg}b3oSE~-d0j2oRxOyJeP~1TihItl_Q05SK+q5K;3xuMzpa&u$K1R1^Rm{n2 zZT*4yP2TMfl;f>UN5A*yS<=r|doH(bwNqlOU#(=UKYRP@Eq06eyHcF1_eqF;qos-C zgNI$P?PODvn@X^?MRMvM4CQ`>wzp%5iS)Aej;(qt7dv!p+&TS|4^@AxbOyHV(L;#0 zUVj=dh}jh`Ca#|PqUIKeS#XzDX?23JPrJWc4va*GyLsBt9CmOtZP|zgq7pVK7XL0S zH`4j~P|ae5+t3ZY7-UG{*&gZN$O`WgarR|2Z7v6k{oLOIQS)ZhPNkd3hhF`iaKdz`S!d-J_1P1hbPFDnj{ zk~tQdQCpVlAqr5+kGvkwt?58SY;AQsT-Zft#rwFIwFQ=SUlnC8eBCN84E`WEKUf!f z6?S1a!ZB_@9v+>sDH9N9sxRxT;zPy^8W_*a+O}LWI#ij*^#oQM z12aO2=#B!oOFN;Nv2^tiJxcqI$jIC*!AR+8a zcwZaI`2Nn}C(zJTgvV&+R5Cq)LN%lq8<3B=vXU0TrxeVw!D@JpJGkY*9kiq(B zp%=l#h-GJR;Y)~0t1ZnnBI%h1&DDzfvEs4PyU()!;KC#N&P8a4rsA!-lcb^(%=Xfc z{$2p%bj;KfzE*JKCZ9{=c1X8ZmhoFlStUzc(kxS)fn3kB+`EFt zy>fd|1NTsnCn{4q_izADuuc={^5;gwJU&cuHpZJBS{f~8E~MDmM%@g6d-_6V(BpMg zR&~8_6=`6s5sbC?XY%^|3nxjx62|WP*c`T&gJAnNmFBweY%5{5#v#x(%frxmG0t_s zif+wc-vlG?0&2r(pl?_keEc5Yp++u) zu@Cr|JYo&rddSEBj+lVOQu*k|x(q&*&PV@rDPWbQ1cqhtQ-e2#;L|yL49GckU_^me zZxCRyJbuX{Ul=&SRt4{n{+~(#wIiZHHX8wE7ao)}`5!EbMTJ2>&)H)B+n8b$UnZCS zTl$qANLiqGR8;^DutsgcE1iH*t1O`3B@EOvMFB4k0=(V>5IDX9bbxzs=K)v8)Fpom aN$jA*iGw)(v(pdw2;`5Q`^A|4gZ~HOz+3bH From 13ed2493b5a34b5ac740c41ddb7c8087bd7f475b Mon Sep 17 00:00:00 2001 From: Duncan Sterken Date: Wed, 22 Nov 2017 15:04:33 +0100 Subject: [PATCH 09/14] Change the bot icon --- src/main/java/ml/duncte123/skybot/utils/Settings.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/java/ml/duncte123/skybot/utils/Settings.java b/src/main/java/ml/duncte123/skybot/utils/Settings.java index d9ca6fdd5..9c5bbecef 100644 --- a/src/main/java/ml/duncte123/skybot/utils/Settings.java +++ b/src/main/java/ml/duncte123/skybot/utils/Settings.java @@ -66,7 +66,7 @@ public class Settings { /** * The icon url for the embeds */ - public static final String defaultIcon = "https://dshelmondgames.ml/favicon"; + public static final String defaultIcon = "https://bot.duncte123.me/img/favicon.png"; /** * The colour of the bar that your embed has */ From b90dc202ab917da94821fc4100c450d9932047b3 Mon Sep 17 00:00:00 2001 From: Ramid Khan Date: Thu, 23 Nov 2017 17:52:13 +1100 Subject: [PATCH 10/14] Log on exceptions/errors --- src/main/java/ml/duncte123/skybot/EventManager.java | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/src/main/java/ml/duncte123/skybot/EventManager.java b/src/main/java/ml/duncte123/skybot/EventManager.java index 8835b6174..6dac5cb43 100644 --- a/src/main/java/ml/duncte123/skybot/EventManager.java +++ b/src/main/java/ml/duncte123/skybot/EventManager.java @@ -2,6 +2,8 @@ import net.dv8tion.jda.core.events.Event; import net.dv8tion.jda.core.hooks.IEventManager; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; import java.util.Arrays; import java.util.List; @@ -9,9 +11,11 @@ /** * A single event listener container */ -class EventManager +public class EventManager implements IEventManager { + private static final Logger logger = LoggerFactory.getLogger(EventManager.class); + private BotListener botListener = new BotListener(); @Override @@ -26,7 +30,11 @@ public void unregister(Object listener) { @Override public void handle(Event event) { - botListener.onEvent(event); + try { + botListener.onEvent(event); + } catch (Throwable thr) { + logger.warn("Error while handling event " + event + "; " + thr.getLocalizedMessage(), thr); + } } @Override From 29af6ee774fba6426ff3c886faa3d520733e2673 Mon Sep 17 00:00:00 2001 From: duncte123 Date: Thu, 23 Nov 2017 10:29:41 +0100 Subject: [PATCH 11/14] Kill the bot if we can log in. --- src/main/java/ml/duncte123/skybot/SkyBot.java | 23 ++++++++++++------- .../skybot/objects/command/Command.java | 7 ++++-- 2 files changed, 20 insertions(+), 10 deletions(-) diff --git a/src/main/java/ml/duncte123/skybot/SkyBot.java b/src/main/java/ml/duncte123/skybot/SkyBot.java index 7dcc2ba0a..ee0e8cff7 100644 --- a/src/main/java/ml/duncte123/skybot/SkyBot.java +++ b/src/main/java/ml/duncte123/skybot/SkyBot.java @@ -88,14 +88,21 @@ public static void main(String... args) throws Exception { //But this time we are going to shard it int TOTAL_SHARDS = AirUtils.config.getInt("discord.totalShards", 1); - //Set up sharding for the bot - new DefaultShardManagerBuilder() - .setEventManager(new EventManager()) - .setAudioSendFactory(new NativeAudioSendFactory()) - .setShardsTotal(TOTAL_SHARDS) - .setGameProvider(shardId -> Game.watching("Danny Phantom on shard #" + (shardId + 1))) - .setToken(token) - .build(); + try { + //Set up sharding for the bot + new DefaultShardManagerBuilder() + .setEventManager(new EventManager()) + .setAudioSendFactory(new NativeAudioSendFactory()) + .setShardsTotal(TOTAL_SHARDS) + .setGameProvider(shardId -> Game.watching("Danny Phantom on shard #" + (shardId + 1))) + .setToken(token) + .build(); + } + catch(RuntimeException e) { + //Kill the system if we can't log in + e.printStackTrace(); + System.exit(-4); + } //Load all the commands for the help embed last HelpEmbeds.init(); diff --git a/src/main/java/ml/duncte123/skybot/objects/command/Command.java b/src/main/java/ml/duncte123/skybot/objects/command/Command.java index 9a3371a4d..38aaad7d1 100644 --- a/src/main/java/ml/duncte123/skybot/objects/command/Command.java +++ b/src/main/java/ml/duncte123/skybot/objects/command/Command.java @@ -29,7 +29,10 @@ import ml.duncte123.skybot.utils.Settings; import net.dv8tion.jda.core.MessageBuilder; import net.dv8tion.jda.core.Permission; -import net.dv8tion.jda.core.entities.*; +import net.dv8tion.jda.core.entities.Guild; +import net.dv8tion.jda.core.entities.Message; +import net.dv8tion.jda.core.entities.MessageEmbed; +import net.dv8tion.jda.core.entities.User; import net.dv8tion.jda.core.events.message.guild.GuildMessageReceivedEvent; import okhttp3.OkHttpClient; import okhttp3.Request; @@ -76,7 +79,7 @@ public boolean contains(Object o) { */ protected static void reloadUpvoted() { try { - String token = AirUtils.config.getString("apis.discordbots_userToken"); + String token = AirUtils.config.getString("apis.discordbots_userToken", ""); if (token == null) { AirUtils.logger.warn("Discord Bots token not found"); From c08769828fcd82a4e39b34d4ffa2502d6071b420 Mon Sep 17 00:00:00 2001 From: duncte123 Date: Thu, 23 Nov 2017 11:09:35 +0100 Subject: [PATCH 12/14] Add a comment --- src/main/java/ml/duncte123/skybot/utils/AirUtils.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/java/ml/duncte123/skybot/utils/AirUtils.java b/src/main/java/ml/duncte123/skybot/utils/AirUtils.java index 41c91f5f2..520ff5c1e 100644 --- a/src/main/java/ml/duncte123/skybot/utils/AirUtils.java +++ b/src/main/java/ml/duncte123/skybot/utils/AirUtils.java @@ -41,6 +41,7 @@ import java.net.URL; import java.sql.*; import java.util.*; +import java.util.regex.Pattern; public class AirUtils { @@ -50,6 +51,7 @@ public class AirUtils { public static Config config = new ConfigUtils().loadConfig(); /** * The {@link WAEngine engine} to query Wolfram|Alpha + * This has to be loadded before the commands are loaded */ public static final WAEngine alphaEngine = getWolframEngine(); /** From 07764c567bdaec01e9d530f0e4dd7d706413bac3 Mon Sep 17 00:00:00 2001 From: Ramid Khan Date: Thu, 23 Nov 2017 21:56:36 +1100 Subject: [PATCH 13/14] Use regex for URL checking --- .../java/ml/duncte123/skybot/utils/AirUtils.java | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/src/main/java/ml/duncte123/skybot/utils/AirUtils.java b/src/main/java/ml/duncte123/skybot/utils/AirUtils.java index 520ff5c1e..32556da1a 100644 --- a/src/main/java/ml/duncte123/skybot/utils/AirUtils.java +++ b/src/main/java/ml/duncte123/skybot/utils/AirUtils.java @@ -229,7 +229,9 @@ public static void checkUnbans(ShardManager jda) { } } } - + + public static final Pattern URL_REGEX = Pattern.compile("[-a-zA-Z0-9@:%._\\+~#=]{2,256}\\.[a-z]{2,6}\\b([-a-zA-Z0-9@:%_\\+.~#?&\\/\\/=]*)"); + /** * This will validate a link * @@ -237,15 +239,9 @@ public static void checkUnbans(ShardManager jda) { * @return true or false depending on if the url is valid */ public static boolean isURL(String url) { - try { - URL u = new URL(url); - u.openConnection(); - return true; - } catch (IOException e) { - return false; - } + return URL_REGEX.matcher(url).find(); } - + /** * This will check if the number that we are trying to parse is an int * From bf0da18dabe3bd2c44c13e3c0691a80d130fa09f Mon Sep 17 00:00:00 2001 From: duncte123 Date: Thu, 23 Nov 2017 17:44:22 +0100 Subject: [PATCH 14/14] Update shardmanager --- build.gradle | 2 +- .../net/dv8tion/jda/core/entities/Game.java | 385 ------------------ 2 files changed, 1 insertion(+), 386 deletions(-) delete mode 100644 src/main/java/net/dv8tion/jda/core/entities/Game.java diff --git a/build.gradle b/build.gradle index 4c508283a..9d7915e9b 100644 --- a/build.gradle +++ b/build.gradle @@ -72,7 +72,7 @@ buildConfig { dependencies { //JDA (java discord api) - compile group: 'com.github.DV8FromTheWorld', name: 'JDA', version: 'f18b535' //Beta build with ShardManager + compile group: 'com.github.DV8FromTheWorld', name: 'JDA', version: '40ebcf1' //Beta build with ShardManager //Lavaplayer compile group: 'com.sedmelluq', name: 'lavaplayer', version: '1.2.44' //jda-nas diff --git a/src/main/java/net/dv8tion/jda/core/entities/Game.java b/src/main/java/net/dv8tion/jda/core/entities/Game.java deleted file mode 100644 index b4783170c..000000000 --- a/src/main/java/net/dv8tion/jda/core/entities/Game.java +++ /dev/null @@ -1,385 +0,0 @@ -/* - * Skybot, a multipurpose discord bot - * Copyright (C) 2017 Duncan "duncte123" Sterken & Ramid "ramidzkh" Khan & Sanduhr32 - * - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published - * by the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU Affero General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see . - * - */ -package net.dv8tion.jda.core.entities; - -import net.dv8tion.jda.core.utils.Checks; - -import java.util.Objects; - -/** - * Represents a Discord {@link Game}. - *
This should contain all information provided from Discord about a Game. - * - * @since 2.1 - * @author John A. Grosh - * - * This class has been copied from https://github.com/DV8FromTheWorld/JDA/blob/feature/game-types/src/main/java/net/dv8tion/jda/core/entities/Game.java - * and overrides the original game class to allow the bot to see the listening and watching status - * it will also allow the bot to use the status - */ -public class Game -{ - protected final String name; - protected final String url; - protected final Game.GameType type; - - protected Game(String name) - { - this(name, null, GameType.DEFAULT); - } - - protected Game(String name, String url) - { - this(name, url, GameType.STREAMING); - } - - protected Game(String name, String url, GameType type) - { - this.name = name; - this.url = url; - this.type = type; - } - - /** - * The displayed name of the {@link Game Game}. If no name has been set, this returns null. - * - * @return Possibly-null String containing the Game's name. - */ - public String getName() - { - return name; - } - - /** - * The URL of the {@link Game} if the game is actually a Stream. - *
This will return null for regular games. - * - * @return Possibly-null String containing the Game's URL. - */ - public String getUrl() - { - return url; - } - - /** - * The type of {@link Game}. - * - * @return Never-null {@link.GameType GameType} representing the type of Game - */ - public GameType getType() - { - return type; - } - - @Override - public boolean equals(Object o) - { - if (!(o instanceof Game)) - return false; - if (o == this) - return true; - - Game oGame = (Game) o; - return oGame.getType() == type - && Objects.equals(name, oGame.getName()) - && Objects.equals(url, oGame.getUrl()); - } - - @Override - public int hashCode() - { - return Objects.hash(name, type, url); - } - - @Override - public String toString() - { - if (url != null) - return String.format("Game(%s | %s)", name, url); - else - return String.format("Game(%s)", name); - } - - /** - * Creates a new Game instance with the specified name. - *
In order to appear as "streaming" in the official client you must - * provide a valid (see documentation of method) streaming URL in {@link #streaming(String, String) Game.streaming(String, String)}. - * - * @param name - * The not-null name of the newly created game - * - * @throws IllegalArgumentException - * if the specified name is null, empty or blank - * - * @return A valid Game instance with the provided name with {@link GameType#DEFAULT} - */ - public static Game playing(String name) - { - Checks.notBlank(name, "Name"); - return new Game(name, null, GameType.DEFAULT); - } - - /** - * Creates a new Game instance with the specified name. - *
In order to appear as "streaming" in the official client you must - * provide a valid (see documentation of method) streaming URL in {@link #streaming(String, String) Game.of(String, String)}. - * - * @param name - * The not-null name of the newly created game - * - * @throws IllegalArgumentException - * if the specified name is null, empty or blank - * - * @return A valid Game instance with the provided name with {@link GameType#DEFAULT} - * - * @deprecated - * Use {@link #playing(String)} instead - */ - @Deprecated - public static Game of(String name) - { - return playing(name); - } - - /** - * Creates a new Game instance with the specified name and url. - *
The specified URL must be valid according to discord standards in order to display as "streaming" in the official client. - * A valid streaming URL must be derived from {@code https://twitch.tv/} and can be verified using {@link #isValidStreamingUrl(String)}. (see documentation) - * - * @param name - * The not-null name of the newly created game - * @param url - * The streaming url to use, required to display as "streaming" - * - * @throws IllegalArgumentException - * If the specified name is null or empty - * - * @return A valid Game instance with the provided name and url - * - * @see #isValidStreamingUrl(String) - */ - public static Game streaming(String name, String url) - { - Checks.notEmpty(name, "Provided game name"); - GameType type; - if (isValidStreamingUrl(url)) - type = GameType.STREAMING; - else - type = GameType.DEFAULT; - return new Game(name, url, type); - } - - /** - * Creates a new Game instance with the specified name and url. - *
The specified URL must be valid according to discord standards in order to display as "streaming" in the official client. - * A valid streaming URL must be derived from {@code https://twitch.tv/} and can be verified using {@link #isValidStreamingUrl(String)}. (see documentation) - * - * @param name - * The not-null name of the newly created game - * @param url - * The streaming url to use, required to display as "streaming" - * - * @throws IllegalArgumentException - * If the specified name is null or empty - * - * @return A valid Game instance with the provided name and url - * - * @see #isValidStreamingUrl(String) - * - * @deprecated - * Use {@link #streaming(String, String)} instead! - */ - @Deprecated - public static Game of(String name, String url) - { - return streaming(name, url); - } - - /** - * Creates a new Game instance with the specified name. - *
This will display as {@code Listening name} in the official client - * - * @param name - * The not-null name of the newly created game - * - * @throws IllegalArgumentException - * if the specified name is null, empty or blank - * - * @return A valid Game instance with the provided name with {@link GameType#LISTENING} - */ - public static Game listening(String name) - { - Checks.notBlank(name, "Name"); - return new Game(name, null, GameType.LISTENING); - } - - /** - * Creates a new Game instance with the specified name. - *
This will display as {@code Watching name} in the official client - * - * @param name - * The not-null name of the newly created game - * - * @throws IllegalArgumentException - * if the specified name is null, empty or blank - * - * @return A valid Game instance with the provided name with {@link GameType#WATCHING} - */ - public static Game watching(String name) - { - Checks.notBlank(name, "Name"); - return new Game(name, null, GameType.WATCHING); - } - - /** - * Creates a new Game instance with the specified name and url. - * - * @param type - * The {@link.GameType GameType} to use - * @param name - * The not-null name of the newly created game - * - * @throws IllegalArgumentException - * If the specified name is null or empty - * - * @return A valid Game instance with the provided name and url - */ - public static Game of(GameType type, String name) - { - return of(type, name, null); - } - - /** - * Creates a new Game instance with the specified name and url. - *
The provided url would only be used for {@link.GameType#STREAMING GameType.STREAMING} - * and should be a twitch url. - * - * @param type - * The {@link.GameType GameType} to use - * @param name - * The not-null name of the newly created game - * @param url - * The streaming url to use, required to display as "streaming". - * - * @throws IllegalArgumentException - * If the specified name is null or empty - * - * @return A valid Game instance with the provided name and url - * - * @see #isValidStreamingUrl(String) - */ - public static Game of(GameType type, String name, String url) - { - Checks.notNull(type, "Type"); - switch (type) - { - case DEFAULT: - return playing(name); - case STREAMING: - return streaming(name, url); - case LISTENING: - return listening(name); - case WATCHING: - return watching(name); - default: - throw new IllegalArgumentException("GameType " + type + " is not supported!"); - } - } - - /** - * Checks if a given String is a valid Twitch url (ie, one that will display "Streaming" on the Discord client). - * - * @param url - * The url to check. - * - * @return True if the provided url is valid for triggering Discord's streaming status - */ - public static boolean isValidStreamingUrl(String url) - { - return url != null && url.matches("https?://(www\\.)?twitch\\.tv/.+"); - } - - /** - * The type game being played, differentiating between a game and stream types. - */ - public enum GameType - { - /** - * The GameType used to represent a normal {@link Game} status. - */ - DEFAULT(0), - /** - * Used to indicate that the {@link Game} is a stream - *
This type is displayed as "Streaming" in the discord client. - */ - STREAMING(1), - /** - * Used to indicate that the {@link Game} should display - * as {@code Listening...} in the official client. - */ - LISTENING(2), - /** - * Used to indicate that the {@link Game} should display - * as {@code Watching...} in the official client. - */ - WATCHING(3); - - private final int key; - - GameType(int key) - { - this.key = key; - } - - /** - * The Discord defined id key for this GameType. - * - * @return the id key. - */ - public int getKey() - { - return key; - } - - /** - * Gets the GameType related to the provided key. - *
If an unknown key is provided, this returns {@link #DEFAULT} - * - * @param key - * The Discord key referencing a GameType. - * - * @return The GameType that has the key provided, or {@link #DEFAULT} for unknown key. - */ - public static GameType fromKey(int key) - { - switch (key) - { - case 0: - default: - return DEFAULT; - case 1: - return STREAMING; - case 2: - return LISTENING; - case 3: - return WATCHING; - } - } - } -} \ No newline at end of file