diff --git a/assets/config.csv b/assets/config.csv index ffe84af..b2fb4b1 100644 --- a/assets/config.csv +++ b/assets/config.csv @@ -1,5 +1,6 @@ "Type","Key","Value" "Globals","mode (dev or release)","dev" +"Globals","activity","with a laser pointer" "Localized Commands","beans","" "Localized Commands","benchmark, bench","" "Localized Commands","bet","" @@ -57,6 +58,8 @@ "Localized Commands","work","" "Localized Commands","yeet","" "Localized Strings","AddGuildRoleFailure","Failed to add %s to %s" +"Localized Strings","BeansImageBottomText","BEANS" +"Localized Strings","BeansImageTopText","YOU HAVE" "Localized Strings","BeansShowDisplay","You have %s beans!" "Localized Strings","BeansShowInfo","Displays how many beans you have" "Localized Strings","BeansShowMentioned","I took a look and %sbeans!" diff --git a/src/core/ConfigGlobals.java b/src/core/ConfigGlobals.java index d6b5db9..58ac963 100644 --- a/src/core/ConfigGlobals.java +++ b/src/core/ConfigGlobals.java @@ -18,13 +18,20 @@ public class ConfigGlobals implements IConfigSection private static final String startupStyleKey = "mode (dev or release)"; private KittyStartupMode startupStyleValue = KittyStartupMode.Dev; - // Constructor + private static final String activityKey = "activity"; + private String activityValue = "with a laser pointer"; // Appears as "Playing with a laser pointer" + + // Singleton Constructor - explode if there's a problem. public ConfigGlobals() { if(instance == null) + { instance = this; + } else + { GlobalLog.error("Attempted to initialize a second config globals! Probably don't do this!"); + } } @Override @@ -38,6 +45,11 @@ public class ConfigGlobals implements IConfigSection return instance.startupStyleValue; } + public static String getActivity() + { + return instance.activityValue; + } + @Override public void consume(List pairs) { @@ -52,8 +64,29 @@ public class ConfigGlobals implements IConfigSection startupStyleValue = KittyStartupMode.Dev; if(value.equalsIgnoreCase(KittyStartupMode.Release.name())) + { startupStyleValue = KittyStartupMode.Release; + } + + if(value.equalsIgnoreCase(KittyStartupMode.PoguRelease.name())) + { + startupStyleValue = KittyStartupMode.PoguRelease; + } + + continue; } + + // Parse text for 'playing' + if(key.equalsIgnoreCase(activityKey)) + { + activityValue = value; + } + } + + // If we change any globals, update anything we need to. + if(ObjectBuilder.getHasInitialized()) + { + ObjectBuilder.updateActivity(); } } @@ -62,6 +95,7 @@ public class ConfigGlobals implements IConfigSection { List items = new ArrayList(); items.add(new ConfigItem(getSectionTitle(), startupStyleKey, startupStyleValue.name().toLowerCase())); + items.add(new ConfigItem(getSectionTitle(), activityKey, activityValue)); return items; } diff --git a/src/core/ObjectBuilder.java b/src/core/ObjectBuilder.java index b452a63..4db819f 100644 --- a/src/core/ObjectBuilder.java +++ b/src/core/ObjectBuilder.java @@ -39,7 +39,7 @@ import utils.GlobalLog; import utils.LogFilter; import utils.audio.AudioUtils; -// NOTE(wisp): Isolated factory to assist with storage and caching if needed. +// NOTE: 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 @@ -82,15 +82,20 @@ public class ObjectBuilder // Lazy initialization multithreaded mutex stuff to prevent explosions. // TODO: Investigate using 'synchronized' instead potentially - private static boolean hasInitialized; + private static Boolean hasInitialized = false; 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; + synchronized(hasInitialized) + { + if(hasInitialized) + { + return; + } + } try { @@ -109,14 +114,17 @@ public class ObjectBuilder 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. + // 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; + synchronized(hasInitialized) + { + hasInitialized = true; + } } } catch(InterruptedException ie) @@ -126,6 +134,14 @@ public class ObjectBuilder } } + public static boolean getHasInitialized() + { + synchronized(hasInitialized) + { + return hasInitialized; + } + } + //////////////////////// // Extraction Methods // //////////////////////// @@ -389,22 +405,32 @@ public class ObjectBuilder // Determine token based on config. Default to test token. String tokenToUse = Ref.TestToken; - if(ConfigGlobals.getStartupMode() == KittyStartupMode.Release) - tokenToUse = Ref.Token; - if(ConfigGlobals.getStartupMode() == KittyStartupMode.PoguRelease) - tokenToUse = Ref.PoguToken; - + switch(ConfigGlobals.getStartupMode()) + { + case Release: tokenToUse = Ref.Token; break; + case PoguRelease: tokenToUse = Ref.PoguToken; break; + default: tokenToUse = Ref.TestToken; break; + } + // Construct bot based on token using the JDA Builder JDABuilder builder = JDABuilder.createDefault(tokenToUse); kitty = builder.build(); // Set activity, and add primariy event listener. - kitty.getPresence().setActivity(Activity.playing("with a laser pointer")); + updateActivity(); kitty.addEventListener(new Main()); return new KittyCore(kitty); } + // Updates the bots current activity based on the globals value. + public static void updateActivity() + { + String activity = ConfigGlobals.getActivity(); + GlobalLog.log(LogFilter.Core, "Updating activity to " + activity); + kitty.getPresence().setActivity(Activity.playing(activity)); + } + // 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