diff --git a/buildSrc/src/main/kotlin/Dependencies.kt b/buildSrc/src/main/kotlin/Dependencies.kt index d463a1db73..cf6faf5c0c 100644 --- a/buildSrc/src/main/kotlin/Dependencies.kt +++ b/buildSrc/src/main/kotlin/Dependencies.kt @@ -27,7 +27,7 @@ object ProjectVersions { const val launcherVersion = "3.0.0" const val rlVersion = "1.8.18.4" - const val openosrsVersion = "4.25.1" + const val openosrsVersion = "4.25.2" const val rsversion = 204.6 const val cacheversion = 165 diff --git a/runelite-client/src/main/java/com/openosrs/client/config/OpenOSRSConfig.java b/runelite-client/src/main/java/com/openosrs/client/config/OpenOSRSConfig.java index 88faf46cb5..bf1b59336e 100644 --- a/runelite-client/src/main/java/com/openosrs/client/config/OpenOSRSConfig.java +++ b/runelite-client/src/main/java/com/openosrs/client/config/OpenOSRSConfig.java @@ -32,7 +32,7 @@ import lombok.Getter; import net.runelite.client.config.Config; import net.runelite.client.config.ConfigGroup; import net.runelite.client.config.ConfigItem; -import net.runelite.client.config.Keybind; +import net.runelite.client.config.ConfigTitle; import net.runelite.client.config.Range; import net.runelite.client.config.Units; import net.runelite.client.plugins.OPRSExternalPluginManager; @@ -40,15 +40,14 @@ import net.runelite.client.plugins.OPRSExternalPluginManager; @ConfigGroup("openosrs") public interface OpenOSRSConfig extends Config { - @Getter(AccessLevel.PUBLIC) + @Getter(AccessLevel.PRIVATE) @AllArgsConstructor - enum SortStyle + enum BootstrapMode { - CATEGORY("Category"), - ALPHABETICALLY("Alphabetically"), - REPOSITORY("Repository"); + STABLE("Stable"), + NIGHTLY("Nightly"); - private String name; + private final String name; @Override public String toString() @@ -57,22 +56,110 @@ public interface OpenOSRSConfig extends Config } } - @ConfigItem( - position = 3, - keyName = "shareLogs", - name = "Share anonymous error data", - description = "Share anonymous error data with the OpenOSRS developers" + @ConfigTitle( + name = "Launcher", + description = "", + position = 0 ) - default boolean shareLogs() + String launcherTitle = "launcherTitle"; + + @ConfigTitle( + keyName = "updateChannelTitle", + name = "Update channel", + description = "", + position = 1, + title = launcherTitle + ) + String updateChannelTitle = "updateChannelTitle"; + + @ConfigItem( + position = 2, + keyName = "askMode", + name = "Prompt for update channel", + description = "Ask for nightly or stable every startup", + title = updateChannelTitle + ) + default boolean askMode() { return true; } + @ConfigItem( + keyName = "bootstrapMode", + name = "Update channel", + description = "Select the update channel", + title = updateChannelTitle, + position = 3, + hide = "askMode" + ) + default BootstrapMode bootstrapMode() + { + return BootstrapMode.STABLE; + } + + @ConfigTitle( + keyName = "miscLauncherTitle", + name = "Miscellaneous", + description = "", + position = 4, + title = launcherTitle + ) + String miscLauncherTitle = "miscLauncherTitle"; + + @ConfigItem( + position = 5, + keyName = "disableHw", + name = "Disable hardware acceleration", + description = "Enable this if you have graphical issues", + title = miscLauncherTitle, + warning = "Toggling this setting requires a restart of the client" + ) + default boolean disableHw() + { + return false; + } + + @ConfigTitle( + name = "Client", + description = "", + position = 6 + ) + String clientTitle = "clientTitle"; + + @ConfigTitle( + name = "Sync", + description = "", + position = 6, + title = clientTitle + ) + String syncTitle = "syncTitle"; + + @ConfigItem( + keyName = "localSync", + name = "Sync local instances", + description = "Enables multiple local instances of OpenOSRS to communicate (this enables syncing plugin state and config options)", + position = 7, + title = syncTitle + ) + default boolean localSync() + { + return true; + } + + @ConfigTitle( + name = "Miscellaneous", + description = "", + position = 8, + title = clientTitle + ) + String miscClientTitle = "miscClientTitle"; + @ConfigItem( keyName = "enableOpacity", name = "Enable opacity", description = "Enables opacity for the whole window.
NOTE: This only stays enabled if your pc supports this!", - position = 18 + position = 9, + title = miscClientTitle ) default boolean enableOpacity() { @@ -87,7 +174,10 @@ public interface OpenOSRSConfig extends Config keyName = "opacityPercentage", name = "Opacity percentage", description = "Changes the opacity of the window if opacity is enabled", - position = 19 + position = 10, + title = miscClientTitle, + hidden = true, + unhide = "enableOpacity" ) @Units(Units.PERCENT) default int opacityPercentage() @@ -95,28 +185,6 @@ public interface OpenOSRSConfig extends Config return 100; } - @ConfigItem( - keyName = "localSync", - name = "Sync local instances", - description = "Enables multiple local instances of OpenOSRS to communicate (this enables syncing plugin state and config options)", - position = 21 - ) - default boolean localSync() - { - return true; - } - - @ConfigItem( - keyName = "detachHotkey", - name = "Detach Cam", - description = "Detach Camera hotkey, press this and it will activate detached camera.", - position = 22 - ) - default Keybind detachHotkey() - { - return Keybind.NOT_SET; - } - @ConfigItem( keyName = "externalRepos", name = "", diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java index c8b8feefb5..278cb5b188 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPlugin.java @@ -24,6 +24,7 @@ */ package net.runelite.client.plugins.config; +import com.openosrs.client.config.OpenOSRSConfig; import java.awt.image.BufferedImage; import javax.inject.Inject; import javax.inject.Provider; @@ -61,6 +62,9 @@ public class ConfigPlugin extends Plugin @Inject private RuneLiteConfig runeLiteConfig; + @Inject + private OpenOSRSConfig openOSRSConfig; + @Inject private ChatColorConfig chatColorConfig; @@ -77,6 +81,11 @@ public class ConfigPlugin extends Plugin new String[]{"client", "notification", "size", "position", "window", "chrome", "focus", "font", "overlay", "tooltip", "infobox"}, runeLiteConfig, configManager.getConfigDescriptor(runeLiteConfig) ), + new PluginConfigurationDescriptor( + "OpenOSRS", "OpenOSRS client settings", + new String[]{"client"}, + openOSRSConfig, configManager.getConfigDescriptor(openOSRSConfig) + ), new PluginConfigurationDescriptor( "Chat Color", "Recolor chat text", new String[]{"colour", "messages"}, chatColorConfig, configManager.getConfigDescriptor(chatColorConfig) diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/openosrs/OS.java b/runelite-client/src/main/java/net/runelite/client/plugins/openosrs/OS.java new file mode 100644 index 0000000000..331fc423a7 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/plugins/openosrs/OS.java @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2016-2018, Adam + * 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.openosrs; + +import javax.annotation.Nonnull; +import lombok.extern.slf4j.Slf4j; + +@Slf4j +public class OS +{ + public enum OSType + { + Windows, MacOS, Linux, Other + } + + private static final OSType DETECTED_OS; + + static + { + final String os = System + .getProperty("os.name", "generic") + .toLowerCase(); + DETECTED_OS = parseOs(os); + log.debug("Detect OS: {}", DETECTED_OS); + } + + static OSType parseOs(@Nonnull String os) + { + os = os.toLowerCase(); + if ((os.contains("mac")) || (os.contains("darwin"))) + { + return OSType.MacOS; + } + else if (os.contains("win")) + { + return OSType.Windows; + } + else if (os.contains("linux")) + { + return OSType.Linux; + } + else + { + return OSType.Other; + } + } + + public static OSType getOs() + { + return DETECTED_OS; + } +} diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/openosrs/OpenOSRSPlugin.java b/runelite-client/src/main/java/net/runelite/client/plugins/openosrs/OpenOSRSPlugin.java index a6f53666cb..e30f1bda86 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/openosrs/OpenOSRSPlugin.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/openosrs/OpenOSRSPlugin.java @@ -26,26 +26,23 @@ */ package net.runelite.client.plugins.openosrs; -import ch.qos.logback.classic.Logger; -import com.openosrs.client.config.OpenOSRSConfig; import java.awt.image.BufferedImage; import javax.annotation.Nullable; import javax.inject.Inject; import javax.inject.Singleton; +import javax.swing.JOptionPane; import lombok.extern.slf4j.Slf4j; import net.runelite.api.Client; -import net.runelite.client.config.Keybind; +import net.runelite.client.config.ConfigManager; import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ConfigChanged; -import net.runelite.client.input.KeyManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.openosrs.externals.ExternalPluginManagerPanel; import net.runelite.client.ui.ClientToolbar; +import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.NavigationButton; -import net.runelite.client.util.HotkeyListener; import net.runelite.client.util.ImageUtil; -import org.slf4j.LoggerFactory; @PluginDescriptor( loadWhenOutdated = true, // prevent users from disabling @@ -57,10 +54,7 @@ import org.slf4j.LoggerFactory; public class OpenOSRSPlugin extends Plugin { @Inject - private OpenOSRSConfig config; - - @Inject - private KeyManager keyManager; + private ConfigManager configManager; @Nullable @Inject @@ -71,23 +65,6 @@ public class OpenOSRSPlugin extends Plugin private NavigationButton navButton; - private final HotkeyListener hotkeyListener = new HotkeyListener(() -> this.keybind) - { - @Override - public void hotkeyPressed() - { - if (client == null) - { - return; - } - detach = !detach; - client.setOculusOrbState(detach ? 1 : 0); - client.setOculusOrbNormalSpeed(detach ? 36 : 12); - } - }; - private boolean detach; - private Keybind keybind; - @Override protected void startUp() { @@ -107,9 +84,6 @@ public class OpenOSRSPlugin extends Plugin .panel(panel) .build(); clientToolbar.addNavigation(navButton); - - this.keybind = config.detachHotkey(); - keyManager.registerKeyListener(hotkeyListener); } @Override @@ -122,20 +96,17 @@ public class OpenOSRSPlugin extends Plugin } @Subscribe - private void onConfigChanged(ConfigChanged event) + protected void onConfigChanged(ConfigChanged event) { - if (!event.getGroup().equals("openosrs")) + if (OS.getOs() == OS.OSType.MacOS && event.getGroup().equals("openosrs") && event.getKey().equals("disableHw")) { - return; - } + boolean disableHw = configManager.getConfiguration("openosrs", "disableHw", Boolean.class); - this.keybind = config.detachHotkey(); - - if (event.getKey().equals("shareLogs") && !config.shareLogs()) - { - final Logger logger = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME); - logger.detachAppender("Sentry"); + if (disableHw) + { + JOptionPane.showMessageDialog(ClientUI.getFrame(), "You can't disable hardware acceleration on MacOS", "Critical situation prevented", JOptionPane.ERROR_MESSAGE); + configManager.setConfiguration("openosrs", "disableHw", false); + } } } - } \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java index 4df9504c89..43c9489e4d 100644 --- a/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java +++ b/runelite-client/src/main/java/net/runelite/client/ui/ClientUI.java @@ -37,15 +37,20 @@ import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.GraphicsConfiguration; import java.awt.GraphicsDevice; +import static java.awt.GraphicsDevice.WindowTranslucency.TRANSLUCENT; import java.awt.GraphicsEnvironment; import java.awt.LayoutManager; import java.awt.Rectangle; import java.awt.Toolkit; import java.awt.TrayIcon; +import java.awt.Window; import java.awt.event.MouseEvent; import java.awt.event.WindowAdapter; import java.awt.event.WindowEvent; import java.awt.image.BufferedImage; +import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.lang.reflect.Method; import java.time.Duration; import javax.annotation.Nullable; import javax.inject.Inject; @@ -107,9 +112,12 @@ import org.pushingpixels.substance.internal.utils.SubstanceTitlePaneUtilities; public class ClientUI { private static final String CONFIG_GROUP = "runelite"; + private static final String OPENOSRS_CONFIG_GROUP = "openosrs"; private static final String CONFIG_CLIENT_BOUNDS = "clientBounds"; private static final String CONFIG_CLIENT_MAXIMIZED = "clientMaximized"; private static final String CONFIG_CLIENT_SIDEBAR_CLOSED = "clientSidebarClosed"; + private static final String CONFIG_OPACITY = "enableOpacity"; + private static final String CONFIG_OPACITY_AMOUNT = "opacityPercentage"; public static final BufferedImage ICON = ImageUtil.loadImageResource(ClientUI.class, "/openosrs.png"); @Getter @@ -147,6 +155,9 @@ public class ClientUI private JButton sidebarNavigationJButton; private Dimension lastClientSize; private Cursor defaultCursor; + private Field opacityField; + private Field peerField; + private Method setOpacityMethod; @Inject private ClientUI( @@ -174,7 +185,10 @@ public class ClientUI @Subscribe public void onConfigChanged(ConfigChanged event) { - if (!event.getGroup().equals(CONFIG_GROUP) || + if (!event.getGroup().equals(CONFIG_GROUP) + && !(event.getGroup().equals(OPENOSRS_CONFIG_GROUP) + && event.getKey().equals(CONFIG_OPACITY) || + event.getKey().equals(CONFIG_OPACITY_AMOUNT)) || event.getKey().equals(CONFIG_CLIENT_MAXIMIZED) || event.getKey().equals(CONFIG_CLIENT_BOUNDS)) { @@ -1113,6 +1127,26 @@ public class ClientUI configManager.unsetConfiguration(CONFIG_GROUP, CONFIG_CLIENT_BOUNDS); } + if (configManager.getConfiguration(OPENOSRS_CONFIG_GROUP, CONFIG_OPACITY, boolean.class)) + { + GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment(); + GraphicsDevice gd = ge.getDefaultScreenDevice(); + + if (gd.isWindowTranslucencySupported(TRANSLUCENT)) + { + setOpacity(); + } + else + { + log.warn("Opacity isn't supported on your system!"); + configManager.setConfiguration(OPENOSRS_CONFIG_GROUP, CONFIG_OPACITY, false); + } + } + else if (frame.getOpacity() != 1F) + { + frame.setOpacity(1F); + } + if (client == null) { return; @@ -1162,4 +1196,41 @@ public class ClientUI configManager.setConfiguration(CONFIG_GROUP, CONFIG_CLIENT_BOUNDS, bounds); } } + + private void setOpacity() + { + SwingUtilities.invokeLater(() -> + { + try + { + if (opacityField == null) + { + opacityField = Window.class.getDeclaredField("opacity"); + opacityField.setAccessible(true); + } + if (peerField == null) + { + peerField = Component.class.getDeclaredField("peer"); + peerField.setAccessible(true); + } + if (setOpacityMethod == null) + { + setOpacityMethod = Class.forName("java.awt.peer.WindowPeer").getDeclaredMethod("setOpacity", float.class); + } + + + final float opacity = Float.parseFloat(configManager.getConfiguration(OPENOSRS_CONFIG_GROUP, CONFIG_OPACITY_AMOUNT)) / 100F; + assert opacity > 0F && opacity <= 1F : "I don't know who you are, I don't know why you tried, and I don't know how you tried, but this is NOT what you're supposed to do and you should honestly feel terrible about what you did, so I want you to take a nice long amount of time to think about what you just tried to do so you are not gonna do this in the future."; + + opacityField.setFloat(frame, opacity); + setOpacityMethod.invoke(peerField.get(frame), opacity); + + } + catch (NoSuchFieldException | NoSuchMethodException | ClassNotFoundException | IllegalAccessException | + InvocationTargetException e) + { + e.printStackTrace(); + } + }); + } } diff --git a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java index 01f81d46ca..90b7628fe6 100644 --- a/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java +++ b/runelite-mixins/src/main/java/net/runelite/mixins/RSNPCMixin.java @@ -149,7 +149,8 @@ public abstract class RSNPCMixin implements RSNPC || this.getId() == NpcID.TREE_SPIRIT && this.getAnimation() == AnimationID.IDLE || this.getId() == NpcID.TREE_SPIRIT_6380 && this.getAnimation() == AnimationID.IDLE || this.getId() == NpcID.TREE_SPIRIT_HARD && this.getAnimation() == AnimationID.IDLE - ) { + ) + { return copy$getModel(); } int actionFrame = getActionFrame();