From 6e3f8fef565027780727dfa256aac10c059fc488 Mon Sep 17 00:00:00 2001 From: Gocnak Date: Sat, 7 Feb 2015 15:16:48 -0500 Subject: [PATCH] 2.29 Added: Global Moderator support (closes #58) Message clearing/cleanup is now on MessageQueue Fixed: Subscriber sounds now don't trigger twice Font issue (closes #68) Null Pointer with checking Subscribers (closes #69) --- src/main/java/Boot.java | 2 - src/main/java/gui/ChatPane.java | 88 ++++++++---------- src/main/java/gui/DraggableTabbedPane.java | 5 +- src/main/java/gui/GUISettings.java | 15 ++- src/main/java/gui/listeners/ListenerName.java | 7 +- .../java/gui/listeners/PaneMenuListener.java | 4 +- src/main/java/image/globalmod.png | Bin 0 -> 397 bytes src/main/java/irc/IRCBot.java | 18 +--- src/main/java/irc/message/Message.java | 4 +- src/main/java/irc/message/MessageQueue.java | 7 +- src/main/java/irc/message/MessageWrapper.java | 30 +++--- .../pircbot/org/jibble/pircbot/PircBot.java | 11 +-- .../lib/pircbot/org/jibble/pircbot/User.java | 16 +++- src/main/java/sound/SoundEngine.java | 18 +--- src/main/java/util/Constants.java | 2 +- src/main/java/util/Utils.java | 47 ++++++---- src/main/java/util/settings/Settings.java | 2 +- .../java/util/settings/SubscriberManager.java | 8 +- version.txt | 12 +-- 19 files changed, 141 insertions(+), 155 deletions(-) create mode 100644 src/main/java/image/globalmod.png diff --git a/src/main/java/Boot.java b/src/main/java/Boot.java index e4dd744..86240b3 100644 --- a/src/main/java/Boot.java +++ b/src/main/java/Boot.java @@ -1,10 +1,8 @@ import gui.GUIMain; import gui.GUIUpdate; -import util.Utils; import util.settings.Settings; import javax.swing.*; - import java.awt.*; public class Boot { diff --git a/src/main/java/gui/ChatPane.java b/src/main/java/gui/ChatPane.java index 393873c..5523a36 100644 --- a/src/main/java/gui/ChatPane.java +++ b/src/main/java/gui/ChatPane.java @@ -5,6 +5,7 @@ import gui.listeners.ListenerURL; import irc.Donor; import irc.message.Message; +import irc.message.MessageQueue; import irc.message.MessageWrapper; import lib.pircbot.org.jibble.pircbot.User; import lib.scalr.Scalr; @@ -16,7 +17,10 @@ import javax.swing.*; import javax.swing.event.DocumentEvent; import javax.swing.event.DocumentListener; -import javax.swing.text.*; +import javax.swing.text.DefaultCaret; +import javax.swing.text.SimpleAttributeSet; +import javax.swing.text.StyleConstants; +import javax.swing.text.StyledDocument; import javax.swing.text.html.HTML; import java.awt.*; import java.awt.event.WindowAdapter; @@ -166,8 +170,11 @@ public void doScrollToBottom() { } } + private boolean messageOut = false; + @Override public void insertUpdate(DocumentEvent e) { + maybeScrollToBottom(); if (GUIMain.currentSettings.cleanupChat) { try { if (e.getDocument().getText(e.getOffset(), e.getLength()).contains("\n")) { @@ -176,9 +183,10 @@ public void insertUpdate(DocumentEvent e) { } catch (Exception ignored) { } if (cleanupCounter > GUIMain.currentSettings.chatMax) { - /* cleanup every n messages */ - if (cleanupChat()) { - resetCleanupCounter(); + /* cleanup every n messages */ + if (!messageOut) { + MessageQueue.addMessage(new Message().setType(Message.MessageType.CLEAR_TEXT).setExtra(this)); + messageOut = true; } } } @@ -186,32 +194,19 @@ public void insertUpdate(DocumentEvent e) { @Override public void removeUpdate(DocumentEvent e) { + maybeScrollToBottom(); } @Override public void changedUpdate(DocumentEvent e) { + maybeScrollToBottom(); } - // ScrollingDocumentListener takes care of re-scrolling when appropriate - class ScrollingDocumentListener implements DocumentListener { - public void changedUpdate(DocumentEvent e) { - maybeScrollToBottom(); - } - - public void insertUpdate(DocumentEvent e) { - maybeScrollToBottom(); - } - - public void removeUpdate(DocumentEvent e) { - maybeScrollToBottom(); - } - - private void maybeScrollToBottom() { - JScrollBar scrollBar = scrollPane.getVerticalScrollBar(); - boolean scrollBarAtBottom = isScrollBarFullyExtended(scrollBar); - if (scrollBarAtBottom) { - scrollToBottom(); - } + private void maybeScrollToBottom() { + JScrollBar scrollBar = scrollPane.getVerticalScrollBar(); + boolean scrollBarAtBottom = isScrollBarFullyExtended(scrollBar); + if (scrollBarAtBottom) { + scrollToBottom(); } } @@ -296,7 +291,6 @@ public ChatPane(String channel, JScrollPane scrollPane, JTextPane pane, int inde this.index = index; this.scrollPane = scrollPane; textPane.getDocument().addDocumentListener(this); - textPane.getDocument().addDocumentListener(new ScrollingDocumentListener()); } public ChatPane() { @@ -338,10 +332,13 @@ public void onMessage(MessageWrapper m, boolean showChannel) { insertIcon(m, 1, null); } if (u.isOp(channel)) { - if (!channel.substring(1).equals(sender) && !u.isStaff() && !u.isAdmin()) {//not the broadcaster again + if (!channel.substring(1).equals(sender) && !u.isStaff() && !u.isAdmin() && !u.isGlobalMod()) {//not the broadcaster again insertIcon(m, 0, null); } } + if (u.isGlobalMod()) { + insertIcon(m, 11, null); + } if (u.isDonor()) { insertIcon(m, u.getDonationStatus(), null); } @@ -561,6 +558,10 @@ public void insertIcon(MessageWrapper m, int type, String channel) { icon = sizeIcon(ChatPane.class.getResource("/image/diamond.png")); kind = "Donator"; break; + case 11: + icon = sizeIcon(ChatPane.class.getResource("/image/globalmod.png")); + kind = "Global Mod"; + break; default: icon = sizeIcon(GUIMain.currentSettings.modIcon); kind = "Mod"; @@ -581,41 +582,32 @@ public String getText() { // Source: http://stackoverflow.com/a/4628879 // by http://stackoverflow.com/users/131872/camickr & Community - public boolean cleanupChat() { - if (textPane == null || textPane.getParent() == null) return false; + public void cleanupChat() { + if (textPane == null || textPane.getParent() == null) return; if (!(textPane.getParent() instanceof JViewport)) { - return false; + return; } JViewport viewport = ((JViewport) textPane.getParent()); Point startPoint = viewport.getViewPosition(); // we are not deleting right before the visible area, but one screen behind // for convenience, otherwise flickering. - if (startPoint == null) return false; + if (startPoint == null) return; final int start = textPane.viewToModel(startPoint); if (start > 0) // not equal zero, because then we don't have to delete anything { final StyledDocument doc = textPane.getStyledDocument(); try { - if (GUIMain.currentSettings.cleanupChat) { - if (GUIMain.currentSettings.logChat && chan != null) { - String[] toRemove = doc.getText(0, start).split("\\n"); - Utils.logChat(toRemove, chan, 1); - } - EventQueue.invokeLater(() -> { - try { - doc.remove(0, start); - } catch (Exception ignored) { - } - }); - return true; + if (GUIMain.currentSettings.logChat && chan != null) { + String[] toRemove = doc.getText(0, start).split("\\n"); + Utils.logChat(toRemove, chan, 1); } - } catch (BadLocationException e) { - // we cannot do anything here - GUIMain.log("CLEANUP CHAT " + e.getMessage()); - return false; + doc.remove(0, start); + resetCleanupCounter(); + } catch (Exception e) { + GUIMain.log("Failed clearing chat: " + e.getMessage()); } } - return false; + messageOut = false; } /** @@ -665,4 +657,4 @@ public void log(MessageWrapper message, boolean isSystem) { print(message, "\n" + getTime(), GUIMain.norm); print(message, " " + (isSystem ? "SYS: " : "") + message.getLocal().getContent(), GUIMain.norm); } -} +} \ No newline at end of file diff --git a/src/main/java/gui/DraggableTabbedPane.java b/src/main/java/gui/DraggableTabbedPane.java index 05a3344..5008024 100644 --- a/src/main/java/gui/DraggableTabbedPane.java +++ b/src/main/java/gui/DraggableTabbedPane.java @@ -496,7 +496,7 @@ enum TabTypeEnum { TAB_NEITHER } - class TabType { + private class TabType { Rectangle rectangle; TabTypeEnum type; @@ -514,5 +514,4 @@ public TabTypeEnum getType() { return type; } } - -} +} \ No newline at end of file diff --git a/src/main/java/gui/GUISettings.java b/src/main/java/gui/GUISettings.java index 328d1f3..44a9626 100644 --- a/src/main/java/gui/GUISettings.java +++ b/src/main/java/gui/GUISettings.java @@ -372,11 +372,16 @@ public void changeFontButtonActionPerformed() { JFontChooser jfc = new JFontChooser(Constants.fontSizeArray); jfc.setSelectedFont(GUIMain.currentSettings.font); if (jfc.showDialog(this) == JFontChooser.OK_OPTION) { - if (jfc.getSelectedFont() != null) GUIMain.currentSettings.font = jfc.getSelectedFont(); - StyleConstants.setFontFamily(GUIMain.norm, GUIMain.currentSettings.font.getFamily()); - StyleConstants.setFontSize(GUIMain.norm, GUIMain.currentSettings.font.getSize()); - currentFontLabel.setText(Utils.fontToString(GUIMain.currentSettings.font)); - currentFontLabel.setFont(GUIMain.currentSettings.font); + Font f = jfc.getSelectedFont(); + if (f != null) { + GUIMain.currentSettings.font = f; + StyleConstants.setFontFamily(GUIMain.norm, GUIMain.currentSettings.font.getFamily()); + StyleConstants.setFontSize(GUIMain.norm, GUIMain.currentSettings.font.getSize()); + StyleConstants.setBold(GUIMain.norm, GUIMain.currentSettings.font.isBold()); + StyleConstants.setItalic(GUIMain.norm, GUIMain.currentSettings.font.isItalic()); + currentFontLabel.setText(Utils.fontToString(GUIMain.currentSettings.font)); + currentFontLabel.setFont(GUIMain.currentSettings.font); + } } } diff --git a/src/main/java/gui/listeners/ListenerName.java b/src/main/java/gui/listeners/ListenerName.java index 274d0df..e5c7ea5 100644 --- a/src/main/java/gui/listeners/ListenerName.java +++ b/src/main/java/gui/listeners/ListenerName.java @@ -24,9 +24,6 @@ */ public class ListenerName extends MouseAdapter implements ActionListener { - public ListenerName() { - } - @Override public void mouseReleased(MouseEvent e) { JTextPane textPane = (JTextPane) e.getSource(); @@ -50,8 +47,8 @@ public void mouseReleased(MouseEvent e) { User main = GUIMain.currentSettings.channelManager.getUser(GUIMain.currentSettings.accountManager.getUserAccount().getName(), false);//get yourself if (main != null) { int count = 0; //don't worry about it - //can't ban broadcaster or admin/staff - if (u != null && (u.isAdmin() || u.isStaff() || name.equalsIgnoreCase(channel.replace("#", "")))) + //can't ban broadcaster or admin/staff/global mod + if (u != null && (u.isAdmin() || u.isGlobalMod() || u.isStaff() || name.equalsIgnoreCase(channel.replace("#", "")))) count++; //can't ban other mods if you aren't the broadcaster diff --git a/src/main/java/gui/listeners/PaneMenuListener.java b/src/main/java/gui/listeners/PaneMenuListener.java index a04fcc6..86bc111 100644 --- a/src/main/java/gui/listeners/PaneMenuListener.java +++ b/src/main/java/gui/listeners/PaneMenuListener.java @@ -76,7 +76,7 @@ public void actionPerformed(ActionEvent e) { if (pane instanceof CombinedChatPane) pane = ((CombinedChatPane) pane).getActiveChatPane(); pane.resetCleanupCounter(); final ChatPane pane1 = pane; - EventQueue.invokeLater(() -> { + EventQueue.invokeLater(() -> {//this should be fine, no need for message queue since clearing would be situational anyways if (GUIMain.currentSettings.logChat) { String[] toPrint = pane1.getText().split("\\n"); Utils.logChat(toPrint, pane1.getChannel(), 1); @@ -103,4 +103,4 @@ public void actionPerformed(ActionEvent e) { } } } -} +} \ No newline at end of file diff --git a/src/main/java/image/globalmod.png b/src/main/java/image/globalmod.png new file mode 100644 index 0000000000000000000000000000000000000000..10d69fb98e264cc423b47b1e0664b1a5101cb868 GIT binary patch literal 397 zcmV;80doF{P)Px#1ZP1_K>z@;j|==^1poj532;bRa{vGi!~g&e!~vBn4jTXf0U}96K~y+TW8}$K z_|HHEzyzf!2J|tg%AgS rTmU5= 2.50) { - permission = Constants.PERMISSION_DONOR; - } - } - if ((u.isOp(channel) || u.isAdmin() || u.isStaff())) { - permission = Constants.PERMISSION_MOD; - } - if (GUIMain.currentSettings.accountManager.getUserAccount() != null && - GUIMain.currentSettings.accountManager.getUserAccount().getName().equalsIgnoreCase(sender)) { - permission = Constants.PERMISSION_DEV; - } + int permission = Utils.getUserPermission(u, channel); if (permission >= permBase) { r.addUser(u.getNick()); } diff --git a/src/main/java/irc/message/Message.java b/src/main/java/irc/message/Message.java index 4b98300..3e9efe8 100644 --- a/src/main/java/irc/message/Message.java +++ b/src/main/java/irc/message/Message.java @@ -98,7 +98,7 @@ public enum MessageType { HOSTING_NOTIFY, HOSTED_NOTIFY, DONATION_NOTIFY, - JTV_NOTIFY + JTV_NOTIFY, + CLEAR_TEXT } - } \ No newline at end of file diff --git a/src/main/java/irc/message/MessageQueue.java b/src/main/java/irc/message/MessageQueue.java index ca6b4d4..f594f13 100644 --- a/src/main/java/irc/message/MessageQueue.java +++ b/src/main/java/irc/message/MessageQueue.java @@ -1,5 +1,6 @@ package irc.message; +import gui.ChatPane; import gui.CombinedChatPane; import gui.GUIMain; import lib.pircbot.org.jibble.pircbot.Queue; @@ -63,10 +64,6 @@ public static void addMessage(Message mess) { } else if (mess.getType() == Message.MessageType.SUB_NOTIFY) { String channel = mess.getChannel().substring(1); GUIMain.chatPanes.get(channel).onSub(wrap); - if (channel.equalsIgnoreCase(GUIMain.currentSettings.accountManager.getUserAccount().getName())) { - if (GUIMain.currentSettings.subSound != null) - SoundEngine.getEngine().playSpecialSound(true); - } } else if (mess.getType() == Message.MessageType.BAN_NOTIFY || mess.getType() == Message.MessageType.HOSTED_NOTIFY || mess.getType() == Message.MessageType.HOSTING_NOTIFY || @@ -77,6 +74,8 @@ public static void addMessage(Message mess) { if (GUIMain.currentSettings.donationSound != null) { SoundEngine.getEngine().playSpecialSound(false); } + } else if (mess.getType() == Message.MessageType.CLEAR_TEXT) { + wrap.addPrint(((ChatPane) mess.getExtra())::cleanupChat); } addToQueue(wrap); } catch (Exception e) { diff --git a/src/main/java/irc/message/MessageWrapper.java b/src/main/java/irc/message/MessageWrapper.java index 5b702b6..399713a 100644 --- a/src/main/java/irc/message/MessageWrapper.java +++ b/src/main/java/irc/message/MessageWrapper.java @@ -29,20 +29,22 @@ public void addPrint(Runnable r) { } public void print() { - Runnable handler = () -> { - try { - prints.forEach(java.lang.Runnable::run); - } catch (Exception e) { - GUIMain.log(e.getMessage()); - } - }; - if (EventQueue.isDispatchThread()) { - handler.run(); - } else { - try { - EventQueue.invokeLater(handler); - } catch (Exception e) { - GUIMain.log(e.getMessage()); + if (!prints.isEmpty()) { + Runnable handler = () -> { + try { + prints.forEach(java.lang.Runnable::run); + } catch (Exception e) { + GUIMain.log(e.getMessage()); + } + }; + if (EventQueue.isDispatchThread()) { + handler.run(); + } else { + try { + EventQueue.invokeLater(handler); + } catch (Exception e) { + GUIMain.log(e.getMessage()); + } } } } diff --git a/src/main/java/lib/pircbot/org/jibble/pircbot/PircBot.java b/src/main/java/lib/pircbot/org/jibble/pircbot/PircBot.java index e8dd780..654b785 100644 --- a/src/main/java/lib/pircbot/org/jibble/pircbot/PircBot.java +++ b/src/main/java/lib/pircbot/org/jibble/pircbot/PircBot.java @@ -1000,15 +1000,14 @@ public void handleSpecial(String channel, String line) { String user = split[1].toLowerCase(); if (split[2].equalsIgnoreCase("admin")) { getChannelManager().getUser(user, true).setAdmin(true); - } - if (split[2].equalsIgnoreCase("staff")) { + } else if (split[2].equalsIgnoreCase("staff")) { getChannelManager().getUser(user, true).setStaff(true); - } - if (split[2].equalsIgnoreCase("turbo")) { + } else if (split[2].equalsIgnoreCase("turbo")) { getChannelManager().getUser(user, true).setTurbo(true); - } - if (split[2].equalsIgnoreCase("subscriber")) { + } else if (split[2].equalsIgnoreCase("subscriber")) { getChannelManager().getChannel(channel).addSubscriber(user); + } else if (split[2].equalsIgnoreCase("global_mod")) { + getChannelManager().getUser(user, true).setGlobalMod(true); } } } diff --git a/src/main/java/lib/pircbot/org/jibble/pircbot/User.java b/src/main/java/lib/pircbot/org/jibble/pircbot/User.java index 1d1e387..72e1c7e 100644 --- a/src/main/java/lib/pircbot/org/jibble/pircbot/User.java +++ b/src/main/java/lib/pircbot/org/jibble/pircbot/User.java @@ -34,7 +34,7 @@ General Public License (GPL) and the www.jibble.org Commercial License. */ public class User implements Comparable { - private boolean staff = false, admin = false, turbo = false; + private boolean staff = false, admin = false, global_mod = false, turbo = false; private HashSet emotes = new HashSet<>(); @@ -71,12 +71,15 @@ public String getPrefix() { //if (isSubscriber()) { // foxStevenson.append("$"); //} - if (isAdmin()) { + if (isGlobalMod()) { foxStevenson.append("!"); } - if (isStaff()) { + if (isAdmin()) { foxStevenson.append("!!"); } + if (isStaff()) { + foxStevenson.append("!!!"); + } return foxStevenson.toString(); } @@ -94,6 +97,13 @@ public boolean isOp(String channel) { return c != null && c.isMod(getNick()); } + public boolean isGlobalMod() { + return global_mod; + } + + public void setGlobalMod(boolean newBool) { + global_mod = newBool; + } /** * Checks to see if the user is an Admin on Twitch. * diff --git a/src/main/java/sound/SoundEngine.java b/src/main/java/sound/SoundEngine.java index de84287..eb26e2d 100644 --- a/src/main/java/sound/SoundEngine.java +++ b/src/main/java/sound/SoundEngine.java @@ -2,7 +2,6 @@ import gui.GUIMain; import lib.pircbot.org.jibble.pircbot.User; -import util.Constants; import util.Response; import util.Timer; import util.Utils; @@ -181,23 +180,8 @@ public boolean soundTrigger(String s, String send, String channel) { */ private boolean soundCheck(String sound, String sender, String channel) { //set the permission - int permission = Constants.PERMISSION_ALL; User u = GUIMain.currentSettings.channelManager.getUser(sender, true); - if (u.isSubscriber(channel)) { - permission = Constants.PERMISSION_SUB; - } - if (u.isDonor()) { - if (u.getDonated() >= 2.50) { - permission = Constants.PERMISSION_DONOR; - } - } - if (u.isOp(channel) || u.isAdmin() || u.isStaff()) { - permission = Constants.PERMISSION_MOD; - } - if (GUIMain.currentSettings.accountManager.getUserAccount() != null && - GUIMain.currentSettings.accountManager.getUserAccount().getName().equalsIgnoreCase(sender)) { - permission = Constants.PERMISSION_DEV; - } + int permission = Utils.getUserPermission(u, channel); String[] keys = soundMap.keySet().toArray(new String[soundMap.keySet().size()]); for (String s : keys) { if (s != null && s.equalsIgnoreCase(sound)) { diff --git a/src/main/java/util/Constants.java b/src/main/java/util/Constants.java index dc3bd62..2197f5a 100644 --- a/src/main/java/util/Constants.java +++ b/src/main/java/util/Constants.java @@ -12,7 +12,7 @@ public class Constants { - public static final double VERSION = 2.28; + public static final double VERSION = 2.29; /** * All users may do it diff --git a/src/main/java/util/Utils.java b/src/main/java/util/Utils.java index 2039683..6bdbb89 100644 --- a/src/main/java/util/Utils.java +++ b/src/main/java/util/Utils.java @@ -797,21 +797,7 @@ public static ConsoleCommand getConsoleCommand(String key, String channel, User } } } else {//int class permission - int permission = Constants.PERMISSION_ALL; - if (u.isSubscriber(channel)) { - permission = Constants.PERMISSION_SUB; - } - if (u.isDonor()) { - if (u.getDonated() >= 2.50) { - permission = Constants.PERMISSION_DONOR; - } - } - if (u.isOp(channel) || u.isAdmin() || u.isStaff()) { - permission = Constants.PERMISSION_MOD; - } - if (GUIMain.viewer != null && master.equalsIgnoreCase(u.getNick())) { - permission = Constants.PERMISSION_DEV; - } + int permission = getUserPermission(u, channel); if (permission >= conPerm) { return c; } @@ -822,6 +808,32 @@ public static ConsoleCommand getConsoleCommand(String key, String channel, User return null; } + /** + * Gets the permission of the user based on their status. + * + * @param u The user to check. + * @param channel The channel this is for. + * @return The permission they have. + */ + public static int getUserPermission(User u, String channel) { + int permission = Constants.PERMISSION_ALL; + if (u.isSubscriber(channel)) { + permission = Constants.PERMISSION_SUB; + } + if (u.isDonor()) { + if (u.getDonated() >= 2.50) { + permission = Constants.PERMISSION_DONOR; + } + } + if (u.isOp(channel) || u.isAdmin() || u.isStaff() || u.isGlobalMod()) { + permission = Constants.PERMISSION_MOD; + } + if (GUIMain.viewer != null && GUIMain.currentSettings.accountManager.getUserAccount().getName().equalsIgnoreCase(u.getNick())) { + permission = Constants.PERMISSION_DEV; + } + return permission; + } + /** * Sets the permission of a console command based on the input received. *

@@ -886,6 +898,8 @@ public static Response getCurrentlyPlaying() { if (line != null) { toReturn.wasSuccessful(); toReturn.setResponseText("The current song is: " + line); + } else { + toReturn.setResponseText("There is no song currently playing!"); } } catch (Exception e) { toReturn.setResponseText("Failed to fetch current playing song due to Exception: " + e.getMessage()); @@ -931,7 +945,7 @@ public static Response getUptimeString(String channelName) { * @return The set with the correct color. */ public static SimpleAttributeSet getSetForKeyword(String message) { - SimpleAttributeSet setToRet = (SimpleAttributeSet) GUIMain.norm.clone(); + SimpleAttributeSet setToRet = new SimpleAttributeSet(GUIMain.norm); Set keys = GUIMain.keywordMap.keySet(); //case doesnt matter keys.stream().filter( @@ -1137,5 +1151,4 @@ public static boolean checkName(String toCheck) { Matcher m = Constants.fileExclPattern.matcher(toCheck); return m.find(); } - } \ No newline at end of file diff --git a/src/main/java/util/settings/Settings.java b/src/main/java/util/settings/Settings.java index 5565502..76e77e9 100644 --- a/src/main/java/util/settings/Settings.java +++ b/src/main/java/util/settings/Settings.java @@ -184,7 +184,7 @@ public void load() { donationManager.ranFirstCheck = true; } //TODO implement #canCheckSubs() - if (!subscriberManager.ranInitialCheck) { + if (!subscriberManager.ranInitialCheck && accountManager.getUserAccount() != null) { subscriberManager.scanInitialSubscribers(accountManager.getUserAccount().getName(), accountManager.getUserAccount().getKey().getKey().split(":")[1], 0, new HashSet<>()); } diff --git a/src/main/java/util/settings/SubscriberManager.java b/src/main/java/util/settings/SubscriberManager.java index a2e38b0..40c0dfb 100644 --- a/src/main/java/util/settings/SubscriberManager.java +++ b/src/main/java/util/settings/SubscriberManager.java @@ -7,6 +7,7 @@ import lib.JSON.JSONArray; import lib.JSON.JSONObject; import lib.pircbot.org.jibble.pircbot.User; +import sound.SoundEngine; import util.misc.Donation; import java.io.BufferedReader; @@ -141,8 +142,9 @@ public void fillSubscribers(HashSet set) { } public void addSub(Subscriber s) { - subscribers.add(s); - setLastSubscriber(s); + if (subscribers.add(s)) { + setLastSubscriber(s); + } } public boolean addNewSubscriber(String name, String channel) { @@ -176,6 +178,8 @@ public boolean addNewSubscriber(String name, String channel) { private void addSubDonation(String who, String content, double amt) { GUIMain.currentSettings.donationManager.addDonation( new Donation("SUBSCRIBER", who, content, amt, Date.from(Instant.now())), true); + if (GUIMain.currentSettings.subSound != null) + SoundEngine.getEngine().playSpecialSound(true); } diff --git a/version.txt b/version.txt index 22be93f..540d2af 100644 --- a/version.txt +++ b/version.txt @@ -1,12 +1,12 @@ -2.28 +2.29 Added: -"!uptime" command -Support for the new subscriber messages -All commands moved to Response framework (closes #63) +Global Moderator support (closes #58) +Message clearing/cleanup is now on MessageQueue Fixed: -MessageQueue is significantly faster -Heartbeat Threads don't overlap each other \ No newline at end of file +Subscriber sounds now don't trigger twice +Font issue (closes #68) +Null Pointer with checking Subscribers (closes #69) \ No newline at end of file