From a295346b5ec3ca1ce51cbafca31b58e5d00f8d75 Mon Sep 17 00:00:00 2001 From: Trevor Guidry Date: Sat, 15 Dec 2018 13:19:15 -0500 Subject: [PATCH] timestamp plugin: allow configuring timestamp Co-authored-by: Adam --- .../plugins/timestamp/TimestampConfig.java | 20 +++++ .../plugins/timestamp/TimestampPlugin.java | 57 +++++++++++-- .../timestamp/TimestampPluginTest.java | 79 +++++++++++++++++++ 3 files changed, 148 insertions(+), 8 deletions(-) create mode 100644 runelite-client/src/test/java/net/runelite/client/plugins/timestamp/TimestampPluginTest.java diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java index da1bf222ce..fda97b0941 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampConfig.java @@ -35,6 +35,7 @@ public interface TimestampConfig extends Config @ConfigItem( keyName = "opaqueTimestamp", name = "Timestamps (opaque)", + position = 1, description = "Colour of Timestamps from the Timestamps plugin (opaque)" ) Color opaqueTimestamp(); @@ -42,7 +43,26 @@ public interface TimestampConfig extends Config @ConfigItem( keyName = "transparentTimestamp", name = "Timestamps (transparent)", + position = 2, description = "Colour of Timestamps from the Timestamps plugin (transparent)" ) Color transparentTimestamp(); + + @ConfigItem( + keyName = "format", + name = "Timestamp Format", + position = 3, + description = "Customize your timestamp format by using the following characters
" + + "'yyyy' : year
" + + "'MM' : month
" + + "'dd' : day
" + + "'HH' : hour in 24 hour format
" + + "'hh' : hour in 12 hour format
" + + "'mm' : minute
" + + "'ss' : second" + ) + default String timestampFormat() + { + return "[HH:mm]"; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java index baf0f5f232..4379d37844 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/timestamp/TimestampPlugin.java @@ -27,14 +27,17 @@ package net.runelite.client.plugins.timestamp; import com.google.inject.Provides; import java.awt.Color; +import java.text.SimpleDateFormat; import java.time.Instant; import java.time.ZoneId; import java.time.ZonedDateTime; -import java.time.temporal.ChronoField; +import java.util.Date; import javax.inject.Inject; +import lombok.Getter; import net.runelite.api.Client; import net.runelite.api.MessageNode; import net.runelite.api.Varbits; +import net.runelite.api.events.ConfigChanged; import net.runelite.api.events.ScriptCallbackEvent; import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; @@ -56,12 +59,36 @@ public class TimestampPlugin extends Plugin @Inject private TimestampConfig config; + @Getter + private SimpleDateFormat formatter; + @Provides public TimestampConfig provideConfig(final ConfigManager configManager) { return configManager.getConfig(TimestampConfig.class); } + @Override + protected void startUp() throws Exception + { + updateFormatter(); + } + + @Override + protected void shutDown() throws Exception + { + formatter = null; + } + + @Subscribe + public void onConfigChanged(ConfigChanged event) + { + if (event.getGroup().equals("timestamp") && event.getKey().equals("format")) + { + updateFormatter(); + } + } + @Subscribe public void onScriptCallbackEvent(ScriptCallbackEvent event) { @@ -80,13 +107,7 @@ public class TimestampPlugin extends Plugin MessageNode messageNode = (MessageNode) client.getMessages().get(messageId); - final ZonedDateTime time = ZonedDateTime.ofInstant( - Instant.ofEpochSecond(messageNode.getTimestamp()), ZoneId.systemDefault()); - - final String dateFormat = time.get(ChronoField.HOUR_OF_DAY) + ":" + - String.format("%02d", time.get(ChronoField.MINUTE_OF_HOUR)); - - String timestamp = "[" + dateFormat + "] "; + String timestamp = generateTimestamp(messageNode.getTimestamp(), ZoneId.systemDefault()) + " "; Color timestampColour = getTimestampColour(); if (timestampColour != null) @@ -103,4 +124,24 @@ public class TimestampPlugin extends Plugin return isChatboxTransparent ? config.transparentTimestamp() : config.opaqueTimestamp(); } + + String generateTimestamp(int timestamp, ZoneId zoneId) + { + final ZonedDateTime time = ZonedDateTime.ofInstant( + Instant.ofEpochSecond(timestamp), zoneId); + + return formatter.format(Date.from(time.toInstant())); + } + + private void updateFormatter() + { + try + { + formatter = new SimpleDateFormat(config.timestampFormat()); + } + catch (IllegalArgumentException e) + { + formatter = new SimpleDateFormat("[HH:mm]"); + } + } } \ No newline at end of file diff --git a/runelite-client/src/test/java/net/runelite/client/plugins/timestamp/TimestampPluginTest.java b/runelite-client/src/test/java/net/runelite/client/plugins/timestamp/TimestampPluginTest.java new file mode 100644 index 0000000000..e9033043cf --- /dev/null +++ b/runelite-client/src/test/java/net/runelite/client/plugins/timestamp/TimestampPluginTest.java @@ -0,0 +1,79 @@ +/* + * Copyright (c) 2019, Trevor + * All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are met: + * + * 1. Redistributions of source code must retain the above copyright notice, this + * list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND + * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE + * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR + * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ +package net.runelite.client.plugins.timestamp; + +import com.google.inject.Guice; +import com.google.inject.testing.fieldbinder.Bind; +import com.google.inject.testing.fieldbinder.BoundFieldModule; +import java.util.TimeZone; +import javax.inject.Inject; +import net.runelite.api.Client; +import net.runelite.api.events.ConfigChanged; +import static org.junit.Assert.assertTrue; +import org.junit.Before; +import org.junit.Test; +import org.junit.runner.RunWith; +import org.mockito.Mock; +import static org.mockito.Mockito.when; +import org.mockito.runners.MockitoJUnitRunner; + +@RunWith(MockitoJUnitRunner.class) +public class TimestampPluginTest +{ + @Mock + @Bind + Client client; + + @Mock + @Bind + TimestampConfig config; + + @Inject + TimestampPlugin plugin; + + @Before + public void before() + { + Guice.createInjector(BoundFieldModule.of(this)).injectMembers(this); + } + + @Test + public void testGenerateTimestamp() + { + when(config.timestampFormat()).thenReturn("[yyyy:MM:dd:HH:hh:mm:ss]"); + + ConfigChanged configChanged = new ConfigChanged(); + configChanged.setGroup("timestamp"); + configChanged.setKey("format"); + configChanged.setNewValue("true"); + plugin.onConfigChanged(configChanged); + + int testInput = 1554667116; + String testOutput = "[2019:04:07:15:03:58:36]"; + TimeZone timeZone = TimeZone.getTimeZone("America/New_York"); + plugin.getFormatter().setTimeZone(timeZone); + assertTrue(plugin.generateTimestamp(testInput, timeZone.toZoneId()).equals(testOutput)); + } +}