diff --git a/.github/workflows/gradle.yml b/.github/workflows/gradle.yml index e9cb4f3619..8d16f9b50c 100644 --- a/.github/workflows/gradle.yml +++ b/.github/workflows/gradle.yml @@ -26,25 +26,3 @@ jobs: body: This is an auto-generated PR with an updated gradle version labels: automated-pull-request, gradle signoff: false - - update-dependencies: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v2.3.4 - - name: Make gradlew executable - run: chmod +x ./gradlew - - name: Update Gradle Dependencies - run: ./gradlew useLatestVersions --console=plain - - name: Create Gradle dependencies update Pull Request - uses: peter-evans/create-pull-request@v3.4.1 - with: - token: ${{ secrets.OpenOSRS }} - author: OpenOSRS - committer: OpenOSRS - branch: GRADLE-DEPS-UPDATE - commit-message: 'gradle: Update gradle dependencies' - title: 'gradle: Update gradle dependencies' - body: This is an auto-generated PR with an updated gradle dependencies - labels: automated-pull-request, gradle - signoff: false diff --git a/build.gradle.kts b/build.gradle.kts index 74c9e1bbd8..016a6f6dcf 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -23,7 +23,6 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ -import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask import org.ajoberstar.grgit.Grgit buildscript { @@ -35,14 +34,10 @@ buildscript { } dependencies { classpath("org.ajoberstar.grgit:grgit-core:4.1.0") - classpath("com.github.ben-manes:gradle-versions-plugin:0.36.0") } } plugins { - id("com.adarshr.test-logger") version "2.1.1" apply false - id("com.github.ben-manes.versions") version "0.36.0" - id("se.patrikerdes.use-latest-versions") version "0.2.15" id("org.ajoberstar.grgit") version "4.1.0" application @@ -55,12 +50,6 @@ val localGitCommit = try { "n/a" } -fun isNonStable(version: String): Boolean { - return listOf("ALPHA", "BETA", "RC").any { - version.toUpperCase().contains(it) - } -} - allprojects { group = "com.openosrs" version = ProjectVersions.openosrsVersion @@ -112,7 +101,6 @@ subprojects { } filter { includeModule("net.runelite", "fernflower") - includeModule("com.openosrs.rxrelay3", "rxrelay") } } @@ -121,9 +109,6 @@ subprojects { apply() //apply() - apply(plugin = "com.adarshr.test-logger") - apply(plugin = "com.github.ben-manes.versions") - apply(plugin = "se.patrikerdes.use-latest-versions") project.extra["gitCommit"] = localGitCommit project.extra["rootPath"] = rootDir.toString().replace("\\", "/") @@ -185,27 +170,13 @@ subprojects { exclude("**/LayoutSolver.java") exclude("**/RoomType.java") } - - named("dependencyUpdates") { - checkForGradleUpdate = false - - resolutionStrategy { - componentSelection { - all { - if (candidate.displayName.contains("fernflower") || isNonStable(candidate.version)) { - reject("Non stable") - } - } - } - } - } } configurations["compileOnly"].extendsFrom(configurations["annotationProcessor"]) } application { - mainClassName = "net.runelite.client.RuneLite" + mainClass.set("net.runelite.client.RuneLite") } tasks { @@ -215,18 +186,4 @@ tasks { classpath = project(":runelite-client").sourceSets.main.get().runtimeClasspath enableAssertions = true } - - named("dependencyUpdates") { - checkForGradleUpdate = false - - resolutionStrategy { - componentSelection { - all { - if (candidate.displayName.contains("fernflower") || isNonStable(candidate.version)) { - reject("Non stable") - } - } - } - } - } } diff --git a/deobfuscator/deobfuscator.gradle.kts b/deobfuscator/deobfuscator.gradle.kts index 62da0b0dca..25b6ae3e94 100644 --- a/deobfuscator/deobfuscator.gradle.kts +++ b/deobfuscator/deobfuscator.gradle.kts @@ -35,23 +35,23 @@ dependencies { deobjars(group = "net.runelite.rs", name = "vanilla", version = ProjectVersions.rsversion.toString()) deobjars(project(":runescape-client")) - annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.16") + annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.4") + implementation(project(":runelite-api")) + implementation(project(":runescape-api")) implementation(group = "org.jetbrains", name = "annotations", version = "20.1.0") implementation(group = "org.ow2.asm", name = "asm", version = "9.0") implementation(group = "org.ow2.asm", name = "asm-util", version = "9.0") implementation(group = "net.runelite", name = "fernflower", version = "07082019") implementation(group = "com.google.code.gson", name = "gson", version = "2.8.6") - implementation(group = "com.google.guava", name = "guava", version = "30.0-jre") - implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") - implementation(project(":runelite-api")) - implementation(project(":runescape-api")) + implementation(group = "com.google.guava", name = "guava", version = "23.2-jre") + implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") - runtimeOnly(group = "org.slf4j", name = "slf4j-simple", version = "1.7.30") + runtimeOnly(group = "org.slf4j", name = "slf4j-simple", version = "1.7.12") testImplementation(deobjars) - testImplementation(group = "junit", name = "junit", version = "4.13.1") - testImplementation(group = "org.mockito", name = "mockito-core", version = "3.6.0") + testImplementation(group = "junit", name = "junit", version = "4.12") + testImplementation(group = "org.mockito", name = "mockito-core", version = "3.1.0") } tasks { diff --git a/http-api/http-api.gradle.kts b/http-api/http-api.gradle.kts index 642dd7bf0b..0ccafa95e5 100644 --- a/http-api/http-api.gradle.kts +++ b/http-api/http-api.gradle.kts @@ -28,21 +28,20 @@ import org.apache.tools.ant.filters.ReplaceTokens description = "Web API" dependencies { - annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.16") + annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.4") - compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.16") + compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.4") - implementation(group = "com.google.code.gson", name = "gson", version = "2.8.6") - implementation(group = "com.google.guava", name = "guava", version = "30.0-jre") - implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "4.9.0") - implementation(group = "io.reactivex.rxjava3", name = "rxjava", version = "3.0.7") - implementation(group = "org.apache.commons", name = "commons-csv", version = "1.8") - implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") implementation(project(":runelite-api")) + implementation(group = "com.google.code.gson", name = "gson", version = "2.8.5") + implementation(group = "com.google.guava", name = "guava", version = "23.2-jre") + implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "3.7.0") + implementation(group = "org.apache.commons", name = "commons-csv", version = "1.4") + implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") testImplementation(group = "com.squareup.okhttp3", name = "mockwebserver", version = "4.9.0") - testImplementation(group = "junit", name = "junit", version = "4.13.1") - testImplementation(group = "org.slf4j", name = "slf4j-simple", version = "1.7.30") + testImplementation(group = "junit", name = "junit", version = "4.12") + testImplementation(group = "org.slf4j", name = "slf4j-simple", version = "1.7.12") } tasks { diff --git a/injector/injector.gradle.kts b/injector/injector.gradle.kts index 00c2bb7d3f..d99d51cf46 100644 --- a/injector/injector.gradle.kts +++ b/injector/injector.gradle.kts @@ -13,18 +13,21 @@ plugins { dependencies { vanillaDep(group = "net.runelite.rs", name = "vanilla", version = rsversion.toString()) - implementation(gradleApi()) - annotationProcessor("org.projectlombok:lombok:1.18.12") - compileOnly("org.projectlombok:lombok:1.18.12") + annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.4") + + compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.4") + + implementation(gradleApi()) - implementation("org.ow2.asm:asm:8.0.1") - implementation("org.ow2.asm:asm-util:8.0.1") - implementation("org.jetbrains:annotations:19.0.0") - implementation("com.google.guava:guava:29.0-jre") implementation(project(":deobfuscator")) implementation(project(":runescape-api")) implementation(project(":runescape-client")) implementation(project(":runelite-mixins")) + + implementation(group = "org.ow2.asm", name = "asm", version = "8.0.1") + implementation(group = "org.ow2.asm", name = "asm-util", version = "8.0.1") + implementation(group = "org.jetbrains", name = "annotations", version = "19.0.0") + implementation(group = "com.google.guava", name = "guava", version = "23.2-jre") } tasks.register("inject") { diff --git a/runelite-api/runelite-api.gradle.kts b/runelite-api/runelite-api.gradle.kts index 9cb15fe98d..3f24b5b9d5 100644 --- a/runelite-api/runelite-api.gradle.kts +++ b/runelite-api/runelite-api.gradle.kts @@ -26,14 +26,14 @@ description = "RuneLite API" dependencies { - annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.16") + annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.4") - compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.16") + compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.4") implementation(group = "com.google.code.findbugs", name = "jsr305", version = "3.0.2") - implementation(group = "com.google.guava", name = "guava", version = "30.0-jre") - implementation(group = "org.apache.commons", name = "commons-text", version = "1.9") - implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") + implementation(group = "com.google.guava", name = "guava", version = "23.2-jre") + implementation(group = "org.apache.commons", name = "commons-text", version = "1.2") + implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") - testImplementation(group = "junit", name = "junit", version = "4.13.1") + testImplementation(group = "junit", name = "junit", version = "4.12") } \ No newline at end of file diff --git a/runelite-client/runelite-client.gradle.kts b/runelite-client/runelite-client.gradle.kts index cfc8667c28..adc413c31c 100644 --- a/runelite-client/runelite-client.gradle.kts +++ b/runelite-client/runelite-client.gradle.kts @@ -43,50 +43,46 @@ apply() description = "RuneLite Client" dependencies { - annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.16") + annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.4") annotationProcessor(group = "org.pf4j", name = "pf4j", version = "3.5.0") api(project(":runelite-api")) compileOnly(group = "javax.annotation", name = "javax.annotation-api", version = "1.3.2") - compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.16") + compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.4") compileOnly(group = "net.runelite", name = "orange-extensions", version = "1.0") + implementation(project(":http-api")) implementation(group = "ch.qos.logback", name = "logback-classic", version = "1.2.3") - implementation(group = "com.google.code.gson", name = "gson", version = "2.8.6") - implementation(group = "com.google.guava", name = "guava", version = "30.0-jre") - implementation(group = "com.google.inject", name = "guice", version = "4.2.3", classifier = "no_aop") + implementation(group = "com.google.code.gson", name = "gson", version = "2.8.5") + implementation(group = "com.google.guava", name = "guava", version = "23.2-jre") + implementation(group = "com.google.inject", name = "guice", version = "4.1.0", classifier = "no_aop") implementation(group = "com.h2database", name = "h2", version = "1.4.200") implementation(group = "com.jakewharton.rxrelay3", name = "rxrelay", version = "3.0.0") - implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "4.9.0") - implementation(group = "io.reactivex.rxjava3", name = "rxjava", version = "3.0.7") - implementation(group = "net.java.dev.jna", name = "jna", version = "5.6.0") + implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "3.7.0") + implementation(group = "io.reactivex.rxjava3", name = "rxjava", version = "3.0.10") + implementation(group = "net.java.dev.jna", name = "jna", version = "4.5.1") implementation(group = "org.jgroups", name = "jgroups", version = "5.0.4.Final") - implementation(group = "net.java.dev.jna", name = "jna-platform", version = "5.6.0") - implementation(group = "net.runelite", name = "discord", version = "1.2") - implementation(group = "org.pushing-pixels", name = "radiance-substance", version = "2.5.1") - implementation(group = "net.sf.jopt-simple", name = "jopt-simple", version = "5.0.4") - implementation(group = "org.apache.commons", name = "commons-text", version = "1.9") + implementation(group = "net.java.dev.jna", name = "jna-platform", version = "4.5.1") + implementation(group = "net.runelite", name = "discord", version = "1.4") + implementation(group = "net.runelite.pushingpixels", name = "substance", version = "8.0.02") + implementation(group = "net.sf.jopt-simple", name = "jopt-simple", version = "5.0.1") + implementation(group = "org.apache.commons", name = "commons-text", version = "1.2") implementation(group = "commons-io", name = "commons-io", version = "2.8.0") implementation(group = "org.jetbrains", name = "annotations", version = "20.1.0") - implementation(group = "org.jooq", name = "jooq", version = "3.14.3") - implementation(group = "org.jooq", name = "jooq-codegen", version = "3.14.3") - implementation(group = "org.jooq", name = "jooq-meta", version = "3.14.3") - implementation(group = "io.sentry", name = "sentry-logback", version = "3.1.3") implementation(group = "com.github.zafarkhaja", name = "java-semver", version = "0.9.0") - implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") - implementation(group = "org.pf4j", name = "pf4j", version = "3.5.0") { + implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") + implementation(group = "org.pf4j", name = "pf4j", version = "3.6.0") { exclude(group = "org.slf4j") } implementation(group = "org.pf4j", name = "pf4j-update", version = "2.3.0") implementation(group = "com.google.archivepatcher", name = "archive-patch-applier", version= "1.0.4") - implementation(project(":http-api")) implementation(group = "net.runelite.gluegen", name = "gluegen-rt", version = "2.4.0-rc-20200429") implementation(group = "net.runelite.jogl", name = "jogl-all", version = "2.4.0-rc-20200429") implementation(group = "net.runelite.jocl", name = "jocl", version = "1.0") - runtimeOnly(group = "org.pushing-pixels", name = "radiance-trident", version = "2.5.1") runtimeOnly(project(":runescape-api")) + runtimeOnly(group = "net.runelite.pushingpixels", name = "trident", version = "1.5.00") runtimeOnly(group = "net.runelite.gluegen", name = "gluegen-rt", version = "2.4.0-rc-20200429", classifier = "natives-linux-amd64") runtimeOnly(group = "net.runelite.gluegen", name = "gluegen-rt", version = "2.4.0-rc-20200429", classifier = "natives-windows-amd64") runtimeOnly(group = "net.runelite.gluegen", name = "gluegen-rt", version = "2.4.0-rc-20200429", classifier = "natives-windows-i586") @@ -98,18 +94,18 @@ dependencies { runtimeOnly(group = "net.runelite.jocl", name = "jocl", version = "1.0", classifier = "macos-x64") runtimeOnly(group = "net.runelite.jocl", name = "jocl", version = "1.0", classifier = "macos-arm64") - testAnnotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.16") + testAnnotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.4") - testCompileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.16") + testCompileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.4") - testImplementation(group = "com.google.inject.extensions", name = "guice-grapher", version = "4.2.3") - testImplementation(group = "com.google.inject.extensions", name = "guice-testlib", version = "4.2.3") - testImplementation(group = "org.hamcrest", name = "hamcrest-library", version = "2.2") - testImplementation(group = "junit", name = "junit", version = "4.13.1") - testImplementation(group = "org.mockito", name = "mockito-core", version = "3.6.0") - testImplementation(group = "org.mockito", name = "mockito-inline", version = "3.6.0") - testImplementation(group = "com.squareup.okhttp3", name = "mockwebserver", version = "4.9.0") - testImplementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") + testImplementation(group = "com.google.inject.extensions", name = "guice-grapher", version = "4.1.0") + testImplementation(group = "com.google.inject.extensions", name = "guice-testlib", version = "4.1.0") + testImplementation(group = "org.hamcrest", name = "hamcrest-library", version = "1.3") + testImplementation(group = "junit", name = "junit", version = "4.12") + testImplementation(group = "org.mockito", name = "mockito-core", version = "3.1.0") + testImplementation(group = "org.mockito", name = "mockito-inline", version = "3.1.0") + testImplementation(group = "com.squareup.okhttp3", name = "mockwebserver", version = "3.7.0") + testImplementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") } fun formatDate(date: Date?) = with(date ?: Date()) { diff --git a/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java b/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java index 4d64898bce..53e83b4869 100644 --- a/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java +++ b/runelite-client/src/main/java/com/openosrs/client/OpenOSRS.java @@ -1,22 +1,28 @@ package com.openosrs.client; +import com.google.common.base.Strings; import java.io.File; import java.io.IOException; import java.util.Properties; import java.util.UUID; +import lombok.AccessLevel; +import lombok.Getter; public class OpenOSRS { public static final File OPENOSRS_DIR = new File(System.getProperty("user.home"), ".openosrs"); public static final File EXTERNALPLUGIN_DIR = new File(OPENOSRS_DIR, "plugins"); + public static final String PLUGIN_DEVELOPMENT_PATH = "plugin.development.path"; public static final String SYSTEM_VERSION; public static final String SYSTEM_API_VERSION; + @Getter(AccessLevel.PACKAGE) + private static final Properties properties = new Properties(); + public static String uuid = UUID.randomUUID().toString(); static { - Properties properties = new Properties(); try { properties.load(OpenOSRS.class.getResourceAsStream("/openosrs.properties")); @@ -25,10 +31,25 @@ public class OpenOSRS { e.printStackTrace(); } + SYSTEM_VERSION = properties.getProperty("oprs.version", "0.0.0"); SYSTEM_API_VERSION = properties.getProperty("oprs.api.version"); } + public static String[] getPluginDevelopmentPath() + { + // First check if property supplied as environment variable PLUGIN_DEVELOPMENT_PATHS + String developmentPluginPaths = System.getenv(PLUGIN_DEVELOPMENT_PATH.replace('.', '_').toUpperCase()); + + if (Strings.isNullOrEmpty(developmentPluginPaths)) + { + // Otherwise check the property file + developmentPluginPaths = properties.getProperty(PLUGIN_DEVELOPMENT_PATH); + } + + return Strings.isNullOrEmpty(developmentPluginPaths) ? new String[0] : developmentPluginPaths.split(";"); + } + public static void preload() { } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java index b234e756d6..19554fad18 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigDescriptor.java @@ -32,12 +32,14 @@ public class ConfigDescriptor { private final ConfigGroup group; private final Collection sections; + private final Collection titles; private final Collection items; - public ConfigDescriptor(ConfigGroup group, Collection sections, Collection items) + public ConfigDescriptor(ConfigGroup group, Collection sections, Collection titles, Collection items) { this.group = group; this.sections = sections; + this.titles = titles; this.items = items; } } diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java index f56aad7934..182a03f4ae 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigItem.java @@ -49,6 +49,8 @@ public @interface ConfigItem String section() default ""; + String title() default ""; + boolean parse() default false; Class clazz() default void.class; diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java index 42a6d4e965..8890bdc49b 100644 --- a/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigManager.java @@ -56,6 +56,8 @@ import java.time.Instant; import java.util.ArrayList; import java.util.Arrays; import java.util.Base64; +import java.util.Collection; +import java.util.Collections; import java.util.Date; import java.util.HashMap; import java.util.HashSet; @@ -65,6 +67,7 @@ import java.util.Map; import java.util.Objects; import java.util.Properties; import java.util.Set; +import java.util.Stack; import java.util.concurrent.CompletableFuture; import java.util.concurrent.Future; import java.util.concurrent.ScheduledExecutorService; @@ -647,6 +650,30 @@ public class ConfigManager .result()) .collect(Collectors.toList()); + final List titles = Arrays.stream(inter.getDeclaredFields()) + .filter(m -> m.isAnnotationPresent(ConfigTitle.class) && m.getType() == String.class) + .map(m -> + { + try + { + return new ConfigTitleDescriptor( + String.valueOf(m.get(inter)), + m.getDeclaredAnnotation(ConfigTitle.class) + ); + } + catch (IllegalAccessException e) + { + log.warn("Unable to load title {}::{}", inter.getSimpleName(), m.getName()); + return null; + } + }) + .filter(Objects::nonNull) + .sorted((a, b) -> ComparisonChain.start() + .compare(a.getTitle().position(), b.getTitle().position()) + .compare(a.getTitle().name(), b.getTitle().name()) + .result()) + .collect(Collectors.toList()); + final List items = Arrays.stream(inter.getMethods()) .filter(m -> m.getParameterCount() == 0 && m.isAnnotationPresent(ConfigItem.class)) .map(m -> new ConfigItemDescriptor( @@ -662,7 +689,7 @@ public class ConfigManager .result()) .collect(Collectors.toList()); - return new ConfigDescriptor(group, sections, items); + return new ConfigDescriptor(group, sections, titles, items); } /** @@ -680,7 +707,7 @@ public class ConfigManager return; } - for (Method method : clazz.getDeclaredMethods()) + for (Method method : getAllDeclaredInterfaceMethods(clazz)) { ConfigItem item = method.getAnnotation(ConfigItem.class); @@ -868,6 +895,25 @@ public class ConfigManager return object == null ? null : object.toString(); } + /** + * Does DFS on a class's interfaces to find all of its implemented methods. + */ + private Collection getAllDeclaredInterfaceMethods(Class clazz) + { + Collection methods = new HashSet<>(); + Stack> interfazes = new Stack<>(); + interfazes.push(clazz); + + while (!interfazes.isEmpty()) + { + Class interfaze = interfazes.pop(); + Collections.addAll(methods, interfaze.getDeclaredMethods()); + Collections.addAll(interfazes, interfaze.getInterfaces()); + } + + return methods; + } + @Subscribe(priority = 100) private void onClientShutdown(ClientShutdown e) { diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigTitle.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitle.java new file mode 100644 index 0000000000..649beae4a0 --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitle.java @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2019, Hydrox6 + * 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.config; + +import java.lang.annotation.ElementType; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; + +@Retention(RetentionPolicy.RUNTIME) +@Target(ElementType.FIELD) +public @interface ConfigTitle +{ + String name(); + + String description(); + + int position(); + + String title() default ""; + + /* + OpenOSRS Lazy Helpers tm + */ + String keyName() default ""; + String section() default ""; + boolean hidden() default false; + String unhide() default ""; +} diff --git a/runelite-client/src/main/java/net/runelite/client/config/ConfigTitleDescriptor.java b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitleDescriptor.java new file mode 100644 index 0000000000..17413d574d --- /dev/null +++ b/runelite-client/src/main/java/net/runelite/client/config/ConfigTitleDescriptor.java @@ -0,0 +1,52 @@ +/* + * Copyright (c) 2020, Hydrox6 + * 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.config; + +import lombok.Value; + +@Value +public class ConfigTitleDescriptor implements ConfigObject +{ + private final String key; + private final ConfigTitle title; + + @Override + public String key() + { + return key; + } + + @Override + public String name() + { + return title.name(); + } + + @Override + public int position() + { + return title.position(); + } +} \ No newline at end of file diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java index 30abbfa8eb..cbbe334f48 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPf4jPluginManager.java @@ -5,6 +5,7 @@ import java.io.Closeable; import java.io.IOException; import java.nio.file.Files; import java.nio.file.Path; +import java.nio.file.Paths; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -19,6 +20,7 @@ import org.pf4j.CompoundPluginLoader; import org.pf4j.CompoundPluginRepository; import org.pf4j.DefaultPluginManager; import org.pf4j.DependencyResolver; +import org.pf4j.DevelopmentPluginRepository; import org.pf4j.JarPluginLoader; import org.pf4j.JarPluginRepository; import org.pf4j.ManifestPluginDescriptorFinder; @@ -35,12 +37,9 @@ import org.pf4j.RuntimeMode; @Slf4j class OPRSExternalPf4jPluginManager extends DefaultPluginManager { - private final OPRSExternalPluginManager externalPluginManager; - - public OPRSExternalPf4jPluginManager(OPRSExternalPluginManager externalPluginManager) + public OPRSExternalPf4jPluginManager() { super(OpenOSRS.EXTERNALPLUGIN_DIR.toPath()); - this.externalPluginManager = externalPluginManager; } @Override @@ -68,8 +67,30 @@ class OPRSExternalPf4jPluginManager extends DefaultPluginManager { CompoundPluginRepository compoundPluginRepository = new CompoundPluginRepository(); - JarPluginRepository jarPluginRepository = new JarPluginRepository(getPluginsRoot()); - compoundPluginRepository.add(jarPluginRepository); + if (isNotDevelopment()) + { + JarPluginRepository jarPluginRepository = new JarPluginRepository(getPluginsRoot()); + compoundPluginRepository.add(jarPluginRepository); + } + + if (isDevelopment()) + { + for (String developmentPluginPath : OpenOSRS.getPluginDevelopmentPath()) + { + DevelopmentPluginRepository developmentPluginRepository = new DevelopmentPluginRepository(Paths.get(developmentPluginPath)) + { + @Override + public boolean deletePluginPath(Path pluginPath) + { + // Do nothing, because we'd be deleting our sources! + return filter.accept(pluginPath.toFile()); + } + }; + + developmentPluginRepository.setFilter(new OPRSExternalPluginFileFilter()); + compoundPluginRepository.add(developmentPluginRepository); + } + } return compoundPluginRepository; } @@ -121,6 +142,12 @@ class OPRSExternalPf4jPluginManager extends DefaultPluginManager { if (!(e instanceof PluginAlreadyLoadedException)) { + if (!OPRSExternalPluginManager.isDevelopmentMode()) + { + String plugin = pluginPath.toString().substring(pluginsRoots.get(0).toString().length() + 1); + duplicatePlugins.add(plugin); + } + log.error("Could not load plugin {}", pluginPath, e); } } @@ -220,7 +247,7 @@ class OPRSExternalPf4jPluginManager extends DefaultPluginManager @Override public RuntimeMode getRuntimeMode() { - return RuntimeMode.DEPLOYMENT; + return OPRSExternalPluginManager.isDevelopmentMode() ? RuntimeMode.DEVELOPMENT : RuntimeMode.DEPLOYMENT; } @Override diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java index dd6c86d1ee..81c63f272d 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/OPRSExternalPluginManager.java @@ -33,6 +33,7 @@ import com.google.inject.CreationException; import com.google.inject.Injector; import com.google.inject.Key; import com.google.inject.Module; +import com.openosrs.client.OpenOSRS; import static com.openosrs.client.OpenOSRS.EXTERNALPLUGIN_DIR; import static com.openosrs.client.OpenOSRS.SYSTEM_API_VERSION; import com.openosrs.client.config.OpenOSRSConfig; @@ -108,6 +109,8 @@ public class OPRSExternalPluginManager private final ConfigManager configManager; private final Map pluginsMap = new HashMap<>(); @Getter(AccessLevel.PUBLIC) + private static final boolean developmentMode = OpenOSRS.getPluginDevelopmentPath().length > 0; + @Getter(AccessLevel.PUBLIC) private final Map> pluginsInfoMap = new HashMap<>(); private final Groups groups; @Getter(AccessLevel.PUBLIC) @@ -143,7 +146,7 @@ public class OPRSExternalPluginManager private void initPluginManager() { - externalPluginManager = new OPRSExternalPf4jPluginManager(this); + externalPluginManager = new OPRSExternalPf4jPluginManager(); externalPluginManager.setSystemVersion(SYSTEM_API_VERSION); } @@ -826,29 +829,39 @@ public class OPRSExternalPluginManager try { - PluginInfo.PluginRelease latest = updateManager.getLastPluginRelease(pluginId); - - // Null version returns the last release version of this plugin for given system version - if (latest == null) + if (!developmentMode) { - try + PluginInfo.PluginRelease latest = updateManager.getLastPluginRelease(pluginId); + + // Null version returns the last release version of this plugin for given system version + if (latest == null) { - SwingUtil.syncExec(() -> - JOptionPane.showMessageDialog(ClientUI.getFrame(), - pluginId + " is outdated and cannot be installed", - "Installation error", - JOptionPane.ERROR_MESSAGE)); - } - catch (InvocationTargetException | InterruptedException ignored) - { - return false; + try + { + SwingUtil.syncExec(() -> + JOptionPane.showMessageDialog(ClientUI.getFrame(), + pluginId + " is outdated and cannot be installed", + "Installation error", + JOptionPane.ERROR_MESSAGE)); + } + catch (InvocationTargetException | InterruptedException ignored) + { + return false; + } + + return true; } - return true; + updateManager.installPlugin(pluginId, null); + scanAndInstantiate(loadPlugin(pluginId), true, true); + } + else + { + // In development mode our plugin will already be present in a repository, so we can just load it + externalPluginManager.loadPlugins(); + externalPluginManager.startPlugin(pluginId); } - updateManager.installPlugin(pluginId, null); - scanAndInstantiate(loadPlugin(pluginId), true, true); ExternalPluginsChanged event = new ExternalPluginsChanged(null); eventBus.post(event); groups.broadcastSring("STARTEXTERNAL;" + pluginId); @@ -908,6 +921,11 @@ public class OPRSExternalPluginManager log.info("Not updating external plugins since there is more than 1 client open"); return; } + else if (developmentMode) + { + log.info("Not updating because we're running in developer mode"); + return; + } OpenOSRSSplashScreen.stage(.59, "Updating external plugins"); diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java index 4ba0bde255..46a68d4ea3 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/ConfigPanel.java @@ -27,10 +27,15 @@ package net.runelite.client.plugins.config; import com.google.common.base.Strings; import com.google.common.collect.ComparisonChain; import com.google.common.primitives.Ints; +import java.awt.BasicStroke; import java.awt.BorderLayout; import java.awt.Color; import java.awt.Component; import java.awt.Dimension; +import java.awt.Font; +import java.awt.Graphics; +import java.awt.Graphics2D; +import java.awt.GridLayout; import java.awt.event.FocusAdapter; import java.awt.event.FocusEvent; import java.awt.event.ItemEvent; @@ -56,6 +61,7 @@ import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPasswordField; import javax.swing.JScrollPane; +import javax.swing.JSeparator; import javax.swing.JSpinner; import javax.swing.JTextArea; import javax.swing.ScrollPaneConstants; @@ -79,6 +85,8 @@ import net.runelite.client.config.ConfigManager; import net.runelite.client.config.ConfigObject; import net.runelite.client.config.ConfigSection; import net.runelite.client.config.ConfigSectionDescriptor; +import net.runelite.client.config.ConfigTitle; +import net.runelite.client.config.ConfigTitleDescriptor; import net.runelite.client.config.Keybind; import net.runelite.client.config.ModifierlessKeybind; import net.runelite.client.config.Range; @@ -89,6 +97,7 @@ import net.runelite.client.events.ExternalPluginsChanged; import net.runelite.client.events.PluginChanged; import net.runelite.client.externalplugins.ExternalPluginManager; import net.runelite.client.externalplugins.ExternalPluginManifest; +import net.runelite.client.plugins.OPRSExternalPluginManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginManager; import net.runelite.client.ui.ColorScheme; @@ -102,6 +111,7 @@ import net.runelite.client.ui.components.colorpicker.RuneliteColorPicker; import net.runelite.client.util.ColorUtil; import net.runelite.client.util.DeferredDocumentChangedListener; import net.runelite.client.util.ImageUtil; +import net.runelite.client.util.LinkBrowser; import net.runelite.client.util.SwingUtil; import net.runelite.client.util.Text; @@ -134,6 +144,9 @@ class ConfigPanel extends PluginPanel @Inject private ExternalPluginManager externalPluginManager; + @Inject + private OPRSExternalPluginManager oprsExternalPluginManager; + @Inject private ColorPickerManager colorPickerManager; @@ -259,7 +272,55 @@ class ConfigPanel extends PluginPanel ConfigDescriptor cd = pluginConfig.getConfigDescriptor(); + Map> pluginsInfoMap = oprsExternalPluginManager.getPluginsInfoMap(); + + if (pluginConfig.getPlugin() != null && pluginsInfoMap.containsKey(pluginConfig.getPlugin().getClass().getSimpleName())) + { + + JPanel infoPanel = new JPanel(); + infoPanel.setBackground(ColorScheme.DARKER_GRAY_COLOR); + infoPanel.setBorder(new EmptyBorder(10, 10, 10, 10)); + infoPanel.setLayout(new GridLayout(0, 1)); + + final Font smallFont = FontManager.getRunescapeSmallFont(); + + Map pluginInfo = pluginsInfoMap.get(pluginConfig.getPlugin().getClass().getSimpleName()); + + JLabel idLabel = new JLabel(htmlLabel("id", pluginInfo.get("id"))); + idLabel.setFont(smallFont); + infoPanel.add(idLabel); + + JLabel versionLabel = new JLabel(htmlLabel("version", pluginInfo.get("version"))); + versionLabel.setFont(smallFont); + infoPanel.add(versionLabel); + + JLabel providerLabel = new JLabel(htmlLabel("provider", pluginInfo.get("provider"))); + providerLabel.setFont(smallFont); + infoPanel.add(providerLabel); + + JButton button = new JButton("Support"); + button.addActionListener(e -> LinkBrowser.browse(pluginInfo.get("support"))); + + JSeparator separator = new JSeparator() + { + @Override + protected void paintComponent(Graphics g) + { + int width = this.getSize().width; + Graphics2D g2 = (Graphics2D) g; + g2.setStroke(new BasicStroke(2)); + g2.setColor(ColorScheme.BRAND_BLUE); + g2.drawLine(0, 0, width, 0); + } + }; + + mainPanel.add(infoPanel); + mainPanel.add(button); + mainPanel.add(separator); + } + final Map sectionWidgets = new HashMap<>(); + final Map titleWidgets = new HashMap<>(); final Map topLevelPanels = new TreeMap<>((a, b) -> ComparisonChain.start() .compare(a.position(), b.position()) @@ -327,6 +388,53 @@ class ConfigPanel extends PluginPanel topLevelPanels.put(csd, section); } + for (ConfigTitleDescriptor ctd : cd.getTitles()) + { + ConfigTitle ct = ctd.getTitle(); + final JPanel title = new JPanel(); + title.setLayout(new BoxLayout(title, BoxLayout.Y_AXIS)); + title.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + + final JPanel sectionHeader = new JPanel(); + sectionHeader.setLayout(new BorderLayout()); + sectionHeader.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + + title.add(sectionHeader, BorderLayout.NORTH); + + String name = ct.name(); + final JLabel sectionName = new JLabel(name); + sectionName.setForeground(ColorScheme.BRAND_ORANGE); + sectionName.setFont(FontManager.getRunescapeBoldFont()); + sectionName.setToolTipText("" + name + ":
" + ct.description() + ""); + sectionName.setBorder(new EmptyBorder(0, 0, 3, 1)); + sectionHeader.add(sectionName, BorderLayout.CENTER); + + final JPanel sectionContents = new JPanel(); + sectionContents.setLayout(new DynamicGridLayout(0, 1, 0, 5)); + sectionContents.setMinimumSize(new Dimension(PANEL_WIDTH, 0)); + sectionContents.setBorder(new EmptyBorder(0, 5, 0, 0)); + title.add(sectionContents, BorderLayout.SOUTH); + + titleWidgets.put(ctd.getKey(), sectionContents); + + // Allow for sub-sections + JPanel section = sectionWidgets.get(ct.section()); + JPanel titleSection = titleWidgets.get(ct.title()); + + if (section != null) + { + section.add(title); + } + else if (titleSection != null) + { + titleSection.add(title); + } + else + { + topLevelPanels.put(ctd, title); + } + } + for (ConfigItemDescriptor cid : cd.getItems()) { if (cid.getItem().hidden()) @@ -595,13 +703,19 @@ class ConfigPanel extends PluginPanel } JPanel section = sectionWidgets.get(cid.getItem().section()); - if (section == null) + JPanel title = titleWidgets.get(cid.getItem().title()); + + if (section != null) { - topLevelPanels.put(cid, item); + section.add(item); + } + else if (title != null) + { + title.add(item); } else { - section.add(item); + topLevelPanels.put(cid, item); } } @@ -769,4 +883,9 @@ class ConfigPanel extends PluginPanel }); return menuItem; } + + private static String htmlLabel(String key, String value) + { + return "" + key + ": " + value + ""; + } } diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java index 767fddbc1a..6c3099fa36 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListItem.java @@ -37,17 +37,23 @@ import java.awt.image.BufferedImage; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Map; import javax.swing.ImageIcon; import javax.swing.JButton; import javax.swing.JLabel; import javax.swing.JMenuItem; +import javax.swing.JOptionPane; import javax.swing.JPanel; import javax.swing.JPopupMenu; import javax.swing.JToggleButton; import javax.swing.SwingUtilities; +import javax.swing.SwingWorker; import javax.swing.border.EmptyBorder; import lombok.Getter; +import net.runelite.client.RuneLiteProperties; import net.runelite.client.externalplugins.ExternalPluginManifest; +import net.runelite.client.plugins.OPRSExternalPluginManager; +import net.runelite.client.ui.ClientUI; import net.runelite.client.ui.ColorScheme; import net.runelite.client.ui.PluginPanel; import net.runelite.client.util.ImageUtil; @@ -57,6 +63,8 @@ class PluginListItem extends JPanel implements SearchablePlugin { private static final ImageIcon CONFIG_ICON; private static final ImageIcon CONFIG_ICON_HOVER; + private static final ImageIcon REFRESH_ICON; + private static final ImageIcon REFRESH_ICON_HOVER; private static final ImageIcon ON_STAR; private static final ImageIcon OFF_STAR; @@ -74,10 +82,13 @@ class PluginListItem extends JPanel implements SearchablePlugin static { BufferedImage configIcon = ImageUtil.loadImageResource(ConfigPanel.class, "config_edit_icon.png"); + BufferedImage refreshIcon = ImageUtil.getResourceStreamFromClass(ConfigPanel.class, "refresh.png"); BufferedImage onStar = ImageUtil.loadImageResource(ConfigPanel.class, "star_on.png"); CONFIG_ICON = new ImageIcon(configIcon); + REFRESH_ICON = new ImageIcon(refreshIcon); ON_STAR = new ImageIcon(onStar); CONFIG_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(configIcon, -100)); + REFRESH_ICON_HOVER = new ImageIcon(ImageUtil.luminanceOffset(refreshIcon, -100)); BufferedImage offStar = ImageUtil.luminanceScale( ImageUtil.grayscaleImage(onStar), @@ -86,7 +97,7 @@ class PluginListItem extends JPanel implements SearchablePlugin OFF_STAR = new ImageIcon(offStar); } - PluginListItem(PluginListPanel pluginListPanel, PluginConfigurationDescriptor pluginConfig) + PluginListItem(PluginListPanel pluginListPanel, PluginConfigurationDescriptor pluginConfig, OPRSExternalPluginManager oprsExternalPluginManager) { this.pluginListPanel = pluginListPanel; this.pluginConfig = pluginConfig; @@ -133,6 +144,60 @@ class PluginListItem extends JPanel implements SearchablePlugin buttonPanel.setLayout(new GridLayout(1, 2)); add(buttonPanel, BorderLayout.LINE_END); + Map> pluginsInfoMap = oprsExternalPluginManager.getPluginsInfoMap(); + + if ((OPRSExternalPluginManager.isDevelopmentMode() || RuneLiteProperties.getLauncherVersion() == null) && pluginConfig.getPlugin() != null && pluginsInfoMap.containsKey(pluginConfig.getPlugin().getClass().getSimpleName())) + { + JButton hotSwapButton = new JButton(REFRESH_ICON); + hotSwapButton.setRolloverIcon(REFRESH_ICON_HOVER); + SwingUtil.removeButtonDecorations(hotSwapButton); + hotSwapButton.setPreferredSize(new Dimension(25, 0)); + hotSwapButton.setVisible(false); + buttonPanel.add(hotSwapButton); + + hotSwapButton.addActionListener(e -> + { + Map pluginInfo = pluginsInfoMap.get(pluginConfig.getPlugin().getClass().getSimpleName()); + String pluginId = pluginInfo.get("id"); + + hotSwapButton.setIcon(REFRESH_ICON); + + new SwingWorker<>() + { + @Override + protected Boolean doInBackground() + { + return oprsExternalPluginManager.uninstall(pluginId); + } + + @Override + protected void done() + { + // In development mode our plugins will be loaded directly from sources, so we don't need to prompt + if (!OPRSExternalPluginManager.isDevelopmentMode()) + { + JOptionPane.showMessageDialog(ClientUI.getFrame(), + pluginId + " is unloaded, put the new jar file in the externalmanager folder and click `ok`", + "Hotswap " + pluginId, + JOptionPane.INFORMATION_MESSAGE); + } + + new SwingWorker<>() + { + @Override + protected Boolean doInBackground() + { + return oprsExternalPluginManager.reloadStart(pluginId); + } + }.execute(); + } + }.execute(); + }); + + hotSwapButton.setVisible(true); + hotSwapButton.setToolTipText("Hotswap plugin"); + } + JMenuItem configMenuItem = null; if (pluginConfig.hasConfigurables()) { diff --git a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java index 286b534877..b4ce131eb7 100644 --- a/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java +++ b/runelite-client/src/main/java/net/runelite/client/plugins/config/PluginListPanel.java @@ -57,6 +57,7 @@ import net.runelite.client.eventbus.Subscribe; import net.runelite.client.events.ExternalPluginsChanged; import net.runelite.client.events.PluginChanged; import net.runelite.client.externalplugins.ExternalPluginManager; +import net.runelite.client.plugins.OPRSExternalPluginManager; import net.runelite.client.plugins.Plugin; import net.runelite.client.plugins.PluginDescriptor; import net.runelite.client.plugins.PluginInstantiationException; @@ -93,6 +94,7 @@ class PluginListPanel extends PluginPanel @Getter private final ExternalPluginManager externalPluginManager; + private final OPRSExternalPluginManager oprsExternalPluginManager; @Getter private final MultiplexingPluginPanel muxer; @@ -107,6 +109,7 @@ class PluginListPanel extends PluginPanel ConfigManager configManager, PluginManager pluginManager, ExternalPluginManager externalPluginManager, + OPRSExternalPluginManager oprsExternalPluginManager, EventBus eventBus, Provider configPanelProvider, Provider pluginHubPanelProvider) @@ -116,6 +119,7 @@ class PluginListPanel extends PluginPanel this.configManager = configManager; this.pluginManager = pluginManager; this.externalPluginManager = externalPluginManager; + this.oprsExternalPluginManager = oprsExternalPluginManager; this.configPanelProvider = configPanelProvider; muxer = new MultiplexingPluginPanel(this) @@ -215,7 +219,7 @@ class PluginListPanel extends PluginPanel ) .map(desc -> { - PluginListItem listItem = new PluginListItem(this, desc); + PluginListItem listItem = new PluginListItem(this, desc, oprsExternalPluginManager); listItem.setPinned(pinnedPlugins.contains(desc.getName())); return listItem; }) diff --git a/runelite-client/src/main/resources/net/runelite/client/plugins/config/refresh.png b/runelite-client/src/main/resources/net/runelite/client/plugins/config/refresh.png new file mode 100644 index 0000000000..cd26305f7a Binary files /dev/null and b/runelite-client/src/main/resources/net/runelite/client/plugins/config/refresh.png differ diff --git a/runelite-mixins/runelite-mixins.gradle.kts b/runelite-mixins/runelite-mixins.gradle.kts index 1fe26ca866..c6227a67b6 100644 --- a/runelite-mixins/runelite-mixins.gradle.kts +++ b/runelite-mixins/runelite-mixins.gradle.kts @@ -14,7 +14,6 @@ * 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 @@ -26,9 +25,9 @@ description = "RuneLite Mixins" dependencies { - compileOnly(group = "com.google.guava", name = "guava", version = "30.0-jre") + compileOnly(group = "com.google.guava", name = "guava", version = "23.2-jre") compileOnly(group = "javax.inject", name = "javax.inject", version = "1") - compileOnly(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") + compileOnly(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") compileOnly(group = "commons-io", name = "commons-io", version = "2.8.0") compileOnly(project(":injection-annotations")) compileOnly(project(":runescape-api")) diff --git a/runelite-script-assembler-plugin/runelite-script-assembler-plugin.gradle.kts b/runelite-script-assembler-plugin/runelite-script-assembler-plugin.gradle.kts index 6f92983453..1f129469dc 100644 --- a/runelite-script-assembler-plugin/runelite-script-assembler-plugin.gradle.kts +++ b/runelite-script-assembler-plugin/runelite-script-assembler-plugin.gradle.kts @@ -32,11 +32,11 @@ dependencies { compileOnly(group = "org.apache.maven.plugin-tools", name = "maven-plugin-annotations", version = "3.6.0") - implementation(group = "com.google.guava", name = "guava", version = "30.0-jre") - implementation(group = "org.apache.maven", name = "maven-plugin-api", version = "3.6.3") - implementation(group = "org.slf4j", name = "slf4j-nop", version = "1.7.30") implementation(project(":cache")) implementation(project(":runelite-api")) + implementation(group = "com.google.guava", name = "guava", version = "23.2-jre") + implementation(group = "org.apache.maven", name = "maven-plugin-api", version = "3.6.3") + implementation(group = "org.slf4j", name = "slf4j-nop", version = "1.7.12") } tasks { diff --git a/runescape-client/runescape-client.gradle.kts b/runescape-client/runescape-client.gradle.kts index b47321710a..f3615cd1bf 100644 --- a/runescape-client/runescape-client.gradle.kts +++ b/runescape-client/runescape-client.gradle.kts @@ -29,9 +29,9 @@ description = "RuneScape Client" dependencies { implementation(project(":injection-annotations")) - testImplementation(group = "junit", name = "junit", version = "4.13.1") - testImplementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") - testImplementation(group = "org.slf4j", name = "slf4j-simple", version = "1.7.30") + testImplementation(group = "junit", name = "junit", version = "4.12") + testImplementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") + testImplementation(group = "org.slf4j", name = "slf4j-simple", version = "1.7.12") } tasks { diff --git a/wiki-scraper/wiki-scraper.gradle.kts b/wiki-scraper/wiki-scraper.gradle.kts index 176544d479..79bdfc0f6b 100644 --- a/wiki-scraper/wiki-scraper.gradle.kts +++ b/wiki-scraper/wiki-scraper.gradle.kts @@ -29,16 +29,16 @@ dependencies { api(project(":cache")) api(project(":runelite-api")) - annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.16") + annotationProcessor(group = "org.projectlombok", name = "lombok", version = "1.18.4") - compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.16") + compileOnly(group = "org.projectlombok", name = "lombok", version = "1.18.4") - implementation(group = "com.google.code.gson", name = "gson", version = "2.8.6") - implementation(group = "com.google.guava", name = "guava", version = "30.0-jre") + implementation(group = "com.google.code.gson", name = "gson", version = "2.8.5") + implementation(group = "com.google.guava", name = "guava", version = "23.2-jre") implementation(group = "com.github.petitparser", name = "java-petitparser", version = "2.3.1") - implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "4.9.0") - implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.30") - implementation(group = "org.slf4j", name = "slf4j-simple", version = "1.7.30") + implementation(group = "com.squareup.okhttp3", name = "okhttp", version = "3.7.0") + implementation(group = "org.slf4j", name = "slf4j-api", version = "1.7.12") + implementation(group = "org.slf4j", name = "slf4j-simple", version = "1.7.12") implementation(group = "org.junit.jupiter", name = "junit-jupiter-api", version = "5.7.0") }