diff --git a/.editorconfig b/.editorconfig new file mode 100644 index 0000000..059f2de --- /dev/null +++ b/.editorconfig @@ -0,0 +1,8 @@ +root = true + +[*] +end_of_line = lf +insert_final_newline = true +charset = utf-8 +indent_style = tab +indent_size = 4 diff --git a/build.gradle b/build.gradle index 6ce9076..cbc8a91 100644 --- a/build.gradle +++ b/build.gradle @@ -9,20 +9,29 @@ buildscript { } } +//plugins { +// id 'com.gradle.build-scan' version '1.12.1' +//} + apply plugin: 'net.minecraftforge.gradle.forge' apply plugin: 'com.github.johnrengelman.shadow' apply plugin: 'java' targetCompatibility = sourceCompatibility = JavaVersion.VERSION_1_8 -version = "1.12.2-0.3.0" -group= "com.derimagia.forgeslack" +version = "1.12.2-0.3.1" +group = "com.derimagia.forgeslack" archivesBaseName = "forgeslack" repositories { maven { url = "https://jitpack.io" } } +buildScan { + licenseAgreementUrl = 'https://gradle.com/terms-of-service' + licenseAgree = 'yes' +} + minecraft { version = "1.12.2-14.23.2.2611" runDir = "run" @@ -40,7 +49,7 @@ dependencies { compile group: 'org.slf4j', name: 'slf4j-simple', version: '1.7.25' } -processResources { +processResources { // this will ensure that this task is redone when the versions change. inputs.property "version", project.version inputs.property "mcversion", project.minecraft.version @@ -60,7 +69,7 @@ processResources { } shadowJar { - classifier = "" + classifier = '' // Can't relocate this because of something with AsyncHttpClientConfigDefaults:ASYNC_CLIENT_CONFIG_ROOT // but most likely this won't matter because these libraries aren't probably used elsewhere. // relocate "allbegray.slack", "com.derimagia.lib.com.github.allbegray" diff --git a/src/main/java/com/derimagia/forgeslack/ForgeSlack.java b/src/main/java/com/derimagia/forgeslack/ForgeSlack.java index 792ef7e..57e7573 100644 --- a/src/main/java/com/derimagia/forgeslack/ForgeSlack.java +++ b/src/main/java/com/derimagia/forgeslack/ForgeSlack.java @@ -1,8 +1,8 @@ package com.derimagia.forgeslack; -import com.derimagia.forgeslack.handler.ConfigurationHandler; import com.derimagia.forgeslack.handler.ForgeEventHandler; import com.derimagia.forgeslack.slack.SlackRelay; +import net.minecraftforge.common.config.Configuration; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.event.FMLServerStartingEvent; @@ -10,36 +10,78 @@ import net.minecraftforge.fml.common.event.FMLServerStoppedEvent; import org.apache.logging.log4j.Logger; -@Mod(modid = ForgeSlack.modId, name = ForgeSlack.modId, version = ForgeSlack.version, acceptableRemoteVersions = "*") +import java.io.File; + +@Mod(modid = ForgeSlack.modId, useMetadata=true, acceptableRemoteVersions = "*", guiFactory = "com.derimagia.forgeslack.client.gui.ForgeSlackConfigGuiFactory") public class ForgeSlack { public static final String modId = "forgeslack"; - public static final String version = "0.3.0"; - public static Logger log; + public static Logger logger; private static SlackRelay slackRelay; + private static Configuration config; + private static boolean enabled = false; + private static String slackToken = ""; + private static String channel = ""; + @Mod.EventHandler public void preInit(FMLPreInitializationEvent event) { - log = event.getModLog(); - ConfigurationHandler.init(event.getSuggestedConfigurationFile()); + logger = event.getModLog(); + config = new Configuration(event.getSuggestedConfigurationFile()); + syncConfig(); - if (ConfigurationHandler.enabled) { + if (enabled) { MinecraftForge.EVENT_BUS.register(new ForgeEventHandler()); } } +// @Mod.EventHandler +// public void postInit(FMLPostInitializationEvent evt) +// { +// ForgeSlackConfig.sync(); +// } + @Mod.EventHandler public void serverStarting(FMLServerStartingEvent event) { - if (ConfigurationHandler.enabled) { - slackRelay = SlackRelay.getInstance(); + if (enabled) { + slackRelay = new SlackRelay(channel, slackToken); slackRelay.startup(); } } @Mod.EventHandler public void serverStopped(FMLServerStoppedEvent event) { - if (ConfigurationHandler.enabled) { + if (enabled) { slackRelay.shutdown(); + slackRelay = null; + } + } + + /** + * Sync the config. + */ + private static void syncConfig() + { + enabled = config.getBoolean("enabled", Configuration.CATEGORY_GENERAL, true, "Whether ForgeSlack is enabled."); + slackToken = config.getString("slackToken", Configuration.CATEGORY_GENERAL, "", "Token Slack provides to Accept Slack Messages"); + channel = config.getString("channel", Configuration.CATEGORY_GENERAL, "#general", "Slack Channel to Listen/Send on"); + + if (channel.isEmpty() || slackToken.isEmpty()) { + enabled = false; + ForgeSlack.logger.error("Either Slack Channel or Slack Token is empty. ForgeSlack will be disabled."); } + + if (config.hasChanged()) { + ForgeSlack.logger.error("Loading Configuration."); + config.save(); + } + } + + public static Configuration getConfig() { + return config; + } + + public static SlackRelay getSlackRelay() { + return slackRelay; } -} \ No newline at end of file +} diff --git a/src/main/java/com/derimagia/forgeslack/client/gui/ForgeSlackConfigGuiFactory.java b/src/main/java/com/derimagia/forgeslack/client/gui/ForgeSlackConfigGuiFactory.java new file mode 100644 index 0000000..e790d1a --- /dev/null +++ b/src/main/java/com/derimagia/forgeslack/client/gui/ForgeSlackConfigGuiFactory.java @@ -0,0 +1,205 @@ +package com.derimagia.forgeslack.client.gui; + +import com.derimagia.forgeslack.ForgeSlack; +import com.google.common.collect.ImmutableSet; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraft.client.resources.I18n; +import net.minecraftforge.client.gui.ForgeGuiFactory; +import net.minecraftforge.common.ForgeChunkManager; +import net.minecraftforge.common.ForgeModContainer; +import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.common.config.ConfigCategory; +import net.minecraftforge.common.config.ConfigElement; +import net.minecraftforge.common.config.Configuration; +import net.minecraftforge.common.config.Property; +import net.minecraftforge.fml.client.FMLConfigGuiFactory; +import net.minecraftforge.fml.client.IModGuiFactory; +import net.minecraftforge.fml.client.config.*; +import net.minecraftforge.fml.common.ModContainer; + +import java.util.List; +import java.util.ArrayList; +import java.util.Set; +import java.util.regex.Pattern; + +public class ForgeSlackConfigGuiFactory implements IModGuiFactory { + public static class ForgeSlackConfigGuiScreen extends GuiConfig { + public ForgeConfigGui(GuiScreen parentScreen) + { + super(parentScreen, getConfigElements(), ForgeVersion.MOD_ID, false, false, I18n.format("forge.configgui.forgeConfigTitle")); + } + + private static List getConfigElements() + { + List list = new ArrayList(); + list.add(new DummyConfigElement.DummyCategoryElement("forgeCfg", "forge.configgui.ctgy.forgeGeneralConfig", ForgeGuiFactory.ForgeConfigGui.GeneralEntry.class)); + list.add(new DummyConfigElement.DummyCategoryElement("forgeClientCfg", "forge.configgui.ctgy.forgeClientConfig", ForgeGuiFactory.ForgeConfigGui.ClientEntry.class)); + list.add(new DummyConfigElement.DummyCategoryElement("forgeChunkLoadingCfg", "forge.configgui.ctgy.forgeChunkLoadingConfig", ForgeGuiFactory.ForgeConfigGui.ChunkLoaderEntry.class)); + list.add(new DummyConfigElement.DummyCategoryElement("forgeVersionCheckCfg", "forge.configgui.ctgy.VersionCheckConfig", ForgeGuiFactory.ForgeConfigGui.VersionCheckEntry.class)); + return list; + } + + /** + * This custom list entry provides the General Settings entry on the Minecraft Forge Configuration screen. + * It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen. + */ + public static class GeneralEntry extends GuiConfigEntries.CategoryEntry + { + public GeneralEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) + { + super(owningScreen, owningEntryList, prop); + } + + @Override + protected GuiScreen buildChildScreen() + { + // This GuiConfig object specifies the configID of the object and as such will force-save when it is closed. The parent + // GuiConfig object's entryList will also be refreshed to reflect the changes. + return new GuiConfig(this.owningScreen, + (new ConfigElement(ForgeModContainer.getConfig().getCategory(Configuration.CATEGORY_GENERAL))).getChildElements(), + this.owningScreen.modID, Configuration.CATEGORY_GENERAL, this.configElement.requiresWorldRestart() || this.owningScreen.allRequireWorldRestart, + this.configElement.requiresMcRestart() || this.owningScreen.allRequireMcRestart, + GuiConfig.getAbridgedConfigPath(ForgeModContainer.getConfig().toString())); + } + } + + /** + * This custom list entry provides the Client only Settings entry on the Minecraft Forge Configuration screen. + * It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen. + */ + public static class ClientEntry extends GuiConfigEntries.CategoryEntry + { + public ClientEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) + { + super(owningScreen, owningEntryList, prop); + } + + @Override + protected GuiScreen buildChildScreen() + { + // This GuiConfig object specifies the configID of the object and as such will force-save when it is closed. The parent + // GuiConfig object's entryList will also be refreshed to reflect the changes. + return new GuiConfig(this.owningScreen, + (new ConfigElement(ForgeModContainer.getConfig().getCategory(Configuration.CATEGORY_CLIENT))).getChildElements(), + this.owningScreen.modID, Configuration.CATEGORY_CLIENT, this.configElement.requiresWorldRestart() || this.owningScreen.allRequireWorldRestart, + this.configElement.requiresMcRestart() || this.owningScreen.allRequireMcRestart, + GuiConfig.getAbridgedConfigPath(ForgeModContainer.getConfig().toString())); + } + } + + /** + * This custom list entry provides the Forge Chunk Manager Config entry on the Minecraft Forge Configuration screen. + * It extends the base Category entry class and defines the IConfigElement objects that will be used to build the child screen. + */ + public static class ChunkLoaderEntry extends GuiConfigEntries.CategoryEntry + { + public ChunkLoaderEntry(GuiConfig owningScreen, GuiConfigEntries owningEntryList, IConfigElement prop) + { + super(owningScreen, owningEntryList, prop); + } + + @Override + protected GuiScreen buildChildScreen() + { + List list = new ArrayList(); + + list.add(new DummyConfigElement.DummyCategoryElement("forgeChunkLoadingModCfg", "forge.configgui.ctgy.forgeChunkLoadingModConfig", + ForgeGuiFactory.ForgeConfigGui.ModOverridesEntry.class)); + list.addAll((new ConfigElement(ForgeChunkManager.getDefaultsCategory())).getChildElements()); + + // This GuiConfig object specifies the configID of the object and as such will force-save when it is closed. The parent + // GuiConfig object's propertyList will also be refreshed to reflect the changes. + return new GuiConfig(this.owningScreen, list, this.owningScreen.modID, "chunkLoader", + this.configElement.requiresWorldRestart() || this.owningScreen.allRequireWorldRestart, + this.configElement.requiresMcRestart() || this.owningScreen.allRequireMcRestart, + GuiConfig.getAbridgedConfigPath(ForgeChunkManager.getConfig().toString()), + I18n.format("forge.configgui.ctgy.forgeChunkLoadingConfig")); + } + } + + public ForgeSlackConfigGuiScreen(GuiScreen parent) + { + super(parent, getConfigElements(), "Forgeslack", false, false, I18n.format("fml.config.sample.title")); + } + + private static List getConfigElements() + { + List list = new ArrayList(); + List listsList = new ArrayList(); + List stringsList = new ArrayList(); + List numbersList = new ArrayList(); + Pattern commaDelimitedPattern = Pattern.compile("([A-Za-z]+((,){1}( )*|$))+?"); + + // Top Level Settings + list.add(new DummyConfigElement("imABoolean", true, ConfigGuiType.BOOLEAN, "fml.config.sample.imABoolean").setRequiresMcRestart(true)); + list.add(new DummyConfigElement("imAnInteger", 42, ConfigGuiType.INTEGER, "fml.config.sample.imAnInteger", -1, 256).setRequiresMcRestart(true)); + list.add(new DummyConfigElement("imADouble", 42.4242D, ConfigGuiType.DOUBLE, "fml.config.sample.imADouble", -1.0D, 256.256D).setRequiresMcRestart(true)); + list.add(new DummyConfigElement("imAString", "http://www.montypython.net/scripts/string.php", ConfigGuiType.STRING, "fml.config.sample.imAString").setRequiresMcRestart(true)); + + // Lists category + listsList.add(new DummyConfigElement.DummyListElement("booleanList", new Boolean[] {true, false, true, false, true, false, true, false}, ConfigGuiType.BOOLEAN, "fml.config.sample.booleanList")); + listsList.add(new DummyConfigElement.DummyListElement("booleanListFixed", new Boolean[] {true, false, true, false, true, false, true, false}, ConfigGuiType.BOOLEAN, "fml.config.sample.booleanListFixed", true)); + listsList.add(new DummyConfigElement.DummyListElement("booleanListMax", new Boolean[] {true, false, true, false, true, false, true, false}, ConfigGuiType.BOOLEAN, "fml.config.sample.booleanListMax", 10)); + listsList.add(new DummyConfigElement.DummyListElement("doubleList", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleList")); + listsList.add(new DummyConfigElement.DummyListElement("doubleListFixed", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleListFixed", true)); + listsList.add(new DummyConfigElement.DummyListElement("doubleListMax", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleListMax", 15)); + listsList.add(new DummyConfigElement.DummyListElement("doubleListBounded", new Double[] {0.0D, 1.1D, 2.2D, 3.3D, 4.4D, 5.5D, 6.6D, 7.7D, 8.8D, 9.9D}, ConfigGuiType.DOUBLE, "fml.config.sample.doubleListBounded", -1.0D, 10.0D)); + listsList.add(new DummyConfigElement.DummyListElement("integerList", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerList")); + listsList.add(new DummyConfigElement.DummyListElement("integerListFixed", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerListFixed", true)); + listsList.add(new DummyConfigElement.DummyListElement("integerListMax", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerListMax", 15)); + listsList.add(new DummyConfigElement.DummyListElement("integerListBounded", new Integer[] {0, 1, 2, 3, 4, 5, 6, 7, 8, 9}, ConfigGuiType.INTEGER, "fml.config.sample.integerListBounded", -1, 10)); + listsList.add(new DummyConfigElement.DummyListElement("stringList", new String[] {"An", "array", "of", "string", "values"}, ConfigGuiType.STRING, "fml.config.sample.stringList")); + listsList.add(new DummyConfigElement.DummyListElement("stringListFixed", new String[] {"A", "fixed", "length", "array", "of", "string", "values"}, ConfigGuiType.STRING, "fml.config.sample.stringListFixed", true)); + listsList.add(new DummyConfigElement.DummyListElement("stringListMax", new String[] {"An", "array", "of", "string", "values", "with", "a", "max", "length", "of", "15"}, ConfigGuiType.STRING, "fml.config.sample.stringListMax", 15)); + listsList.add(new DummyConfigElement.DummyListElement("stringListPattern", new String[] {"Valid", "Not Valid", "Is, Valid", "Comma, Separated, Value"}, ConfigGuiType.STRING, "fml.config.sample.stringListPattern", commaDelimitedPattern)); + listsList.add(new DummyConfigElement.DummyListElement("stringListCustom", new Object[0], ConfigGuiType.STRING, "fml.config.sample.stringListCustom").setArrayEntryClass(FMLConfigGuiFactory.CustomArrayEntry.class)); + + list.add(new DummyConfigElement.DummyCategoryElement("lists", "fml.config.sample.ctgy.lists", listsList)); + + // Strings category + stringsList.add(new DummyConfigElement("basicString", "Just a regular String value, anything goes.", ConfigGuiType.STRING, "fml.config.sample.basicString")); + stringsList.add(new DummyConfigElement("cycleString", "this", ConfigGuiType.STRING, "fml.config.sample.cycleString", new String[] {"this", "property", "cycles", "through", "a", "list", "of", "valid", "choices"})); + stringsList.add(new DummyConfigElement("patternString", "only, comma, separated, words, can, be, entered, in, this, box", ConfigGuiType.STRING, "fml.config.sample.patternString", commaDelimitedPattern)); + stringsList.add(new DummyConfigElement("chatColorPicker", "c", ConfigGuiType.COLOR, "fml.config.sample.chatColorPicker", new String[] {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "a", "b", "c", "d", "e", "f"})); + stringsList.add(new DummyConfigElement("modIDSelector", "FML", ConfigGuiType.MOD_ID, "fml.config.sample.modIDSelector")); + + list.add(new DummyConfigElement.DummyCategoryElement("strings", "fml.config.sample.ctgy.strings", stringsList)); + + // Numbers category + numbersList.add((new DummyConfigElement("basicInteger", 42, ConfigGuiType.INTEGER, "fml.config.sample.basicInteger"))); + numbersList.add((new DummyConfigElement("boundedInteger", 42, ConfigGuiType.INTEGER, "fml.config.sample.boundedInteger", -1, 256))); + numbersList.add((new DummyConfigElement("sliderInteger", 2000, ConfigGuiType.INTEGER, "fml.config.sample.sliderInteger", 100, 10000)).setCustomListEntryClass(GuiConfigEntries.NumberSliderEntry.class)); + numbersList.add(new DummyConfigElement("basicDouble", 42.4242D, ConfigGuiType.DOUBLE, "fml.config.sample.basicDouble")); + numbersList.add(new DummyConfigElement("boundedDouble", 42.4242D, ConfigGuiType.DOUBLE, "fml.config.sample.boundedDouble", -1.0D, 256.256D)); + numbersList.add(new DummyConfigElement("sliderDouble", 42.4242D, ConfigGuiType.DOUBLE, "fml.config.sample.sliderDouble", -1.0D, 256.256D).setCustomListEntryClass(GuiConfigEntries.NumberSliderEntry.class)); + + list.add(new DummyConfigElement.DummyCategoryElement("numbers", "fml.config.sample.ctgy.numbers", numbersList)); + + return list; + } + } + + @Override + public void initialize(Minecraft minecraftInstance) { + ForgeSlack.logger.info("TESTING!!"); + } + + @Override + public boolean hasConfigGui() { + return true; + } + + @Override + public GuiScreen createConfigGui(GuiScreen parent) { + return new ForgeSlackConfigGuiScreen(parent); + } + + private static final Set fmlCategories = ImmutableSet.of(new RuntimeOptionCategoryElement("HELP", "FORGESLACK")); + + @Override + public Set runtimeGuiCategories() + { + return fmlCategories; + } +} diff --git a/src/main/java/com/derimagia/forgeslack/handler/ConfigurationHandler.java b/src/main/java/com/derimagia/forgeslack/handler/ConfigurationHandler.java deleted file mode 100644 index 800facf..0000000 --- a/src/main/java/com/derimagia/forgeslack/handler/ConfigurationHandler.java +++ /dev/null @@ -1,40 +0,0 @@ -package com.derimagia.forgeslack.handler; - -import com.derimagia.forgeslack.ForgeSlack; -import net.minecraftforge.common.config.Configuration; - -import java.io.File; - -public class ConfigurationHandler -{ - private static Configuration configuration; - public static boolean enabled = true; - public static String slackToken = ""; - public static String channel = ""; - - public static void init(File configFile) - { - if (configuration == null) - { - configuration = new Configuration(configFile); - loadConfiguration(); - } - } - - private static void loadConfiguration() - { - enabled = configuration.getBoolean("enabled", Configuration.CATEGORY_GENERAL, true, "Whether ForgeSlack is enabled."); - slackToken = configuration.getString("slackToken", Configuration.CATEGORY_GENERAL, "", "Token Slack provides to Accept Slack Messages"); - channel = configuration.getString("channel", Configuration.CATEGORY_GENERAL, "#general", "Slack Channel to Listen/Send on"); - - if (channel.isEmpty() || slackToken.isEmpty()) { - enabled = false; - ForgeSlack.log.error("Either Slack Channel or Slack Token is empty. ForgeSlack will be disabled."); - } - - if (configuration.hasChanged()) { - ForgeSlack.log.error("Loading Configuration."); - configuration.save(); - } - } -} \ No newline at end of file diff --git a/src/main/java/com/derimagia/forgeslack/handler/ForgeEventHandler.java b/src/main/java/com/derimagia/forgeslack/handler/ForgeEventHandler.java index 41ac19f..389c772 100644 --- a/src/main/java/com/derimagia/forgeslack/handler/ForgeEventHandler.java +++ b/src/main/java/com/derimagia/forgeslack/handler/ForgeEventHandler.java @@ -1,10 +1,9 @@ package com.derimagia.forgeslack.handler; +import com.derimagia.forgeslack.ForgeSlack; import com.derimagia.forgeslack.slack.SlackRelay; import net.minecraft.entity.player.EntityPlayer; import net.minecraft.scoreboard.ScorePlayerTeam; -import net.minecraft.util.text.ITextComponent; -import net.minecraft.util.text.TextComponentString; import net.minecraftforge.common.util.FakePlayer; import net.minecraftforge.event.entity.living.LivingDeathEvent; import net.minecraftforge.event.entity.player.AdvancementEvent; @@ -17,25 +16,25 @@ public class ForgeEventHandler { @SubscribeEvent public void onServerChat(ServerChatEvent event) { - SlackRelay.getInstance().sendMessage(event.getMessage(), event.getUsername()); + ForgeSlack.getSlackRelay().sendMessage(event.getMessage(), event.getPlayer()); } @SubscribeEvent public void onJoin(PlayerEvent.PlayerLoggedInEvent event) { // @TODO: Localize this? - SlackRelay.getInstance().sendMessage("_[Joined the Game]_", getName(event.player)); + ForgeSlack.getSlackRelay().sendMessage("_[Joined the Game]_", event.player); } @SubscribeEvent public void onLeave(PlayerEvent.PlayerLoggedOutEvent event) { // @TODO: Localize this? - SlackRelay.getInstance().sendMessage("_[Left the Game]_", getName(event.player)); + ForgeSlack.getSlackRelay().sendMessage("_[Left the Game]_", event.player); } @SubscribeEvent public void onLivingDeath(LivingDeathEvent event) { if (event.getEntity() instanceof EntityPlayer && !(event.getEntityLiving() instanceof FakePlayer) && !event.getEntity().world.isRemote) { - SlackRelay.getInstance().sendMessage("_" + ((EntityPlayer) event.getEntity()).getCombatTracker().getDeathMessage().getUnformattedText() + "_", getName((EntityPlayer) event.getEntity())); + ForgeSlack.getSlackRelay().sendMessage("_" + ((EntityPlayer) event.getEntity()).getCombatTracker().getDeathMessage().getUnformattedText() + "_", (EntityPlayer) event.getEntity()); } } @@ -49,14 +48,15 @@ public void onPlayerReceiveAdvancement(AdvancementEvent event) { return; } - ITextComponent achievementText = event.getAdvancement().getDisplayText(); - String playerName = getName(event.getEntityPlayer()); - String msg = MessageFormat.format("_{0} has earned the achievement: {1}_", playerName, achievementText.getUnformattedText()); + String achievementText = event.getAdvancement().getDisplayText().getUnformattedText(); + EntityPlayer player = event.getEntityPlayer(); + String playerName = getName(player); + String msg = MessageFormat.format("_{0} has earned the achievement: {1}_", playerName, achievementText); - SlackRelay.getInstance().sendMessage(msg, playerName); + ForgeSlack.getSlackRelay().sendMessage(msg, player); } private static String getName(EntityPlayer player) { return ScorePlayerTeam.formatPlayerName(player.getTeam(), player.getDisplayName().getUnformattedText()); } -} \ No newline at end of file +} diff --git a/src/main/java/com/derimagia/forgeslack/handler/SlackMessageHandler.java b/src/main/java/com/derimagia/forgeslack/handler/SlackMessageHandler.java index 3c1b9dd..70c2262 100644 --- a/src/main/java/com/derimagia/forgeslack/handler/SlackMessageHandler.java +++ b/src/main/java/com/derimagia/forgeslack/handler/SlackMessageHandler.java @@ -21,7 +21,7 @@ public class SlackMessageHandler implements EventListener { @Override public void onMessage(JsonNode jsonMessage) { - SlackRelay slackRelay = SlackRelay.getInstance(); + SlackRelay slackRelay = ForgeSlack.getSlackRelay(); // @TODO: Bot ID is different from user id, so this isn't working right now. if (jsonMessage.hasNonNull("bot_id")) { @@ -40,7 +40,7 @@ public void onMessage(JsonNode jsonMessage) { } if (!jsonMessage.hasNonNull("channel") || !jsonMessage.hasNonNull("text")) { - ForgeSlack.log.error(String.format("Invalid RTM Message for onMessage: %s", jsonMessage)); + ForgeSlack.logger.error(String.format("Invalid RTM Message for onMessage: %s", jsonMessage)); return; } @@ -60,7 +60,7 @@ public void onMessage(JsonNode jsonMessage) { User user = slackRelay.getUsernameFromId(userid); username = user != null ? user.getName() : userid; } else { - ForgeSlack.log.error(String.format("Invalid RTM Message for onMessage: %s", jsonMessage)); + ForgeSlack.logger.error(String.format("Invalid RTM Message for onMessage: %s", jsonMessage)); return; } @@ -102,4 +102,4 @@ private String cleanMessageLinks(String text) { return cleanedString.toString(); } -} \ No newline at end of file +} diff --git a/src/main/java/com/derimagia/forgeslack/slack/SlackRelay.java b/src/main/java/com/derimagia/forgeslack/slack/SlackRelay.java index 6685736..40d7365 100644 --- a/src/main/java/com/derimagia/forgeslack/slack/SlackRelay.java +++ b/src/main/java/com/derimagia/forgeslack/slack/SlackRelay.java @@ -9,8 +9,8 @@ import allbegray.slack.webapi.SlackWebApiClient; import allbegray.slack.webapi.method.chats.ChatPostMessageMethod; import com.derimagia.forgeslack.ForgeSlack; -import com.derimagia.forgeslack.handler.ConfigurationHandler; import com.derimagia.forgeslack.handler.SlackMessageHandler; +import net.minecraft.entity.player.EntityPlayer; import java.text.MessageFormat; import java.util.HashMap; @@ -21,26 +21,17 @@ public class SlackRelay { private SlackWebApiClient api; private SlackRealTimeMessagingClient rtmapi; private String channel; + private String slackToken; private String channelId; private Authentication auth; private HashMap users; - private SlackRelay() { - channel = ConfigurationHandler.channel; + public SlackRelay(String channel, String slackToken) { + this.channel = channel; + this.slackToken = slackToken; users = new HashMap<>(); } - /** - * Returns the Instance - */ - public static SlackRelay getInstance() { - if (instance == null) { - instance = new SlackRelay(); - } - - return instance; - } - /** * Fetches and caches a usermap */ @@ -69,67 +60,79 @@ private void fetchChannel() { * Connects the relay */ public void startup() { - api = SlackClientFactory.createWebApiClient(ConfigurationHandler.slackToken); - rtmapi = SlackClientFactory.createSlackRealTimeMessagingClient(ConfigurationHandler.slackToken); - rtmapi.addListener(Event.MESSAGE, new SlackMessageHandler()); - (new Thread(() -> { + api = SlackClientFactory.createWebApiClient(slackToken); + rtmapi = SlackClientFactory.createSlackRealTimeMessagingClient(slackToken); + rtmapi.addListener(Event.MESSAGE, new SlackMessageHandler()); + fetchChannel(); fetchUsers(); auth = api.auth(); rtmapi.connect(); sendMessage("Server is online"); - })).start(); + }, "ForgeSlack-Startup")).start(); } /** * Shutdown the Relay */ public void shutdown() { - sendMessage("Server is now offline"); + (new Thread(() -> { + sendMessage("Server is now offline"); - if (rtmapi != null) { - rtmapi.close(); - } + if (rtmapi != null) { + rtmapi.close(); + } + + if (api != null) { + api.shutdown(); + } + + instance = null; + }, "ForgeSlack-Shutdown")).start(); - if (api != null) { - api.shutdown(); - } } /** * Sends a Slack Message * - * @param message - Message to be sent + * @param txt - Message to be sent */ - public void sendMessage(String message) { - sendMessage(message, ""); + public void sendMessage(String txt) { + ChatPostMessageMethod message = new ChatPostMessageMethod(channel, txt); + sendMessage(message); + } + + + /** + * Sends a Slack Message from a EntityPlayer + * + * @param txt - Message to be sent + * @param player - Minecraft User + */ + public void sendMessage(String txt, EntityPlayer player) { + ChatPostMessageMethod message = new ChatPostMessageMethod(channel, txt); + message.setUsername(player.getDisplayName().getUnformattedText()); + String uuid = player.getCachedUniqueIdString().replaceAll("-", ""); + message.setIcon_url(MessageFormat.format("https://use.gameapis.net/mc/images/avatar/{0}", uuid)); + sendMessage(message); } /** * Sends a Slack Message in a new Thread - * + * * @param message - Message to be sent - * @param username - Minecraft Username of User. */ - public void sendMessage(String message, String username) { - ChatPostMessageMethod chatMessage = new ChatPostMessageMethod(channel, message); - - if (!username.isEmpty()) { - chatMessage.setUsername(username); - chatMessage.setIcon_url(MessageFormat.format("https://use.gameapis.net/mc/images/avatar/{0}", username)); - } - - // @TODO: Use the rtm instead. + public void sendMessage(ChatPostMessageMethod message) { (new Thread(() -> { try { if (api != null) { - api.postMessage(chatMessage); + api.postMessage(message); } else { - ForgeSlack.log.error(String.format("Tried to send slack message: '%s'. Slack Web API Client is not started.", chatMessage)); + ForgeSlack.logger.error(String.format("Tried to send slack message: '%s'. Slack Web API Client is not started.", message)); } } catch (Exception e) { - ForgeSlack.log.error(e.getMessage()); + ForgeSlack.logger.error(e.getMessage()); } }, "ForgeSlack-message")).start(); } @@ -164,4 +167,4 @@ public User getUsernameFromId(String userId) { fetchUsers(); return users.get(userId); } -} \ No newline at end of file +} diff --git a/src/main/resources/mod_ForgeSlack.logo.png b/src/main/resources/forgeslack-logo.png similarity index 100% rename from src/main/resources/mod_ForgeSlack.logo.png rename to src/main/resources/forgeslack-logo.png diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index 6a9459e..56782a4 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -1,17 +1,15 @@ -{ - "modListVersion": 2, - "modList": [{ - "modid": "mod_forgeslack", - "name": "forgeslack", +[ + { + "modid": "forgeslack", + "name": "Forgeslack", "description": "A mod which enables chat to be connected with Slack.", - "version": "1.12.2-0.3.0", - "mcversion": "1.12.2", + "version": "${version}", + "mcversion": "${mcversion}", "url": "https://github.com/derimagia/forgeslack", "updateUrl": "", - "authorList": [ "derimagia" ], - "logoFile": "/mod_ForgeSlack.logo.png", + "authorList": ["derimagia"], + "logoFile": "/forgeslack-logo.png", "credits": "Authored by derimagia. https://docs.gameapis.net/ for supplying API for avatar images. Updated to 1.9.4 by Illyohs.", - "requiredMods": [ "Forge" ], - "useDependencyInformation": true - }] -} \ No newline at end of file + "requiredMods": [] + } +]