From 68e7361c005cdd04b1d2c9d3ba6d2af7ef80b5fd Mon Sep 17 00:00:00 2001 From: Spencer Date: Thu, 12 Apr 2018 03:38:52 -0400 Subject: [PATCH] Chat Refactor, chat suffixes and update bugfixes (#599) --- .../mineplex/core/common/util/UtilText.java | 33 +- .../core/account/CoreClientManager.java | 4 +- .../account/repository/AccountRepository.java | 9 +- .../core/admin/command/SeenCommand.java | 15 +- .../mineplex/core/bonuses/gui/BonusGui.java | 12 +- ...{TwitterButton.java => DiscordButton.java} | 35 +- ...bookButton.java => SocialMediaButton.java} | 20 +- .../src/mineplex/core/chat/BackupFilter.java | 83 ++ .../src/mineplex/core/chat/Chat.java | 986 ++++++++++-------- .../core/chat/command/SilenceCommand.java | 10 +- .../chat/command/extra/ChatExtraCommand.java | 105 ++ .../mineplex/core/command/CommandCenter.java | 29 +- .../core/communities/CommunityManager.java | 4 +- .../commands/CommunityDescriptionCommand.java | 2 +- .../mineplex/core/message/MessageManager.java | 20 +- .../mineplex/core/preferences/Preference.java | 6 + .../core/preferences/PreferencesManager.java | 9 +- .../mineplex/core/updater/FileUpdater.java | 4 +- .../src/mineplex/game/clans/Clans.java | 2 +- .../game/clans/clans/ClansManager.java | 6 +- .../clans/clans/commands/ClansCommand.java | 2 +- .../TntGenerator.java | 0 .../TntGeneratorManager.java | 0 .../game/clans/tutorial/TutorialManager.java | 2 +- .../src/mineplex/clanshub/ClansHub.java | 2 +- .../Mineplex.Hub/src/mineplex/hub/Hub.java | 2 +- .../src/mineplex/staffServer/StaffServer.java | 3 +- .../src/nautilus/game/arcade/Arcade.java | 2 +- .../nautilus/game/arcade/ArcadeManager.java | 26 - .../src/nautilus/game/arcade/game/Game.java | 6 +- .../game/arcade/game/games/draw/Draw.java | 6 +- .../arcade/game/games/draw/DrawRound.java | 2 +- .../arcade/game/games/event/EventModule.java | 10 +- .../games/gladiators/hotbar/HotbarEditor.java | 2 - .../game/games/minestrike/Minestrike.java | 2 +- .../game/games/mineware/BawkBawkBattles.java | 4 +- .../games/moba/prepare/PrepareManager.java | 4 +- .../game/arcade/game/games/uhc/UHC.java | 2 +- .../arcade/game/modules/HubClockModule.java | 57 +- .../arcade/gametutorial/GameTutorial.java | 6 +- .../game/arcade/managers/GameHostManager.java | 2 +- .../arcade/managers/GameSpectatorManager.java | 2 +- .../arcade/managers/chat/GameChatManager.java | 4 +- .../src/mineplex/mavericks/review/Hub.java | 2 +- .../src/mineplex/gemhunters/GemHunters.java | 2 +- .../mineplex/gemhunters/chat/ChatModule.java | 2 +- 46 files changed, 982 insertions(+), 566 deletions(-) rename Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/{TwitterButton.java => DiscordButton.java} (66%) rename Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/{FacebookButton.java => SocialMediaButton.java} (68%) create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/chat/BackupFilter.java create mode 100644 Plugins/Mineplex.Core/src/mineplex/core/chat/command/extra/ChatExtraCommand.java rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/{tntGenerator => tntgenerator}/TntGenerator.java (100%) rename Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/{tntGenerator => tntgenerator}/TntGeneratorManager.java (100%) diff --git a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java index a86048666..92e9e8128 100644 --- a/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java +++ b/Plugins/Mineplex.Core.Common/src/mineplex/core/common/util/UtilText.java @@ -13,19 +13,30 @@ import java.io.InputStream; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.Map; import org.apache.commons.lang.WordUtils; import org.bukkit.ChatColor; public class UtilText { - private static HashMap _characters = new HashMap<>(); - private static HashMap _characterImages = new HashMap<>(); + private static Map _leetReplace = new HashMap<>(); + private static Map _characters = new HashMap<>(); + private static Map _characterImages = new HashMap<>(); - private final static char[] VOWELS = new char[]{'a', 'e', 'i', 'o', 'u'}; + private final static char[] VOWELS = new char[]{'a', 'e', 'i', 'o', 'u'}; static { + _leetReplace.put("4", "a"); + _leetReplace.put("3", "e"); + _leetReplace.put("6", "d"); + _leetReplace.put("1", "i"); + _leetReplace.put("0", "o"); + _leetReplace.put("5", "s"); + _leetReplace.put("7", "t"); + _leetReplace.put("_", ""); + try { InputStream inputStream = UtilText.class.getResourceAsStream("/ascii.png"); @@ -834,6 +845,22 @@ public class UtilText RN_I[number % 10]; } + + public static String replaceLeet(String in) + { + if (in.trim().isEmpty()) + { + return in; + } + + for (Map.Entry entry : _leetReplace.entrySet()) + { + in = in.replaceAll(entry.getKey(), entry.getValue()); + } + + return in; + } + public static String capitalise(String input) { return Character.toUpperCase(input.charAt(0)) + input.toLowerCase().substring(1); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java index 7e352124c..7ec57d0b0 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/account/CoreClientManager.java @@ -886,8 +886,8 @@ public class CoreClientManager extends MiniPlugin _loginProcessors.add(processor); } - public void loadLastLogin(int accountId, Consumer lastLogin) + public void loadLastLogin(String name, Consumer lastLogin) { - _repository.loadLastLogin(accountId, lastLogin); + _repository.loadLastLogin(name, lastLogin); } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java index caf960140..c414ef349 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/account/repository/AccountRepository.java @@ -18,7 +18,6 @@ import java.util.function.Consumer; import java.util.stream.Collectors; import org.apache.commons.dbcp2.BasicDataSource; -import org.bukkit.Bukkit; import com.google.gson.reflect.TypeToken; @@ -53,7 +52,7 @@ public class AccountRepository extends MinecraftRepository private static String SELECT_ACCOUNT_UUID_BY_ID = "SELECT uuid FROM accounts WHERE id=?;"; private static String SELECT_ACCOUNT_ID_BY_UUID = "SELECT id FROM accounts WHERE accounts.uuid = ? LIMIT 1"; - private static final String SELECT_LAST_LOGIN_BY_ID = "SELECT lastLogin FROM accounts WHERE id = ?"; + private static final String SELECT_LAST_LOGIN_BY_NAME = "SELECT lastLogin FROM accounts WHERE name = ? ORDER BY lastLogin DESC LIMIT 1;"; public AccountRepository() { @@ -461,14 +460,14 @@ public class AccountRepository extends MinecraftRepository return handleSyncMSSQLCallStream("PlayerAccount/GetAccount", playerName); } - public void loadLastLogin(int accountId, Consumer lastLogin) + public void loadLastLogin(String name, Consumer lastLogin) { UtilServer.runAsync(() -> { try (Connection connection = DBPool.getAccount().getConnection(); - PreparedStatement statement = connection.prepareStatement(SELECT_LAST_LOGIN_BY_ID)) + PreparedStatement statement = connection.prepareStatement(SELECT_LAST_LOGIN_BY_NAME)) { - statement.setInt(1, accountId); + statement.setString(1, name); try (ResultSet resultSet = statement.executeQuery()) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/admin/command/SeenCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/admin/command/SeenCommand.java index b895ad2a9..fa681d84b 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/admin/command/SeenCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/admin/command/SeenCommand.java @@ -48,24 +48,15 @@ public class SeenCommand extends CommandBase return; } - Plugin.getCoreClientManager().getOrLoadClient(target, (client) -> + Plugin.getCoreClientManager().loadLastLogin(target, (lastLogin) -> { - if (client == null) + if (lastLogin == null) { reply(caller, "The player " + F.name(target) + " was not found."); return; } - Plugin.getCoreClientManager().loadLastLogin(client.getAccountId(), (lastLogin) -> - { - if (lastLogin == null) - { - reply(caller, "Unable to load that player's last login. Try again later?"); - return; - } - - reply(caller, "The player " + F.name(target) + " last logged in at " + F.elem(UtilTime.when(lastLogin))); - }); + reply(caller, "The player " + F.name(target) + " last logged in at " + F.elem(UtilTime.when(lastLogin))); }); } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java index febc94a74..3dcd9bb01 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/BonusGui.java @@ -7,12 +7,12 @@ import mineplex.core.bonuses.BonusManager; import mineplex.core.bonuses.gui.buttons.CarlSpinButton; import mineplex.core.bonuses.gui.buttons.ClaimTipsButton; import mineplex.core.bonuses.gui.buttons.DailyBonusButton; -import mineplex.core.bonuses.gui.buttons.FacebookButton; +import mineplex.core.bonuses.gui.buttons.DiscordButton; +import mineplex.core.bonuses.gui.buttons.SocialMediaButton; import mineplex.core.bonuses.gui.buttons.LevelRewardsButton; import mineplex.core.bonuses.gui.buttons.PollButton; import mineplex.core.bonuses.gui.buttons.PowerPlayClubButton; import mineplex.core.bonuses.gui.buttons.RankBonusButton; -import mineplex.core.bonuses.gui.buttons.TwitterButton; import mineplex.core.bonuses.gui.buttons.VoteButton; import mineplex.core.bonuses.gui.buttons.YoutubeButton; import mineplex.core.gui.SimpleGui; @@ -26,12 +26,12 @@ public class BonusGui extends SimpleGui private static final int RANK_BONUS_SLOT = 10; private static final int DAILY_BONUS_SLOT = 12; private static final int POLL_SLOT = 28; - private static final int FACEBOOK_SLOT = 20; + private static final int DISCORD_SLOT = 20; private static final int CLAIM_TIPS_SLOT = 30; private static final int POWER_PLAY_SLOT = 16; private static final int CARL_SPINNER_SLOT = 14; private static final int YOUTUBE_SLOT = 24; - private static final int TWITTER_SLOT = 34; + private static final int SOCIAL_MEDIA_SLOT = 34; private static final int LEVEL_REWARDS_SLOT = 22; private static final int INV_SIZE = 45; @@ -48,11 +48,11 @@ public class BonusGui extends SimpleGui setItem(POLL_SLOT, new PollButton(getPlugin(), player, manager.getPollManager(), manager.getClientManager(), this, manager)); - setItem(FACEBOOK_SLOT, new FacebookButton(player)); + setItem(SOCIAL_MEDIA_SLOT, new SocialMediaButton(player)); setItem(YOUTUBE_SLOT, new YoutubeButton(player, youtubeManager)); - setItem(TWITTER_SLOT, new TwitterButton(player)); + setItem(DISCORD_SLOT, new DiscordButton(player)); setItem(CLAIM_TIPS_SLOT, new ClaimTipsButton(getPlugin(), player, this, manager, thankManager)); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/TwitterButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DiscordButton.java similarity index 66% rename from Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/TwitterButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DiscordButton.java index 4700bad1c..f5623e559 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/TwitterButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/DiscordButton.java @@ -1,32 +1,36 @@ package mineplex.core.bonuses.gui.buttons; +import org.bukkit.Material; +import org.bukkit.Sound; +import org.bukkit.entity.Player; +import org.bukkit.event.inventory.ClickType; +import org.bukkit.inventory.ItemStack; + import mineplex.core.common.jsonchat.ClickEvent; import mineplex.core.common.jsonchat.JsonMessage; import mineplex.core.common.util.C; import mineplex.core.common.util.UtilPlayer; import mineplex.core.gui.GuiItem; import mineplex.core.itemstack.ItemBuilder; -import org.bukkit.Material; -import org.bukkit.Sound; -import org.bukkit.entity.Player; -import org.bukkit.event.inventory.ClickType; -import org.bukkit.inventory.ItemStack; -public class TwitterButton implements GuiItem +public class DiscordButton implements GuiItem { - private static final ItemStack ICON = new ItemBuilder(Material.EGG) - .setTitle(C.cGreen + C.Bold + "Visit us on Twitter") + private static final ItemStack ICON = new ItemBuilder(Material.STAINED_GLASS) + // Cyan + .setData((short) 9) + .setTitle(C.cGreen + C.Bold + "Visit our Discord Server") .addLore( - C.cWhite + "Check out and follow Mineplex on", - C.cWhite + "Twitter for Giveaways, Announcements,", - C.cWhite + "Teasers, and Tips!", + C.cWhite + "Check our our official Discord server where", + C.cWhite + "you will find news, changelogs, giveaways,", + C.cWhite + "direct feedback to our admins, and more!", " ", - C.cGreen + "Click to visit us on Twitter!" + C.cGreen + "Click to visit our discord!" ) .build(); + private static final String URL = "http://discord.mineplex.com"; private final Player _player; - public TwitterButton(Player player) + public DiscordButton(Player player) { this._player = player; } @@ -46,9 +50,8 @@ public class TwitterButton implements GuiItem UtilPlayer.message(_player, C.cGold + C.Bold + C.Strike + "============================================="); UtilPlayer.message(_player, ""); - - new JsonMessage(" " + C.Bold + "Click to Open in Web Browser").click(ClickEvent.OPEN_URL, "https://www.twitter.com/Mineplex").sendToPlayer(_player); - new JsonMessage(" " + C.cGreen + C.Line + "https://www.twitter.com/Mineplex").click(ClickEvent.OPEN_URL, "https://www.twitter.com/Mineplex").sendToPlayer(_player); + new JsonMessage(" " + C.Bold + "Click to Open in Web Browser").click(ClickEvent.OPEN_URL, URL).sendToPlayer(_player); + new JsonMessage(" " + C.cGreen + C.Line + URL).click(ClickEvent.OPEN_URL, URL).sendToPlayer(_player); UtilPlayer.message(_player, ""); UtilPlayer.message(_player, C.cGold + C.Bold + C.Strike + "============================================="); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/FacebookButton.java b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/SocialMediaButton.java similarity index 68% rename from Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/FacebookButton.java rename to Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/SocialMediaButton.java index f6bea7b6b..78c1f2690 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/FacebookButton.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/bonuses/gui/buttons/SocialMediaButton.java @@ -12,22 +12,26 @@ import org.bukkit.entity.Player; import org.bukkit.event.inventory.ClickType; import org.bukkit.inventory.ItemStack; -public class FacebookButton implements GuiItem +public class SocialMediaButton implements GuiItem { private static final ItemStack ICON = new ItemBuilder(Material.LAPIS_BLOCK) - .setTitle(C.cGreen + C.Bold + "Visit us on Facebook") + .setTitle(C.cGreen + C.Bold + "Visit our Social Media") .addLore( C.cWhite + "Be sure to \"Like\" us on", C.cWhite + "Facebook for Giveaways, Announcements,", C.cWhite + "and Much More!", " ", - C.cGreen + "Click to visit us on Facebook!" + C.cWhite + "Check out and follow Mineplex on", + C.cWhite + "Twitter for Giveaways, Announcements,", + C.cWhite + "Teasers, and Tips!", + " ", + C.cGreen + "Click to visit us on Facebook and Twitter!" ) .build(); private final Player _player; - public FacebookButton(Player player) + public SocialMediaButton(Player player) { _player = player; } @@ -46,11 +50,17 @@ public class FacebookButton implements GuiItem _player.playSound(_player.getLocation(), Sound.NOTE_PLING, 1, 1.6f); UtilPlayer.message(_player, C.cGold + C.Bold + C.Strike + "============================================="); + // FB UtilPlayer.message(_player, ""); - new JsonMessage(" " + C.Bold + "Click to Open in Web Browser").click(ClickEvent.OPEN_URL, "https://www.facebook.com/MineplexGames").sendToPlayer(_player); new JsonMessage(" " + C.cGreen + C.Line + "https://www.facebook.com/MineplexGames").click(ClickEvent.OPEN_URL, "https://www.facebook.com/MineplexGames").sendToPlayer(_player); UtilPlayer.message(_player, ""); + // Twitter + UtilPlayer.message(_player, ""); + new JsonMessage(" " + C.Bold + "Click to Open in Web Browser").click(ClickEvent.OPEN_URL, "https://www.twitter.com/Mineplex").sendToPlayer(_player); + new JsonMessage(" " + C.cGreen + C.Line + "https://www.twitter.com/Mineplex").click(ClickEvent.OPEN_URL, "https://www.twitter.com/Mineplex").sendToPlayer(_player); + UtilPlayer.message(_player, ""); + UtilPlayer.message(_player, C.cGold + C.Bold + C.Strike + "============================================="); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/BackupFilter.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/BackupFilter.java new file mode 100644 index 000000000..4c8700b9b --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/BackupFilter.java @@ -0,0 +1,83 @@ +package mineplex.core.chat; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Collections; +import java.util.List; +import java.util.stream.Collectors; + +import mineplex.core.common.util.UtilText; + +public class BackupFilter +{ + private static final List INAPPROPRIATE_WORDS = Arrays.asList( + "nigger", "honkey", "beaner", "chink", "anus", "anal", "ballsack", + "nutsack", "bitch", "bastard", "cum", "jizz", "orgasm", "faggot", + "fag", "faqq", "fuck", "fqck", "niqq", "masturbate", "wank", + "penis", "dick", "cock", "porn", "rape", "queer", "dyke", "dildo", + "shit", "tits", "vagina", "pussy", "twat", "cunt", "whore", + "prostitute", "thot", "slut", "succ", "niger", "hypixel" + ); + + private static String getFilterStars(String word) + { + StringBuilder stars = new StringBuilder(); + + for (int i = 0; i < word.length(); i++) + { + stars.append("*"); + } + + return stars.toString(); + } + + public static String filterMessage(String message) + { + // Remove unicode and leet from the message + String deLeeted = UtilText.replaceLeet(Chat.replaceUnicode(message)); + + if (deLeeted.trim().isEmpty()) + { + return deLeeted; + } + + List starPositions = new ArrayList<>(Collections.nCopies(deLeeted.length(), false)); + + //Bukkit.broadcastMessage(starPositions.stream().map(v -> v ? "*" : "_").collect(Collectors.joining(","))); + + for (String inappropriateWord : INAPPROPRIATE_WORDS) + { + String starred = deLeeted.replaceAll("(?i)" + inappropriateWord, getFilterStars(inappropriateWord)); + + for (int i = 0; i < starPositions.size(); i++) + { + if (starPositions.get(i)) + { + continue; + } + + if (starred.charAt(i) == '*') + { + starPositions.set(i, true); + } + } + } + + StringBuilder builder = new StringBuilder(deLeeted); + + for (int i = 0; i < starPositions.size(); i++) + { + if (starPositions.get(i)) + { + builder.setCharAt(i, '*'); + } + } + + return builder.toString(); + } + + public static List filterMessages(String... messages) + { + return Arrays.stream(messages).map(BackupFilter::filterMessage).collect(Collectors.toList()); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java index 5bf616d5b..ed47ad7d9 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/Chat.java @@ -8,16 +8,17 @@ import java.net.URL; import java.nio.charset.Charset; import java.security.cert.X509Certificate; import java.util.ArrayList; +import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.UUID; import java.util.function.Function; +import java.util.stream.Collectors; import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManager; import javax.net.ssl.X509TrustManager; @@ -30,12 +31,13 @@ import org.bukkit.event.block.SignChangeEvent; import org.bukkit.event.player.AsyncPlayerChatEvent; import org.bukkit.event.player.PlayerCommandPreprocessEvent; import org.bukkit.event.player.PlayerQuitEvent; -import org.bukkit.plugin.java.JavaPlugin; +import org.bukkit.scheduler.BukkitTask; import org.json.simple.JSONArray; import org.json.simple.JSONObject; import org.json.simple.JSONValue; import mineplex.core.MiniPlugin; +import mineplex.core.account.CoreClient; import mineplex.core.account.CoreClientManager; import mineplex.core.account.permissions.Permission; import mineplex.core.account.permissions.PermissionGroup; @@ -44,9 +46,9 @@ import mineplex.core.chat.command.BroadcastCommand; import mineplex.core.chat.command.ChatSlowCommand; import mineplex.core.chat.command.HelpCommand; import mineplex.core.chat.command.SilenceCommand; +import mineplex.core.chat.command.extra.ChatExtraCommand; import mineplex.core.common.util.C; import mineplex.core.common.util.F; -import mineplex.core.common.util.UtilPlayer; import mineplex.core.common.util.UtilServer; import mineplex.core.common.util.UtilText; import mineplex.core.common.util.UtilTime; @@ -55,8 +57,6 @@ import mineplex.core.incognito.IncognitoManager; import mineplex.core.preferences.Preference; import mineplex.core.preferences.PreferencesManager; import mineplex.core.recharge.Recharge; -import mineplex.core.updater.UpdateType; -import mineplex.core.updater.event.UpdateEvent; public class Chat extends MiniPlugin { @@ -67,43 +67,54 @@ public class Chat extends MiniPlugin BYPASS_SLOW, BYPASS_SILENCE, BYPASS_SIGNS, + BYPASS_CHAT_FILTER, ALLOW_HACKUSATE, ALLOW_SIMILAR, SILENCE_COMMAND, SLOW_CHAT_COMMAND, BROADCAST_COMMAND, - HELP_COMMAND + HELP_COMMAND, + + CHAT_EXTRA_COMMAND, + MOD_CHAT_EXTRA_COMMAND, + ADMIN_CHAT_EXTRA_COMMAND } - - private CoreClientManager _clientManager; - private PreferencesManager _preferences; - private AchievementManager _achievements; - private IncognitoManager _incognitoManager; - private String[] _hackusations = {"hack", "hax", "hacker", "hacking", "cheat", "cheater", "cheating", "forcefield", "flyhack", "flyhacking", "autoclick", "aimbot"}; - private String _filterUrl = "https://chat.mineplex.com:8003/content/item/moderate"; - private String _appId = "34018d65-466d-4a91-8e92-29ca49f022c4"; - private String _apiKey = "oUywMpwZcIzZO5AWnfDx"; - private String _serverName; + private static final String STRIP_UNICODE_REGEX = "[^\\x00-\\x7F]"; + private static final String STRIP_HACKUSATION_REGEX = "[^A-Za-z ]"; + private static final List HACKUSATIONS = Arrays.asList("hack", "hax", "hacker", "hacking", "cheat", "cheater", "cheating", "forcefield", "flyhack", "flyhacking", "autoclick", "aimbot"); + private static final int MAX_CAPS_PER_MSG = 30; - private int _chatSlow = 0; - private long _silenced = 0; + // Cleanspeak + private static final String FILTER_URL = "https://chat.mineplex.com:8003/content/item/moderate"; + private static final String APP_ID = "34018d65-466d-4a91-8e92-29ca49f022c4"; + private static final String API_KEY = "oUywMpwZcIzZO5AWnfDx"; + private final IncognitoManager _incognitoManager; + private final CoreClientManager _clientManager; + private final PreferencesManager _preferencesManager; + private final AchievementManager _achievementManager; + + private int _chatSlowCooldown = 0; + private long _silenceLength; + private BukkitTask _silenceTask; + + //TODO: remove this because it's stupid private List> _highPriorityFilters = new ArrayList<>(); private List> _lowPriorityFilters = new ArrayList<>(); private Map _playerLastMessage = new HashMap<>(); + private Map> _transformNextMessage = new HashMap<>(); - public Chat(JavaPlugin plugin, IncognitoManager incognitoManager, CoreClientManager clientManager, PreferencesManager preferences, AchievementManager achievements, String serverName) + public Chat() { - super("Chat", plugin); + super("Chat"); + + _incognitoManager = require(IncognitoManager.class); + _clientManager = require(CoreClientManager.class); + _preferencesManager = require(PreferencesManager.class); + _achievementManager = require(AchievementManager.class); - _incognitoManager = incognitoManager; - _clientManager = clientManager; - _serverName = serverName; - _preferences = preferences; - _achievements = achievements; - new SpamHandler(); try @@ -114,10 +125,10 @@ public class Chat extends MiniPlugin { e.printStackTrace(); } - + generatePermissions(); } - + private void generatePermissions() { PermissionGroup.ADMIN.setPermission(Perm.ALLOW_CAPS, true, true); @@ -131,6 +142,11 @@ public class Chat extends MiniPlugin PermissionGroup.SRMOD.setPermission(Perm.SLOW_CHAT_COMMAND, true, true); PermissionGroup.MOD.setPermission(Perm.BROADCAST_COMMAND, true, true); PermissionGroup.PLAYER.setPermission(Perm.HELP_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.BYPASS_CHAT_FILTER, true, true); + + PermissionGroup.TITAN.setPermission(Perm.CHAT_EXTRA_COMMAND, true, true); + PermissionGroup.MOD.setPermission(Perm.MOD_CHAT_EXTRA_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.ADMIN_CHAT_EXTRA_COMMAND, true, true); } @Override @@ -140,411 +156,197 @@ public class Chat extends MiniPlugin addCommand(new BroadcastCommand(this)); addCommand(new ChatSlowCommand(this)); addCommand(new HelpCommand(this)); + + ChatExtraCommand.addCommands(this); + } + + public CoreClientManager getClientManager() + { + return _clientManager; + } + + public PreferencesManager getPreferencesManager() + { + return _preferencesManager; } public void setChatSlow(int seconds, boolean inform) { - if (seconds < 0) - seconds = 0; + seconds = Math.max(seconds, 0); - _chatSlow = seconds; + _chatSlowCooldown = seconds; + + if (!inform) + { + return; + } + + if (seconds == 0) + { + UtilServer.broadcast(F.main(getName(), "Chat slow has been " + C.cRed + "disabled" + C.mBody + ".")); + } + else + { + UtilServer.broadcast(F.main(getName(), "Chat slow has been " + C.cGreen + "enabled" + C.mBody + " with a cooldown of " + F.time(seconds + " seconds") + ".")); + } + } + + public long getChatSilence() { + return _silenceLength; + } + + public void setChatSilence(long duration, boolean inform) + { + // Cancel existing silence which has a pending re-enable + if (_silenceTask != null) + { + _silenceTask.cancel(); + _silenceTask = null; + } + + long durationTicks = (duration / 1000) * 20L; + + if (duration > 0) + { + // If duration is positive, convert it to milliseconds and store the end time + _silenceLength = duration + System.currentTimeMillis(); + + // Only set the task to disable the silence if it is a positive number of ticks + _silenceTask = UtilServer.runSyncLater(this::endChatSilence, durationTicks); + } + else + { + // If duration is 0/neg, store it directly + _silenceLength = duration; + } + + // Return if the player is not to be informed of this silencing + if (!inform) + { + return; + } + + // Permanent silence if negative + if (duration < 0) + { + UtilServer.broadcast(F.main("Chat", "Chat has been silenced for " + F.time("Permanent") + ".")); + } + // Disabled if 0 + else if (duration == 0) + { + UtilServer.broadcast(F.main("Chat", "Chat is no longer silenced.")); + } + // Otherwise it's just some amount of time... + else + { + // Divide duration by 20 before turning it into a time string so it's in seconds instead of ticks + UtilServer.broadcast(F.main("Chat", "Chat has been silenced for " + F.time(UtilTime.MakeStr(duration, 1)) + ".")); + } + } + + public void endChatSilence() + { + // Silence is not enabled + if (_silenceLength == 0) + { + return; + } + + setChatSilence(0, true); + } + + public boolean isSilenced(Player player, boolean inform) + { + if (_silenceLength == 0) + { + return false; + } + + if (_clientManager.Get(player).hasPermission(Perm.BYPASS_SILENCE)) + { + return false; + } if (inform) { - if (seconds == 0) - UtilServer.broadcast(F.main("Chat", "Chat Slow is now disabled")); - else - UtilServer.broadcast(F.main("Chat", "Chat slow is now enabled with a cooldown of " + F.time(seconds + " seconds"))); - } - } - - public void Silence(long duration, boolean inform) - { - // Set Silenced - if (duration > 0) - _silenced = System.currentTimeMillis() + duration; - else - _silenced = duration; - - if (!inform) - return; - - // Announce - if (duration == -1) - UtilServer.broadcast(F.main("Chat", "Chat has been silenced for " + F.time("Permanent") + ".")); - else if (duration == 0) - UtilServer.broadcast(F.main("Chat", "Chat is no longer silenced.")); - else - UtilServer.broadcast(F.main("Chat", "Chat has been silenced for " + F.time(UtilTime.MakeStr(duration, 1)) - + ".")); - } - - @EventHandler - public void preventMe(PlayerCommandPreprocessEvent event) - { - if (event.getMessage().toLowerCase().startsWith("/me ") - || event.getMessage().toLowerCase().startsWith("/bukkit") - || event.getMessage().toLowerCase().startsWith("/minecraft")) - { - if (!event.getPlayer().isOp()) + if (_silenceLength == -1) { - event.getPlayer().sendMessage(F.main(getName(), "Nope, not allowed!")); - event.setCancelled(true); + player.sendMessage(F.main(getName(), "Chat is silenced permanently.")); + } + else + { + player.sendMessage(F.main(getName(),"Chat is silenced for " + F.time(UtilTime.MakeStr(_silenceLength - System.currentTimeMillis(), 1)) + ".")); } } - } - - @EventHandler - public void lagTest(PlayerCommandPreprocessEvent event) - { - if (event.getMessage().equals("/lag") || event.getMessage().equals("/ping")) - { - event.getPlayer().sendMessage(F.main(getName(), "PONG!")); - event.setCancelled(true); - } - } - - @EventHandler - public void SilenceUpdate(UpdateEvent event) - { - if (event.getType() != UpdateType.FAST) - return; - - SilenceEnd(); - } - - public void SilenceEnd() - { - if (_silenced <= 0) - return; - - if (System.currentTimeMillis() > _silenced) - Silence(0, true); - } - - public boolean SilenceCheck(Player player) - { - SilenceEnd(); - - if (_silenced == 0) - return false; - - if (_clientManager.Get(player).hasPermission(Perm.BYPASS_SILENCE)) - return false; - - if (_silenced == -1) - UtilPlayer.message(player, F.main(getName(), "Chat is silenced permanently.")); - else - UtilPlayer.message( - player, - F.main(getName(), - "Chat is silenced for " - + F.time(UtilTime.MakeStr(_silenced - System.currentTimeMillis(), 1)) + ".")); return true; } - @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) - public void onSignChange(SignChangeEvent event) + public boolean isSilenced(Player player) { - if (_clientManager.Get(event.getPlayer()).hasPermission(Perm.BYPASS_SIGNS)) - { - return; - } - - // Prevent silenced players from using signs - if (SilenceCheck(event.getPlayer())) - { - event.setCancelled(true); - return; - } - - String[] lines = event.getLines(); - - runAsync(() -> - { - for (int i = 0; i < lines.length; i++) - { - String line = lines[i]; - if (line != null && line.length() > 0) - { - String filteredLine = getFilteredMessage(event.getPlayer(), line); - if (filteredLine != null) - { - lines[i] = filteredLine; - } - } - } - - runSync(() -> - { - Sign sign = (Sign) event.getBlock().getState(); - for (int i = 0; i < lines.length; i++) - { - sign.setLine(i, lines[i]); - } - sign.update(); - }); - }); + return isSilenced(player, true); } - @EventHandler(priority = EventPriority.LOWEST) - public void filterChat(AsyncPlayerChatEvent event) + public static String replaceUnicode(String original) { - if (event.isCancelled()) - return; - - if (event.isAsynchronous()) - { - String filtered = getFilteredMessage(event.getPlayer(), event.getMessage()); - if (filtered.isEmpty()) - { - event.setCancelled(true); - } - else - { - event.setMessage(getFilteredMessage(event.getPlayer(), event.getMessage())); - } - } + return original.replaceAll(STRIP_UNICODE_REGEX, ""); } - /** - * This should only be called from an async thread! - */ - public String getFilteredMessage(Player player, String originalMessage) + private boolean containsHackusation(String message) { - final String playerName = player.getUniqueId().toString(); - originalMessage = originalMessage.replaceAll("[^\\x00-\\x7F]", "").trim(); - final String filterType = "moderate"; - final String displayName = player.getPlayerListName(); + String[] parts = message.toLowerCase().replaceAll(STRIP_HACKUSATION_REGEX, "").split(" "); - JSONObject message = buildJsonChatObject(filterType, displayName, playerName, originalMessage, _serverName, 1); - String response = getResponseFromCleanSpeak(message, filterType); - - if (response == null) + for (String part : parts) { - System.out.println("[ERROR] Unable to filter chat message...thanks a lot CleanSpeak."); - return originalMessage; - } - - /* TESTING OUTPUT - POSSIBLY USEFUL - System.out.println(message); - System.out.println(response); - System.out.println(JSONValue.parse(response)); - //NullPointerException occasionally happening, JSONValue.parse(String) returns null randomly, why? - - for (Object o : ((JSONObject)JSONValue.parse(response)).values()) - { - System.out.println(o.toString()); - } - */ - - String filteredMsg = ""; - - filteredMsg = ((JSONObject) JSONValue.parse(response)).get("content").toString(); - if (filteredMsg.contains("parts")) - { - filteredMsg = ((JSONObject) JSONValue.parse(filteredMsg)).get("parts").toString(); - filteredMsg = filteredMsg.replace('[', ' ').replace(']', ' ').trim(); - filteredMsg = ((JSONObject) JSONValue.parse(filteredMsg)).get("replacement").toString(); - - return filteredMsg; - } - else - { - return originalMessage; - } - } - - @EventHandler(priority = EventPriority.LOW) - public void HandleChat(AsyncPlayerChatEvent event) - { - if (event.isCancelled()) - return; - - Player sender = event.getPlayer(); - - if (_incognitoManager != null && _incognitoManager.Get(sender).Status - && !event.getMessage().startsWith(CommunityManager.CHAT_PREFIX) - && !UtilServer.isTestServer()) - { - UtilPlayer.message(sender, C.cYellow + "You can not chat while incognito."); - event.setCancelled(true); - return; - } - - for (Function filter : _highPriorityFilters) - { - if (filter.apply(event)) + if (HACKUSATIONS.contains(part)) { - event.setCancelled(true); - return; - } - } - - if (SilenceCheck(sender)) - { - event.setCancelled(true); - return; - } - else if (!_clientManager.Get(sender).hasPermission(Perm.BYPASS_COOLDOWN) && - !Recharge.Instance.use(sender, "Chat Message", 400, false, false)) - { - UtilPlayer.message(sender, F.main("Chat", "You are sending messages too fast.")); - event.setCancelled(true); - } - else if (!_clientManager.Get(sender).hasPermission(Perm.ALLOW_HACKUSATE) && - msgContainsHack(event.getMessage())) - { - UtilPlayer.message(sender, F.main("Chat", - "Accusing players of cheating in-game is against the rules. " - + "If you think someone is cheating, please gather evidence and report it at " - + F.link("www.mineplex.com/reports"))); - event.setCancelled(true); - } - else if (_playerLastMessage.containsKey(sender.getUniqueId())) - { - MessageData lastMessage = _playerLastMessage.get(sender.getUniqueId()); - long chatSlowTime = 1000L * _chatSlow; - long timeDiff = System.currentTimeMillis() - lastMessage.getTimeSent(); - if (timeDiff < chatSlowTime && !_clientManager.Get(sender).hasPermission(Perm.BYPASS_SLOW)) - { - UtilPlayer.message(sender, F.main("Chat", "Chat slow enabled. Please wait " + F.time(UtilTime.convertString(chatSlowTime - timeDiff, 1, UtilTime.TimeUnit.FIT)))); - event.setCancelled(true); - } - else if (!_clientManager.Get(sender).hasPermission(Perm.ALLOW_SIMILAR) && - UtilText.isStringSimilar(event.getMessage(), lastMessage.getMessage(), 0.8f)) - { - UtilPlayer.message(sender, F.main("Chat", "This message is too similar to your previous message.")); - event.setCancelled(true); - } - } - - if (!event.isCancelled()) - { - String oldMessage = event.getMessage(); - if (!_clientManager.Get(sender).hasPermission(Perm.ALLOW_CAPS)) - { - int capsCount = 0; - for (char c : oldMessage.toCharArray()) - { - if (Character.isUpperCase(c)) - { - capsCount++; - } - } - if (capsCount > 30) - { - event.setMessage(oldMessage.toLowerCase()); - } - } - _playerLastMessage.put(sender.getUniqueId(), new MessageData(event.getMessage())); - } - - for (Function filter : _lowPriorityFilters) - { - if (filter.apply(event)) - { - event.setCancelled(true); - return; - } - } - - if (event.isAsynchronous()) - { - event.getRecipients().removeIf(player -> !_preferences.get(player).isActive(Preference.SHOW_CHAT)); - } - } - - private boolean msgContainsHack(String msg) - { - msg = " " + msg.toLowerCase().replaceAll("[^a-z ]", "") + " "; - for (String s : _hackusations) { - if (msg.contains(" " + s + " ")) { return true; } } + return false; } - public String hasher(JSONArray hasharray, String message) + private JSONObject buildMessageObject(String message) { - StringBuilder newmsg = new StringBuilder(message); + JSONObject content = new JSONObject(); - for (int i = 0; i < hasharray.size(); i++) + content.put("content", message); + content.put("type", "text"); + + return content; + } + + private JSONArray buildPartsArray(String ...messages) + { + JSONArray parts = new JSONArray(); + + for (String message : messages) { - Long charindex = ((Long) hasharray.get(i)); - int charidx = charindex.intValue(); - newmsg.setCharAt(charidx, '*'); + parts.add(buildMessageObject(message)); } - return newmsg.toString(); + return parts; } - public JSONArray parseHashes(String response) + private JSONObject buildRequestObject(Player player, String ...messages) { - JSONObject checkhash = (JSONObject) JSONValue.parse(response); - JSONArray hasharray; - hasharray = (JSONArray) checkhash.get("hashes"); + JSONObject content = new JSONObject(); - return hasharray; - } + content.put("applicationId", APP_ID); + content.put("createInstant", System.currentTimeMillis()); + content.put("parts", buildPartsArray(messages)); + content.put("senderDisplayName", player.getPlayerListName()); + content.put("senderId", player.getUniqueId().toString()); - @SuppressWarnings("unchecked") - private JSONObject buildJsonChatObject(String filtertype, String name, String player, String msg, String server, int rule) - { JSONObject message = new JSONObject(); - switch (filtertype) - { - case "chat": - /* - message.put("player_display_name", name); - message.put("player", player); - message.put("text", msg); - message.put("server", "gamma"); - message.put("room", server); - message.put("language", "en"); - message.put("rule", rule); - */ - message.put("content", msg); - break; - case "moderate": - JSONObject content = new JSONObject(); - content.put("content", msg); - content.put("type", "text"); + message.put("content", content); - JSONArray parts = new JSONArray(); - parts.add(content); - - JSONObject mainContent = new JSONObject(); - mainContent.put("applicationId", _appId); - mainContent.put("createInstant", System.currentTimeMillis()); - mainContent.put("parts", parts); - mainContent.put("senderDisplayName", name); - mainContent.put("senderId", player); - - message.put("content", mainContent); - break; - case "username": - message.put("player_id", name); - message.put("username", name); - message.put("language", "en"); - message.put("rule", rule); - break; - } return message; } - private String getResponseFromCleanSpeak(JSONObject message, String filtertype) + private String makeCleanspeakRequest(JSONObject message) { - /* - String authString = _authName + ":" + _apiKey; - byte[] authEncBytes = Base64.encodeBase64(authString.getBytes()); - String authStringEnc = new String(authEncBytes); - String url = _filterUrl + filtertype; - */ - String url = _filterUrl; - StringBuffer response = null; HttpsURLConnection connection = null; @@ -554,22 +356,20 @@ public class Chat extends MiniPlugin try { - URL obj = new URL(url); + URL url = new URL(FILTER_URL); - connection = (HttpsURLConnection) obj.openConnection(); + connection = (HttpsURLConnection) url.openConnection(); - // add request header con.setRequestMethod("POST"); connection.setRequestProperty("Content-Type", "application/json"); - //connection.setRequestProperty("Authorization", "Basic " + authStringEnc); connection.setRequestProperty("Connection", "Keep-Alive"); - connection.addRequestProperty("Authentication", _apiKey); + connection.addRequestProperty("Authentication", API_KEY); - String urlParameters = message.toString(); + String jsonString = message.toString(); // Send post request connection.setDoOutput(true); outputStream = new DataOutputStream(connection.getOutputStream()); - outputStream.writeBytes(urlParameters); + outputStream.writeBytes(jsonString); outputStream.flush(); outputStream.close(); @@ -642,65 +442,162 @@ public class Chat extends MiniPlugin } } - String pmresponse = null; - if (response != null) - pmresponse = response.toString(); + { + return response.toString(); + } - return pmresponse; + return null; } public static void trustCert() throws Exception { - TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() - { - public java.security.cert.X509Certificate[] getAcceptedIssuers() - { - return null; - } + TrustManager[] trustAllCerts = new TrustManager[] { + new X509TrustManager() + { + public java.security.cert.X509Certificate[] getAcceptedIssuers() + { + return null; + } - public void checkClientTrusted(X509Certificate[] certs, String authType) - { - } + public void checkClientTrusted(X509Certificate[] certs, String authType) { } - public void checkServerTrusted(X509Certificate[] certs, String authType) - { - } + public void checkServerTrusted(X509Certificate[] certs, String authType) { } - } }; + } + }; SSLContext sc = SSLContext.getInstance("SSL"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // Create all-trusting host name verifier - HostnameVerifier allHostsValid = new HostnameVerifier() - { - public boolean verify(String hostname, SSLSession session) - { - return true; - } - }; + HostnameVerifier allHostsValid = (hostname, session) -> true; // Install the all-trusting host verifier HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } - public long Silenced() + public List getReplacements(JSONObject responseJson, String ...originalMessages) { - return _silenced; + // Again, no content means no good + if (!responseJson.containsKey("content")) + { + return Arrays.stream(originalMessages).collect(Collectors.toList()); + } + + List replacements = new ArrayList<>(); + + JSONObject content = (JSONObject) responseJson.get("content"); + + // No parts means the message is clean, so it's all good + if (!content.containsKey("parts")) + { + return Arrays.stream(originalMessages).collect(Collectors.toList()); + } + + // {"parts":[{"replacement":"the string to replace the entire part with"}]} + JSONArray parts = (JSONArray) content.get("parts"); + + // Iterate over all the original messages... + // If the original message is empty, just add a blank and go to the next one + // If it's not, add its part and increment the part counter. + // This means that each non-space element moves the part counter forward one, + // So spaces are properly perserved in order + int partIndex = 0; + for (String originalMessage : originalMessages) + { + if (originalMessage.trim().isEmpty()) + { + replacements.add(""); + continue; + } + + Object obj = parts.get(partIndex); + + // Increment index regardless of further checks + partIndex++; + + JSONObject jsonObject = (JSONObject) obj; + + if (!jsonObject.containsKey("replacement")) + { + replacements.add(originalMessage); + continue; + } + + replacements.add(jsonObject.get("replacement").toString()); + } + + return replacements; } - @EventHandler - public void playerQuit(PlayerQuitEvent event) + public List filterMessages(Player player, boolean useBackup, String ...messages) { - _playerLastMessage.remove(event.getPlayer().getUniqueId()); + if (_clientManager.Get(player).hasPermission(Perm.BYPASS_CHAT_FILTER) + && _preferencesManager.get(player).isActive(Preference.BYPASS_CHAT_FILTER)) + { + return Arrays.stream(messages).collect(Collectors.toList()); + } + + // Trim and unicode-sanitize all of the inputs + messages = Arrays.stream(messages).map(m -> replaceUnicode(m).trim()).toArray(String[]::new); + + // If all are empty anyways just return the original messages + if (Arrays.stream(messages).allMatch(s -> s.trim().isEmpty())) + { + return Arrays.stream(messages).collect(Collectors.toList()); + } + + // Get the request body's json object + // Remove empties in the request because getReplacements handles that + JSONObject requestJson = buildRequestObject(player, Arrays.stream(messages).filter(s -> !s.isEmpty()).toArray(String[]::new)); + + // Get cleanspeak's response + String response = makeCleanspeakRequest(requestJson); + + // Some kind of error, apparently + if (response == null) + { + System.out.println("[ERROR] Unable to filter chat message...thanks a lot CleanSpeak."); + + if (useBackup) + { + return BackupFilter.filterMessages(messages); + } + + return Arrays.stream(messages).collect(Collectors.toList()); + } + + // Parse response body + JSONObject responseJson = (JSONObject) JSONValue.parse(response); + + // If there is no content then we can't do anything with it + if (!responseJson.containsKey("content")) + { + return Arrays.stream(messages).collect(Collectors.toList()); + } + + // Get replacements with original messages to preserve blank spaces + return getReplacements(responseJson, messages); } - /** - * If the function returns Boolean.TRUE then the message will be CANCELLED. - */ - public void AddFilter(Function restriction, FilterPriority priority) + public List filterMessages(Player player, String... messages) + { + return filterMessages(player, false, messages); + } + + public String filterMessage(Player player, boolean useBackup, String message) + { + return filterMessages(player, useBackup, message).get(0); + } + + public String filterMessage(Player player, String message) + { + return filterMessages(player, message).get(0); + } + + public void addFilter(Function restriction, FilterPriority priority) { Validate.isTrue(priority != null, "Priority must not be null."); @@ -713,4 +610,241 @@ public class Chat extends MiniPlugin _lowPriorityFilters.add(restriction); } } + + /** + * Check whether the given player is allowed to send a given message in chat. + * This method will also inform the player of why they are not allowed to, if inform is true. + * It will check last sent message, but will not handle updating it. + * @param sender - The player who is sending the message + * @param message - The message the player is attempting to send + * @param inform - Whether the player should be informed if they cannot chat + * @return - Whether this player can chat + */ + public boolean canChat(Player sender, String message, boolean inform) + { + CoreClient client = _clientManager.Get(sender); + + if (_incognitoManager != null && _incognitoManager.Get(sender).Status + && !message.startsWith(CommunityManager.CHAT_PREFIX) + && !UtilServer.isTestServer()) + { + if (inform) + { + sender.sendMessage(C.cYellow + "You can not chat while incognito."); + } + return false; + } + + if (isSilenced(sender, inform)) + { + return false; + } + + if (!client.hasPermission(Perm.BYPASS_COOLDOWN) + && !Recharge.Instance.use(sender, "Chat Message", 400, false, false)) + { + if (inform) + { + sender.sendMessage(F.main(getName(), "You are sending messages too fast.")); + } + return false; + } + + if (_playerLastMessage.containsKey(sender.getUniqueId())) + { + MessageData lastMessage = _playerLastMessage.get(sender.getUniqueId()); + + long chatSlowLengthMillis = _chatSlowCooldown * 1000L; + long timeSinceLastMillis = System.currentTimeMillis() - lastMessage.getTimeSent(); + + if (timeSinceLastMillis < chatSlowLengthMillis && !client.hasPermission(Perm.BYPASS_SLOW)) + { + sender.sendMessage(F.main("Chat", "Chat slow enabled. Please wait " + F.time(UtilTime.convertString(chatSlowLengthMillis - timeSinceLastMillis, 1, UtilTime.TimeUnit.FIT)))); + return false; + } + + if (!client.hasPermission(Perm.ALLOW_SIMILAR) + && UtilText.isStringSimilar(message, lastMessage.getMessage(), 0.8f)) + { + sender.sendMessage(F.main("Chat", "This message is too similar to your previous message.")); + return false; + } + } + + + if (!client.hasPermission(Perm.ALLOW_HACKUSATE) + && containsHackusation(message)) + { + if (inform) + { + sender.sendMessage(F.main("Chat", + "Accusing players of cheating in-game is against the rules. " + + "If you think someone is cheating, please gather evidence and report it at " + + F.link("www.mineplex.com/reports"))); + } + return false; + } + + return true; + } + + public boolean canChat(Player sender, String message) + { + return canChat(sender, message, true); + } + + public String decapsify(String original) + { + int capsCount = 0; + + for (char c : original.toCharArray()) + { + if (Character.isUpperCase(c)) + { + capsCount++; + } + + if (capsCount > MAX_CAPS_PER_MSG) + { + return original.toLowerCase(); + } + } + + return original; + } + + public String decapsifyIfNecessary(Player sender, String original) + { + if (!_clientManager.Get(sender).hasPermission(Chat.Perm.ALLOW_CAPS)) + { + return decapsify(original); + } + + return original; + } + + public void updateLastMessage(Player sender, String message) + { + _playerLastMessage.put(sender.getUniqueId(), new MessageData(message)); + } + + @EventHandler + public void preventMe(PlayerCommandPreprocessEvent event) + { + if (event.getMessage().toLowerCase().startsWith("/me ") + || event.getMessage().toLowerCase().startsWith("/bukkit") + || event.getMessage().toLowerCase().startsWith("/minecraft")) + { + if (!event.getPlayer().isOp()) + { + event.getPlayer().sendMessage(F.main(getName(), "Nope, not allowed!")); + event.setCancelled(true); + } + } + } + + @EventHandler + public void lagTest(PlayerCommandPreprocessEvent event) + { + if (event.getMessage().equals("/lag") || event.getMessage().equals("/ping")) + { + event.getPlayer().sendMessage(F.main(getName(), "PONG!")); + event.setCancelled(true); + } + } + + @EventHandler(priority = EventPriority.LOWEST) + public void filterChat(AsyncPlayerChatEvent event) + { + if (event.isCancelled()) + return; + + if (event.isAsynchronous()) + { + Player player = event.getPlayer(); + + String message = filterMessage(player, true, event.getMessage()); + + if (message.isEmpty()) + { + event.setCancelled(true); + } + else + { + event.setMessage(message); + } + } + } + + @EventHandler(priority = EventPriority.LOW) + public void handleChat(AsyncPlayerChatEvent event) + { + if (event.isCancelled()) + { + return; + } + + Player sender = event.getPlayer(); + + for (Function filter : _highPriorityFilters) + { + if (filter.apply(event)) + { + event.setCancelled(true); + return; + } + } + + if (!canChat(sender, event.getMessage(), true)) + { + event.setCancelled(true); + return; + } + + event.setMessage(decapsifyIfNecessary(sender, event.getMessage())); + + updateLastMessage(sender, event.getMessage()); + + if (event.isAsynchronous()) + { + event.getRecipients().removeIf(player -> !_preferencesManager.get(player).isActive(Preference.SHOW_CHAT)); + } + } + + @EventHandler(priority = EventPriority.HIGHEST, ignoreCancelled = true) + public void onSignChange(SignChangeEvent event) + { + if (_clientManager.Get(event.getPlayer()).hasPermission(Perm.BYPASS_SIGNS)) + { + return; + } + + // Prevent silenced players from using signs + if (isSilenced(event.getPlayer())) + { + event.setCancelled(true); + return; + } + + runAsync(() -> + { + List lines = filterMessages(event.getPlayer(), event.getLines()); + + runSync(() -> + { + Sign sign = (Sign) event.getBlock().getState(); + for (int i = 0; i < lines.size(); i++) + { + sign.setLine(i, lines.get(i)); + } + sign.update(); + }); + }); + } + + @EventHandler + public void playerQuit(PlayerQuitEvent event) + { + _playerLastMessage.remove(event.getPlayer().getUniqueId()); + } } \ No newline at end of file diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/command/SilenceCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/command/SilenceCommand.java index d707e1d18..2a6309097 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/chat/command/SilenceCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/command/SilenceCommand.java @@ -23,22 +23,22 @@ public class SilenceCommand extends CommandBase if (args.length == 0) { //Disable - if (Plugin.Silenced() != 0) + if (Plugin.getChatSilence() != 0) { - Plugin.Silence(0, true); + Plugin.setChatSilence(0, true); } //Enable else { - Plugin.Silence(-1, true); + Plugin.setChatSilence(-1, true); } } //Timer else { - long time = (long) (Double.valueOf(args[0]) * 3600000); + long time = (long) (Double.valueOf(args[0]) * 1000 * 60); - Plugin.Silence(time, true); + Plugin.setChatSilence(time, true); } } catch (Exception e) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/chat/command/extra/ChatExtraCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/chat/command/extra/ChatExtraCommand.java new file mode 100644 index 000000000..a4c38e39b --- /dev/null +++ b/Plugins/Mineplex.Core/src/mineplex/core/chat/command/extra/ChatExtraCommand.java @@ -0,0 +1,105 @@ +package mineplex.core.chat.command.extra; + +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.stream.Collectors; + +import org.bukkit.entity.Player; + +import mineplex.core.account.permissions.Permission; +import mineplex.core.chat.Chat; +import mineplex.core.command.CommandBase; +import mineplex.core.command.CommandCenter; +import mineplex.core.common.Pair; +import mineplex.core.common.util.C; +import mineplex.core.common.util.UtilServer; +import mineplex.core.preferences.Preference; +import mineplex.core.recharge.Recharge; + +public class ChatExtraCommand extends CommandBase +{ + private static final long RECHARGE_TIME = 1000; + private static final String RECHARGE_FORMAT = "ChatPrefixCmd-%s"; + private static final List> DEFAULT_EXTRA_COMMANDS = new ArrayList<>(); + private final String _extra; + + static + { + addDefaultExtraCommand("ヽ༼ຈل͜ຈ༽ノ", "donger"); + addDefaultExtraCommand("¯\\_(ツ)_/¯", "shrug"); + addDefaultExtraCommand("༼ つ ◕_◕ ༽つ", "ameno"); + addDefaultExtraCommand("(╯°□°)╯︵ ┻━┻", "tableflip"); + addDefaultExtraCommand("┬─┬ノ(ಠ_ಠノ)", "tablesit"); + addDefaultExtraCommand("(౮⦦ʖ౮)", "lenny"); + addDefaultExtraCommand("ಠ_ಠ", "disapproval"); + addDefaultExtraCommand("(☞゚ヮ゚)☞", "same", "fingerguns", "thisguy"); + addDefaultExtraCommand("ლ(ಥ Д ಥ )ლ", "why"); + addDefaultExtraCommand("(≖_≖)", "squint"); + } + + public ChatExtraCommand(Chat plugin, Permission permission, String extra, String... aliases) + { + super(plugin, permission, aliases); + + _extra = extra; + + CommandCenter.ALLOW_SPAM_IF_LAST.add(_extra); + } + + public ChatExtraCommand(Chat plugin, String extra, String... aliases) + { + this(plugin, Chat.Perm.CHAT_EXTRA_COMMAND, extra, aliases); + } + + public static void addCommands(Chat plugin) + { + for (Pair defaultCommand : DEFAULT_EXTRA_COMMANDS) + { + plugin.addCommand(new ChatExtraCommand(plugin, defaultCommand.getRight(), defaultCommand.getLeft())); + } + + plugin.addCommand(new ChatExtraCommand(plugin, Chat.Perm.MOD_CHAT_EXTRA_COMMAND, C.cGold + "›⪾", "fishy")); + plugin.addCommand(new ChatExtraCommand(plugin, Chat.Perm.ADMIN_CHAT_EXTRA_COMMAND, C.cPurple + "(ノ◕ヮ◕)ノ*:・゚✧", "magic")); + } + + public static void addDefaultExtraCommand(String extra, String... aliases) + { + DEFAULT_EXTRA_COMMANDS.add(Pair.create(aliases, extra)); + } + + private String getRechargeName() + { + return String.format(RECHARGE_FORMAT, _extra); + } + + @Override + public void Execute(Player caller, String[] args) + { + if (!Recharge.Instance.use(caller, getRechargeName(), RECHARGE_TIME, false, false)) + { + reply(caller, "Please wait before using that command again."); + return; + } + + UtilServer.runAsync(() -> { + String chatMessage = ""; + + if (args.length > 0) + { + chatMessage = Plugin.filterMessage(caller, Arrays.stream(args).collect(Collectors.joining(" "))) + " "; + } + + if (Plugin.getPreferencesManager().get(caller).isActive(Preference.COLOR_SUFFIXES)) + { + chatMessage += Plugin.getClientManager().Get(caller).getPrimaryGroup().getColor() + _extra; + } + else + { + chatMessage += _extra; + } + + caller.chat(chatMessage.trim()); + }); + } +} diff --git a/Plugins/Mineplex.Core/src/mineplex/core/command/CommandCenter.java b/Plugins/Mineplex.Core/src/mineplex/core/command/CommandCenter.java index c77060419..a6d494381 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/command/CommandCenter.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/command/CommandCenter.java @@ -1,9 +1,14 @@ package mineplex.core.command; import java.lang.reflect.Field; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.HashMap; import java.util.HashSet; import java.util.List; +import java.util.Map; import java.util.Set; +import java.util.UUID; import java.util.concurrent.atomic.AtomicIntegerFieldUpdater; import net.minecraft.server.v1_8_R3.PacketPlayInTabComplete; @@ -35,6 +40,7 @@ import mineplex.core.recharge.Recharge; public class CommandCenter implements Listener, IPacketHandler { + public static final List ALLOW_SPAM_IF_LAST = new ArrayList<>(); public static CommandCenter Instance; protected JavaPlugin Plugin; @@ -47,6 +53,8 @@ public class CommandCenter implements Listener, IPacketHandler private static AtomicIntegerFieldUpdater chatSpamField = null; + private Map _playerLastCommand = new HashMap<>(); + public enum Perm implements Permission { BLOCKED_COMMAND, @@ -110,7 +118,9 @@ public class CommandCenter implements Listener, IPacketHandler args = argString.split(" "); } - ICommand command = Commands.get(commandName.toLowerCase()); + String commandLabel = commandName.toLowerCase(); + + ICommand command = Commands.get(commandLabel); if (command != null) { @@ -119,13 +129,24 @@ public class CommandCenter implements Listener, IPacketHandler if (ClientManager.Get(event.getPlayer()).hasPermission(command.getPermission()) || UtilPlayer.isCommandAllowed(event.getPlayer(), commandName.toLowerCase())) { + // Disallow the player to spam if they have sent a command in the last 500ms, if (!Recharge.Instance.use(event.getPlayer(), "Command", 500, false, false)) { - event.getPlayer().sendMessage(F.main("Command Center", "You can't spam commands that fast.")); - return; + // They must have not sent a command yet, + // or their command is not part of the whitelisted for spamming + // and they didn't last send the same one (to prevent infinite chains) + String lastCommand = _playerLastCommand.get(event.getPlayer().getUniqueId()); + + if (lastCommand == null || (!ALLOW_SPAM_IF_LAST.contains(lastCommand) && !lastCommand.equalsIgnoreCase(commandLabel))) + { + event.getPlayer().sendMessage(F.main("Command Center", "You can't spam commands that fast.")); + return; + } } - command.SetAliasUsed(commandName.toLowerCase()); + _playerLastCommand.put(event.getPlayer().getUniqueId(), commandLabel); + + command.SetAliasUsed(commandLabel); if (command instanceof LoggedCommand) { diff --git a/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java b/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java index 4f68b2435..473a17d2f 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/communities/CommunityManager.java @@ -154,8 +154,6 @@ public class CommunityManager extends MiniDbClientPlugin _clientManager = require(CoreClientManager.class); _customDataManager = require(CustomDataManager.class); - _customDataManager.getRepository().registerKey(COMMUNITY_CHAT_KEY); - _clientManager.addStoredProcedureLoginProcessor(new ILoginProcessor() { @Override @@ -284,7 +282,7 @@ public class CommunityManager extends MiniDbClientPlugin public boolean isNameAllowed(Player caller, String communityName) { - return !Managers.get(Chat.class).getFilteredMessage(caller, communityName).contains("*"); + return !Managers.get(Chat.class).filterMessage(caller, communityName).contains("*"); } public void communityExists(String name, Consumer result) diff --git a/Plugins/Mineplex.Core/src/mineplex/core/communities/commands/CommunityDescriptionCommand.java b/Plugins/Mineplex.Core/src/mineplex/core/communities/commands/CommunityDescriptionCommand.java index be099ef91..8d082251e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/communities/commands/CommunityDescriptionCommand.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/communities/commands/CommunityDescriptionCommand.java @@ -62,7 +62,7 @@ public class CommunityDescriptionCommand extends CommandBase final String description = desc; Plugin.runAsync(() -> { - if (Managers.get(Chat.class).getFilteredMessage(caller, description).contains("*")) + if (Managers.get(Chat.class).filterMessage(caller, description).contains("*")) { UtilPlayer.message(caller, F.main(Plugin.getName(), "That description is not allowed!")); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java b/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java index 0ca3d99e5..4a87fe786 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/message/MessageManager.java @@ -26,6 +26,7 @@ import mineplex.core.common.util.UtilTextMiddle; import mineplex.core.common.util.UtilTime; import mineplex.core.common.util.UtilTime.TimeUnit; import mineplex.core.friend.FriendManager; +import mineplex.core.friend.FriendStatusType; import mineplex.core.friend.data.FriendData; import mineplex.core.friend.data.FriendStatus; import mineplex.core.ignore.IgnoreManager; @@ -306,7 +307,7 @@ public class MessageManager extends MiniClientPlugin public void DoMessageAdmin(Player from, Player to, String message) { // Inform - UtilPlayer.message(from, C.cPurple + "-> " + _clientManager.Get(to).getRealOrDisguisedPrimaryGroup().getDisplay(true, false, false, true) + " " + to.getName() + " " + UtilPlayer.message(from, C.cDPurple + "-> " + _clientManager.Get(to).getRealOrDisguisedPrimaryGroup().getDisplay(true, false, false, true) + " " + to.getName() + " " + C.cPurple + message); // Inform Admins @@ -316,7 +317,7 @@ public class MessageManager extends MiniClientPlugin { if (_clientManager.Get(staff).hasPermission(Perm.SEE_ADMIN)) { - UtilPlayer.message(staff, _clientManager.Get(from).getRealOrDisguisedPrimaryGroup().getDisplay(true, false, false, true) + " " + from.getName() + C.cPurple + UtilPlayer.message(staff, _clientManager.Get(from).getRealOrDisguisedPrimaryGroup().getDisplay(true, false, false, true) + " " + from.getName() + C.cDPurple + " -> " + _clientManager.Get(to).getRealOrDisguisedPrimaryGroup().getDisplay(true, false, false, true) + " " + to.getName() + " " + C.cPurple + message); } } @@ -326,7 +327,7 @@ public class MessageManager extends MiniClientPlugin Get(from).LastAdminTo = to.getName(); // Send - UtilPlayer.message(to, C.cPurple + "<- " + _clientManager.Get(from).getRealOrDisguisedPrimaryGroup().getDisplay(true, false, false, true) + " " + from.getName() + " " + UtilPlayer.message(to, C.cDPurple + "<- " + _clientManager.Get(from).getRealOrDisguisedPrimaryGroup().getDisplay(true, false, false, true) + " " + from.getName() + " " + C.cPurple + message); // Sound @@ -421,7 +422,7 @@ public class MessageManager extends MiniClientPlugin if (globalMessage.isStaffMessage()) { // Message the receiver - UtilPlayer.message(to, C.cPurple + "<- " + globalMessage.getRank() + " " + globalMessage.getSender() + " " + UtilPlayer.message(to, C.cDPurple + "<- " + globalMessage.getRank() + " " + globalMessage.getSender() + " " + C.cPurple + globalMessage.getMessage()); to.playSound(to.getLocation(), Sound.NOTE_PIANO, 2f, 2f); @@ -431,7 +432,7 @@ public class MessageManager extends MiniClientPlugin // Message the sender RedisMessageCallback message = new RedisMessageCallback(globalMessage, true, to.getName(), - C.cPurple + "-> " + toRank + " " + to.getName() + " " + C.cPurple + globalMessage.getMessage(), false); + C.cDPurple + "-> " + toRank + " " + to.getName() + " " + C.cPurple + globalMessage.getMessage(), false); // Inform Admins for (Player staff : UtilServer.getPlayers()) @@ -544,6 +545,13 @@ public class MessageManager extends MiniClientPlugin { for (FriendStatus friendInfo : friends.getFriends()) { + // Don't consider them "the friend" if their request has not been accepted + // and the player doesn't want pending/prior requesting players to msg them + if (friendInfo.Status != FriendStatusType.Accepted + && !_preferences.get(sender).isActive(Preference.UNCONFIRMED_FRIEND_MESSAGES)) + { + continue; + } // We don't grab this guy even if name matches because he is offline. This way, we can get a free message without // extra coding as we can't do anything extra with a offline friend.. @@ -566,7 +574,7 @@ public class MessageManager extends MiniClientPlugin runAsync(() -> { - final String newMessage = _chat.getFilteredMessage(sender, message); + final String newMessage = adminMessage ? message : _chat.filterMessage(sender, message); runSync(() -> sendMessage(sender, target, newMessage, adminMessage, isReply, friendInfo)); }); } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/preferences/Preference.java b/Plugins/Mineplex.Core/src/mineplex/core/preferences/Preference.java index 5c341f722..fcf28e15e 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/preferences/Preference.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/preferences/Preference.java @@ -58,6 +58,12 @@ public enum Preference implements Permission UNLOCK_KITS(true, PreferenceCategory.EXCLUSIVE, Material.IRON_DOOR, "Unlock All Kits", "Enabling this will allow you", "to have access to every kit ", "in every game for free!"), AUTO_QUEUE(true, PreferenceCategory.USER, Material.EMERALD, "Teleport to Game Area", "Enabling this will teleport you to the", "game area instead of opening the server", "selector when choosing a game."), + + UNCONFIRMED_FRIEND_MESSAGES(true, PreferenceCategory.SOCIAL, Material.SKULL_ITEM, "Unconfirmed Friend Messages", "Enabling this will allow you to receive", "private messages from players who", "have a pending/prior friend request with you!"), + + BYPASS_CHAT_FILTER(false, PreferenceCategory.EXCLUSIVE, Material.GLASS, "Bypass Chat Filter", "Enabling this will allow you", "to bypass the chat filter everywhere.", "", "Proceed with caution."), + + COLOR_SUFFIXES(true, PreferenceCategory.USER, Material.WOOL, "Color Chat Suffixes", "Enabling this will color your", "chat suffixes like ¯\\_(ツ)_/¯", "based on your rank.") ; private static final Map PREFERENCE_MAP = Maps.newHashMap(); diff --git a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java index 8b1a485de..cdb5fdac7 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/preferences/PreferencesManager.java @@ -102,7 +102,14 @@ public class PreferencesManager extends MiniPlugin implements ILoginProcessor } else { - PermissionGroup.PLAYER.setPermission(p, true, true); + if (p == Preference.COLOR_SUFFIXES) + { + PermissionGroup.TITAN.setPermission(p, true, true); + } + else + { + PermissionGroup.PLAYER.setPermission(p, true, true); + } } } diff --git a/Plugins/Mineplex.Core/src/mineplex/core/updater/FileUpdater.java b/Plugins/Mineplex.Core/src/mineplex/core/updater/FileUpdater.java index e72629d7b..e55619a95 100644 --- a/Plugins/Mineplex.Core/src/mineplex/core/updater/FileUpdater.java +++ b/Plugins/Mineplex.Core/src/mineplex/core/updater/FileUpdater.java @@ -80,7 +80,9 @@ public class FileUpdater extends MiniPlugin private void generatePermissions() { - PermissionGroup.MOD.setPermission(Perm.BVERSION_COMMAND, true, true); + PermissionGroup.QA.setPermission(Perm.BVERSION_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.BVERSION_COMMAND, true, true); + PermissionGroup.ADMIN.setPermission(Perm.RESTART_COMMAND, true, true); PermissionGroup.QAM.setPermission(Perm.RESTART_COMMAND, false, true); } diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java index 6ee45ce86..e3b2f7b92 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/Clans.java @@ -161,7 +161,7 @@ public class Clans extends JavaPlugin StatsManager statsManager = new StatsManager(this, _clientManager); EloManager eloManager = new EloManager(this, _clientManager); AchievementManager achievementManager = new AchievementManager(statsManager, _clientManager, _donationManager, incognito, eloManager); - Chat chat = new Chat(this, incognito, _clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName()); + Chat chat = new Chat(); new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, new FriendManager(this, _clientManager, preferenceManager, portal), chat); new MemoryFix(this); diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java index 60e5129aa..9e0687908 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/ClansManager.java @@ -948,7 +948,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat { for (Player cur : clan.getOnlinePlayers()) { - message = _chat.getFilteredMessage(player, message); + message = _chat.filterMessage(player, message); UtilPlayer.message(cur, String.format(rank + C.cAqua + "%s " + C.cDAqua + "%s", player.getName(), message)); } @@ -968,7 +968,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat ally.getOnlinePlayers().forEach(recipients::add); } - final String filtered = _chat.getFilteredMessage(player, message); + final String filtered = _chat.filterMessage(player, message); recipients.forEach(p -> UtilPlayer.message(p, String.format(rank + C.cDGreen + clan.getName() + " " + C.cDGreen + "%s " + C.cGreen + "%s", player.getName(), filtered))); @@ -993,7 +993,7 @@ public class ClansManager extends MiniClientPlugin implements IRelat List recipients = new ArrayList<>(); - String message = event.getMessage();//_chat.getFilteredMessage(event.getPlayer(), event.getMessage()); + String message = event.getMessage();//_chat.filterMessage(event.getPlayer(), event.getMessage()); for (Player other : event.getRecipients()) { diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java index 6c70629f5..1a7401850 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/commands/ClansCommand.java @@ -304,7 +304,7 @@ public class ClansCommand extends CommandBase return; } - if (Plugin.getChat().getFilteredMessage(caller, args[1]).contains("*")) + if (Plugin.getChat().filterMessage(caller, args[1]).contains("*")) { UtilPlayer.message(caller, F.main("Clans", "Clan name inappropriate. Please try a different name")); return; diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntGenerator/TntGenerator.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGenerator.java similarity index 100% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntGenerator/TntGenerator.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGenerator.java diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntGenerator/TntGeneratorManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGeneratorManager.java similarity index 100% rename from Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntGenerator/TntGeneratorManager.java rename to Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/clans/tntgenerator/TntGeneratorManager.java diff --git a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialManager.java b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialManager.java index 126ce0bfc..d3b9ab399 100644 --- a/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialManager.java +++ b/Plugins/Mineplex.Game.Clans/src/mineplex/game/clans/tutorial/TutorialManager.java @@ -61,7 +61,7 @@ public class TutorialManager extends MiniPlugin implements ScoreboardElement addTutorial(TutorialType.MAIN, new ClansMainTutorial(plugin, clansManager, _clansMessageManager, hologram, npcManager, taskManager)); - chat.AddFilter(event -> + chat.addFilter(event -> { if (inTutorial(event.getPlayer())) { diff --git a/Plugins/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansHub.java b/Plugins/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansHub.java index b7db2c4da..90732a053 100644 --- a/Plugins/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansHub.java +++ b/Plugins/Mineplex.Hub.Clans/src/mineplex/clanshub/ClansHub.java @@ -157,7 +157,7 @@ public class ClansHub extends JavaPlugin ClansTransferManager serverManager = new ClansTransferManager(this, clientManager, donationManager, partyManager, portal); - Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName()); + Chat chat = new Chat(); new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, chat); new MemoryFix(this); new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.CLANS_HUB); diff --git a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java index da59a5064..2bea97ea7 100644 --- a/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java +++ b/Plugins/Mineplex.Hub/src/mineplex/hub/Hub.java @@ -157,7 +157,7 @@ public class Hub extends JavaPlugin implements IRelation require(MineplexGameManager.class); - Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName()); + Chat chat = new Chat(); new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, friendManager, chat); new MemoryFix(this); new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.HUB); diff --git a/Plugins/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java b/Plugins/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java index a75af4799..d2091dfcf 100644 --- a/Plugins/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java +++ b/Plugins/Mineplex.StaffServer/src/mineplex/staffServer/StaffServer.java @@ -69,7 +69,8 @@ public class StaffServer extends JavaPlugin StatsManager statsManager = new StatsManager(this, clientManager); InventoryManager inventoryManager = new InventoryManager(this, clientManager); BonusRepository bonusRepository = new BonusRepository(this, null, donationManager); - new Chat(this, null, clientManager, preferenceManager, new AchievementManager(statsManager, clientManager, donationManager, null, eloManager), serverStatusManager.getCurrentServerName()); + new AchievementManager(statsManager, clientManager, donationManager, null, eloManager); + new Chat(); new MemoryFix(this); new FileUpdater(this, portal, serverStatusManager.getCurrentServerName(), serverStatusManager.getRegion(), GenericServer.HUB); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java index 18ca4d9c4..7d6a76e22 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/Arcade.java @@ -179,7 +179,7 @@ public class Arcade extends JavaPlugin EloManager eloManager = new EloManager(this, _clientManager); AchievementManager achievementManager = new AchievementManager(statsManager, _clientManager, _donationManager, incognito, eloManager); FriendManager friendManager = new FriendManager(this, _clientManager, preferenceManager, portal); - Chat chat = new Chat(this, incognito, _clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName()); + Chat chat = new Chat(); new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, friendManager, chat); SnapshotManager snapshotManager = new SnapshotManager(this, new SnapshotRepository(serverStatusManager.getCurrentServerName(), getLogger())); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java index 43ba0df32..583c22ddb 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/ArcadeManager.java @@ -1106,30 +1106,6 @@ public class ArcadeManager extends MiniPlugin implements IRelation return GetServerConfig().MaxPlayers; } - public void HubClock(Player player) - { - if (!IsHotbarHubClock()) - return; - - if (_game != null && !_game.GiveClock) - return; - - if (player.getOpenInventory().getType() != InventoryType.CRAFTING && - player.getOpenInventory().getType() != InventoryType.CREATIVE) - return; - - if (!UtilGear.isMat(player.getInventory().getItem(8), Material.WATCH) && !UtilGear.isMat(player.getInventory().getItem(8), Material.SPECKLED_MELON)) - { - player.getInventory().setItem( - 8, - ItemStackFactory.Instance.CreateStack(Material.WATCH, (byte) 0, 1, (short) 0, C.cGreen - + "Return to Hub", new String[]{"", ChatColor.RESET + "Click while holding this", - ChatColor.RESET + "to return to the Hub."})); - - UtilInv.Update(player); - } - } - @EventHandler public void Login(PlayerLoginEvent event) { @@ -1290,8 +1266,6 @@ public class ArcadeManager extends MiniPlugin implements IRelation for (PotionEffect potion : player.getActivePotionEffects()) player.removePotionEffect(potion.getType()); - HubClock(player); - Gadget morph = getCosmeticManager().getGadgetManager().getActive(player, GadgetType.MORPH); if (morph != null && morph.isActive(player)) morph.disable(player); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java index 1664d4ac7..7880f4456 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/Game.java @@ -1485,7 +1485,7 @@ public abstract class Game extends ListenerComponent implements Lifetimed AnnounceGame(player); if (AnnounceSilence) - Manager.GetChat().Silence(PrepareTime, false); + Manager.GetChat().setChatSilence(PrepareTime, false); } public void AnnounceGame(Player player) @@ -1615,7 +1615,7 @@ public abstract class Game extends ListenerComponent implements Lifetimed UtilTextMiddle.display(winnerText, subColor + "won the game", 20, 120, 20); if (AnnounceSilence) - Manager.GetChat().Silence(5000, false); + Manager.GetChat().setChatSilence(5000, false); endElo(); } @@ -1689,7 +1689,7 @@ public abstract class Game extends ListenerComponent implements Lifetimed UtilTextMiddle.display(winnerText, subColor + "won the game", 20, 120, 20); if (AnnounceSilence) - Manager.GetChat().Silence(5000, false); + Manager.GetChat().setChatSilence(5000, false); endElo(); } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/Draw.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/Draw.java index a6f7ef731..f24fc8b3b 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/Draw.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/Draw.java @@ -130,7 +130,7 @@ public class Draw extends SoloGame { "Bird", "Volcano", "Sloth", "Love", "Dance", "Hair", "Glasses", "Domino", "Dice", "Computer", "Top Hat", "Beard", "Wind", "Rain", "Minecraft", "Push", "Fighting", "Juggle", "Clown", "Miner", "Creeper", - "Ghast", "Spider", "Punch", "Roll", "River", "Desert", "Cold", "Pregnant", "Photo", "Quick", "Mario", + "Ghast", "Spider", "Punch", "Roll", "River", "Desert", "Cold", "Photo", "Quick", "Mario", "Luigi", "Bridge", "Turtle", "Door Knob", "Mineplex", "Binoculars", "Telescope", "Planet", "Mountain Bike", "Moon", "Comet", "Flower", "Squirrel", "Horse Riding", "Chef", "Elephant", "Yoshi", "Shotgun", "Pistol", "James Bond", "Money", "Salt and Pepper", "Truck", "Helicopter", "Hot Air Balloon", @@ -153,7 +153,7 @@ public class Draw extends SoloGame "Spikes", "Bridge", "Bomb", "Spoon", "Rainbow", "Staircase", "Poop", "Dragon", "Fire", "Apple", "Shoe", "Squid", "Cookie", "Tooth", "Camera", "Sock", "Monkey", "Unicorn", "Smile", "Pool", "Rabbit", "Cupcake", "Pancake", "Princess", "Castle", "Flag", "Planet", "Stars", "Camp Fire", "Rose", "Spray", - "Pencil", "Ice Cream", "Toilet", "Moose", "Bear", "Beer", "Batman", "Eggs", "Teapot", "Golf Club", + "Pencil", "Ice Cream", "Toilet", "Moose", "Bear", "Batman", "Eggs", "Teapot", "Golf Club", "Tennis Racket", "Shield", "Crab", "Pot of Gold", "Cactus", "Television", "Pumpkin Pie", "Chimney", "Stable", "Nether", "Wither", "Beach", "Stop Sign", "Chestplate", "Pokeball", "Christmas Tree", "Present", "Snowflake", "Laptop", "Superman", "Football", "Basketball", "Creeper", "Tetris", "Jump", @@ -162,7 +162,7 @@ public class Draw extends SoloGame "Bikini", "Butterfly", "Bumblebee", "Pizza", "Jellyfish", "Sideburns", "Speedboat", "Treehouse", "Water Gun", "Drink", "Hook", "Dance", "Fall", "Summer", "Autumn", "Spring", "Winter", "Night Time", "Galaxy", "Sunrise", "Sunset", "Picnic", "Snowflake", "Holding Hands", "America", "Laptop", "Anvil", - "Bagel", "Bench", "Cigar", "Darts", "Muffin", "Queen", "Wheat", "Dolphin", "Scarf", "Swing", "Thumb", + "Bagel", "Bench", "Darts", "Muffin", "Queen", "Wheat", "Dolphin", "Scarf", "Swing", "Thumb", "Tomato", "Armor", "Alien", "Beans", "Cheek", "Phone", "Keyboard", "Orange", "Calculator", "Paper", "Desk", "Disco", "Elbow", "Drool", "Giant", "Golem", "Grave", "Llama", "Moose", "Party", "Panda", "Plumber", "Salsa", "Salad", "Skunk", "Skull", "Stump", "Sugar", "Ruler", "Bookcase", diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/DrawRound.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/DrawRound.java index c7f346f8d..7bdc57345 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/DrawRound.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/draw/DrawRound.java @@ -61,7 +61,7 @@ public class DrawRound UtilPlayer.message(Drawer, C.cWhite + C.Bold + "You must draw: " + C.cGreen + C.Bold + Word); - Host.Manager.GetChat().Silence(0, false); + Host.Manager.GetChat().setChatSilence(0, false); } public boolean Guessed(Player player) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java index 345df00fe..9be8e14dc 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/event/EventModule.java @@ -1076,7 +1076,7 @@ public class EventModule extends MiniPlugin commandHelp(player); } - //Silence + //setChatSilence public void commandSilence(Player player, String[] args) { try @@ -1085,14 +1085,14 @@ public class EventModule extends MiniPlugin if (args.length == 1) { //Disable - if (Manager.GetChat().Silenced() != 0) + if (Manager.GetChat().getChatSilence() != 0) { - Manager.GetChat().Silence(0, true); + Manager.GetChat().setChatSilence(0, true); } //Enable else { - Manager.GetChat().Silence(-1, true); + Manager.GetChat().setChatSilence(-1, true); } } //Timer @@ -1100,7 +1100,7 @@ public class EventModule extends MiniPlugin { long time = (long) (Double.valueOf(args[1]) * 3600000); - Manager.GetChat().Silence(time, true); + Manager.GetChat().setChatSilence(time, true); } } catch (Exception e) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/gladiators/hotbar/HotbarEditor.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/gladiators/hotbar/HotbarEditor.java index a8001f647..76aec5115 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/gladiators/hotbar/HotbarEditor.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/gladiators/hotbar/HotbarEditor.java @@ -105,8 +105,6 @@ public class HotbarEditor extends Module { if (event.GetState() == Game.GameState.Recruit) { - getGame().getArcadeManager().getCustomDataManager().getRepository().registerKey(HOTBAR_DATA_KEY); - for (Player player : Bukkit.getOnlinePlayers()) { player.getInventory().setItem(0, _item); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java index 8cb652047..e66399ee6 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/minestrike/Minestrike.java @@ -1087,7 +1087,7 @@ public class Minestrike extends TeamGame _shopManager.leaveShop(player, false, false); } - @EventHandler(priority = EventPriority.HIGHEST) + @EventHandler(priority = EventPriority.HIGH) public void specToTeam(PlayerJoinEvent event) { if (GetState() == GameState.Recruit || GetState() == GameState.Loading) diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java index 9b4fc50a6..63ac223be 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/mineware/BawkBawkBattles.java @@ -674,9 +674,9 @@ public class BawkBawkBattles extends TeamGame implements IThrown private void silenceChat() { - if (Manager.GetChat().Silenced() < 0) + if (Manager.GetChat().getChatSilence() < 0) { - Manager.GetChat().Silence(SILENCE_DURATION, false); + Manager.GetChat().setChatSilence(SILENCE_DURATION, false); } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/prepare/PrepareManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/prepare/PrepareManager.java index d968f8239..c7fa42c99 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/prepare/PrepareManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/moba/prepare/PrepareManager.java @@ -94,7 +94,7 @@ public class PrepareManager implements Listener } _host.SetStateTime(System.currentTimeMillis()); - _host.getArcadeManager().GetChat().Silence(-1, false); + _host.getArcadeManager().GetChat().setChatSilence(-1, false); _host.PrepareTime = POST_SELECTION_PREPARE_TIME; _host.PrepareFreeze = true; } @@ -164,6 +164,6 @@ public class PrepareManager implements Listener } } - _host.getArcadeManager().GetChat().Silence(0, true); + _host.getArcadeManager().GetChat().setChatSilence(0, true); } } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java index d19956657..58ae94783 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/games/uhc/UHC.java @@ -1194,7 +1194,7 @@ public abstract class UHC extends Game if (event.GetState() != GameState.Prepare) return; - Manager.GetChat().Silence(1000 * 120, false); + Manager.GetChat().setChatSilence(1000 * 120, false); _isTeleporting = true; diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/HubClockModule.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/HubClockModule.java index a1361dd4b..a07a19b54 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/HubClockModule.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/game/modules/HubClockModule.java @@ -1,5 +1,7 @@ package nautilus.game.arcade.game.modules; +import java.util.Arrays; + import org.bukkit.ChatColor; import org.bukkit.Material; import org.bukkit.entity.Player; @@ -13,25 +15,38 @@ import org.bukkit.inventory.ItemStack; import mineplex.core.common.util.C; import mineplex.core.common.util.F; +import mineplex.core.common.util.UtilServer; import mineplex.core.itemstack.ItemStackFactory; import mineplex.core.portal.GenericServer; import mineplex.core.portal.Intent; import mineplex.core.recharge.Recharge; +import nautilus.game.arcade.events.GameStateChangeEvent; import nautilus.game.arcade.events.PlayerStateChangeEvent; +import nautilus.game.arcade.game.Game; import nautilus.game.arcade.game.GameTeam; import nautilus.game.arcade.managers.GameSpectatorManager; public class HubClockModule extends Module { private static final int HUB_CLOCK_SLOT = 8; - private static final ItemStack HUB_CLOCK_ITEM = ItemStackFactory.Instance.CreateStack(Material.WATCH, (byte) 0, 1, (short) 0, C.cGreen - + "Return to Hub", new String[]{"", ChatColor.RESET + "Click while holding this", - ChatColor.RESET + "to return to the Hub."}); + private static final ItemStack HUB_CLOCK_ITEM = ItemStackFactory.Instance.CreateStack(Material.WATCH, (byte) 0, 1, (short) 0, + C.cGreen + "Return to Hub", + new String[]{"", ChatColor.RESET + "Click while holding this", ChatColor.RESET + "to return to the Hub."}); + + public HubClockModule() + { + Player[] players = UtilServer.getPlayers(); + + if (players.length > 0) + { + Arrays.stream(players).forEach(this::giveClock); + } + } public void giveClock(Player player) { - if (!getGame().GiveClock) + if (getGame() != null && !getGame().GiveClock) { return; } @@ -39,12 +54,33 @@ public class HubClockModule extends Module player.getInventory().setItem(HUB_CLOCK_SLOT, HUB_CLOCK_ITEM); } + public void removeClock(Player player) + { + if (!player.getInventory().getItem(HUB_CLOCK_SLOT).equals(HUB_CLOCK_ITEM)) + { + return; + } + + player.getInventory().remove(HUB_CLOCK_ITEM); + } + @EventHandler public void giveOnJoin(PlayerJoinEvent event) { giveClock(event.getPlayer()); } + @EventHandler + public void giveOnNextLobby(GameStateChangeEvent event) + { + if (event.GetState() != Game.GameState.Recruit) + { + return; + } + + Arrays.stream(UtilServer.getPlayers()).forEach(this::giveClock); + } + @EventHandler public void giveOnDeath(PlayerStateChangeEvent event) { @@ -57,6 +93,19 @@ public class HubClockModule extends Module getGame().getArcadeManager().runSyncLater(() -> giveClock(event.GetPlayer()), GameSpectatorManager.ITEM_GIVE_DELAY); } + @EventHandler + public void removeOnRespawn(PlayerStateChangeEvent event) + { + // Only handle when the player is now in. + // This should make MS not have a persistent clock after round end + if (event.GetState() != GameTeam.PlayerState.IN) + { + return; + } + + removeClock(event.GetPlayer()); + } + @EventHandler public void preventDrop(PlayerDropItemEvent event) { diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gametutorial/GameTutorial.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gametutorial/GameTutorial.java index 374e0003f..3867392be 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gametutorial/GameTutorial.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/gametutorial/GameTutorial.java @@ -85,7 +85,7 @@ public abstract class GameTutorial phase.setText(newText); } - Manager.GetChat().Silence(60000, false); + Manager.GetChat().setChatSilence(60000, false); _started = System.currentTimeMillis(); Manager.getPluginManager().callEvent(new GameTutorialStartEvent(this)); onStart(); @@ -135,7 +135,7 @@ public abstract class GameTutorial // setting another Phase, if Tutorial hasn't stopped yet if (!_hasEnded) { - Manager.GetChat().Silence(70000, false); + Manager.GetChat().setChatSilence(70000, false); onPhaseChange(_currentPhase); Manager.getPluginManager().callEvent(new GameTutorialPhaseEvent(this, from, _currentPhase)); _currentPhase.start(phaseOne); @@ -184,7 +184,7 @@ public abstract class GameTutorial } } // setting the right prepare Time after the Tutorial ends - Manager.GetChat().Silence(StartAfterTutorial, false); + Manager.GetChat().setChatSilence(StartAfterTutorial, false); Manager.GetGame().PrepareTime = (System.currentTimeMillis() - Manager.GetGame().GetStateTime()) + StartAfterTutorial; } diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java index 3de7e7bbe..08ff73511 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameHostManager.java @@ -502,7 +502,7 @@ public class GameHostManager implements Listener } msg = msg.trim(); - msg = Manager.GetChat().getFilteredMessage(event.getPlayer(), msg); + msg = Manager.GetChat().filterMessage(event.getPlayer(), msg); if (msg == null) { diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameSpectatorManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameSpectatorManager.java index 3ea538e31..57c764c50 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameSpectatorManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/GameSpectatorManager.java @@ -48,7 +48,7 @@ public class GameSpectatorManager implements Listener, IPacketHandler { // Common delay for giving items when a spectator dies, // to prevent them from accidentally switching servers. - public final static long ITEM_GIVE_DELAY = 3 * 20L; + public final static long ITEM_GIVE_DELAY = 30L; // A map of a player UUID to the UUID of the entity they want to spectate private final Map _pendingSpectate = Collections.synchronizedMap(new HashMap<>()); diff --git a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java index 4dfad47d8..688007d2b 100644 --- a/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java +++ b/Plugins/Nautilus.Game.Arcade/src/nautilus/game/arcade/managers/chat/GameChatManager.java @@ -176,9 +176,9 @@ public class GameChatManager implements Listener name = _manager.GetColor(sender) + sender.getName() + C.Reset; if (event.getMessage().charAt(0) == '#') - message = event.getFormat().split(sender.getName())[1].replace("%2$s", "") + _manager.GetChat().getFilteredMessage(sender, event.getMessage().substring(1, event.getMessage().length())); + message = event.getFormat().split(sender.getName())[1].replace("%2$s", "") + event.getMessage().substring(1); else - message = event.getFormat().split(sender.getName())[1].replace("%2$s", "") + _manager.GetChat().getFilteredMessage(sender, event.getMessage()); + message = event.getFormat().split(sender.getName())[1].replace("%2$s", "") + event.getMessage(); if (_manager.GetGame() == null || _manager.GetGame().GetState() != GameState.Live) { diff --git a/Plugins/mavericks-review-hub/src/mineplex/mavericks/review/Hub.java b/Plugins/mavericks-review-hub/src/mineplex/mavericks/review/Hub.java index b2f8a7a1c..c6c999ddb 100644 --- a/Plugins/mavericks-review-hub/src/mineplex/mavericks/review/Hub.java +++ b/Plugins/mavericks-review-hub/src/mineplex/mavericks/review/Hub.java @@ -114,7 +114,7 @@ public class Hub extends JavaPlugin EloManager eloManager = new EloManager(this, _clientManager); AchievementManager achievementManager = new AchievementManager(statsManager, _clientManager, _donationManager, incognito, eloManager); FriendManager friendManager = new FriendManager(this, _clientManager, preferenceManager, portal); - Chat chat = new Chat(this, incognito, _clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName()); + Chat chat = new Chat(); new MessageManager(this, incognito, _clientManager, preferenceManager, ignoreManager, punish, friendManager, chat); BlockRestore blockRestore = require(BlockRestore.class); diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java index f57d0ce29..46ecabf76 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/GemHunters.java @@ -210,7 +210,7 @@ public class GemHunters extends JavaPlugin AchievementManager achievementManager = new AchievementManager(statsManager, clientManager, donationManager, incognito, eloManager); // Chat/Messaging - Chat chat = new Chat(this, incognito, clientManager, preferenceManager, achievementManager, serverStatusManager.getCurrentServerName()); + Chat chat = new Chat(); new MessageManager(this, incognito, clientManager, preferenceManager, ignoreManager, punish, new FriendManager(this, clientManager, preferenceManager, portal), chat); // Parties diff --git a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/chat/ChatModule.java b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/chat/ChatModule.java index 61286d772..ad154fe01 100644 --- a/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/chat/ChatModule.java +++ b/Plugins/mineplex-game-gemhunters/src/mineplex/gemhunters/chat/ChatModule.java @@ -99,7 +99,7 @@ public class ChatModule extends MiniPlugin message = _progression.getTitle(_economy.getGems(player)).getTitle() + " " + message + C.cWhite; } - message += _chat.getFilteredMessage(player, event.getMessage()); + message += _chat.filterMessage(player, event.getMessage()); message = message.trim();