Add 2 new notifications modes (message, flash)
- Change the notification mode selection to be dropdown - Add chat message notification mode that will send game message on notificiation - Add screen flash notification that will flash screen for few ticks Signed-off-by: Tomas Slusny <slusnucky@gmail.com>
This commit is contained in:
@@ -27,19 +27,28 @@ package net.runelite.client;
|
||||
import com.google.common.escape.Escaper;
|
||||
import com.google.common.escape.Escapers;
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Toolkit;
|
||||
import java.awt.TrayIcon;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.nio.file.Files;
|
||||
import java.nio.file.Path;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Optional;
|
||||
import java.util.concurrent.ScheduledExecutorService;
|
||||
import javax.inject.Provider;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.Getter;
|
||||
import lombok.RequiredArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.api.ChatMessageType;
|
||||
import net.runelite.api.Client;
|
||||
import net.runelite.api.GameState;
|
||||
import net.runelite.client.config.RuneLiteConfig;
|
||||
import net.runelite.client.ui.ClientUI;
|
||||
import net.runelite.client.util.OSType;
|
||||
@@ -48,6 +57,25 @@ import net.runelite.client.util.OSType;
|
||||
@Slf4j
|
||||
public class Notifier
|
||||
{
|
||||
@Getter
|
||||
@RequiredArgsConstructor
|
||||
public enum NotificationMode
|
||||
{
|
||||
TRAY("System tray"),
|
||||
BEEP("System beep"),
|
||||
MESSAGE("Game message"),
|
||||
FLASH("Screen flash"),
|
||||
OFF("Off");
|
||||
|
||||
private final String name;
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return name;
|
||||
}
|
||||
}
|
||||
|
||||
// Default timeout of notification in milliseconds
|
||||
private static final int DEFAULT_TIMEOUT = 10000;
|
||||
private static final String DOUBLE_QUOTE = "\"";
|
||||
@@ -55,24 +83,32 @@ public class Notifier
|
||||
.addEscape('"', "'")
|
||||
.build();
|
||||
|
||||
// Notifier properties
|
||||
private static final Color FLASH_COLOR = new Color(255, 0, 0, 70);
|
||||
private static final int FLASH_DURATION = 2000;
|
||||
private static final String MESSAGE_COLOR = "FF0000";
|
||||
|
||||
private final Provider<Client> client;
|
||||
private final String appName;
|
||||
private final RuneLiteConfig runeLiteConfig;
|
||||
private final Provider<ClientUI> clientUI;
|
||||
private final ScheduledExecutorService executorService;
|
||||
private final Path notifyIconPath;
|
||||
private Instant flashStart;
|
||||
|
||||
@Inject
|
||||
private Notifier(
|
||||
final Provider<ClientUI> clientUI,
|
||||
final Provider<Client> client,
|
||||
final RuneLiteConfig runeliteConfig,
|
||||
final RuneLiteProperties runeLiteProperties,
|
||||
final ScheduledExecutorService executorService)
|
||||
{
|
||||
this.client = client;
|
||||
this.appName = runeLiteProperties.getTitle();
|
||||
this.clientUI = clientUI;
|
||||
this.runeLiteConfig = runeliteConfig;
|
||||
this.executorService = executorService;
|
||||
|
||||
this.notifyIconPath = RuneLite.RUNELITE_DIR.toPath().resolve("icon.png");
|
||||
storeIcon();
|
||||
}
|
||||
@@ -101,26 +137,63 @@ public class Notifier
|
||||
clientUI.requestFocus();
|
||||
}
|
||||
|
||||
if (runeLiteConfig.enableTrayNotifications())
|
||||
switch (runeLiteConfig.notificationMode())
|
||||
{
|
||||
sendNotification(appName, message, type, null);
|
||||
case TRAY:
|
||||
sendNotification(appName, message, type);
|
||||
break;
|
||||
case BEEP:
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
break;
|
||||
case MESSAGE:
|
||||
final Client client = this.client.get();
|
||||
|
||||
if (client != null && client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
client.addChatMessage(ChatMessageType.GAME, appName,
|
||||
"<col=" + MESSAGE_COLOR + ">" + message + "</col>", "");
|
||||
}
|
||||
|
||||
break;
|
||||
case FLASH:
|
||||
flashStart = Instant.now();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
public void processFlash(final Graphics2D graphics)
|
||||
{
|
||||
if (flashStart == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (runeLiteConfig.enableNotificationSound())
|
||||
final Client client = this.client.get();
|
||||
|
||||
if (client == null || client.getGameCycle() % 40 >= 20)
|
||||
{
|
||||
Toolkit.getDefaultToolkit().beep();
|
||||
return;
|
||||
}
|
||||
|
||||
final Color color = graphics.getColor();
|
||||
graphics.setColor(FLASH_COLOR);
|
||||
graphics.fill(new Rectangle(client.getCanvas().getSize()));
|
||||
graphics.setColor(color);
|
||||
|
||||
if (Instant.now().minusMillis(FLASH_DURATION).isAfter(flashStart))
|
||||
{
|
||||
flashStart = null;
|
||||
}
|
||||
}
|
||||
|
||||
private void sendNotification(
|
||||
final String title,
|
||||
final String message,
|
||||
final TrayIcon.MessageType type,
|
||||
final String subtitle)
|
||||
final TrayIcon.MessageType type)
|
||||
{
|
||||
final String escapedTitle = SHELL_ESCAPE.escape(title);
|
||||
final String escapedMessage = SHELL_ESCAPE.escape(message);
|
||||
final String escapedSubtitle = subtitle != null ? SHELL_ESCAPE.escape(subtitle) : null;
|
||||
final String escapedSubtitle = null;
|
||||
|
||||
switch (OSType.getOSType())
|
||||
{
|
||||
|
||||
@@ -64,6 +64,7 @@ import net.runelite.api.events.ProjectileMoved;
|
||||
import net.runelite.api.events.SetMessage;
|
||||
import net.runelite.api.widgets.Widget;
|
||||
import static net.runelite.api.widgets.WidgetID.WORLD_MAP;
|
||||
import net.runelite.client.Notifier;
|
||||
import net.runelite.client.RuneLite;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
@@ -98,6 +99,7 @@ public class Hooks
|
||||
private static final ClientThread clientThread = injector.getInstance(ClientThread.class);
|
||||
private static final GameTick tick = new GameTick();
|
||||
private static final DrawManager renderHooks = injector.getInstance(DrawManager.class);
|
||||
private static final Notifier notifier = injector.getInstance(Notifier.class);
|
||||
|
||||
private static Dimension lastStretchedDimensions;
|
||||
private static BufferedImage stretchedImage;
|
||||
@@ -267,6 +269,8 @@ public class Hooks
|
||||
log.warn("Error during overlay rendering", ex);
|
||||
}
|
||||
|
||||
notifier.processFlash(graphics2d);
|
||||
|
||||
// Stretch the game image if the user has that enabled
|
||||
if (!client.isResized() && client.isStretchedEnabled())
|
||||
{
|
||||
|
||||
@@ -26,6 +26,7 @@ package net.runelite.client.config;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import net.runelite.api.Constants;
|
||||
import net.runelite.client.Notifier;
|
||||
|
||||
@ConfigGroup(
|
||||
keyName = "runelite",
|
||||
@@ -80,32 +81,21 @@ public interface RuneLiteConfig extends Config
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationTray",
|
||||
name = "Enable tray notifications",
|
||||
description = "Enables tray notifications",
|
||||
keyName = "notificationMode",
|
||||
name = "Notification mode",
|
||||
description = "Determines mode of notifications",
|
||||
position = 5
|
||||
)
|
||||
default boolean enableTrayNotifications()
|
||||
default Notifier.NotificationMode notificationMode()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationSound",
|
||||
name = "Enable sound on notifications",
|
||||
description = "Enables the playing of a beep sound when notifications are displayed",
|
||||
position = 6
|
||||
)
|
||||
default boolean enableNotificationSound()
|
||||
{
|
||||
return true;
|
||||
return Notifier.NotificationMode.TRAY;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationFocused",
|
||||
name = "Send notifications when focused",
|
||||
description = "Toggles idle notifications for when the client is focused",
|
||||
position = 7
|
||||
position = 6
|
||||
)
|
||||
default boolean sendNotificationsWhenFocused()
|
||||
{
|
||||
@@ -116,7 +106,7 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "notificationRequestFocus",
|
||||
name = "Request focus on notification",
|
||||
description = "Toggles window focus request",
|
||||
position = 8
|
||||
position = 7
|
||||
)
|
||||
default boolean requestFocusOnNotification()
|
||||
{
|
||||
@@ -127,7 +117,7 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "fontType",
|
||||
name = "Dynamic Overlay Font",
|
||||
description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.",
|
||||
position = 9
|
||||
position = 8
|
||||
)
|
||||
default FontType fontType()
|
||||
{
|
||||
@@ -138,7 +128,7 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "infoBoxVertical",
|
||||
name = "Display infoboxes vertically",
|
||||
description = "Toggles the infoboxes to display vertically",
|
||||
position = 10
|
||||
position = 9
|
||||
)
|
||||
default boolean infoBoxVertical()
|
||||
{
|
||||
@@ -149,7 +139,7 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "infoBoxWrap",
|
||||
name = "Infobox wrap count",
|
||||
description = "Configures the amount of infoboxes shown before wrapping",
|
||||
position = 11
|
||||
position = 10
|
||||
)
|
||||
default int infoBoxWrap()
|
||||
{
|
||||
@@ -160,7 +150,7 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "containInScreen",
|
||||
name = "Contain in screen",
|
||||
description = "Makes the client stay contained in the screen when attempted to move out of it.<br>Note: Only works if custom chrome is enabled.",
|
||||
position = 12
|
||||
position = 11
|
||||
)
|
||||
default boolean containInScreen()
|
||||
{
|
||||
@@ -171,7 +161,7 @@ public interface RuneLiteConfig extends Config
|
||||
keyName = "rememberScreenBounds",
|
||||
name = "Remember client position",
|
||||
description = "Save the position and size of the client after exiting",
|
||||
position = 13
|
||||
position = 12
|
||||
)
|
||||
default boolean rememberScreenBounds()
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user