diff options
author | Cow <cow@volloeko.de> | 2020-03-08 00:12:57 +0100 |
---|---|---|
committer | Cow <cow@volloeko.de> | 2020-03-08 00:12:57 +0100 |
commit | 0a105c807a3f8040ada76c4e4edac4a79fe32fe6 (patch) | |
tree | b0631894c6547b2fe3daf73539fec6935dd9659d | |
parent | 508f872ba076f4e767ff2c374656bc47637eb229 (diff) | |
download | Cowlection-0a105c807a3f8040ada76c4e4edac4a79fe32fe6.tar.gz Cowlection-0a105c807a3f8040ada76c4e4edac4a79fe32fe6.tar.bz2 Cowlection-0a105c807a3f8040ada76c4e4edac4a79fe32fe6.zip |
Added mod update notification (opt-out via /moo config)
Standardized versioning (now includes Minecraft version)
Bug fixes:
- Reduced greediness of login/logout notification detection
-rw-r--r-- | CHANGELOG.md | 28 | ||||
-rw-r--r-- | README.md | 15 | ||||
-rw-r--r-- | build.gradle | 2 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/Cowmoonication.java | 26 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/command/MooCommand.java | 86 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/config/MooConfig.java | 7 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/config/MooGuiConfig.java | 1 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/listener/ChatListener.java | 7 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/listener/PlayerListener.java | 18 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/util/Utils.java | 9 | ||||
-rw-r--r-- | src/main/java/eu/olli/cowmoonication/util/VersionChecker.java | 140 | ||||
-rw-r--r-- | src/main/resources/assets/cowmoonication/lang/en_us.lang | 1 | ||||
-rw-r--r-- | src/main/resources/mcmod.info | 4 | ||||
-rw-r--r-- | update.json | 10 |
14 files changed, 326 insertions, 28 deletions
diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..14ac786 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,28 @@ +# Changelog +All notable changes to this project will be documented in this file. + +The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). + +## [1.8.9-0.2.0] - 08.03.2020 +### Added +- Mod update notification (opt-out via config) + +### Changed +- *Mod versioning now includes Minecraft version*: `<mc-version>-<modversion>` instead of just `<modversion>` +- Manage 'best friends' list via GUI instead of add/remove commands + +### Fixed +- Reduced greediness of login/logout notification detection + +## [0.1] - 01.03.2020 +### Added +- Toggle to hide all join/leave notifications (`/moo toggle`) +- 'Best friends' list to limit the amount of join and leave notifications (see below) +- Auto-replace `/r` with `/msg <latest username>` +- Copy chat components via <kbd>ALT</kbd> + <kbd>right click</kbd> +- Change guiScale to any value (`/moo guiscale [newValue]`) + +*Note:* The 'best friends' list is currently available via <kbd>ESC</kbd> > Mod Options > Cowmoonication > Config > bestFriends. + +[1.8.9-0.2.0]: https://github.com/cow-mc/Cowmoonication/compare/v0.1...v1.8.9-0.2.0 +[0.1]: https://github.com/cow-mc/Cowmoonication/releases/tag/v0.1 @@ -1,12 +1,19 @@ # Cowmoonication -A client-side only Forge mod by [Cow](https://namemc.com/profile/Cow) providing various things related to communication. - -**Current features:** +A client-side only Forge mod by [Cow](https://namemc.com/profile/Cow) providing various things related to communication. :cow2: +## Current features | Feature | Command/Usage | |-------------------------------------------------------------------------|-----------------------------------------| | Toggle to hide all join/leave notifications | `/moo toggle` | | 'Best friends' list to limit the amount of join and leave notifications | `/moo friends` | | Change guiScale to any value | `/moo guiscale [newValue]` | -| Auto-replace `/r` with `/msg <latest username>` | `/r ` | +| Auto-replace `/r` with `/w <latest username>` | `/r ` | | Copy chat components | <kbd>ALT</kbd> + <kbd>right click</kbd> | +| Check for mod updates on server login and via command | `/moo update` | + +➜ Use `/moo help` to see all available commands. + +## Download +You can download the compiled .jar files from the [release section](https://github.com/cow-mc/Cowmoonication/releases). + +➜ View [Changelog](CHANGELOG.md) diff --git a/build.gradle b/build.gradle index 3d002c6..f108a60 100644 --- a/build.gradle +++ b/build.gradle @@ -20,7 +20,7 @@ plugins { id "net.minecraftforge.gradle.forge" version "2.0.2" } */ -version = "0.1" +version = "1.8.9-0.2.0" group= "eu.olli.cowmoonication" // http://maven.apache.org/guides/mini/guide-naming-conventions.html archivesBaseName = "Cowmoonication" diff --git a/src/main/java/eu/olli/cowmoonication/Cowmoonication.java b/src/main/java/eu/olli/cowmoonication/Cowmoonication.java index 3a93fe6..78f1905 100644 --- a/src/main/java/eu/olli/cowmoonication/Cowmoonication.java +++ b/src/main/java/eu/olli/cowmoonication/Cowmoonication.java @@ -3,24 +3,32 @@ package eu.olli.cowmoonication; import eu.olli.cowmoonication.command.MooCommand; import eu.olli.cowmoonication.config.MooConfig; import eu.olli.cowmoonication.listener.ChatListener; +import eu.olli.cowmoonication.listener.PlayerListener; import eu.olli.cowmoonication.util.Utils; +import eu.olli.cowmoonication.util.VersionChecker; import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.common.MinecraftForge; import net.minecraftforge.common.config.Configuration; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLInitializationEvent; +import net.minecraftforge.fml.common.event.FMLPostInitializationEvent; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import org.apache.logging.log4j.Logger; import java.io.File; -@Mod(modid = Cowmoonication.MODID, version = Cowmoonication.VERSION, clientSideOnly = true, guiFactory = "eu.olli." + Cowmoonication.MODID + ".config.MooGuiFactory") +@Mod(modid = Cowmoonication.MODID, name = Cowmoonication.MODNAME, version = Cowmoonication.VERSION, + clientSideOnly = true, + guiFactory = "eu.olli." + Cowmoonication.MODID + ".config.MooGuiFactory", + updateJSON = "https://raw.githubusercontent.com/cow-mc/Cowmoonication/master/update.json") public class Cowmoonication { public static final String MODID = "cowmoonication"; - public static final String VERSION = "1.0"; + public static final String VERSION = "1.8.9-0.2.0"; + public static final String MODNAME = "Cowmoonication"; private MooConfig config; private Friends friends; + private VersionChecker versionChecker; private Utils utils; private Logger logger; @@ -35,16 +43,23 @@ public class Cowmoonication { friends = new Friends(this); config = new MooConfig(new Configuration(new File(modDir, MODID + ".cfg")), this); + + utils = new Utils(this, e.getSourceFile()); } @EventHandler public void init(FMLInitializationEvent e) { - utils = new Utils(this); MinecraftForge.EVENT_BUS.register(new ChatListener(this)); + MinecraftForge.EVENT_BUS.register(new PlayerListener(this)); ClientCommandHandler.instance.registerCommand(new MooCommand(this)); } + @EventHandler + public void postInit(FMLPostInitializationEvent e) { + versionChecker = new VersionChecker(this); + } + public MooConfig getConfig() { return config; } @@ -53,6 +68,10 @@ public class Cowmoonication { return friends; } + public VersionChecker getVersionChecker() { + return versionChecker; + } + public Utils getUtils() { return utils; } @@ -60,5 +79,4 @@ public class Cowmoonication { public Logger getLogger() { return logger; } - } diff --git a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java index f3d234b..08c377d 100644 --- a/src/main/java/eu/olli/cowmoonication/command/MooCommand.java +++ b/src/main/java/eu/olli/cowmoonication/command/MooCommand.java @@ -8,13 +8,15 @@ import net.minecraft.client.Minecraft; import net.minecraft.command.CommandBase; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.util.BlockPos; -import net.minecraft.util.ChatComponentTranslation; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.MathHelper; +import net.minecraft.event.ClickEvent; +import net.minecraft.event.HoverEvent; +import net.minecraft.util.*; +import java.awt.*; +import java.io.IOException; import java.util.List; import java.util.Set; +import java.util.concurrent.TimeUnit; public class MooCommand extends CommandBase { private final Cowmoonication main; @@ -29,21 +31,55 @@ public class MooCommand extends CommandBase { main.getUtils().sendMessage(new ChatComponentTranslation(getCommandUsage(sender))); return; } - if (args[0].equalsIgnoreCase("friends") || args[0].equalsIgnoreCase("f")) { + if (args[0].equalsIgnoreCase("friends") || args[0].equalsIgnoreCase("config")) { new TickDelay(() -> Minecraft.getMinecraft().displayGuiScreen(new MooGuiConfig(null)), 1); // delay by 1 tick, because the chat closing would close the new gui instantly as well. } else if (args[0].equalsIgnoreCase("list")) { handleListBestFriends(); } else if (args[0].equalsIgnoreCase("toggle")) { main.getConfig().toggleNotifications(); - main.getUtils().sendMessage(EnumChatFormatting.GREEN + "Switched all non-best friend login/logout notifications " + (MooConfig.filterFriendNotifications ? EnumChatFormatting.DARK_GREEN + "off" : EnumChatFormatting.DARK_RED + "on")); + main.getUtils().sendMessage(EnumChatFormatting.GREEN + "\u2714 Switched all non-best friend login/logout notifications " + (MooConfig.filterFriendNotifications ? EnumChatFormatting.DARK_GREEN + "off" : EnumChatFormatting.DARK_RED + "on")); } else if (args[0].equalsIgnoreCase("guiscale")) { int currentGuiScale = (Minecraft.getMinecraft()).gameSettings.guiScale; if (args.length == 1) { - main.getUtils().sendMessage(EnumChatFormatting.GREEN + "Current GUI scale: " + EnumChatFormatting.DARK_GREEN + currentGuiScale); + main.getUtils().sendMessage(EnumChatFormatting.GREEN + "\u279C Current GUI scale: " + EnumChatFormatting.DARK_GREEN + currentGuiScale); } else { int scale = Math.min(10, MathHelper.parseIntWithDefault(args[1], 6)); Minecraft.getMinecraft().gameSettings.guiScale = scale; - main.getUtils().sendMessage(EnumChatFormatting.GREEN + "New GUI scale: " + EnumChatFormatting.DARK_GREEN + scale + EnumChatFormatting.GREEN + " (previous: " + EnumChatFormatting.DARK_GREEN + currentGuiScale + EnumChatFormatting.GREEN + ")"); + main.getUtils().sendMessage(EnumChatFormatting.GREEN + "\u2714 New GUI scale: " + EnumChatFormatting.DARK_GREEN + scale + EnumChatFormatting.GREEN + " (previous: " + EnumChatFormatting.DARK_GREEN + currentGuiScale + EnumChatFormatting.GREEN + ")"); + } + } else if (args[0].equalsIgnoreCase("update")) { + boolean updateCheckStarted = main.getVersionChecker().runUpdateCheck(true); + + if (updateCheckStarted) { + main.getUtils().sendMessage(EnumChatFormatting.GREEN + "\u279C Checking for a newer mod version..."); + // VersionChecker#handleVersionStatus will run with a 5 seconds delay + } else { + long nextUpdate = main.getVersionChecker().getNextCheck(); + String waitingTime = String.format("%02d:%02d", + TimeUnit.MILLISECONDS.toMinutes(nextUpdate), + TimeUnit.MILLISECONDS.toSeconds(nextUpdate) - TimeUnit.MINUTES.toSeconds(TimeUnit.MILLISECONDS.toMinutes(nextUpdate))); + main.getUtils().sendMessage(new ChatComponentText("\u26A0 Update checker is on cooldown. Please wait " + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + waitingTime + EnumChatFormatting.RESET + EnumChatFormatting.RED + " more minutes before checking again.").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + } + } else if (args[0].equalsIgnoreCase("updateHelp")) { + main.getUtils().sendMessage(new ChatComponentText("\u279C Update instructions:").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(true)) + .appendSibling(new ChatComponentText("\n\u278A" + EnumChatFormatting.YELLOW + " download latest mod version").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, main.getVersionChecker().getDownloadUrl())) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Download the latest version of Cowmoonication\n\u279C Click to download latest mod file"))))) + .appendSibling(new ChatComponentText("\n\u278B" + EnumChatFormatting.YELLOW + " exit Minecraft").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.GOLD + "\u278B" + EnumChatFormatting.YELLOW + " Without closing Minecraft first,\n" + EnumChatFormatting.YELLOW + "you can't delete the old .jar file!"))))) + .appendSibling(new ChatComponentText("\n\u278C" + EnumChatFormatting.YELLOW + " copy " + EnumChatFormatting.GOLD + "Cowmoonication-" + main.getVersionChecker().getNewVersion() + ".jar" + EnumChatFormatting.YELLOW + " into mods folder").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/moo folder")) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Open mods folder with command " + EnumChatFormatting.GOLD + "/moo folder\n\u279C Click to open mods folder"))))) + .appendSibling(new ChatComponentText("\n\u278D" + EnumChatFormatting.YELLOW + " delete old mod file " + EnumChatFormatting.GOLD + "Cowmoonication-" + Cowmoonication.VERSION + ".jar ").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false))) + .appendSibling(new ChatComponentText("\n\u278E" + EnumChatFormatting.YELLOW + " start Minecraft again").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(false)))); + } else if (args[0].equalsIgnoreCase("version")) { + main.getVersionChecker().handleVersionStatus(true); + } else if (args[0].equalsIgnoreCase("folder")) { + try { + Desktop.getDesktop().open(main.getUtils().getModsFolder()); + } catch (IOException e) { + main.getUtils().sendMessage(new ChatComponentText("\u2716 An error occurred trying to open the mod's folder. I guess you have to open it manually \u00af\\_(\u30c4)_/\u00af").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED))); + e.printStackTrace(); } } else { main.getUtils().sendMessage(new ChatComponentTranslation(getCommandUsage(sender))); @@ -54,7 +90,7 @@ public class MooCommand extends CommandBase { Set<String> bestFriends = main.getFriends().getBestFriends(); // TODO show fancy gui with list of best friends (maybe just the mod's settings?) - main.getUtils().sendMessage(EnumChatFormatting.GREEN + "Best friends: " + String.join(", ", bestFriends)); + main.getUtils().sendMessage(EnumChatFormatting.GREEN + "\u279C Best friends: " + EnumChatFormatting.DARK_GREEN + String.join(EnumChatFormatting.GREEN + ", " + EnumChatFormatting.DARK_GREEN, bestFriends)); } @Override @@ -64,7 +100,35 @@ public class MooCommand extends CommandBase { @Override public String getCommandUsage(ICommandSender sender) { - return Cowmoonication.MODID + ":command.moo.usage"; + IChatComponent usage = new ChatComponentText("\u279C Cowmoonication commands:").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(true)) + .appendSibling(createCmdHelpSection(1, "Login/Logout Notifications")) + .appendSibling(createCmdHelpEntry("friends", "Add/remove best friends")) + .appendSibling(createCmdHelpEntry("list", "View list of best friends")) + .appendSibling(createCmdHelpEntry("toggle", "Toggle show/hide all join/leave notifications")) + .appendSibling(createCmdHelpSection(2, "Miscellaneous")) + .appendSibling(createCmdHelpEntry("config", "Open configuration GUI")) + .appendSibling(createCmdHelpEntry("guiScale", "Change GUI scale")) + .appendSibling(createCmdHelpSection(3, "Update mod")) + .appendSibling(createCmdHelpEntry("update", "Check for new mod updates")) + .appendSibling(createCmdHelpEntry("updateHelp", "Show mod update instructions")) + .appendSibling(createCmdHelpEntry("version", "View results of last mod update check")) + .appendSibling(createCmdHelpEntry("folder", "Open Minecraft's mods folder")); + sender.addChatMessage(usage); + return ""; + } + + private IChatComponent createCmdHelpSection(int nr, String title) { + String prefix = Character.toString((char) (0x2789 + nr)); + return new ChatComponentText("\n").appendSibling(new ChatComponentText(prefix + " " + title).setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GOLD).setBold(true))); + } + + private IChatComponent createCmdHelpEntry(String cmd, String usage) { + String command = "/" + this.getCommandName() + " " + cmd; + ChatStyle clickableMsg = new ChatStyle() + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Run " + EnumChatFormatting.GOLD + command))) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, command)); + return new ChatComponentText("\n").appendSibling(new ChatComponentText(command).setChatStyle(clickableMsg.createDeepCopy().setColor(EnumChatFormatting.GOLD))) + .appendSibling(new ChatComponentText(" \u27A1 " + usage).setChatStyle(clickableMsg.createDeepCopy().setColor(EnumChatFormatting.YELLOW))); } @Override @@ -75,7 +139,7 @@ public class MooCommand extends CommandBase { @Override public List<String> addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) { if (args.length == 1) { - return getListOfStringsMatchingLastWord(args, "friends", "list", "toggle", "guiscale"); + return getListOfStringsMatchingLastWord(args, "config", "friends", "list", "toggle", "guiscale", "update", "updateHelp", "version", "folder", "help"); } return null; } diff --git a/src/main/java/eu/olli/cowmoonication/config/MooConfig.java b/src/main/java/eu/olli/cowmoonication/config/MooConfig.java index 97cea9b..e9b2146 100644 --- a/src/main/java/eu/olli/cowmoonication/config/MooConfig.java +++ b/src/main/java/eu/olli/cowmoonication/config/MooConfig.java @@ -13,6 +13,7 @@ import java.util.ArrayList; import java.util.List; public class MooConfig { + public static boolean doUpdateCheck; public static boolean filterFriendNotifications; private static String[] bestFriends; private static Configuration cfg = null; @@ -69,6 +70,9 @@ public class MooConfig { cfg.load(); } + final boolean DO_UPDATE_CHECK = true; + Property propDoUpdateCheck = cfg.get(Configuration.CATEGORY_CLIENT, "doUpdateCheck", DO_UPDATE_CHECK, "Check for mod updates?"); + final boolean FILTER_FRIEND_NOTIFICATIONS = true; Property propFilterFriendNotify = cfg.get(Configuration.CATEGORY_CLIENT, "filterFriendNotifications", FILTER_FRIEND_NOTIFICATIONS, "Set to false to receive all login/logout messages, set to true to only get notifications of 'best friends' joining/leaving"); @@ -77,15 +81,18 @@ public class MooConfig { propBestFriends.setValidationPattern(Utils.VALID_USERNAME); List<String> propOrderGeneral = new ArrayList<>(); + propOrderGeneral.add(propDoUpdateCheck.getName()); propOrderGeneral.add(propFilterFriendNotify.getName()); propOrderGeneral.add(propBestFriends.getName()); cfg.setCategoryPropertyOrder(Configuration.CATEGORY_CLIENT, propOrderGeneral); if (readFieldsFromConfig) { + doUpdateCheck = propDoUpdateCheck.getBoolean(DO_UPDATE_CHECK); filterFriendNotifications = propFilterFriendNotify.getBoolean(FILTER_FRIEND_NOTIFICATIONS); bestFriends = propBestFriends.getStringList(); } + propDoUpdateCheck.set(doUpdateCheck); propFilterFriendNotify.set(filterFriendNotifications); propBestFriends.set(bestFriends); diff --git a/src/main/java/eu/olli/cowmoonication/config/MooGuiConfig.java b/src/main/java/eu/olli/cowmoonication/config/MooGuiConfig.java index e7b7862..c8c68c1 100644 --- a/src/main/java/eu/olli/cowmoonication/config/MooGuiConfig.java +++ b/src/main/java/eu/olli/cowmoonication/config/MooGuiConfig.java @@ -24,7 +24,6 @@ public class MooGuiConfig extends GuiConfig { // optional: add buttons and initialize fields } - @Override public void drawScreen(int mouseX, int mouseY, float partialTicks) { super.drawScreen(mouseX, mouseY, partialTicks); diff --git a/src/main/java/eu/olli/cowmoonication/listener/ChatListener.java b/src/main/java/eu/olli/cowmoonication/listener/ChatListener.java index 83b3890..54f8025 100644 --- a/src/main/java/eu/olli/cowmoonication/listener/ChatListener.java +++ b/src/main/java/eu/olli/cowmoonication/listener/ChatListener.java @@ -36,8 +36,9 @@ public class ChatListener { public void onLogInOutMessage(ClientChatReceivedEvent e) { if (e.type != 2 && MooConfig.filterFriendNotifications) { // normal chat or system msg String text = e.message.getUnformattedText(); - if (text.endsWith(" joined.") || text.endsWith(" left.") // Hypixel - || text.endsWith(" joined the game") || text.endsWith(" left the game.")) { // Spigot + if (text.length() < 42 && // to prevent the party disbanded message from being filtered: "The party was disbanded because all invites have expired and all members have left." + (text.endsWith(" joined.") || text.endsWith(" left.") // Hypixel + || text.endsWith(" joined the game") || text.endsWith(" left the game."))) { // Spigot // TODO maybe check which server thePlayer is on and check for logout pattern accordingly int nameEnd = text.indexOf(" joined"); if (nameEnd == -1) { @@ -76,7 +77,7 @@ public class ChatListener { if (lastTypedChars.equalsIgnoreCase("/r ")) { // replace /r with /msg <last user> main.getUtils().sendAboveChatMessage("Sending message to " + lastPMSender + "!"); - Minecraft.getMinecraft().displayGuiScreen(new GuiChat("/msg " + lastPMSender + " ")); + Minecraft.getMinecraft().displayGuiScreen(new GuiChat("/w " + lastPMSender + " ")); } } else if (Keyboard.getEventKey() == Keyboard.KEY_BACK) { // Backspace lastTypedChars = lastTypedChars.substring(0, Math.max(lastTypedChars.length() - 1, 0)); diff --git a/src/main/java/eu/olli/cowmoonication/listener/PlayerListener.java b/src/main/java/eu/olli/cowmoonication/listener/PlayerListener.java new file mode 100644 index 0000000..b817ed8 --- /dev/null +++ b/src/main/java/eu/olli/cowmoonication/listener/PlayerListener.java @@ -0,0 +1,18 @@ +package eu.olli.cowmoonication.listener; + +import eu.olli.cowmoonication.Cowmoonication; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.network.FMLNetworkEvent; + +public class PlayerListener { + private final Cowmoonication main; + + public PlayerListener(Cowmoonication main) { + this.main = main; + } + + @SubscribeEvent + public void onServerJoin(FMLNetworkEvent.ClientConnectedToServerEvent e) { + main.getVersionChecker().runUpdateCheck(false); + } +} diff --git a/src/main/java/eu/olli/cowmoonication/util/Utils.java b/src/main/java/eu/olli/cowmoonication/util/Utils.java index d10c2ed..60e2ea3 100644 --- a/src/main/java/eu/olli/cowmoonication/util/Utils.java +++ b/src/main/java/eu/olli/cowmoonication/util/Utils.java @@ -7,6 +7,7 @@ import net.minecraft.util.IChatComponent; import net.minecraftforge.client.event.ClientChatReceivedEvent; import net.minecraftforge.common.MinecraftForge; +import java.io.File; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -14,11 +15,13 @@ public class Utils { public static final Pattern VALID_USERNAME = Pattern.compile("^[\\w]{1,16}$"); private static final Pattern USELESS_JSON_CONTENT_PATTERN = Pattern.compile("\"[A-Za-z]+\":false,?"); private final Cowmoonication main; + private final File modsDir; private String[] aboveChatMessage; private long aboveChatMessageExpiration; - public Utils(Cowmoonication main) { + public Utils(Cowmoonication main, File sourceFile) { this.main = main; + modsDir = sourceFile.getParentFile(); } public void sendMessage(String text) { @@ -55,4 +58,8 @@ public class Utils { Matcher jsonMatcher = USELESS_JSON_CONTENT_PATTERN.matcher(component); return jsonMatcher.replaceAll(""); } + + public File getModsFolder() { + return modsDir; + } } diff --git a/src/main/java/eu/olli/cowmoonication/util/VersionChecker.java b/src/main/java/eu/olli/cowmoonication/util/VersionChecker.java new file mode 100644 index 0000000..5c29ae5 --- /dev/null +++ b/src/main/java/eu/olli/cowmoonication/util/VersionChecker.java @@ -0,0 +1,140 @@ +package eu.olli.cowmoonication.util; + +import eu.olli.cowmoonication.Cowmoonication; +import eu.olli.cowmoonication.config.MooConfig; +import net.minecraft.client.Minecraft; +import net.minecraft.event.ClickEvent; +import net.minecraft.event.HoverEvent; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.IChatComponent; +import net.minecraftforge.common.ForgeModContainer; +import net.minecraftforge.common.ForgeVersion; +import net.minecraftforge.fml.common.Loader; + +import java.util.concurrent.TimeUnit; + +/** + * @see ForgeVersion + */ +public class VersionChecker { + /** + * Cooldown between to update checks in minutes + */ + private static final int CHECK_COOLDOWN = 15; + private static final String CHANGELOG_URL = "https://github.com/cow-mc/Cowmoonication/blob/master/CHANGELOG.md"; + private final Cowmoonication main; + private long lastCheck; + private String newVersion; + private String downloadUrl; + + public VersionChecker(Cowmoonication main) { + this.main = main; + this.lastCheck = Minecraft.getSystemTime(); + newVersion = "[newVersion]"; + downloadUrl = "https://github.com/cow-mc/Cowmoonication/releases"; + } + + public boolean runUpdateCheck(boolean isCommandTriggered) { + if (isCommandTriggered || (!ForgeModContainer.disableVersionCheck && MooConfig.doUpdateCheck)) { + Runnable handleResults = () -> main.getVersionChecker().handleVersionStatus(isCommandTriggered); + + long now = Minecraft.getSystemTime(); + + // only re-run if last check was >CHECK_COOLDOWN minutes ago# + if (getNextCheck() < 0) { // next allowed check is "in the past", so we're good to go + lastCheck = now; + ForgeVersion.startVersionCheck(); + + // check status after 5 seconds - hopefully that's enough to check + new TickDelay(handleResults, 5 * 20); + return true; + } else { + new TickDelay(handleResults, 1); + } + } + return false; + } + + public void handleVersionStatus(boolean isCommandTriggered) { + ForgeVersion.CheckResult versionResult = ForgeVersion.getResult(Loader.instance().activeModContainer()); + if (versionResult.target != null) { + newVersion = versionResult.target.toString(); + downloadUrl = "https://github.com/cow-mc/Cowmoonication/releases/download/v" + newVersion + "/" + Cowmoonication.MODNAME + "-" + newVersion + ".jar"; + } + + IChatComponent statusMsg = null; + + if (isCommandTriggered) { + if (versionResult.status == ForgeVersion.Status.UP_TO_DATE) { + // up to date + statusMsg = new ChatComponentText("\u2714 You're running the latest version (" + Cowmoonication.VERSION + ").").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN)); + } else if (versionResult.status == ForgeVersion.Status.PENDING) { + // pending + statusMsg = new ChatComponentText("\u279C " + "Version check either failed or is still running.").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.YELLOW)) + .appendSibling(new ChatComponentText("\n \u278A Check for results again in a few seconds with " + EnumChatFormatting.GOLD + "/moo version").setChatStyle(new ChatStyle() + .setColor(EnumChatFormatting.YELLOW) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/moo version")) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Run " + EnumChatFormatting.GOLD + "/moo version"))))) + .appendSibling(new ChatComponentText("\n \u278B Re-run update check with " + EnumChatFormatting.GOLD + "/moo update").setChatStyle(new ChatStyle() + .setColor(EnumChatFormatting.YELLOW) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/moo update")) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Run " + EnumChatFormatting.GOLD + "/moo update"))))); + } else if (versionResult.status == ForgeVersion.Status.FAILED) { + // check failed + statusMsg = new ChatComponentText("\u2716 Version check failed for an unknown reason. Check again in a few seconds with ").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.RED)) + .appendSibling(new ChatComponentText("/moo update").setChatStyle(new ChatStyle() + .setColor(EnumChatFormatting.GOLD) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/moo update")) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Run " + EnumChatFormatting.GOLD + "/moo update"))))); + } + } + if (versionResult.status == ForgeVersion.Status.OUTDATED || versionResult.status == ForgeVersion.Status.BETA_OUTDATED) { + // outdated + IChatComponent spacer = new ChatComponentText(" ").setChatStyle(new ChatStyle().setParentStyle(null)); + + IChatComponent text = new ChatComponentText("\u279C New version of " + EnumChatFormatting.DARK_GREEN + "Cowmoonication " + EnumChatFormatting.GREEN + "available (" + Cowmoonication.VERSION + " \u27A1 " + newVersion + ")\n").setChatStyle(new ChatStyle().setColor(EnumChatFormatting.GREEN)); + + IChatComponent download = new ChatComponentText("[Download]").setChatStyle(new ChatStyle() + .setColor(EnumChatFormatting.DARK_GREEN).setBold(true) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, downloadUrl)) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Download the latest version of Cowmoonication")))); + + IChatComponent changelog = new ChatComponentText("[Changelog]").setChatStyle(new ChatStyle() + .setColor(EnumChatFormatting.DARK_AQUA).setBold(true) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.OPEN_URL, CHANGELOG_URL)) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "View changelog")))); + + IChatComponent updateInstructions = new ChatComponentText("[Update instructions]").setChatStyle(new ChatStyle() + .setColor(EnumChatFormatting.GOLD).setBold(true) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/moo updateHelp")) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Run " + EnumChatFormatting.GOLD + "/moo updateHelp")))); + + IChatComponent openModsFolder = new ChatComponentText("\n[Open Mods folder]").setChatStyle(new ChatStyle() + .setColor(EnumChatFormatting.GREEN).setBold(true) + .setChatClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, "/moo folder")) + .setChatHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new ChatComponentText(EnumChatFormatting.YELLOW + "Open mods folder with command " + EnumChatFormatting.GOLD + "/moo folder\n\u279C Click to open mods folder")))); + + statusMsg = text.appendSibling(download).appendSibling(spacer).appendSibling(changelog).appendSibling(spacer).appendSibling(updateInstructions).appendSibling(spacer).appendSibling(openModsFolder); + } + + if (statusMsg != null) { + main.getUtils().sendMessage(statusMsg); + } + } + + public long getNextCheck() { + long cooldown = TimeUnit.MINUTES.toMillis(CHECK_COOLDOWN); + long systemTime = Minecraft.getSystemTime(); + return cooldown - (systemTime - lastCheck); + } + + public String getNewVersion() { + return newVersion; + } + + public String getDownloadUrl() { + return downloadUrl; + } +} diff --git a/src/main/resources/assets/cowmoonication/lang/en_us.lang b/src/main/resources/assets/cowmoonication/lang/en_us.lang deleted file mode 100644 index b7e77d4..0000000 --- a/src/main/resources/assets/cowmoonication/lang/en_us.lang +++ /dev/null @@ -1 +0,0 @@ -cowmoonication:command.moo.usage=/moo diff --git a/src/main/resources/mcmod.info b/src/main/resources/mcmod.info index e6c8f6e..581572b 100644 --- a/src/main/resources/mcmod.info +++ b/src/main/resources/mcmod.info @@ -4,8 +4,8 @@ "description": "Adding various things related to communication.", "version": "${version}", "mcversion": "${mcversion}", - "url": "https://github.com/cow-mc/Cowmoonication", - "updateUrl": "", + "url": "https://github.com/cow-mc/Cowmoonication/", + "updateUrl": "https://raw.githubusercontent.com/cow-mc/Cowmoonication/master/update.json", "authorList": ["Cow"], "logoFile": "", "screenshots": [], diff --git a/update.json b/update.json new file mode 100644 index 0000000..44a3ab2 --- /dev/null +++ b/update.json @@ -0,0 +1,10 @@ +{ + "homepage": "https://github.com/cow-mc/Cowmoonication/", + "1.8.9": { + "1.8.9-0.2.0": "https://github.com/cow-mc/Cowmoonication/blob/master/CHANGELOG.md" + }, + "promos": { + "1.8.9-latest": "1.8.9-0.2.0", + "1.8.9-recommended": "1.8.9-0.2.0" + } +} |