Merge branch 'master' of https://github.com/open-osrs/runelite into spawn
# Conflicts: # runelite-client/src/main/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPlugin.java # runelite-client/src/test/java/net/runelite/client/plugins/npchighlight/NpcIndicatorsPluginTest.java
This commit is contained in:
2
.github/CONTRIBUTING.md
vendored
2
.github/CONTRIBUTING.md
vendored
@@ -54,7 +54,7 @@ Before you submit your pull request consider the following guidelines:
|
||||
* After cloning, set a new remote [upstream](https://help.github.com/articles/configuring-a-remote-for-a-fork/) (this helps to keep your fork up to date)
|
||||
|
||||
```shell
|
||||
git remote add upstream https://github.com/runelite-extended/runelite.git
|
||||
git remote add upstream https://github.com/open-osrs/runelite.git
|
||||
```
|
||||
|
||||
* Make your changes in a new git branch:
|
||||
|
||||
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
2
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
@@ -4,7 +4,7 @@ about: Create a report to help us improve
|
||||
|
||||
---
|
||||
|
||||
Please check if your issue is not a duplicate by [searching existing issues](https://github.com/runelite/runelite/search?type=Issues)
|
||||
Please check if your issue is not a duplicate by [searching existing issues](https://github.com/open-osrs/runelite/search?type=Issues)
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
25
.github/release-drafter.yml
vendored
Normal file
25
.github/release-drafter.yml
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
version-template: '$MAJOR.$MINOR.$PATCH.0'
|
||||
name-template: 'v$NEXT_PATCH_VERSION'
|
||||
tag-template: 'v$NEXT_PATCH_VERSION'
|
||||
exclude-labels:
|
||||
- 'skip-changelog'
|
||||
- 'automated-pull-request'
|
||||
categories:
|
||||
- title: '🚀 Features'
|
||||
labels:
|
||||
- 'feature'
|
||||
- 'enhancement'
|
||||
- title: '🐛 Bug Fixes'
|
||||
labels:
|
||||
- 'fix'
|
||||
- 'bugfix'
|
||||
- 'bug'
|
||||
- title: '🧰 Maintenance'
|
||||
label: 'chore'
|
||||
change-template: '* $TITLE (#$NUMBER) @$AUTHOR'
|
||||
template: |
|
||||
Thanks to: $CONTRIBUTORS
|
||||
|
||||
## Changes
|
||||
|
||||
$CHANGES
|
||||
72
.github/workflows/build.yml
vendored
72
.github/workflows/build.yml
vendored
@@ -1,72 +0,0 @@
|
||||
name: OpenOSRS - CI
|
||||
|
||||
on: [pull_request, push]
|
||||
|
||||
jobs:
|
||||
pr-lint:
|
||||
name: PR title
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: PR title lint
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: seferov/pr-lint-action@master
|
||||
with:
|
||||
title-regex: '^([\w-/]+): \w+'
|
||||
|
||||
build:
|
||||
runs-on: windows-latest
|
||||
name: Build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@master
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: gradlew assemble --console=plain
|
||||
- name: Building
|
||||
run: gradlew build --stacktrace -x test -x checkstyleMain --console=plain
|
||||
|
||||
test:
|
||||
runs-on: windows-latest
|
||||
name: Test
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@master
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: gradlew assemble --console=plain
|
||||
- name: Testing
|
||||
run: gradlew test --stacktrace --console=plain
|
||||
|
||||
checkstyle:
|
||||
name: Checkstyle
|
||||
runs-on: windows-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@master
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: gradlew assemble --console=plain
|
||||
- name: Checking code conventions
|
||||
run: gradlew checkstyleMain --console=plain
|
||||
|
||||
approve:
|
||||
name: Approve
|
||||
needs: [build, test, checkstyle]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Approve pull request
|
||||
if: github.event_name == 'pull_request' && github.actor == 'OpenOSRS'
|
||||
uses: hmarr/auto-approve-action@master
|
||||
with:
|
||||
github-token: "${{ secrets.GITHUB_TOKEN }}"
|
||||
29
.github/workflows/gradle.yml
vendored
29
.github/workflows/gradle.yml
vendored
@@ -9,7 +9,13 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Update Gradle Wrapper
|
||||
@@ -22,23 +28,4 @@ jobs:
|
||||
PULL_REQUEST_TITLE: 'project: Update gradle wrapper'
|
||||
PULL_REQUEST_BODY: This is an auto-generated PR with an updated gradle version
|
||||
COMMIT_MESSAGE: 'project: Update gradle wrapper'
|
||||
PULL_REQUEST_LABELS: automated pull request, gradle
|
||||
|
||||
update-dependencies:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- 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: Owain94/create-pull-request@master
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.OpenOSRS }}
|
||||
PULL_REQUEST_BRANCH: GRADLE-DEPENDENCY-UPDATE
|
||||
PULL_REQUEST_TITLE: 'project: Update gradle dependencies'
|
||||
PULL_REQUEST_BODY: This is an auto-generated PR with an updated gradle dependencies versions
|
||||
COMMIT_MESSAGE: 'project: Update gradle dependencies'
|
||||
PULL_REQUEST_LABELS: automated pull request, gradle
|
||||
PULL_REQUEST_LABELS: automated-pull-request, gradle
|
||||
15
.github/workflows/greetings.yml
vendored
Normal file
15
.github/workflows/greetings.yml
vendored
Normal file
@@ -0,0 +1,15 @@
|
||||
name: OpenOSRS - First interaction
|
||||
|
||||
on:
|
||||
issues:
|
||||
types: [opened]
|
||||
|
||||
jobs:
|
||||
check:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/first-interaction@v1
|
||||
with:
|
||||
repo-token: ${{ secrets.GITHUB_TOKEN }}
|
||||
issue-message: 'Thank you for opening your first issue! Please make sure to join our [Discord](https://discord.gg/openosrs).'
|
||||
37
.github/workflows/merge.yml
vendored
Normal file
37
.github/workflows/merge.yml
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
name: OpenOSRS - Auto merge
|
||||
|
||||
on:
|
||||
pull_request_review:
|
||||
types:
|
||||
- submitted
|
||||
|
||||
jobs:
|
||||
automerge:
|
||||
name: Auto merge
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: automerge
|
||||
uses: pascalgn/automerge-action@f84dd310ea4a19890c70a4ff11ab282a872fb94b
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
MERGE_FORKS: false
|
||||
LABELS: automated-pull-request
|
||||
AUTOMERGE: automated-pull-request
|
||||
|
||||
cleanup:
|
||||
name: Cleanup
|
||||
needs: automerge
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Extract branch name
|
||||
shell: bash
|
||||
run: echo "##[set-output name=branch;]$(echo $(jq --raw-output .pull_request.head.ref "$GITHUB_EVENT_PATH"))"
|
||||
id: extract_branch
|
||||
- name: Delete PR head branch
|
||||
uses: dawidd6/action-delete-branch@master
|
||||
with:
|
||||
github_token: ${{ secrets.GITHUB_TOKEN }}
|
||||
branch: ${{ steps.extract_branch.outputs.branch }}
|
||||
be_kind: true
|
||||
119
.github/workflows/pr.yml
vendored
Normal file
119
.github/workflows/pr.yml
vendored
Normal file
@@ -0,0 +1,119 @@
|
||||
name: OpenOSRS - CI (PR)
|
||||
|
||||
on: pull_request
|
||||
|
||||
jobs:
|
||||
pr-lint:
|
||||
name: PR title
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: PR title lint
|
||||
if: github.event_name == 'pull_request'
|
||||
uses: seferov/pr-lint-action@master
|
||||
with:
|
||||
title-regex: '^([\w-/]+): \w+'
|
||||
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Building
|
||||
run: ./gradlew build --stacktrace -x test -x checkstyleMain --console=plain
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Testing
|
||||
run: ./gradlew test --stacktrace --console=plain
|
||||
|
||||
checkstyleMain:
|
||||
name: Checkstyle main
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Checking code conventions
|
||||
run: ./gradlew checkstyleMain --console=plain
|
||||
|
||||
checkstyleTest:
|
||||
name: Checkstyle test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Checking code conventions
|
||||
run: ./gradlew checkstyleTest --console=plain
|
||||
|
||||
approve:
|
||||
name: Approve
|
||||
needs: [build, test, checkstyleMain, checkstyleTest]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Approve pull request
|
||||
if: github.event_name == 'pull_request' && github.actor == 'OpenOSRS'
|
||||
uses: hmarr/auto-approve-action@v2.0.0
|
||||
with:
|
||||
github-token: ${{ secrets.Owain }}
|
||||
108
.github/workflows/push.yml
vendored
Normal file
108
.github/workflows/push.yml
vendored
Normal file
@@ -0,0 +1,108 @@
|
||||
name: OpenOSRS - CI (push)
|
||||
|
||||
on:
|
||||
push:
|
||||
branches:
|
||||
- master
|
||||
|
||||
jobs:
|
||||
build:
|
||||
runs-on: ubuntu-latest
|
||||
name: Build
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Building
|
||||
run: ./gradlew build --stacktrace -x test -x checkstyleMain --console=plain
|
||||
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
name: Test
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Testing
|
||||
run: ./gradlew test --stacktrace --console=plain
|
||||
|
||||
checkstyleMain:
|
||||
name: Checkstyle main
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Checking code conventions
|
||||
run: ./gradlew checkstyleMain --console=plain
|
||||
|
||||
checkstyleTest:
|
||||
name: Checkstyle test
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Make gradlew executable
|
||||
run: chmod +x ./gradlew
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Assembling
|
||||
run: ./gradlew assemble --console=plain
|
||||
- name: Checking code conventions
|
||||
run: ./gradlew checkstyleTest --console=plain
|
||||
|
||||
update_draft_release:
|
||||
name: Draft release
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: toolmantim/release-drafter@v5.2.0
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
14
.github/workflows/scraper.yml
vendored
14
.github/workflows/scraper.yml
vendored
@@ -9,9 +9,15 @@ jobs:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@master
|
||||
- uses: actions/checkout@v1
|
||||
- uses: actions/cache@v1
|
||||
with:
|
||||
path: ~/.gradle/caches
|
||||
key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle.kts') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-gradle-
|
||||
- name: Set up JDK 11
|
||||
uses: actions/setup-java@master
|
||||
uses: actions/setup-java@v1
|
||||
with:
|
||||
java-version: 11
|
||||
- name: Make gradlew executable
|
||||
@@ -25,7 +31,7 @@ jobs:
|
||||
- name: Building scraper
|
||||
run: ./gradlew :wiki-scraper:build --console=plain
|
||||
- name: Downloading jagex cache
|
||||
run: ./gradlew :cache-client:update --console=plain
|
||||
run: ./gradlew :cache-client:download --console=plain
|
||||
- name: Scraping NPC stats
|
||||
run: ./gradlew :wiki-scraper:npcStatsScrape --console=plain
|
||||
- name: Create NPC stats Pull Request
|
||||
@@ -36,4 +42,4 @@ jobs:
|
||||
PULL_REQUEST_TITLE: 'Client: Update NPC stats'
|
||||
PULL_REQUEST_BODY: This is an auto-generated PR with changes from the OSRS wiki
|
||||
COMMIT_MESSAGE: 'Client: Update NPC stats'
|
||||
PULL_REQUEST_LABELS: automated pull request, NPC stats
|
||||
PULL_REQUEST_LABELS: automated-pull-request, NPC stats
|
||||
2
.github/workflows/stale.yml
vendored
2
.github/workflows/stale.yml
vendored
@@ -19,4 +19,4 @@ jobs:
|
||||
exempt-issue-label: 'awaiting-approval'
|
||||
exempt-pr-label: 'awaiting-approval'
|
||||
days-before-stale: 60
|
||||
days-before-close: 30
|
||||
days-before-close: 30
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
|
||||
# OpenOSRS
|
||||
[](https://github.com/open-osrs/runelite/actions)
|
||||
[/badge.svg)](https://github.com/open-osrs/runelite/actions?query=workflow%3A%22OpenOSRS+-+CI+%28push%29%22)
|
||||
[](http://hits.dwyl.io/open-osrs/runelite)
|
||||
[OpenOSRS](https://openosrs.com) is an extended version of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying more open-source. We are not affiliated with RuneLite.
|
||||
|
||||
@@ -54,3 +54,7 @@ OpenOSRS is licensed under the BSD 2-clause license. See the license header in t
|
||||
## Contribute and Develop
|
||||
|
||||
We've set up a separate document for our [contribution guidelines](https://github.com/open-osrs/runelite/blob/master/.github/CONTRIBUTING.md).
|
||||
|
||||
## Supported By
|
||||
|
||||
OpenOSRS uses profiling tools provided by [](https://www.yourkit.com/java/profiler/)
|
||||
|
||||
207
build.gradle
207
build.gradle
@@ -1,207 +0,0 @@
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
maven {
|
||||
url "https://plugins.gradle.org/m2/"
|
||||
}
|
||||
}
|
||||
dependencies {
|
||||
classpath "org.ajoberstar.grgit:grgit-gradle:3.1.1"
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id 'com.adarshr.test-logger' version '1.7.0' apply false
|
||||
id "com.github.ben-manes.versions" version "0.22.0"
|
||||
id "com.gradle.build-scan" version "2.4"
|
||||
id 'se.patrikerdes.use-latest-versions' version '0.2.8'
|
||||
}
|
||||
|
||||
apply plugin: 'application'
|
||||
|
||||
ext {
|
||||
grgit = Grgit.open(dir: "${rootProject.projectDir}")
|
||||
localGitCommit = grgit.head().id
|
||||
localGitCommitShort = grgit.head().getAbbreviatedId(7)
|
||||
localGitDirty = !grgit.status().clean
|
||||
|
||||
// sets the minimum launcher version that is output for the bootstrapper
|
||||
launcherVersion = '2.0.3'
|
||||
|
||||
// Dependencies versions
|
||||
annotations = '17.0.0'
|
||||
antlr = '4.7.2'
|
||||
apacheCommonsCompress = '1.19'
|
||||
apacheCommonsCsv = '1.7'
|
||||
apacheCommonsText = '1.8'
|
||||
asm = '7.2'
|
||||
commonsCli = '1.4'
|
||||
discord = '1.1'
|
||||
fernflower = '07082019'
|
||||
findbugs = '3.0.2'
|
||||
gson = '2.8.6'
|
||||
guava = '28.1-jre'
|
||||
guice = '4.2.2'
|
||||
h2 = '1.4.200'
|
||||
hamcrest = '2.2'
|
||||
httpcore = '4.4.12'
|
||||
httpmime = '4.5.10'
|
||||
javassist = '3.26.0-GA'
|
||||
javax = '1.3.2'
|
||||
javaxInject = '1'
|
||||
jbsdiff = '1.0'
|
||||
jclCore = '2.8'
|
||||
jedis = '3.1.0'
|
||||
jfoenix = '9.0.9'
|
||||
jna = '5.4.0'
|
||||
jogamp = '2.3.2'
|
||||
jopt = '5.0.4'
|
||||
jooq = '3.12.1'
|
||||
junit = '4.12'
|
||||
jupiter = '5.5.2'
|
||||
logback = '1.2.3'
|
||||
lombok = '1.18.10'
|
||||
mapstruct = '1.3.1.Final'
|
||||
mariadbJdbc = '2.5.1'
|
||||
mavenPluginAnnotations = '3.6.0'
|
||||
mavenPluginApi = '3.6.2'
|
||||
minio = '6.0.11'
|
||||
mockito = '3.1.0'
|
||||
mongodbDriverSync = '3.11.1'
|
||||
mysqlConnectorJava = '8.0.18'
|
||||
netty = '4.1.42.Final'
|
||||
okhttp3 = '4.2.2'
|
||||
orangeExtensions = '1.0'
|
||||
petitparser = '2.2.0'
|
||||
plexus = '3.3.0'
|
||||
rxjava = '2.2.13'
|
||||
rxrelay = '2.1.1'
|
||||
scribejava = '6.9.0'
|
||||
sisu = '0.3.3'
|
||||
slf4j = '1.7.28'
|
||||
springJdbc = '5.2.0.RELEASE'
|
||||
springboot = '2.2.0.RELEASE'
|
||||
sql2o = '1.6.0'
|
||||
substance = '8.0.02'
|
||||
trident = '1.5.00'
|
||||
}
|
||||
|
||||
allprojects {
|
||||
apply plugin: 'maven'
|
||||
if (this.name != 'rs-client') apply plugin: 'checkstyle'
|
||||
|
||||
group = 'com.openosrs'
|
||||
version = '1.5.37-SNAPSHOT'
|
||||
|
||||
ext {
|
||||
rsversion = 184
|
||||
cacheversion = 165
|
||||
plusVersion = '2.1.8.0'
|
||||
|
||||
gitCommit = localGitCommit
|
||||
gitCommitShort = localGitCommitShort
|
||||
gitDirty = localGitDirty
|
||||
|
||||
|
||||
rootPath = rootDir.toString().replace('\\', '/')
|
||||
injectedClassesPath = rootPath + "/injector-plugin/out/injected-client/"
|
||||
}
|
||||
}
|
||||
|
||||
subprojects {
|
||||
apply plugin: 'com.adarshr.test-logger'
|
||||
apply plugin: 'java-library'
|
||||
apply plugin: 'maven'
|
||||
apply plugin: 'fernflower'
|
||||
apply plugin: 'maven-publish'
|
||||
|
||||
sourceCompatibility = 1.8
|
||||
targetCompatibility = 1.8
|
||||
|
||||
tasks.withType(JavaCompile) {
|
||||
options.encoding = 'UTF-8'
|
||||
}
|
||||
|
||||
tasks.withType(GroovyCompile).configureEach {
|
||||
options.incremental = true
|
||||
}
|
||||
|
||||
publishing {
|
||||
repositories {
|
||||
maven {
|
||||
name = "runelite"
|
||||
url = uri("https://maven.pkg.github.com/open-osrs/runelite")
|
||||
credentials {
|
||||
username = System.getProperty("gpr_user")
|
||||
password = System.getProperty("gpr_key")
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
gpr(MavenPublication) {
|
||||
from(components.java)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
repositories {
|
||||
mavenLocal()
|
||||
|
||||
maven { url "http://repo1.maven.org/maven2" }
|
||||
maven { url "http://repo.runelite.net" }
|
||||
maven { url "http://repo.maven.apache.org/maven2" }
|
||||
maven { url "https://raw.githubusercontent.com/open-osrs/hosting/master" }
|
||||
|
||||
if (System.getenv("NEXUS-URL") != null) {
|
||||
maven { url System.getenv("NEXUS-URL") }
|
||||
}
|
||||
}
|
||||
|
||||
checkstyle {
|
||||
toolVersion = '6.4.1'
|
||||
sourceSets = [sourceSets.main]
|
||||
configFile = file("${rootDir}/checkstyle/checkstyle.xml")
|
||||
configProperties = [ "suppressionFile" : file("${rootDir}/checkstyle/suppressions.xml")]
|
||||
showViolations = true
|
||||
ignoreFailures = false
|
||||
maxWarnings = 0
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
wrapper {
|
||||
gradleVersion = '5.6.2'
|
||||
|
||||
doLast {
|
||||
def optsEnvVar = "DEFAULT_JVM_OPTS"
|
||||
scriptFile.write scriptFile.text.replace("$optsEnvVar='\"-Xmx64m\" \"-Xms64m\"'", "$optsEnvVar='\"-Xmx4g\" \"-Xms2g\" \"-Dfile.encoding=UTF-8\"'")
|
||||
batchScript.write batchScript.text.replace("set $optsEnvVar=\"-Xmx64m\" \"-Xms64m\"", "set $optsEnvVar=\"-Xmx4g\" \"-Xms2g\" \"-Dfile.encoding=UTF-8\"")
|
||||
}
|
||||
}
|
||||
|
||||
run {
|
||||
classpath = childProjects.client.sourceSets.main.runtimeClasspath
|
||||
mainClassName = "net.runelite.client.RuneLite"
|
||||
}
|
||||
|
||||
def isNonStable = { String version ->
|
||||
def unstableKeyword = ['ALPHA', 'BETA', 'RC'].any { it -> version.toUpperCase().contains(it) }
|
||||
|
||||
return unstableKeyword
|
||||
}
|
||||
|
||||
dependencyUpdates {
|
||||
checkForGradleUpdate = false
|
||||
|
||||
resolutionStrategy {
|
||||
componentSelection {
|
||||
all {
|
||||
if (isNonStable(candidate.version)) {
|
||||
reject()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
166
build.gradle.kts
Normal file
166
build.gradle.kts
Normal file
@@ -0,0 +1,166 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import com.github.benmanes.gradle.versions.updates.DependencyUpdatesTask
|
||||
import org.ajoberstar.grgit.Grgit
|
||||
|
||||
buildscript {
|
||||
repositories {
|
||||
gradlePluginPortal()
|
||||
maven(url = "https://raw.githubusercontent.com/open-osrs/hosting/master")
|
||||
}
|
||||
dependencies {
|
||||
classpath(Plugins.grgitPlugin)
|
||||
classpath(Plugins.versionsPlugin)
|
||||
classpath(Plugins.injectorPlugin)
|
||||
}
|
||||
}
|
||||
|
||||
plugins {
|
||||
id(Plugins.testLogger.first) version Plugins.testLogger.second apply false
|
||||
id(Plugins.versions.first) version Plugins.versions.second
|
||||
id(Plugins.latestVersion.first) version Plugins.latestVersion.second
|
||||
id(Plugins.grgit.first) version Plugins.grgit.second
|
||||
|
||||
checkstyle
|
||||
application
|
||||
}
|
||||
|
||||
val grgit = Grgit.open(mapOf("dir" to rootProject.projectDir.absolutePath))
|
||||
val localGitCommit = grgit.head().id
|
||||
val localGitCommitShort = grgit.head().getAbbreviatedId(7)
|
||||
|
||||
fun isNonStable(version: String): Boolean {
|
||||
return listOf("ALPHA", "BETA", "RC").any {
|
||||
version.toUpperCase().contains(it)
|
||||
}
|
||||
}
|
||||
|
||||
allprojects {
|
||||
group = "com.openosrs"
|
||||
version = ProjectVersions.rlVersion
|
||||
}
|
||||
|
||||
subprojects {
|
||||
repositories {
|
||||
//mavenLocal()
|
||||
jcenter()
|
||||
maven(url = "https://mvnrepository.com/artifact")
|
||||
maven(url = "https://repo.runelite.net")
|
||||
maven(url = "https://raw.githubusercontent.com/open-osrs/hosting/master")
|
||||
maven(url = "https://jitpack.io")
|
||||
}
|
||||
|
||||
apply<JavaLibraryPlugin>()
|
||||
apply<MavenPublishPlugin>()
|
||||
apply(plugin = Plugins.testLogger.first)
|
||||
|
||||
project.extra["gitCommit"] = localGitCommit
|
||||
project.extra["gitCommitShort"] = localGitCommitShort
|
||||
|
||||
project.extra["rootPath"] = rootDir.toString().replace("\\", "/")
|
||||
|
||||
if (this.name != "runescape-client") {
|
||||
apply(plugin = "checkstyle")
|
||||
|
||||
checkstyle {
|
||||
maxWarnings = 0
|
||||
toolVersion = "8.25"
|
||||
isShowViolations = true
|
||||
isIgnoreFailures = false
|
||||
}
|
||||
}
|
||||
|
||||
configure<PublishingExtension> {
|
||||
repositories {
|
||||
maven {
|
||||
name = "runelite"
|
||||
url = uri("https://maven.pkg.github.com/open-osrs/runelite")
|
||||
credentials {
|
||||
username = System.getProperty("gpr_user")
|
||||
password = System.getProperty("gpr_key")
|
||||
}
|
||||
}
|
||||
}
|
||||
publications {
|
||||
register("gpr", MavenPublication::class) {
|
||||
from(components["java"])
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
tasks {
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_1_8
|
||||
targetCompatibility = JavaVersion.VERSION_1_8
|
||||
}
|
||||
|
||||
withType<JavaCompile> {
|
||||
options.encoding = "UTF-8"
|
||||
}
|
||||
|
||||
withType<AbstractArchiveTask> {
|
||||
isPreserveFileTimestamps = false
|
||||
isReproducibleFileOrder = true
|
||||
dirMode = 493
|
||||
fileMode = 420
|
||||
}
|
||||
|
||||
withType<Checkstyle> {
|
||||
group = "verification"
|
||||
|
||||
exclude("**/ScriptVarType.java")
|
||||
exclude("**/LayoutSolver.java")
|
||||
exclude("**/RoomType.java")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
application {
|
||||
mainClassName = "net.runelite.client.RuneLite"
|
||||
}
|
||||
|
||||
tasks {
|
||||
named<JavaExec>("run") {
|
||||
group = "openosrs"
|
||||
|
||||
classpath = project(":runelite-client").sourceSets.main.get().runtimeClasspath
|
||||
}
|
||||
|
||||
named<DependencyUpdatesTask>("dependencyUpdates") {
|
||||
checkForGradleUpdate = false
|
||||
|
||||
resolutionStrategy {
|
||||
componentSelection {
|
||||
all {
|
||||
if (candidate.displayName.contains("fernflower") || isNonStable(candidate.version)) {
|
||||
reject("Non stable")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
repositories {
|
||||
maven { url "https://raw.githubusercontent.com/open-osrs/hosting/master" }
|
||||
}
|
||||
dependencies {
|
||||
compile localGroovy()
|
||||
implementation group: 'net.runelite', name: 'fernflower', version: '07082019'
|
||||
}
|
||||
43
buildSrc/build.gradle.kts
Normal file
43
buildSrc/build.gradle.kts
Normal file
@@ -0,0 +1,43 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
`kotlin-dsl`
|
||||
}
|
||||
|
||||
repositories {
|
||||
jcenter()
|
||||
maven(url = "https://raw.githubusercontent.com/open-osrs/hosting/master")
|
||||
}
|
||||
|
||||
dependencies {
|
||||
implementation(gradleApi())
|
||||
implementation(group = "net.runelite", name = "fernflower", version = "07082019")
|
||||
implementation(group = "org.json", name = "json", version = "20190722")
|
||||
}
|
||||
|
||||
kotlinDslPluginOptions {
|
||||
experimentalWarning.set(false)
|
||||
}
|
||||
@@ -1,16 +0,0 @@
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.StopExecutionException
|
||||
|
||||
class FernflowerPlugin implements Plugin<Project> {
|
||||
void apply(Project project) {
|
||||
project.task('decompile', type: FernflowerTask) {
|
||||
it.dependsOn(project.tasks.jar)
|
||||
it.doFirst {
|
||||
if (!project.tasks.jar.didWork) {
|
||||
throw new StopExecutionException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,32 +0,0 @@
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler
|
||||
|
||||
class FernflowerTask extends DefaultTask {
|
||||
List<String> extraArgs
|
||||
String inputJar
|
||||
String outputDir
|
||||
|
||||
@InputFile
|
||||
File getInputJar() {
|
||||
project.file(inputJar ?: project.buildDir.toString() + '/libs/' + project.getName() + '-' + project.version + '.jar')
|
||||
}
|
||||
|
||||
@OutputDirectory
|
||||
File getOutputDir() {
|
||||
project.file(outputDir ?: project.buildDir.toString() + '/decompiled-sources')
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
void decompile() {
|
||||
getOutputDir().mkdirs()
|
||||
def args = [getInputJar().toString(), getOutputDir().toString()]
|
||||
if (extraArgs) {
|
||||
args.addAll(extraArgs)
|
||||
}
|
||||
|
||||
ConsoleDecompiler.main(args as String[])
|
||||
}
|
||||
}
|
||||
87
buildSrc/src/main/kotlin/BootstrapPlugin.kt
Normal file
87
buildSrc/src/main/kotlin/BootstrapPlugin.kt
Normal file
@@ -0,0 +1,87 @@
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import org.gradle.kotlin.dsl.register
|
||||
import java.io.File
|
||||
|
||||
class BootstrapPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.tasks.register<BootstrapTask>("bootstrapStaging") {
|
||||
dependsOn("jar")
|
||||
dependsOn("shadowJar")
|
||||
|
||||
type = "staging"
|
||||
clientJar = project.tasks["jar"].outputs.files.singleFile
|
||||
|
||||
dependsOn(project.parent!!.project(":runelite-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":runescape-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":http-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":injected-client").tasks["jar"])
|
||||
|
||||
doLast {
|
||||
|
||||
project.copy {
|
||||
from(project.tasks["jar"])
|
||||
from(project.parent!!.project(":runelite-api").tasks["jar"])
|
||||
from(project.parent!!.project(":runescape-api").tasks["jar"])
|
||||
from(project.parent!!.project(":http-api").tasks["jar"])
|
||||
from(project.parent!!.project(":injected-client").tasks["jar"])
|
||||
|
||||
into("${project.buildDir}/bootstrap/${type}/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.register<BootstrapTask>("bootstrapStable") {
|
||||
dependsOn("jar")
|
||||
dependsOn("shadowJar")
|
||||
|
||||
type = "stable"
|
||||
clientJar = project.tasks["jar"].outputs.files.singleFile
|
||||
|
||||
dependsOn(project.parent!!.project(":runelite-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":runescape-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":http-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":injected-client").tasks["jar"])
|
||||
|
||||
doLast {
|
||||
|
||||
project.copy {
|
||||
from(project.tasks["jar"])
|
||||
from(project.parent!!.project(":runelite-api").tasks["jar"])
|
||||
from(project.parent!!.project(":runescape-api").tasks["jar"])
|
||||
from(project.parent!!.project(":http-api").tasks["jar"])
|
||||
from(project.parent!!.project(":injected-client").tasks["jar"])
|
||||
|
||||
into("${project.buildDir}/bootstrap/${type}/")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
project.tasks.register<BootstrapTask>("bootstrapNightly") {
|
||||
dependsOn("jar")
|
||||
dependsOn("shadowJar")
|
||||
|
||||
type = "nightly"
|
||||
clientJar = project.tasks["jar"].outputs.files.singleFile
|
||||
|
||||
dependsOn(project.parent!!.project(":runelite-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":runescape-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":http-api").tasks["jar"])
|
||||
dependsOn(project.parent!!.project(":injected-client").tasks["jar"])
|
||||
|
||||
doLast {
|
||||
|
||||
project.copy {
|
||||
from(project.tasks["jar"])
|
||||
from(project.parent!!.project(":runelite-api").tasks["jar"])
|
||||
from(project.parent!!.project(":runescape-api").tasks["jar"])
|
||||
from(project.parent!!.project(":http-api").tasks["jar"])
|
||||
from(project.parent!!.project(":injected-client").tasks["jar"])
|
||||
|
||||
into("${project.buildDir}/bootstrap/${type}/")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
106
buildSrc/src/main/kotlin/BootstrapTask.kt
Normal file
106
buildSrc/src/main/kotlin/BootstrapTask.kt
Normal file
@@ -0,0 +1,106 @@
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.PathSensitive
|
||||
import org.gradle.api.tasks.PathSensitivity
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.gradle.kotlin.dsl.extra
|
||||
import org.gradle.kotlin.dsl.get
|
||||
import java.io.File
|
||||
import java.security.MessageDigest
|
||||
|
||||
open class BootstrapTask : DefaultTask() {
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
var type: String? = "stable"
|
||||
|
||||
@InputFile
|
||||
@PathSensitive(PathSensitivity.ABSOLUTE)
|
||||
var clientJar: File? = null
|
||||
|
||||
@Input
|
||||
val launcherJvm11Arguments = arrayOf("-XX:+DisableAttachMechanism", "-Drunelite.launcher.nojvm=true", "-Xmx512m", "-Xss2m", "-XX:CompileThreshold=1500", "-Djna.nosys=true")
|
||||
|
||||
@Input
|
||||
val launcherArguments = arrayOf("-XX:+DisableAttachMechanism", "-Drunelite.launcher.nojvm=true", "-Xmx512m", "-Xss2m", "-XX:CompileThreshold=1500", "-Xincgc", "-XX:+UseConcMarkSweepGC", "-XX:+UseParNewGC", "-Djna.nosys=true")
|
||||
|
||||
@Input
|
||||
val clientJvmArguments = arrayOf("-XX:+DisableAttachMechanism", "-Xmx512m", "-Xss2m", "-XX:CompileThreshold=1500", "-Xincgc", "-XX:+UseConcMarkSweepGC", "-XX:+UseParNewGC", "-Djna.nosys=true")
|
||||
|
||||
@Input
|
||||
val clientJvm9Arguments = arrayOf("-XX:+DisableAttachMechanism", "-Xmx512m", "-Xss2m", "-XX:CompileThreshold=1500", "-Djna.nosys=true")
|
||||
|
||||
private fun hash(file: ByteArray): String {
|
||||
return MessageDigest.getInstance("SHA-256").digest(file).fold("", { str, it -> str + "%02x".format(it) })
|
||||
}
|
||||
|
||||
private fun getArtifacts(): Array<JsonBuilder> {
|
||||
val artifacts = ArrayList<JsonBuilder>()
|
||||
|
||||
project.configurations["runtimeClasspath"].resolvedConfiguration.resolvedArtifacts.forEach {
|
||||
val module = it.moduleVersion.id.toString()
|
||||
|
||||
val name = module.split(":")[1]
|
||||
val group = module.split(":")[0]
|
||||
val version = module.split(":")[2]
|
||||
var path = ""
|
||||
|
||||
if (it.file.name.contains(ProjectVersions.rlVersion)) {
|
||||
path = "https://github.com/open-osrs/hosting/raw/master/${type}/${it.file.name}"
|
||||
} else if (!group.contains("runelite")) {
|
||||
path = "https://repo.maven.apache.org/maven2/" + group.replace(".", "/") + "/${name}/$version/${name}-$version"
|
||||
if (it.classifier != null && it.classifier != "no_aop") {
|
||||
path += "-${it.classifier}"
|
||||
}
|
||||
path += ".jar"
|
||||
} else if (it.file.name.contains("trident") || it.file.name.contains("discord") || it.file.name.contains("substance")) {
|
||||
path = "https://repo.runelite.net/net/runelite/"
|
||||
if (!it.file.name.contains("discord")) {
|
||||
path += "pushingpixels/"
|
||||
}
|
||||
path += "${name}/$version/${name}-$version.jar"
|
||||
}
|
||||
|
||||
val artifactFile = File(it.file.absolutePath)
|
||||
|
||||
artifacts.add(JsonBuilder(
|
||||
"name" to it.file.name,
|
||||
"path" to path,
|
||||
"size" to artifactFile.length(),
|
||||
"hash" to hash(artifactFile.readBytes())
|
||||
))
|
||||
}
|
||||
|
||||
artifacts.add(JsonBuilder(
|
||||
"name" to clientJar!!.name,
|
||||
"path" to "https://github.com/open-osrs/hosting/raw/master/${type}/${clientJar!!.name}",
|
||||
"size" to clientJar!!.length(),
|
||||
"hash" to hash(clientJar!!.readBytes())
|
||||
))
|
||||
|
||||
return artifacts.toTypedArray()
|
||||
}
|
||||
|
||||
@TaskAction
|
||||
fun boostrap() {
|
||||
val json = JsonBuilder(
|
||||
"projectVersion" to ProjectVersions.openosrsVersion,
|
||||
"minimumLauncherVersion" to ProjectVersions.launcherVersion,
|
||||
"launcherJvm11Arguments" to launcherJvm11Arguments,
|
||||
"launcherArguments" to launcherArguments,
|
||||
"clientJvmArguments" to clientJvmArguments,
|
||||
"clientJvm9Arguments" to clientJvm9Arguments,
|
||||
"buildCommit" to project.extra["gitCommit"],
|
||||
"artifacts" to getArtifacts()
|
||||
).toString()
|
||||
|
||||
val bootstrapDir = File("${project.buildDir}/bootstrap")
|
||||
bootstrapDir.mkdirs()
|
||||
|
||||
File(bootstrapDir, "bootstrap-${type}.json").printWriter().use { out ->
|
||||
out.println(json)
|
||||
}
|
||||
}
|
||||
}
|
||||
194
buildSrc/src/main/kotlin/Dependencies.kt
Normal file
194
buildSrc/src/main/kotlin/Dependencies.kt
Normal file
@@ -0,0 +1,194 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
const val kotlinVersion = "1.3.50"
|
||||
|
||||
object ProjectVersions {
|
||||
const val launcherVersion = "2.0.4"
|
||||
const val rlVersion = "1.5.41-SNAPSHOT"
|
||||
|
||||
const val openosrsVersion = "2.1.13.0-SNAPSHOT"
|
||||
|
||||
const val rsversion = 185
|
||||
const val cacheversion = 165
|
||||
}
|
||||
|
||||
object Plugins {
|
||||
val grgitPlugin = "org.ajoberstar:grgit:2.3.0"
|
||||
val versionsPlugin = "com.github.ben-manes:gradle-versions-plugin:0.27.0"
|
||||
val injectorPlugin = "com.openosrs:injector-plugin:1.0.2"
|
||||
val testLogger = Pair("com.adarshr.test-logger", "2.0.0")
|
||||
val versions = Pair("com.github.ben-manes.versions", "0.27.0")
|
||||
val latestVersion = Pair("se.patrikerdes.use-latest-versions", "0.2.13")
|
||||
val grgit = Pair("org.ajoberstar.grgit", "4.0.0-rc.1")
|
||||
val jarTest = Pair("com.github.hauner.jarTest", "1.0.1")
|
||||
val shadow = Pair("com.github.johnrengelman.shadow", "5.2.0")
|
||||
}
|
||||
|
||||
object Libraries {
|
||||
private object Versions {
|
||||
const val annotations = "18.0.0"
|
||||
const val antlr = "4.7.2"
|
||||
const val apacheCommonsCompress = "1.19"
|
||||
const val apacheCommonsCsv = "1.7"
|
||||
const val apacheCommonsText = "1.8"
|
||||
const val asm = "7.2"
|
||||
const val commonsCli = "1.4"
|
||||
const val discord = "1.1"
|
||||
const val fernflower = "07082019"
|
||||
const val findbugs = "3.0.2"
|
||||
const val gson = "2.8.6"
|
||||
const val guava = "28.1-jre"
|
||||
const val guice = "4.2.2"
|
||||
const val h2 = "1.4.200"
|
||||
const val hamcrest = "2.2"
|
||||
const val httpcore = "4.4.12"
|
||||
const val httpmime = "4.5.10"
|
||||
const val javassist = "3.26.0-GA"
|
||||
const val javax = "1.3.2"
|
||||
const val javaxInject = "1"
|
||||
const val jbsdiff = "1.0"
|
||||
const val jclCore = "2.8"
|
||||
const val jedis = "3.1.0"
|
||||
const val jna = "5.5.0"
|
||||
const val jogamp = "2.3.2"
|
||||
const val jopt = "5.0.4"
|
||||
const val jooq = "3.12.3"
|
||||
const val junit = "4.12"
|
||||
const val jupiter = "5.6.0-M1"
|
||||
const val logback = "1.2.3"
|
||||
const val lombok = "1.18.10"
|
||||
const val mapstruct = "1.3.1.Final"
|
||||
const val mariadbJdbc = "2.5.1"
|
||||
const val mavenPluginAnnotations = "3.6.0"
|
||||
const val mavenPluginApi = "3.6.2"
|
||||
const val minio = "6.0.11"
|
||||
const val mockito = "3.1.0"
|
||||
const val mongodbDriverSync = "3.11.2"
|
||||
const val mysqlConnectorJava = "8.0.18"
|
||||
const val naturalMouse = "2.0.2"
|
||||
const val netty = "4.1.43.Final"
|
||||
const val okhttp3 = "4.2.2"
|
||||
const val orangeExtensions = "1.0"
|
||||
const val petitparser = "2.2.0"
|
||||
const val plexus = "3.3.0"
|
||||
const val rxjava = "2.2.14"
|
||||
const val rxrelay = "2.1.1"
|
||||
const val scribejava = "6.9.0"
|
||||
const val sisu = "0.3.4"
|
||||
const val sentry = "1.7.28"
|
||||
const val slf4j = "1.7.29"
|
||||
const val springJdbc = "5.2.1.RELEASE"
|
||||
const val springboot = "2.2.1.RELEASE"
|
||||
const val sql2o = "1.6.0"
|
||||
const val substance = "8.0.02"
|
||||
const val trident = "1.5.00"
|
||||
}
|
||||
|
||||
const val annotations = "org.jetbrains:annotations:${Versions.annotations}"
|
||||
const val antlr = "org.antlr:antlr4-runtime:${Versions.antlr}"
|
||||
const val apacheCommonsCompress = "org.apache.commons:commons-compress:${Versions.apacheCommonsCompress}"
|
||||
const val apacheCommonsCsv = "org.apache.commons:commons-csv:${Versions.apacheCommonsCsv}"
|
||||
const val apacheCommonsText = "org.apache.commons:commons-text:${Versions.apacheCommonsText}"
|
||||
const val asmAll = "org.ow2.asm:asm:${Versions.asm}"
|
||||
const val asmUtil = "org.ow2.asm:asm-util:${Versions.asm}"
|
||||
const val asmTree = "org.ow2.asm:asm-tree:${Versions.asm}"
|
||||
const val commonsCli = "commons-cli:commons-cli:${Versions.commonsCli}"
|
||||
const val discord = "net.runelite:discord:${Versions.discord}"
|
||||
const val fernflower = "net.runelite:fernflower:${Versions.fernflower}"
|
||||
const val findbugs = "com.google.code.findbugs:jsr305:${Versions.findbugs}"
|
||||
const val gson = "com.google.code.gson:gson:${Versions.gson}"
|
||||
const val guava = "com.google.guava:guava:${Versions.guava}"
|
||||
const val guice = "com.google.inject:guice:${Versions.guice}:no_aop"
|
||||
const val guiceGrapher = "com.google.inject.extensions:guice-grapher:${Versions.guice}"
|
||||
const val guiceTestlib = "com.google.inject.extensions:guice-testlib:${Versions.guice}"
|
||||
const val h2 = "com.h2database:h2:${Versions.h2}"
|
||||
const val hamcrest = "org.hamcrest:hamcrest-library:${Versions.hamcrest}"
|
||||
const val httpcore = "org.apache.httpcomponents:httpcore:${Versions.httpcore}"
|
||||
const val httpmime = "org.apache.httpcomponents:httpmime:${Versions.httpmime}"
|
||||
const val javassist = "org.javassist:javassist:${Versions.javassist}"
|
||||
const val javax = "javax.annotation:javax.annotation-api:${Versions.javax}"
|
||||
const val javaxInject = "javax.inject:javax.inject:${Versions.javaxInject}"
|
||||
const val jbsdiff = "io.sigpipe:jbsdiff:${Versions.jbsdiff}"
|
||||
const val jclCore = "org.xeustechnologies:jcl-core:${Versions.jclCore}"
|
||||
const val jedis = "redis.clients:jedis:${Versions.jedis}"
|
||||
const val jna = "net.java.dev.jna:jna:${Versions.jna}"
|
||||
const val jnaPlatform = "net.java.dev.jna:jna-platform:${Versions.jna}"
|
||||
const val jogampJogl = "org.jogamp.jogl:jogl-all:${Versions.jogamp}"
|
||||
const val jogampGluegen = "org.jogamp.gluegen:gluegen-rt:${Versions.jogamp}"
|
||||
const val jogampGluegenLinuxAmd64 = "org.jogamp.gluegen:gluegen-rt:${Versions.jogamp}:natives-linux-amd64"
|
||||
const val jogampGluegenLinuxI586 = "org.jogamp.gluegen:gluegen-rt:${Versions.jogamp}:natives-linux-i586"
|
||||
const val jogampGluegenWindowsAmd64 = "org.jogamp.gluegen:gluegen-rt:${Versions.jogamp}:natives-windows-amd64"
|
||||
const val jogampGluegenWindowsI586 = "org.jogamp.gluegen:gluegen-rt:${Versions.jogamp}:natives-windows-i586"
|
||||
const val jogampJoglLinuxAmd64 = "org.jogamp.jogl:jogl-all:${Versions.jogamp}:natives-linux-amd64"
|
||||
const val jogampJoglLinuxI586 = "org.jogamp.jogl:jogl-all:${Versions.jogamp}:natives-linux-i586"
|
||||
const val jogampJoglWindowsAmd64 = "org.jogamp.jogl:jogl-all:${Versions.jogamp}:natives-windows-amd64"
|
||||
const val jogampJoglWindowsI586 = "org.jogamp.jogl:jogl-all:${Versions.jogamp}:natives-windows-i586"
|
||||
const val jopt = "net.sf.jopt-simple:jopt-simple:${Versions.jopt}"
|
||||
const val jooq = "org.jooq:jooq:${Versions.jooq}"
|
||||
const val jooqCodegen = "org.jooq:jooq-codegen:${Versions.jooq}"
|
||||
const val jooqMeta = "org.jooq:jooq-meta:${Versions.jooq}"
|
||||
const val junit = "junit:junit:${Versions.junit}"
|
||||
const val jupiter = "org.junit.jupiter:junit-jupiter-api:${Versions.jupiter}"
|
||||
const val logback = "ch.qos.logback:logback-classic:${Versions.logback}"
|
||||
const val lombok = "org.projectlombok:lombok:${Versions.lombok}"
|
||||
const val mapstruct = "org.mapstruct:mapstruct-jdk8:${Versions.mapstruct}"
|
||||
const val mapstructProcessor = "org.mapstruct:mapstruct-processor:${Versions.mapstruct}"
|
||||
const val mariadbJdbc = "org.mariadb.jdbc:mariadb-java-client:${Versions.mariadbJdbc}"
|
||||
const val mavenPluginAnnotations = "org.apache.maven.plugin-tools:maven-plugin-annotations:${Versions.mavenPluginAnnotations}"
|
||||
const val mavenPluginApi = "org.apache.maven:maven-plugin-api:${Versions.mavenPluginApi}"
|
||||
const val minio = "io.minio:minio:${Versions.minio}"
|
||||
const val mockitoCore = "org.mockito:mockito-core:${Versions.mockito}"
|
||||
const val mockitoInline = "org.mockito:mockito-inline:${Versions.mockito}"
|
||||
const val mongodbDriverSync = "org.mongodb:mongodb-driver-sync:${Versions.mongodbDriverSync}"
|
||||
const val mysqlConnectorJava = "mysql:mysql-connector-java:${Versions.mysqlConnectorJava}"
|
||||
const val naturalMouse = "com.github.joonasvali.naturalmouse:naturalmouse:${Versions.naturalMouse}"
|
||||
const val nettyAll = "io.netty:netty-all:${Versions.netty}"
|
||||
const val nettyBuffer = "io.netty:netty-buffer:${Versions.netty}"
|
||||
const val okhttp3 = "com.squareup.okhttp3:okhttp:${Versions.okhttp3}"
|
||||
const val okhttp3Webserver = "com.squareup.okhttp3:mockwebserver:${Versions.okhttp3}"
|
||||
const val orangeExtensions = "net.runelite:orange-extensions:${Versions.orangeExtensions}"
|
||||
const val petitparser = "com.github.petitparser:java-petitparser:${Versions.petitparser}"
|
||||
const val plexus = "org.codehaus.plexus:plexus-utils:${Versions.plexus}"
|
||||
const val rxjava = "io.reactivex.rxjava2:rxjava:${Versions.rxjava}"
|
||||
const val rxrelay = "com.jakewharton.rxrelay2:rxrelay:${Versions.rxrelay}"
|
||||
const val scribejava = "com.github.scribejava:scribejava-apis:${Versions.scribejava}"
|
||||
const val sisu = "org.eclipse.sisu:org.eclipse.sisu.inject:${Versions.sisu}"
|
||||
const val slf4jApi = "org.slf4j:slf4j-api:${Versions.slf4j}"
|
||||
const val slf4jNop = "org.slf4j:slf4j-nop:${Versions.slf4j}"
|
||||
const val slf4jSimple = "org.slf4j:slf4j-simple:${Versions.slf4j}"
|
||||
const val sentry = "io.sentry:sentry:${Versions.sentry}"
|
||||
const val springbootDevtools = "org.springframework.boot:spring-boot-devtools:${Versions.springboot}"
|
||||
const val springbootStarter = "org.springframework.boot:spring-boot-starter:${Versions.springboot}"
|
||||
const val springbootStarterWeb = "org.springframework.boot:spring-boot-starter-web:${Versions.springboot}"
|
||||
const val springbootStarterJdbc = "org.springframework.boot:spring-boot-starter-jdbc:${Versions.springboot}"
|
||||
const val springbootStarterTest = "org.springframework.boot:spring-boot-starter-test:${Versions.springboot}"
|
||||
const val springbootStarterTomcat = "org.springframework.boot:spring-boot-starter-tomcat:${Versions.springboot}"
|
||||
const val springbootJdbc = "org.springframework:spring-jdbc:${Versions.springJdbc}"
|
||||
const val sql2o = "org.sql2o:sql2o:${Versions.sql2o}"
|
||||
const val substance = "net.runelite.pushingpixels:substance:${Versions.substance}"
|
||||
const val trident = "net.runelite.pushingpixels:trident:${Versions.trident}"
|
||||
const val vanilla = "net.runelite.rs:vanilla:${ProjectVersions.rsversion}"
|
||||
}
|
||||
19
buildSrc/src/main/kotlin/FernflowerPlugin.kt
Normal file
19
buildSrc/src/main/kotlin/FernflowerPlugin.kt
Normal file
@@ -0,0 +1,19 @@
|
||||
import org.gradle.api.Plugin
|
||||
import org.gradle.api.Project
|
||||
import org.gradle.api.tasks.StopExecutionException
|
||||
import org.gradle.api.tasks.diagnostics.DependencyReportTask
|
||||
import org.gradle.kotlin.dsl.register
|
||||
|
||||
class FernflowerPlugin : Plugin<Project> {
|
||||
override fun apply(project: Project) {
|
||||
project.tasks.register<FernflowerTask>("decompile") {
|
||||
dependsOn(project.tasks.getByName("jar"))
|
||||
|
||||
doFirst {
|
||||
if (!project.tasks.getByName("jar").didWork) {
|
||||
throw StopExecutionException()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
45
buildSrc/src/main/kotlin/FernflowerTask.kt
Normal file
45
buildSrc/src/main/kotlin/FernflowerTask.kt
Normal file
@@ -0,0 +1,45 @@
|
||||
import org.gradle.api.DefaultTask
|
||||
import org.gradle.api.tasks.CacheableTask
|
||||
import org.gradle.api.tasks.Input
|
||||
import org.gradle.api.tasks.InputFile
|
||||
import org.gradle.api.tasks.Optional
|
||||
import org.gradle.api.tasks.OutputDirectory
|
||||
import org.gradle.api.tasks.PathSensitive
|
||||
import org.gradle.api.tasks.PathSensitivity
|
||||
import org.gradle.api.tasks.TaskAction
|
||||
import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler
|
||||
|
||||
@CacheableTask
|
||||
open class FernflowerTask: DefaultTask() {
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
var extraArgs: List<String>? = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
var inputJar: String? = null
|
||||
|
||||
@Input
|
||||
@Optional
|
||||
var outputDir: String? = null
|
||||
|
||||
@InputFile
|
||||
@PathSensitive(PathSensitivity.ABSOLUTE)
|
||||
var getInputJar = project.file(inputJar ?: "${project.buildDir}/libs/${project.name}-${project.version}.jar")
|
||||
|
||||
@OutputDirectory
|
||||
var getOutputDir = project.file(outputDir ?: "${project.buildDir}/decompiled-sources")
|
||||
|
||||
|
||||
@TaskAction
|
||||
fun decompile() {
|
||||
getOutputDir.mkdirs()
|
||||
val args = mutableListOf(getInputJar.toString(), getOutputDir.toString())
|
||||
if (extraArgs != null) {
|
||||
args.addAll(extraArgs!!)
|
||||
}
|
||||
|
||||
ConsoleDecompiler.main(args.toTypedArray())
|
||||
}
|
||||
}
|
||||
55
buildSrc/src/main/kotlin/JsonBuilder.kt
Normal file
55
buildSrc/src/main/kotlin/JsonBuilder.kt
Normal file
@@ -0,0 +1,55 @@
|
||||
import org.json.JSONArray
|
||||
import org.json.JSONObject
|
||||
|
||||
class JsonBuilder() {
|
||||
private var json = JSONObject()
|
||||
|
||||
constructor(vararg pairs: Pair<String, *>) : this() {
|
||||
add(*pairs)
|
||||
}
|
||||
|
||||
fun add(vararg pairs: Pair<String, *>) {
|
||||
for ((key, value) in pairs) {
|
||||
when (value) {
|
||||
is Boolean -> json.put(key, value)
|
||||
is Number -> add(key, value)
|
||||
is String -> json.put(key, value)
|
||||
is JsonBuilder -> json.put(key, value.json)
|
||||
is Array<*> -> add(key, value)
|
||||
is JSONObject -> json.put(key, value)
|
||||
is JSONArray -> json.put(key, value)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun add(key: String, value: Number): JsonBuilder {
|
||||
when (value) {
|
||||
is Int -> json.put(key, value)
|
||||
is Long -> json.put(key, value)
|
||||
is Float -> json.put(key, value)
|
||||
is Double -> json.put(key, value)
|
||||
else -> {}
|
||||
}
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
fun <T> add(key: String, items: Array<T>): JsonBuilder {
|
||||
val jsonArray = JSONArray()
|
||||
items.forEach {
|
||||
when (it) {
|
||||
is String,is Long,is Int, is Boolean -> jsonArray.put(it)
|
||||
is JsonBuilder -> jsonArray.put(it.json)
|
||||
else -> try {jsonArray.put(it)} catch (ignored:Exception) {
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json.put(key, jsonArray)
|
||||
|
||||
return this
|
||||
}
|
||||
|
||||
override fun toString() = json.toString()
|
||||
}
|
||||
@@ -1 +0,0 @@
|
||||
implementation-class=FernflowerPlugin
|
||||
@@ -1,28 +0,0 @@
|
||||
description = 'Cache Client'
|
||||
|
||||
dependencies {
|
||||
api project(':cache')
|
||||
api project(':protocol')
|
||||
|
||||
implementation group: 'com.google.guava', name: 'guava', version: guava
|
||||
implementation group: 'io.netty', name: 'netty-all', version: netty
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4j
|
||||
|
||||
testImplementation group: 'junit', name: 'junit', version: junit
|
||||
testImplementation group: 'org.slf4j', name: 'slf4j-simple', version: slf4j
|
||||
testImplementation project(path: ':cache', configuration: 'testArchives')
|
||||
}
|
||||
|
||||
task update {
|
||||
dependsOn ":cache-client:build"
|
||||
|
||||
doLast {
|
||||
def path = sourceSets.main.runtimeClasspath
|
||||
def loader = new URLClassLoader(path.collect { f -> f.toURI().toURL() } as URL[])
|
||||
def cacheClient = loader.loadClass('net.runelite.cache.client.CacheClient')
|
||||
|
||||
cacheClient.getCache(rsversion);
|
||||
|
||||
loader.close()
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2019 ThatGamerBlue
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,28 +22,28 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
description = 'Injected Client'
|
||||
|
||||
compileJava {
|
||||
dependsOn ':injector-plugin:assemble'
|
||||
description = "Cache Client"
|
||||
|
||||
dependencies {
|
||||
api(project(":cache"))
|
||||
api(project(":protocol"))
|
||||
|
||||
implementation(Libraries.guava)
|
||||
implementation(Libraries.nettyAll)
|
||||
implementation(Libraries.slf4jApi)
|
||||
|
||||
testImplementation(Libraries.junit)
|
||||
testImplementation(Libraries.slf4jSimple)
|
||||
testImplementation(project(path = ":cache", configuration = "testArchives"))
|
||||
}
|
||||
|
||||
compileJava.outputs.upToDateWhen { false }
|
||||
tasks {
|
||||
register<JavaExec>("download") {
|
||||
dependsOn(":cache-client:build")
|
||||
|
||||
compileJava.doLast() {
|
||||
copy {
|
||||
File f = file("build/classes/java/main")
|
||||
f.deleteDir()
|
||||
f.mkdirs()
|
||||
from ("${injectedClassesPath}")
|
||||
into ("build/classes/java/main")
|
||||
classpath = project.sourceSets.main.get().runtimeClasspath
|
||||
main = "net.runelite.cache.client.CacheClient"
|
||||
args(listOf(ProjectVersions.rsversion))
|
||||
}
|
||||
}
|
||||
|
||||
classes.doLast() {
|
||||
File f = file("build/classes/java/main/Placeholder.class")
|
||||
f.delete()
|
||||
}
|
||||
|
||||
// tasks.build.dependsOn(tasks.decompile)
|
||||
// this is just here to show how this could be used
|
||||
@@ -85,7 +85,7 @@ public class CacheClient implements AutoCloseable
|
||||
private CompletableFuture<HandshakeResponseType> handshakeFuture;
|
||||
private final Queue<PendingFileRequest> requests = new ArrayDeque<>();
|
||||
|
||||
public static void getCache(int clientRevision)
|
||||
public static void main(String[] args)
|
||||
{
|
||||
Path path = Paths.get(System.getProperty("user.home"), "jagexcache" + File.separator + "oldschool" + File.separator + "LIVE");
|
||||
final File jagexcache = new File(String.valueOf(path));
|
||||
@@ -95,7 +95,7 @@ public class CacheClient implements AutoCloseable
|
||||
try (Store store = new Store(jagexcache))
|
||||
{
|
||||
store.load();
|
||||
CacheClient c = new CacheClient(store, clientRevision);
|
||||
CacheClient c = new CacheClient(store, Integer.parseInt(args[0]));
|
||||
c.connect();
|
||||
CompletableFuture<HandshakeResponseType> handshake = c.handshake();
|
||||
handshake.get();
|
||||
|
||||
@@ -1,15 +0,0 @@
|
||||
description = 'Cache Updater'
|
||||
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
compileOnly group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
implementation group: 'io.minio', name: 'minio', version: minio
|
||||
implementation group: 'mysql', name: 'mysql-connector-java', version: mysqlConnectorJava
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-devtools', version: springboot
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter', version: springboot
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-jdbc', version: springboot
|
||||
implementation group: 'org.sql2o', name: 'sql2o', version: sql2o
|
||||
implementation project(':cache-client')
|
||||
}
|
||||
40
cache-updater/cache-updater.gradle.kts
Normal file
40
cache-updater/cache-updater.gradle.kts
Normal file
@@ -0,0 +1,40 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
description = "Cache Updater"
|
||||
|
||||
dependencies {
|
||||
annotationProcessor(Libraries.lombok)
|
||||
|
||||
compileOnly(Libraries.lombok)
|
||||
|
||||
implementation(Libraries.minio)
|
||||
implementation(Libraries.mysqlConnectorJava)
|
||||
implementation(Libraries.springbootDevtools)
|
||||
implementation(Libraries.springbootStarter)
|
||||
implementation(Libraries.springbootStarterJdbc)
|
||||
implementation(Libraries.sql2o)
|
||||
implementation(project(":cache-client"))
|
||||
}
|
||||
36
cache/build.gradle
vendored
36
cache/build.gradle
vendored
@@ -1,36 +0,0 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
plugins {
|
||||
id "com.github.hauner.jarTest" version "1.0.1"
|
||||
}
|
||||
|
||||
description = 'Cache'
|
||||
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
api project(':http-api')
|
||||
|
||||
compileOnly group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: gson
|
||||
implementation group: 'com.google.guava', name: 'guava', version: guava
|
||||
implementation group: 'commons-cli', name: 'commons-cli', version: commonsCli
|
||||
implementation group: 'io.netty', name: 'netty-buffer', version: netty
|
||||
implementation group: 'org.antlr', name: 'antlr4-runtime', version: antlr
|
||||
implementation group: 'org.apache.commons', name: 'commons-compress', version: apacheCommonsCompress
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4j
|
||||
|
||||
testImplementation group: 'junit', name: 'junit', version: junit
|
||||
testImplementation group: 'net.runelite.rs', name: 'cache', version: cacheversion
|
||||
testImplementation group: 'org.slf4j', name: 'slf4j-simple', version: slf4j
|
||||
}
|
||||
|
||||
processTestResources {
|
||||
from file("src/test/resources/cache.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"rs.version": rsversion.toString(),
|
||||
"cache.version": cacheversion.toString()
|
||||
])
|
||||
}
|
||||
}
|
||||
75
cache/cache.gradle.kts
vendored
Normal file
75
cache/cache.gradle.kts
vendored
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
plugins {
|
||||
id(Plugins.jarTest.first) version Plugins.jarTest.second
|
||||
}
|
||||
|
||||
description = "Cache"
|
||||
|
||||
dependencies {
|
||||
annotationProcessor(Libraries.lombok)
|
||||
|
||||
api(project(":http-api"))
|
||||
|
||||
compileOnly(Libraries.lombok)
|
||||
|
||||
implementation(Libraries.gson)
|
||||
implementation(Libraries.guava)
|
||||
implementation(Libraries.commonsCli)
|
||||
implementation(Libraries.nettyBuffer)
|
||||
implementation(Libraries.antlr)
|
||||
implementation(Libraries.apacheCommonsCompress)
|
||||
implementation(Libraries.slf4jApi)
|
||||
|
||||
testImplementation(Libraries.junit)
|
||||
testImplementation(group = "net.runelite.rs", name = "cache", version = "${ProjectVersions.cacheversion}")
|
||||
testImplementation(Libraries.slf4jSimple)
|
||||
}
|
||||
|
||||
tasks {
|
||||
processTestResources {
|
||||
finalizedBy("filterTestResources")
|
||||
}
|
||||
|
||||
register<Copy>("filterTestResources") {
|
||||
val tokens = mapOf(
|
||||
"rs.version" to ProjectVersions.rsversion.toString(),
|
||||
"cache.version" to ProjectVersions.cacheversion.toString()
|
||||
)
|
||||
|
||||
inputs.properties(tokens)
|
||||
|
||||
from("src/test/resources") {
|
||||
include("cache.properties")
|
||||
}
|
||||
into("${buildDir}/resources/test")
|
||||
|
||||
filter(ReplaceTokens::class, "tokens" to tokens)
|
||||
filteringCharset = "UTF-8"
|
||||
}
|
||||
}
|
||||
@@ -31,38 +31,37 @@ import lombok.Data;
|
||||
@Data
|
||||
public class NpcDefinition
|
||||
{
|
||||
|
||||
public final int id;
|
||||
public short[] recolorToFind;
|
||||
public int rotation = 32;
|
||||
public String name = "null";
|
||||
public short[] recolorToReplace;
|
||||
public int size = 1;
|
||||
public int[] models;
|
||||
public int[] models_2;
|
||||
public int stanceAnimation = -1;
|
||||
public int anInt2165 = -1;
|
||||
public int tileSpacesOccupied = 1;
|
||||
public int walkAnimation = -1;
|
||||
public short[] retextureToReplace;
|
||||
public int rotate90RightAnimation = -1;
|
||||
public boolean aBool2170 = true;
|
||||
public int resizeX = 128;
|
||||
public int contrast = 0;
|
||||
public int[] chatheadModels;
|
||||
public int standingAnimation = -1;
|
||||
public int rotateLeftAnimation = -1;
|
||||
public int rotateRightAnimation = -1;
|
||||
public int walkingAnimation = -1;
|
||||
public int rotate180Animation = -1;
|
||||
public int varbitIndex = -1;
|
||||
public String[] options = new String[5];
|
||||
public boolean renderOnMinimap = true;
|
||||
public int combatLevel = -1;
|
||||
public int rotate90RightAnimation = -1;
|
||||
public int rotate90LeftAnimation = -1;
|
||||
public int resizeY = 128;
|
||||
public boolean hasRenderPriority = false;
|
||||
public int ambient = 0;
|
||||
public int headIcon = -1;
|
||||
public int[] configs;
|
||||
public short[] recolorToFind;
|
||||
public short[] recolorToReplace;
|
||||
public short[] retextureToFind;
|
||||
public short[] retextureToReplace;
|
||||
public String[] actions = new String[5];
|
||||
public boolean isMinimapVisible = true;
|
||||
public int combatLevel = -1;
|
||||
public int widthScale = 128;
|
||||
public int heightScale = 128;
|
||||
public boolean hasRenderPriority;
|
||||
public int ambient;
|
||||
public int contrast;
|
||||
public int headIcon = -1;
|
||||
public int rotationSpeed = 32;
|
||||
public int[] configs;
|
||||
public int varbitId = -1;
|
||||
public int varpIndex = -1;
|
||||
public boolean isClickable = true;
|
||||
public int anInt2189 = -1;
|
||||
public boolean aBool2190 = false;
|
||||
public Map<Integer, Object> params = null;
|
||||
public boolean isInteractable = true;
|
||||
public boolean rotationFlag = true;
|
||||
public boolean isPet;
|
||||
public Map<Integer, Object> params;
|
||||
}
|
||||
|
||||
@@ -24,13 +24,12 @@
|
||||
*/
|
||||
package net.runelite.cache.definitions.loaders;
|
||||
|
||||
import java.util.HashMap;
|
||||
import net.runelite.cache.definitions.NpcDefinition;
|
||||
import net.runelite.cache.io.InputStream;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.util.HashMap;
|
||||
|
||||
public class NpcLoader
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(NpcLoader.class);
|
||||
@@ -67,7 +66,6 @@ public class NpcLoader
|
||||
{
|
||||
def.models[index] = stream.readUnsignedShort();
|
||||
}
|
||||
|
||||
}
|
||||
else if (opcode == 2)
|
||||
{
|
||||
@@ -75,37 +73,37 @@ public class NpcLoader
|
||||
}
|
||||
else if (opcode == 12)
|
||||
{
|
||||
def.tileSpacesOccupied = stream.readUnsignedByte();
|
||||
def.size = stream.readUnsignedByte();
|
||||
}
|
||||
else if (opcode == 13)
|
||||
{
|
||||
def.stanceAnimation = stream.readUnsignedShort();
|
||||
def.standingAnimation = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode == 14)
|
||||
{
|
||||
def.walkAnimation = stream.readUnsignedShort();
|
||||
def.walkingAnimation = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode == 15)
|
||||
{
|
||||
def.anInt2165 = stream.readUnsignedShort();
|
||||
def.rotateLeftAnimation = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode == 16)
|
||||
{
|
||||
def.anInt2189 = stream.readUnsignedShort();
|
||||
def.rotateRightAnimation = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode == 17)
|
||||
{
|
||||
def.walkAnimation = stream.readUnsignedShort();
|
||||
def.walkingAnimation = stream.readUnsignedShort();
|
||||
def.rotate180Animation = stream.readUnsignedShort();
|
||||
def.rotate90RightAnimation = stream.readUnsignedShort();
|
||||
def.rotate90LeftAnimation = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode >= 30 && opcode < 35)
|
||||
{
|
||||
def.options[opcode - 30] = stream.readString();
|
||||
if (def.options[opcode - 30].equalsIgnoreCase("Hidden"))
|
||||
def.actions[opcode - 30] = stream.readString();
|
||||
if (def.actions[opcode - 30].equalsIgnoreCase("Hidden"))
|
||||
{
|
||||
def.options[opcode - 30] = null;
|
||||
def.actions[opcode - 30] = null;
|
||||
}
|
||||
}
|
||||
else if (opcode == 40)
|
||||
@@ -137,17 +135,17 @@ public class NpcLoader
|
||||
else if (opcode == 60)
|
||||
{
|
||||
length = stream.readUnsignedByte();
|
||||
def.models_2 = new int[length];
|
||||
def.chatheadModels = new int[length];
|
||||
|
||||
for (index = 0; index < length; ++index)
|
||||
{
|
||||
def.models_2[index] = stream.readUnsignedShort();
|
||||
def.chatheadModels[index] = stream.readUnsignedShort();
|
||||
}
|
||||
|
||||
}
|
||||
else if (opcode == 93)
|
||||
{
|
||||
def.renderOnMinimap = false;
|
||||
def.isMinimapVisible = false;
|
||||
}
|
||||
else if (opcode == 95)
|
||||
{
|
||||
@@ -155,11 +153,11 @@ public class NpcLoader
|
||||
}
|
||||
else if (opcode == 97)
|
||||
{
|
||||
def.resizeX = stream.readUnsignedShort();
|
||||
def.widthScale = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode == 98)
|
||||
{
|
||||
def.resizeY = stream.readUnsignedShort();
|
||||
def.heightScale = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode == 99)
|
||||
{
|
||||
@@ -179,18 +177,18 @@ public class NpcLoader
|
||||
}
|
||||
else if (opcode == 103)
|
||||
{
|
||||
def.rotation = stream.readUnsignedShort();
|
||||
def.rotationSpeed = stream.readUnsignedShort();
|
||||
}
|
||||
else if (opcode == 106)
|
||||
{
|
||||
def.varbitIndex = stream.readUnsignedShort();
|
||||
if ('\uffff' == def.varbitIndex)
|
||||
def.varbitId = stream.readUnsignedShort();
|
||||
if (def.varbitId == 65535)
|
||||
{
|
||||
def.varbitIndex = -1;
|
||||
def.varbitId = -1;
|
||||
}
|
||||
|
||||
def.varpIndex = stream.readUnsignedShort();
|
||||
if ('\uffff' == def.varpIndex)
|
||||
if (def.varpIndex == 65535)
|
||||
{
|
||||
def.varpIndex = -1;
|
||||
}
|
||||
@@ -212,26 +210,26 @@ public class NpcLoader
|
||||
}
|
||||
else if (opcode == 107)
|
||||
{
|
||||
def.isClickable = false;
|
||||
def.isInteractable = false;
|
||||
}
|
||||
else if (opcode == 109)
|
||||
{
|
||||
def.aBool2170 = false;
|
||||
def.rotationFlag = false;
|
||||
}
|
||||
else if (opcode == 111)
|
||||
{
|
||||
def.aBool2190 = true;
|
||||
def.isPet = true;
|
||||
}
|
||||
else if (opcode == 118)
|
||||
{
|
||||
def.varbitIndex = stream.readUnsignedShort();
|
||||
if ('\uffff' == def.varbitIndex)
|
||||
def.varbitId = stream.readUnsignedShort();
|
||||
if (def.varbitId == 65535)
|
||||
{
|
||||
def.varbitIndex = -1;
|
||||
def.varbitId = -1;
|
||||
}
|
||||
|
||||
def.varpIndex = stream.readUnsignedShort();
|
||||
if ('\uffff' == def.varpIndex)
|
||||
if (def.varpIndex == 65535)
|
||||
{
|
||||
def.varpIndex = -1;
|
||||
}
|
||||
|
||||
@@ -47,45 +47,45 @@ public class NpcSaver
|
||||
out.writeByte(2);
|
||||
out.writeString(npc.name);
|
||||
}
|
||||
if (npc.tileSpacesOccupied != 1)
|
||||
if (npc.size != 1)
|
||||
{
|
||||
out.writeByte(12);
|
||||
out.writeByte(npc.tileSpacesOccupied);
|
||||
out.writeByte(npc.size);
|
||||
}
|
||||
if (npc.stanceAnimation != -1)
|
||||
if (npc.standingAnimation != -1)
|
||||
{
|
||||
out.writeByte(13);
|
||||
out.writeShort(npc.stanceAnimation);
|
||||
out.writeShort(npc.standingAnimation);
|
||||
}
|
||||
if (npc.walkAnimation != -1)
|
||||
if (npc.walkingAnimation != -1)
|
||||
{
|
||||
out.writeByte(14);
|
||||
out.writeShort(npc.walkAnimation);
|
||||
out.writeShort(npc.walkingAnimation);
|
||||
}
|
||||
if (npc.anInt2165 != -1)
|
||||
if (npc.rotateLeftAnimation != -1)
|
||||
{
|
||||
out.writeByte(15);
|
||||
out.writeShort(npc.anInt2165);
|
||||
out.writeShort(npc.rotateLeftAnimation);
|
||||
}
|
||||
if (npc.anInt2189 != -1)
|
||||
if (npc.rotateRightAnimation != -1)
|
||||
{
|
||||
out.writeByte(16);
|
||||
out.writeShort(npc.anInt2189);
|
||||
out.writeShort(npc.rotateRightAnimation);
|
||||
}
|
||||
if (npc.rotate180Animation != -1 || npc.rotate90LeftAnimation != -1 || npc.rotate90RightAnimation != -1)
|
||||
{
|
||||
out.writeByte(17);
|
||||
out.writeShort(npc.walkAnimation);
|
||||
out.writeShort(npc.walkingAnimation);
|
||||
out.writeShort(npc.rotate180Animation);
|
||||
out.writeShort(npc.rotate90RightAnimation);
|
||||
out.writeShort(npc.rotate90LeftAnimation);
|
||||
}
|
||||
for (int i = 0; i < 5; ++i)
|
||||
{
|
||||
if (npc.options[i] != null)
|
||||
if (npc.actions[i] != null)
|
||||
{
|
||||
out.writeByte(30 + i);
|
||||
out.writeString(npc.options[i]);
|
||||
out.writeString(npc.actions[i]);
|
||||
}
|
||||
}
|
||||
if (npc.recolorToFind != null && npc.recolorToReplace != null)
|
||||
@@ -108,16 +108,16 @@ public class NpcSaver
|
||||
out.writeShort(npc.retextureToReplace[i]);
|
||||
}
|
||||
}
|
||||
if (npc.models_2 != null)
|
||||
if (npc.chatheadModels != null)
|
||||
{
|
||||
out.writeByte(60);
|
||||
out.writeByte(npc.models_2.length);
|
||||
for (int modelId : npc.models_2)
|
||||
out.writeByte(npc.chatheadModels.length);
|
||||
for (int modelId : npc.chatheadModels)
|
||||
{
|
||||
out.writeShort(modelId);
|
||||
}
|
||||
}
|
||||
if (!npc.renderOnMinimap)
|
||||
if (!npc.isMinimapVisible)
|
||||
{
|
||||
out.writeByte(93);
|
||||
}
|
||||
@@ -127,9 +127,9 @@ public class NpcSaver
|
||||
out.writeShort(npc.combatLevel);
|
||||
}
|
||||
out.writeByte(97);
|
||||
out.writeShort(npc.resizeX);
|
||||
out.writeShort(npc.widthScale);
|
||||
out.writeByte(98);
|
||||
out.writeShort(npc.resizeY);
|
||||
out.writeShort(npc.heightScale);
|
||||
if (npc.hasRenderPriority)
|
||||
{
|
||||
out.writeByte(99);
|
||||
@@ -144,23 +144,23 @@ public class NpcSaver
|
||||
out.writeShort(npc.headIcon);
|
||||
}
|
||||
out.writeByte(103);
|
||||
out.writeShort(npc.rotation);
|
||||
if (!npc.isClickable)
|
||||
out.writeShort(npc.rotationSpeed);
|
||||
if (!npc.isInteractable)
|
||||
{
|
||||
out.writeByte(107);
|
||||
}
|
||||
if (!npc.aBool2170)
|
||||
if (!npc.rotationFlag)
|
||||
{
|
||||
out.writeByte(109);
|
||||
}
|
||||
if (npc.aBool2190)
|
||||
if (npc.isPet)
|
||||
{
|
||||
out.writeByte(111);
|
||||
}
|
||||
if (npc.configs != null)
|
||||
{
|
||||
out.writeByte(118);
|
||||
out.writeShort(npc.varbitIndex);
|
||||
out.writeShort(npc.varbitId);
|
||||
out.writeShort(npc.varpIndex);
|
||||
|
||||
int[] c = npc.configs;
|
||||
|
||||
@@ -24,18 +24,19 @@
|
||||
*/
|
||||
package net.runelite.cache;
|
||||
|
||||
import com.google.common.io.FileWriteMode;
|
||||
import com.google.common.io.Files;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.nio.charset.Charset;
|
||||
import javax.sound.sampled.AudioFileFormat;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
import net.runelite.cache.definitions.loaders.sound.SoundEffectTrackLoader;
|
||||
import net.runelite.cache.definitions.sound.SoundEffectTrackDefinition;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
@@ -48,11 +49,6 @@ import org.junit.rules.TemporaryFolder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import javax.sound.sampled.AudioFileFormat;
|
||||
import javax.sound.sampled.AudioFormat;
|
||||
import javax.sound.sampled.AudioInputStream;
|
||||
import javax.sound.sampled.AudioSystem;
|
||||
|
||||
public class SoundEffectsDumperTest
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(SoundEffectsDumperTest.class);
|
||||
|
||||
@@ -28,8 +28,8 @@
|
||||
"-//Checkstyle//DTD Checkstyle Configuration 1.3//EN"
|
||||
"https://checkstyle.org/dtds/configuration_1_3.dtd">
|
||||
<module name="Checker">
|
||||
<module name="SuppressionCommentFilter"/>
|
||||
<module name="TreeWalker">
|
||||
<module name="SuppressionCommentFilter"/>
|
||||
<module name="LeftCurly">
|
||||
<property name="option" value="nl"/>
|
||||
</module>
|
||||
@@ -58,6 +58,6 @@
|
||||
<property name="message" value="Newline should not be between else and if"/>
|
||||
</module>
|
||||
<module name="SuppressionFilter">
|
||||
<property name="file" value="${suppressionFile}"/>
|
||||
<property name="file" value="${config_loc}/suppressions.xml"/>
|
||||
</module>
|
||||
</module>
|
||||
@@ -24,11 +24,11 @@
|
||||
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
-->
|
||||
<!DOCTYPE suppressions PUBLIC
|
||||
"-//Checkstyle//DTD SuppressionFilter Configuration 1.1//EN"
|
||||
"https://checkstyle.org/dtds/suppressions_1_1.dtd">
|
||||
"-//Checkstyle//DTD SuppressionFilter Configuration 1.2//EN"
|
||||
"https://checkstyle.org/dtds/suppressions_1_2.dtd">
|
||||
<suppressions>
|
||||
<suppress files="RuntimeTypeAdapterFactory\.java" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files="[\\/]runescape-client[\\/]" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files="[\\/]ScriptVarType[\./]" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files="[\\/]RoomType[\./]" checks="[a-zA-Z0-9]*"/>
|
||||
<suppress files="[\\/]LayoutSolver[\./]" checks="[a-zA-Z0-9]*"/>
|
||||
</suppressions>
|
||||
@@ -1,117 +0,0 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
import org.jetbrains.java.decompiler.main.decompiler.ConsoleDecompiler
|
||||
import java.nio.file.Files
|
||||
import java.nio.file.Paths
|
||||
import java.util.zip.ZipFile
|
||||
|
||||
plugins {
|
||||
id "com.github.hauner.jarTest" version "1.0.1"
|
||||
}
|
||||
|
||||
description = 'Deobfuscator'
|
||||
|
||||
def deobfuscatedJar = "${rootPath}/runescape-client/build/libs/rs-client-${project.version}.jar"
|
||||
|
||||
def unzipFile(String file, String dest)
|
||||
{
|
||||
def zipFile = new ZipFile(file)
|
||||
|
||||
zipFile.entries().each { it ->
|
||||
def path = Paths.get(dest + File.separator + it.name)
|
||||
if (it.directory)
|
||||
{
|
||||
Files.createDirectories(path)
|
||||
}
|
||||
else
|
||||
{
|
||||
def parentDir = path.getParent()
|
||||
if (!Files.exists(parentDir))
|
||||
{
|
||||
Files.createDirectories(parentDir)
|
||||
}
|
||||
Files.copy(zipFile.getInputStream(it), path)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
configurations {
|
||||
deobjars
|
||||
}
|
||||
|
||||
dependencies {
|
||||
deobjars group: 'net.runelite.rs', name: 'vanilla', version: rsversion
|
||||
deobjars project(':rs-client')
|
||||
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: gson
|
||||
implementation group: 'com.google.guava', name: 'guava', version: guava
|
||||
implementation group: 'net.runelite', name: 'fernflower', version: fernflower
|
||||
implementation group: 'org.ow2.asm', name: 'asm', version: asm
|
||||
implementation group: 'org.ow2.asm', name: 'asm-util', version: asm
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4j
|
||||
implementation project(':runelite-api')
|
||||
implementation project(':runescape-api')
|
||||
|
||||
runtime group: 'org.slf4j', name: 'slf4j-simple', version: slf4j
|
||||
|
||||
testImplementation configurations.deobjars.dependencies
|
||||
testImplementation group: 'junit', name: 'junit', version: junit
|
||||
testImplementation group: 'org.mockito', name: 'mockito-core', version: mockito
|
||||
}
|
||||
|
||||
processResources {
|
||||
from file("src/main/resources/deob.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"rs.version": rsversion.toString(),
|
||||
"vanilla.jar": configurations.deobjars.find {it.name.startsWith("vanilla")}.toString().replace('\\', "/"),
|
||||
"rs.client": configurations.deobjars.find {it.name.startsWith("rs-client")}.toString().replace('\\', "/")
|
||||
])
|
||||
}
|
||||
}
|
||||
processTestResources {
|
||||
from file("src/test/resources/deob-test.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"rs.client": configurations.deobjars.find {it.name.startsWith("rs-client")}.toString().replace('\\', "/"),
|
||||
"rs.version": rsversion.toString(),
|
||||
"vanilla.jar": configurations.deobjars.find {it.name.startsWith("vanilla")}.toString().replace('\\', "/")
|
||||
])
|
||||
}
|
||||
}
|
||||
|
||||
task gamepackUpdate {
|
||||
dependsOn ":deobfuscator:build"
|
||||
dependsOn ":rs-client:build"
|
||||
|
||||
doLast {
|
||||
def path = sourceSets.main.runtimeClasspath
|
||||
def loader = new URLClassLoader(path.collect { f -> f.toURI().toURL() } as URL[])
|
||||
def downloader = loader.loadClass('net.runelite.gamepack.Downloader')
|
||||
def clientVersion = loader.loadClass('net.runelite.deob.clientver.ClientVersionMain')
|
||||
def deob = loader.loadClass('net.runelite.deob.Deob')
|
||||
def mappings = loader.loadClass('net.runelite.deob.updater.UpdateMappings')
|
||||
|
||||
String gamepack = downloader.gamepack()
|
||||
int version = clientVersion.version(gamepack)
|
||||
|
||||
String gamepackVersion = gamepack.replace("gamepack.jar", "gamepack-" + version + ".jar")
|
||||
String gamepackDeob = gamepack.replace("gamepack.jar", "gamepack-" + version + "-deob.jar")
|
||||
String gamepackMappings = gamepack.replace("gamepack.jar", "gamepack-" + version + "-updated-mappings.jar")
|
||||
String gamepackMappingsDecomp = gamepackMappings.replace(".jar", "-decomp")
|
||||
String gamepackMappingsFern = gamepackMappingsDecomp + File.separator + gamepackMappings.split("/gamepack/")[1]
|
||||
|
||||
if (version == -1 || version == rsversion)
|
||||
{
|
||||
return
|
||||
}
|
||||
|
||||
deob.main(gamepackVersion, gamepackDeob)
|
||||
mappings.main(deobfuscatedJar, gamepackDeob, gamepackMappings)
|
||||
|
||||
new File(gamepackMappingsDecomp).mkdirs()
|
||||
ConsoleDecompiler.main(gamepackMappings, gamepackMappingsDecomp)
|
||||
|
||||
unzipFile(gamepackMappingsFern, gamepackMappingsDecomp)
|
||||
new File(gamepackMappingsFern).delete()
|
||||
|
||||
loader.close()
|
||||
}
|
||||
}
|
||||
93
deobfuscator/deobfuscator.gradle.kts
Normal file
93
deobfuscator/deobfuscator.gradle.kts
Normal file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
plugins {
|
||||
id(Plugins.jarTest.first) version Plugins.jarTest.second
|
||||
}
|
||||
|
||||
val deobjars = configurations.create("deobjars")
|
||||
|
||||
dependencies {
|
||||
deobjars(group = "net.runelite.rs", name = "vanilla", version = ProjectVersions.rsversion.toString())
|
||||
deobjars(project(":runescape-client"))
|
||||
|
||||
implementation(Libraries.annotations)
|
||||
implementation(Libraries.asmAll)
|
||||
implementation(Libraries.asmUtil)
|
||||
implementation(Libraries.fernflower)
|
||||
implementation(Libraries.gson)
|
||||
implementation(Libraries.guava)
|
||||
implementation(Libraries.slf4jApi)
|
||||
implementation(project(":runelite-api"))
|
||||
implementation(project(":runescape-api"))
|
||||
|
||||
runtimeOnly(Libraries.slf4jSimple)
|
||||
|
||||
testImplementation(deobjars)
|
||||
testImplementation(Libraries.junit)
|
||||
testImplementation(Libraries.mockitoCore)
|
||||
}
|
||||
|
||||
tasks {
|
||||
val tokens = mapOf(
|
||||
"rs.version" to ProjectVersions.rsversion.toString(),
|
||||
"vanilla.jar" to deobjars.find { it.name.startsWith("vanilla") }.toString().replace("\\", "/"),
|
||||
"rs.client" to deobjars.find { it.name.startsWith("runescape-client") }.toString().replace("\\", "/")
|
||||
)
|
||||
|
||||
processResources {
|
||||
finalizedBy("filterResources")
|
||||
}
|
||||
|
||||
register<Copy>("filterResources") {
|
||||
inputs.properties(tokens)
|
||||
|
||||
from("src/main/resources") {
|
||||
include("deob.properties")
|
||||
}
|
||||
into("${buildDir}/resources/main")
|
||||
|
||||
filter(ReplaceTokens::class, "tokens" to tokens)
|
||||
filteringCharset = "UTF-8"
|
||||
}
|
||||
|
||||
processTestResources {
|
||||
finalizedBy("filterTestResources")
|
||||
}
|
||||
|
||||
register<Copy>("filterTestResources") {
|
||||
inputs.properties(tokens)
|
||||
|
||||
from("src/test/resources") {
|
||||
include("deob-test.properties")
|
||||
}
|
||||
into("${buildDir}/resources/test")
|
||||
|
||||
filter(ReplaceTokens::class, "tokens" to tokens)
|
||||
filteringCharset = "UTF-8"
|
||||
}
|
||||
}
|
||||
17
deobfuscator/src/main/java/net/runelite/asm/Annotated.java
Normal file
17
deobfuscator/src/main/java/net/runelite/asm/Annotated.java
Normal file
@@ -0,0 +1,17 @@
|
||||
package net.runelite.asm;
|
||||
|
||||
import java.util.Iterator;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public interface Annotated extends Iterable<Annotation>
|
||||
{
|
||||
Annotations getAnnotations();
|
||||
|
||||
@NotNull
|
||||
default Iterator<Annotation> iterator()
|
||||
{
|
||||
return getAnnotations().iterator();
|
||||
}
|
||||
}
|
||||
@@ -31,13 +31,12 @@ import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import static net.runelite.deob.DeobAnnotations.*;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class ClassFile
|
||||
public class ClassFile implements Annotated, Named
|
||||
{
|
||||
private ClassGroup group;
|
||||
|
||||
@@ -100,10 +99,9 @@ public class ClassFile
|
||||
visitor.visit(version, access, name.getName(), null, super_class.getName(), ints);
|
||||
visitor.visitSource(source, null);
|
||||
|
||||
for (Annotation annotation : annotations.getAnnotations())
|
||||
for (Annotation annotation : annotations)
|
||||
{
|
||||
AnnotationVisitor av = visitor.visitAnnotation(annotation.getType().toString(), true);
|
||||
annotation.accept(av);
|
||||
annotation.accept(visitor.visitAnnotation(annotation.getType().toString(), true));
|
||||
}
|
||||
|
||||
for (Field field : fields)
|
||||
|
||||
@@ -27,13 +27,16 @@ package net.runelite.asm;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.function.Consumer;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import static net.runelite.deob.DeobAnnotations.*;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ClassGroup
|
||||
public class ClassGroup implements Iterable<ClassFile>
|
||||
{
|
||||
private final List<ClassFile> classes = new ArrayList<>(); // to keep order
|
||||
private final Map<String, ClassFile> classMap = new HashMap<>();
|
||||
@@ -156,4 +159,17 @@ public class ClassGroup
|
||||
|
||||
return findClass(name);
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<ClassFile> iterator()
|
||||
{
|
||||
return this.classes.iterator();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void forEach(Consumer<? super ClassFile> action)
|
||||
{
|
||||
this.classes.forEach(action);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,15 +27,13 @@ package net.runelite.asm;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
import static org.objectweb.asm.Opcodes.ACC_PRIVATE;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PROTECTED;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
|
||||
public class Field
|
||||
public class Field implements Annotated, Named
|
||||
{
|
||||
public static final int ACCESS_MODIFIERS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED;
|
||||
|
||||
@@ -53,15 +51,14 @@ public class Field
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
|
||||
annotations = new Annotations();
|
||||
this.annotations = new Annotations();
|
||||
}
|
||||
|
||||
public void accept(FieldVisitor visitor)
|
||||
{
|
||||
for (Annotation annotation : annotations.getAnnotations())
|
||||
{
|
||||
AnnotationVisitor av = visitor.visitAnnotation(annotation.getType().toString(), true);
|
||||
annotation.accept(av);
|
||||
annotation.accept(visitor.visitAnnotation(annotation.getType().toString(), true));
|
||||
}
|
||||
|
||||
visitor.visitEnd();
|
||||
|
||||
@@ -25,12 +25,14 @@
|
||||
package net.runelite.asm;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Collectors;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Interfaces
|
||||
public class Interfaces implements Iterable<Class>
|
||||
{
|
||||
private final ClassFile classFile;
|
||||
|
||||
@@ -107,4 +109,10 @@ public class Interfaces
|
||||
|
||||
return names;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Iterator<Class> iterator()
|
||||
{
|
||||
return this.interfaces.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -36,7 +36,6 @@ import net.runelite.asm.attributes.code.Parameter;
|
||||
import net.runelite.asm.attributes.code.instruction.types.LVTInstruction;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Label;
|
||||
import org.objectweb.asm.MethodVisitor;
|
||||
import static org.objectweb.asm.Opcodes.ACC_FINAL;
|
||||
@@ -47,7 +46,7 @@ import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import static org.objectweb.asm.Opcodes.ACC_STATIC;
|
||||
import static org.objectweb.asm.Opcodes.ACC_SYNCHRONIZED;
|
||||
|
||||
public class Method
|
||||
public class Method implements Annotated, Named
|
||||
{
|
||||
public static final int ACCESS_MODIFIERS = ACC_PUBLIC | ACC_PRIVATE | ACC_PROTECTED;
|
||||
|
||||
@@ -92,8 +91,7 @@ public class Method
|
||||
|
||||
for (Annotation annotation : annotations.getAnnotations())
|
||||
{
|
||||
AnnotationVisitor av = visitor.visitAnnotation(annotation.getType().toString(), true);
|
||||
annotation.accept(av);
|
||||
annotation.accept(visitor.visitAnnotation(annotation.getType().toString(), true));
|
||||
}
|
||||
|
||||
if (code != null)
|
||||
|
||||
6
deobfuscator/src/main/java/net/runelite/asm/Named.java
Normal file
6
deobfuscator/src/main/java/net/runelite/asm/Named.java
Normal file
@@ -0,0 +1,6 @@
|
||||
package net.runelite.asm;
|
||||
|
||||
public interface Named
|
||||
{
|
||||
String getName();
|
||||
}
|
||||
@@ -26,13 +26,16 @@
|
||||
package net.runelite.asm.attributes;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.attributes.annotation.SimpleElement;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Annotations
|
||||
public class Annotations implements Iterable<Annotation>
|
||||
{
|
||||
private final List<Annotation> annotations = new ArrayList<>();
|
||||
|
||||
@@ -40,7 +43,7 @@ public class Annotations
|
||||
{
|
||||
return annotations;
|
||||
}
|
||||
|
||||
|
||||
public void addAnnotation(Annotation annotation)
|
||||
{
|
||||
annotations.add(annotation);
|
||||
@@ -55,7 +58,7 @@ public class Annotations
|
||||
{
|
||||
annotations.clear();
|
||||
}
|
||||
|
||||
|
||||
public Annotation find(Type type)
|
||||
{
|
||||
for (Annotation a : annotations)
|
||||
@@ -68,18 +71,22 @@ public class Annotations
|
||||
{
|
||||
return annotations.size();
|
||||
}
|
||||
|
||||
|
||||
public Annotation addAnnotation(Type type, String name, Object value)
|
||||
{
|
||||
Annotation annotation = new Annotation(this);
|
||||
annotation.setType(type);
|
||||
Annotation annotation = new Annotation(type);
|
||||
addAnnotation(annotation);
|
||||
|
||||
Element element = new Element(annotation);
|
||||
element.setName(name);
|
||||
element.setValue(value);
|
||||
|
||||
Element element = new SimpleElement(name, value);
|
||||
annotation.addElement(element);
|
||||
|
||||
return annotation;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<Annotation> iterator()
|
||||
{
|
||||
return this.annotations.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -41,11 +41,11 @@ public class Code
|
||||
private int maxStack;
|
||||
private Instructions instructions;
|
||||
private final Exceptions exceptions;
|
||||
|
||||
|
||||
public Code(Method method)
|
||||
{
|
||||
this.method = method;
|
||||
|
||||
|
||||
exceptions = new Exceptions(this);
|
||||
instructions = new Instructions(this);
|
||||
}
|
||||
@@ -59,12 +59,12 @@ public class Code
|
||||
{
|
||||
return maxStack;
|
||||
}
|
||||
|
||||
|
||||
public void setMaxStack(int maxStack)
|
||||
{
|
||||
this.maxStack = maxStack;
|
||||
}
|
||||
|
||||
|
||||
private int getMaxLocalsFromSig()
|
||||
{
|
||||
Method m = getMethod();
|
||||
@@ -77,12 +77,11 @@ public class Code
|
||||
|
||||
/**
|
||||
* calculates the size of the lvt required for this method
|
||||
* @return
|
||||
*/
|
||||
public int getMaxLocals()
|
||||
{
|
||||
int max = -1;
|
||||
|
||||
|
||||
for (Instruction ins : instructions.getInstructions())
|
||||
{
|
||||
if (ins instanceof LVTInstruction)
|
||||
@@ -96,19 +95,19 @@ public class Code
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int fromSig = getMaxLocalsFromSig();
|
||||
if (fromSig > max)
|
||||
max = fromSig;
|
||||
|
||||
|
||||
return max;
|
||||
}
|
||||
|
||||
|
||||
public Exceptions getExceptions()
|
||||
{
|
||||
return exceptions;
|
||||
}
|
||||
|
||||
|
||||
public Instructions getInstructions()
|
||||
{
|
||||
return instructions;
|
||||
|
||||
@@ -26,30 +26,26 @@
|
||||
package net.runelite.asm.attributes.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
|
||||
public class Annotation
|
||||
public class Annotation extends Element<List<Element>> implements Iterable<Element>
|
||||
{
|
||||
private final Annotations annotations;
|
||||
private Type type;
|
||||
private final List<Element> elements = new ArrayList<>();
|
||||
private final Type type;
|
||||
|
||||
public Annotation(Annotations annotations)
|
||||
public Annotation(Type type)
|
||||
{
|
||||
this.annotations = annotations;
|
||||
this.value = new ArrayList<>();
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public Annotations getAnnotations()
|
||||
{
|
||||
return annotations;
|
||||
}
|
||||
|
||||
public void setType(Type type)
|
||||
public Annotation(String name, Type type)
|
||||
{
|
||||
this.value = new ArrayList<>();
|
||||
this.name = name;
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@@ -60,23 +56,44 @@ public class Annotation
|
||||
|
||||
public List<Element> getElements()
|
||||
{
|
||||
return elements;
|
||||
return value;
|
||||
}
|
||||
|
||||
|
||||
public Element getElement()
|
||||
{
|
||||
return elements.get(0);
|
||||
return value.get(0);
|
||||
}
|
||||
|
||||
|
||||
public void addElement(Element element)
|
||||
{
|
||||
elements.add(element);
|
||||
value.add(element);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public final void setValue(List<Element> value)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
public void accept(AnnotationVisitor visitor)
|
||||
{
|
||||
for (Element element : elements)
|
||||
visitor.visit(element.getName(), element.getValue());
|
||||
if (visitor == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Element element : this)
|
||||
{
|
||||
accept(visitor, element.name, element.value);
|
||||
}
|
||||
|
||||
visitor.visitEnd();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
public Iterator<Element> iterator()
|
||||
{
|
||||
return this.value.iterator();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,42 @@
|
||||
package net.runelite.asm.attributes.annotation;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.stream.Stream;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class ArrayElement extends Element<List> implements Iterable<Object>
|
||||
{
|
||||
public ArrayElement(String name)
|
||||
{
|
||||
this.name = name;
|
||||
this.value = new ArrayList<>();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void addValue(Object value)
|
||||
{
|
||||
this.value.add(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public final void setValue(List value)
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public Iterator<Object> iterator()
|
||||
{
|
||||
return this.value.iterator();
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Stream<Object> stream()
|
||||
{
|
||||
return this.value.stream();
|
||||
}
|
||||
}
|
||||
@@ -25,21 +25,14 @@
|
||||
|
||||
package net.runelite.asm.attributes.annotation;
|
||||
|
||||
public class Element
|
||||
{
|
||||
private final Annotation annotation;
|
||||
private String name;
|
||||
private Object value;
|
||||
|
||||
public Element(Annotation annotation)
|
||||
{
|
||||
this.annotation = annotation;
|
||||
}
|
||||
import java.util.List;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
|
||||
public Annotation getAnnotation()
|
||||
{
|
||||
return annotation;
|
||||
}
|
||||
public abstract class Element<T>
|
||||
{
|
||||
String name = "value";
|
||||
|
||||
T value;
|
||||
|
||||
public String getName()
|
||||
{
|
||||
@@ -51,18 +44,48 @@ public class Element
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public Object getValue()
|
||||
public T getValue()
|
||||
{
|
||||
return value;
|
||||
}
|
||||
|
||||
public void setValue(Object value)
|
||||
public void setValue(T value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
|
||||
public String getString()
|
||||
{
|
||||
return value.toString();
|
||||
}
|
||||
|
||||
public static void accept(AnnotationVisitor visitor, final String name, final Object value)
|
||||
{
|
||||
if (visitor == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (value instanceof Annotation)
|
||||
{
|
||||
Annotation annotation = (Annotation) value;
|
||||
annotation.accept(visitor.visitAnnotation(name, annotation.getType().toString()));
|
||||
}
|
||||
else if (value instanceof List)
|
||||
{
|
||||
AnnotationVisitor arr = visitor.visitArray(name);
|
||||
List<?> arrayValue = (List<?>) value;
|
||||
|
||||
for (Object o : arrayValue)
|
||||
{
|
||||
accept(arr, null, o);
|
||||
}
|
||||
|
||||
arr.visitEnd();
|
||||
}
|
||||
else
|
||||
{
|
||||
visitor.visit(name, value);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
package net.runelite.asm.attributes.annotation;
|
||||
|
||||
public class SimpleElement extends Element<Object>
|
||||
{
|
||||
public SimpleElement(Object value)
|
||||
{
|
||||
this.value = value;
|
||||
}
|
||||
|
||||
public SimpleElement(String name, Object value)
|
||||
{
|
||||
this.name = name;
|
||||
this.value = value;
|
||||
}
|
||||
}
|
||||
@@ -26,11 +26,14 @@ package net.runelite.asm.attributes.code;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.ListIterator;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class Instructions
|
||||
public class Instructions implements Iterable<Instruction>
|
||||
{
|
||||
private final Code code;
|
||||
private final List<Instruction> instructions = new ArrayList<>();
|
||||
@@ -186,4 +189,25 @@ public class Instructions
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
public int size()
|
||||
{
|
||||
return this.instructions.size();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public Iterator<Instruction> iterator()
|
||||
{
|
||||
return this.instructions.iterator();
|
||||
}
|
||||
|
||||
public ListIterator<Instruction> listIterator()
|
||||
{
|
||||
return this.instructions.listIterator();
|
||||
}
|
||||
|
||||
public ListIterator<Instruction> listIterator(int i)
|
||||
{
|
||||
return this.instructions.listIterator(i);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -52,8 +52,7 @@ public abstract class ArrayStore extends Instruction implements ArrayStoreInstru
|
||||
if (r.getInstruction() instanceof GetFieldInstruction)
|
||||
{
|
||||
GetFieldInstruction gf = (GetFieldInstruction) r.getInstruction();
|
||||
Field f = gf.getMyField();
|
||||
return f;
|
||||
return gf.getMyField();
|
||||
}
|
||||
|
||||
return null;
|
||||
@@ -89,7 +88,7 @@ public abstract class ArrayStore extends Instruction implements ArrayStoreInstru
|
||||
|
||||
Field f1 = gf1.getMyField(),
|
||||
f2 = gf2.getMyField();
|
||||
|
||||
|
||||
assert MappingExecutorUtil.isMaybeEqual(f1, f2);
|
||||
|
||||
if (f1 != null && f2 != null)
|
||||
|
||||
@@ -24,7 +24,6 @@
|
||||
*/
|
||||
package net.runelite.asm.attributes.code.instructions;
|
||||
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.List;
|
||||
import net.runelite.asm.ClassFile;
|
||||
@@ -86,7 +85,7 @@ public class InvokeStatic extends Instruction implements InvokeInstruction
|
||||
@SuppressWarnings("unchecked")
|
||||
public List<net.runelite.asm.Method> getMethods()
|
||||
{
|
||||
return myMethod != null ? Arrays.asList(myMethod) : Collections.EMPTY_LIST;
|
||||
return myMethod != null ? Collections.singletonList(myMethod) : Collections.EMPTY_LIST;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -70,10 +70,9 @@ public class MethodContext
|
||||
return contexts.get(i);
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public Collection<InstructionContext> getInstructionContexts()
|
||||
{
|
||||
return (Collection) contexts.values();
|
||||
return contexts.values();
|
||||
}
|
||||
|
||||
public void reset()
|
||||
|
||||
@@ -43,8 +43,21 @@ public class NonloadingClassWriter extends ClassWriter
|
||||
@Override
|
||||
protected String getCommonSuperClass(String type1, String type2)
|
||||
{
|
||||
ClassFile cf1 = group.findClass(type1),
|
||||
cf2 = group.findClass(type2);
|
||||
// Checking more than this wouldn't make any sense
|
||||
// Object has no super class, and RS api is guaranteed to be interfaces, which always extend from Object
|
||||
// some rl api classes however ARE actual classes, so we can't just assume interface, for the slim chance
|
||||
// we've got rl api on classpath. We could check all implemented interfaces in group, but that means you end up
|
||||
// with Object as super class anyway, just like if you just let the Class.forName call throw.
|
||||
// (maybe we could if we had a better package structure...)
|
||||
if (type1.equals("java/lang/Object")
|
||||
|| type2.equals("java/lang/Object")
|
||||
|| type1.startsWith("net/runelite/rs/api/RS")
|
||||
|| type2.startsWith("net/runelite/rs/api/RS")
|
||||
)
|
||||
return "java/lang/Object";
|
||||
|
||||
ClassFile cf1 = group.findClass(type1);
|
||||
ClassFile cf2 = group.findClass(type2);
|
||||
|
||||
if (cf1 == null && cf2 == null)
|
||||
{
|
||||
@@ -62,10 +75,11 @@ public class NonloadingClassWriter extends ClassWriter
|
||||
|
||||
if (cf1 != null && cf2 != null)
|
||||
{
|
||||
for (ClassFile c = cf1; c != null; c = c.getParent())
|
||||
for (ClassFile c2 = cf2; c2 != null; c2 = c2.getParent())
|
||||
if (c == c2)
|
||||
return c.getName();
|
||||
if (!(cf1.isInterface() || cf2.isInterface()))
|
||||
for (ClassFile c = cf1; c != null; c = c.getParent())
|
||||
for (ClassFile c2 = cf2; c2 != null; c2 = c2.getParent())
|
||||
if (c == c2)
|
||||
return c.getName();
|
||||
|
||||
return "java/lang/Object";
|
||||
}
|
||||
@@ -80,7 +94,6 @@ public class NonloadingClassWriter extends ClassWriter
|
||||
}
|
||||
else
|
||||
{
|
||||
assert cf2 == null;
|
||||
found = cf1;
|
||||
other = type2;
|
||||
}
|
||||
@@ -88,13 +101,10 @@ public class NonloadingClassWriter extends ClassWriter
|
||||
ClassFile prev = null;
|
||||
|
||||
for (ClassFile c = found; c != null; c = c.getParent())
|
||||
{
|
||||
prev = c;
|
||||
|
||||
if (c.getName().equals(other))
|
||||
if ((prev = c).getSuperName().equals(other))
|
||||
return other;
|
||||
}
|
||||
|
||||
// This should pretty much never be hit, right?
|
||||
return super.getCommonSuperClass(prev.getSuperName(), other);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,44 +25,59 @@
|
||||
|
||||
package net.runelite.asm.visitors;
|
||||
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.attributes.annotation.ArrayElement;
|
||||
import net.runelite.asm.attributes.annotation.SimpleElement;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class MethodAnnotationVisitor extends AnnotationVisitor
|
||||
public class AnnotationElementVisitor extends AnnotationVisitor
|
||||
{
|
||||
private final Method method;
|
||||
private final Type type;
|
||||
private final Annotation annotation;
|
||||
|
||||
public MethodAnnotationVisitor(Method method, Type type)
|
||||
|
||||
AnnotationElementVisitor(Annotation annotation)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
|
||||
this.method = method;
|
||||
this.type = type;
|
||||
|
||||
annotation = new Annotation(method.getAnnotations());
|
||||
annotation.setType(type);
|
||||
|
||||
this.annotation = annotation;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visit(String name, Object value)
|
||||
{
|
||||
Element element = new Element(annotation);
|
||||
|
||||
element.setName(name);
|
||||
element.setValue(value);
|
||||
|
||||
SimpleElement element = new SimpleElement(name, value);
|
||||
annotation.addElement(element);
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
public AnnotationVisitor visitArray(String name)
|
||||
{
|
||||
method.getAnnotations().addAnnotation(annotation);
|
||||
ArrayElement element = new ArrayElement(name);
|
||||
this.annotation.addElement(element);
|
||||
return new AnnotationVisitor(Opcodes.ASM5)
|
||||
{
|
||||
@Override
|
||||
public void visit(String name, Object value)
|
||||
{
|
||||
element.addValue(value);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String name, String descriptor)
|
||||
{
|
||||
Annotation annotation = new Annotation(name, new Type(descriptor));
|
||||
element.addValue(annotation);
|
||||
return new AnnotationElementVisitor(annotation);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String name, String descriptor)
|
||||
{
|
||||
Annotation annotation = new Annotation(name, new Type(descriptor));
|
||||
this.annotation.addElement(annotation);
|
||||
return new AnnotationElementVisitor(annotation);
|
||||
}
|
||||
}
|
||||
@@ -22,12 +22,12 @@
|
||||
* (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.asm.visitors;
|
||||
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Attribute;
|
||||
import org.objectweb.asm.FieldVisitor;
|
||||
@@ -35,25 +35,25 @@ import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class ClassFieldVisitor extends FieldVisitor
|
||||
{
|
||||
private final ClassFile classFile;
|
||||
private final Field field;
|
||||
|
||||
public ClassFieldVisitor(ClassFile cf, int access, String name, Type desc, Object value)
|
||||
ClassFieldVisitor(ClassFile cf, int access, String name, Type desc, Object value)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
|
||||
this.classFile = cf;
|
||||
this.field = new Field(cf, name, desc);
|
||||
this.field.setAccessFlags(access);
|
||||
this.field.setValue(value);
|
||||
|
||||
field = new Field(cf, name, desc);
|
||||
field.setAccessFlags(access);
|
||||
field.setValue(value);
|
||||
cf.addField(field);
|
||||
}
|
||||
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
|
||||
{
|
||||
Type type = new Type(desc);
|
||||
return new FieldAnnotationVisitor(field, type);
|
||||
Annotation element = new Annotation(new Type(desc));
|
||||
this.field.getAnnotations().addAnnotation(element);
|
||||
return new AnnotationElementVisitor(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -61,10 +61,4 @@ public class ClassFieldVisitor extends FieldVisitor
|
||||
{
|
||||
System.out.println(attr);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
classFile.addField(field);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ package net.runelite.asm.visitors;
|
||||
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.ClassVisitor;
|
||||
@@ -55,7 +56,7 @@ public class ClassFileVisitor extends ClassVisitor
|
||||
classFile.setSuperName(superName);
|
||||
classFile.setVersion(version);
|
||||
classFile.setAccess(access);
|
||||
|
||||
|
||||
for (String inter : interfaces)
|
||||
classFile.getInterfaces().addInterface(new net.runelite.asm.pool.Class(inter));
|
||||
}
|
||||
@@ -69,8 +70,10 @@ public class ClassFileVisitor extends ClassVisitor
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
|
||||
{
|
||||
Type type = new Type(desc);
|
||||
return new ClassAnnotationVisitor(classFile, type);
|
||||
Annotation annotation = new Annotation(new Type(desc));
|
||||
classFile.getAnnotations().addAnnotation(annotation);
|
||||
|
||||
return new AnnotationElementVisitor(annotation);
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -32,6 +32,7 @@ import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.code.Exceptions;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
@@ -72,18 +73,14 @@ import static org.objectweb.asm.Opcodes.ICONST_5;
|
||||
import static org.objectweb.asm.Opcodes.ICONST_M1;
|
||||
import static org.objectweb.asm.Opcodes.LCONST_0;
|
||||
import static org.objectweb.asm.Opcodes.LCONST_1;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CodeVisitor extends MethodVisitor
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CodeVisitor.class);
|
||||
|
||||
private final ClassFile classFile;
|
||||
private final Method method;
|
||||
private Code code;
|
||||
|
||||
public CodeVisitor(ClassFile classFile, int access, String name, Signature signature, String[] sexceptions)
|
||||
CodeVisitor(ClassFile classFile, int access, String name, Signature signature, String[] sexceptions)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
|
||||
@@ -111,8 +108,9 @@ public class CodeVisitor extends MethodVisitor
|
||||
@Override
|
||||
public AnnotationVisitor visitAnnotation(String desc, boolean visible)
|
||||
{
|
||||
Type type = new Type(desc);
|
||||
return new MethodAnnotationVisitor(method, type);
|
||||
Annotation element = new Annotation(new Type(desc));
|
||||
this.method.getAnnotations().addAnnotation(element);
|
||||
return new AnnotationElementVisitor(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -333,7 +331,7 @@ public class CodeVisitor extends MethodVisitor
|
||||
if (cst instanceof org.objectweb.asm.Type)
|
||||
{
|
||||
org.objectweb.asm.Type t = (org.objectweb.asm.Type) cst;
|
||||
entry = new net.runelite.asm.pool.Class((String) t.getClassName());
|
||||
entry = new net.runelite.asm.pool.Class(t.getClassName());
|
||||
}
|
||||
|
||||
LDC ldc = new LDC(code.getInstructions(), entry);
|
||||
|
||||
@@ -1,68 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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.asm.visitors;
|
||||
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import org.objectweb.asm.AnnotationVisitor;
|
||||
import org.objectweb.asm.Opcodes;
|
||||
|
||||
public class FieldAnnotationVisitor extends AnnotationVisitor
|
||||
{
|
||||
private final Field field;
|
||||
private final Type type;
|
||||
private final Annotation annotation;
|
||||
|
||||
public FieldAnnotationVisitor(Field field, Type type)
|
||||
{
|
||||
super(Opcodes.ASM5);
|
||||
|
||||
this.field = field;
|
||||
this.type = type;
|
||||
|
||||
annotation = new Annotation(field.getAnnotations());
|
||||
annotation.setType(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visit(String name, Object value)
|
||||
{
|
||||
Element element = new Element(annotation);
|
||||
|
||||
element.setName(name);
|
||||
element.setValue(value);
|
||||
|
||||
annotation.addElement(element);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void visitEnd()
|
||||
{
|
||||
field.getAnnotations().addAnnotation(annotation);
|
||||
}
|
||||
}
|
||||
@@ -95,7 +95,7 @@ public class DeobAnnotations
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
return (Number) an.getElement().getValue();
|
||||
}
|
||||
|
||||
|
||||
@@ -193,6 +193,7 @@ public class Renamer implements Deobfuscator
|
||||
}
|
||||
|
||||
@Override
|
||||
@SuppressWarnings("unchecked")
|
||||
public void run(ClassGroup group)
|
||||
{
|
||||
group.buildClassGraph();
|
||||
|
||||
@@ -37,6 +37,7 @@ import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.attributes.annotation.SimpleElement;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.InstructionType;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
@@ -113,7 +114,6 @@ public class ConstantParameter implements Deobfuscator
|
||||
|
||||
List<StackContext> pops = invokeCtx.getPops();
|
||||
|
||||
outer:
|
||||
// object is popped first, then param 1, 2, 3, etc. double and long take two slots.
|
||||
for (int lvtOffset = offset, parameterIndex = 0;
|
||||
parameterIndex < method.getDescriptor().size();
|
||||
@@ -451,9 +451,7 @@ public class ConstantParameter implements Deobfuscator
|
||||
}
|
||||
|
||||
// Add garbage value
|
||||
Element element = new Element(obfuscatedSignature);
|
||||
element.setName("garbageValue");
|
||||
element.setValue(value.toString());
|
||||
Element element = new SimpleElement("garbageValue", value.toString());
|
||||
obfuscatedSignature.addElement(element);
|
||||
}
|
||||
}
|
||||
@@ -464,12 +462,12 @@ public class ConstantParameter implements Deobfuscator
|
||||
public void run(ClassGroup group)
|
||||
{
|
||||
Execution execution = new Execution(group);
|
||||
execution.addExecutionVisitor(i -> findParameters(i));
|
||||
execution.addExecutionVisitor(this::findParameters);
|
||||
execution.populateInitialMethods();
|
||||
execution.run();
|
||||
|
||||
execution = new Execution(group);
|
||||
execution.addMethodContextVisitor(mc -> findDeadParameters(mc));
|
||||
execution.addMethodContextVisitor(this::findDeadParameters);
|
||||
execution.populateInitialMethods();
|
||||
execution.run();
|
||||
|
||||
|
||||
@@ -32,6 +32,7 @@ import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.attributes.annotation.SimpleElement;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@@ -39,7 +40,7 @@ import org.slf4j.LoggerFactory;
|
||||
public class AnnotationMapper
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(AnnotationMapper.class);
|
||||
|
||||
|
||||
private final ClassGroup source, target;
|
||||
private final ParallelExecutorMapping mapping;
|
||||
|
||||
@@ -119,20 +120,17 @@ public class AnnotationMapper
|
||||
|
||||
if (from.getAnnotations() == null)
|
||||
return count;
|
||||
|
||||
|
||||
for (Annotation a : from.getAnnotations())
|
||||
{
|
||||
if (isCopyable(a))
|
||||
{
|
||||
Annotation annotation = new Annotation(to);
|
||||
annotation.setType(a.getType());
|
||||
Annotation annotation = new Annotation(a.getType());
|
||||
to.addAnnotation(annotation);
|
||||
|
||||
for (Element e : a.getElements())
|
||||
{
|
||||
Element element = new Element(annotation);
|
||||
element.setName(e.getName());
|
||||
element.setValue(e.getValue());
|
||||
Element element = new SimpleElement(e.getName(), e.getValue());
|
||||
annotation.addElement(element);
|
||||
}
|
||||
|
||||
@@ -155,7 +153,6 @@ public class AnnotationMapper
|
||||
private boolean isCopyable(Annotation a)
|
||||
{
|
||||
return a.getType().equals(DeobAnnotations.EXPORT)
|
||||
|| a.getType().equals(DeobAnnotations.IMPLEMENTS)
|
||||
|| a.getType().equals(DeobAnnotations.HOOK);
|
||||
|| a.getType().equals(DeobAnnotations.IMPLEMENTS);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -8,6 +8,7 @@ import net.runelite.asm.Method;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.attributes.annotation.SimpleElement;
|
||||
import net.runelite.deob.Deob;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import org.slf4j.Logger;
|
||||
@@ -23,6 +24,7 @@ public class AnnotationAdder
|
||||
private final ClassGroup group;
|
||||
private final Logger log = LoggerFactory.getLogger(AnnotationAdder.class);
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
public void run()
|
||||
{
|
||||
int impl = 0;
|
||||
@@ -50,12 +52,9 @@ public class AnnotationAdder
|
||||
{
|
||||
Annotations an = c.getAnnotations();
|
||||
|
||||
Annotation implAn = new Annotation(an);
|
||||
implAn.setType(DeobAnnotations.IMPLEMENTS);
|
||||
Annotation implAn = new Annotation(DeobAnnotations.IMPLEMENTS);
|
||||
|
||||
Element value = new Element(implAn);
|
||||
value.setValue(c.getClassName());
|
||||
value.setName("value");
|
||||
Element value = new SimpleElement(c.getClassName());
|
||||
|
||||
implAn.addElement(value);
|
||||
an.addAnnotation(implAn);
|
||||
@@ -81,12 +80,9 @@ public class AnnotationAdder
|
||||
Annotation a = an.find(DeobAnnotations.EXPORT);
|
||||
if (a == null)
|
||||
{
|
||||
a = new Annotation(an);
|
||||
a.setType(DeobAnnotations.EXPORT);
|
||||
a = new Annotation(DeobAnnotations.EXPORT);
|
||||
|
||||
Element value = new Element(a);
|
||||
value.setValue(fieldName);
|
||||
value.setName("value");
|
||||
Element value = new SimpleElement(fieldName);
|
||||
a.addElement(value);
|
||||
an.addAnnotation(a);
|
||||
|
||||
@@ -114,12 +110,9 @@ public class AnnotationAdder
|
||||
Annotation a = an.find(DeobAnnotations.EXPORT);
|
||||
if (a == null)
|
||||
{
|
||||
a = new Annotation(an);
|
||||
a.setType(DeobAnnotations.EXPORT);
|
||||
a = new Annotation(DeobAnnotations.EXPORT);
|
||||
|
||||
Element value = new Element(a);
|
||||
value.setValue(methodName);
|
||||
value.setName("value");
|
||||
Element value = new SimpleElement(methodName);
|
||||
a.addElement(value);
|
||||
an.addAnnotation(a);
|
||||
|
||||
|
||||
@@ -34,6 +34,7 @@ import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.annotation.Element;
|
||||
import net.runelite.asm.attributes.annotation.SimpleElement;
|
||||
|
||||
public class AnnotationCopier
|
||||
{
|
||||
@@ -97,15 +98,12 @@ public class AnnotationCopier
|
||||
{
|
||||
if (!isType(a.getType()))
|
||||
continue;
|
||||
|
||||
Annotation a2 = new Annotation(an2);
|
||||
a2.setType(a.getType());
|
||||
|
||||
Annotation a2 = new Annotation(a.getType());
|
||||
|
||||
for (Element element : a.getElements())
|
||||
{
|
||||
Element element2 = new Element(a2);
|
||||
element2.setName(element.getName());
|
||||
element2.setValue(element.getValue());
|
||||
Element element2 = new SimpleElement(element.getName(), element.getValue());
|
||||
a2.addElement(element2);
|
||||
}
|
||||
|
||||
|
||||
@@ -34,13 +34,9 @@ import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.deobfuscators.Renamer;
|
||||
import net.runelite.deob.util.NameMappings;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class AnnotationRenamer
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(AnnotationRenamer.class);
|
||||
|
||||
private ClassGroup group;
|
||||
|
||||
public AnnotationRenamer(ClassGroup group)
|
||||
|
||||
@@ -25,9 +25,11 @@
|
||||
package net.runelite.deob.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.FileOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Collection;
|
||||
import java.util.Enumeration;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarFile;
|
||||
@@ -79,6 +81,41 @@ public class JarUtil
|
||||
return group;
|
||||
}
|
||||
|
||||
public static ClassFile loadClass(byte[] bytes)
|
||||
{
|
||||
ClassReader reader = new ClassReader(bytes);
|
||||
ClassFileVisitor cv = new ClassFileVisitor();
|
||||
reader.accept(cv, ClassReader.SKIP_FRAMES);
|
||||
return cv.getClassFile();
|
||||
}
|
||||
|
||||
public static ClassGroup loadClasses(Collection<File> files) throws IOException
|
||||
{
|
||||
final ClassGroup group = new ClassGroup();
|
||||
|
||||
for (File file : files)
|
||||
{
|
||||
if (!file.getName().endsWith(".class"))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
try (InputStream is = new FileInputStream(file))
|
||||
{
|
||||
ClassReader reader = new ClassReader(is);
|
||||
ClassFileVisitor cv = new ClassFileVisitor();
|
||||
|
||||
reader.accept(cv, ClassReader.SKIP_FRAMES);
|
||||
|
||||
group.addClass(cv.getClassFile());
|
||||
}
|
||||
}
|
||||
|
||||
group.initialize();
|
||||
|
||||
return group;
|
||||
}
|
||||
|
||||
public static void saveJar(ClassGroup group, File jarfile) throws IOException
|
||||
{
|
||||
try (JarOutputStream jout = new JarOutputStream(new FileOutputStream(jarfile), new Manifest()))
|
||||
|
||||
@@ -276,8 +276,7 @@ public class HookImporter
|
||||
{
|
||||
for (Element e : a.getElements())
|
||||
{
|
||||
String str = (String) e.getValue();
|
||||
return str;
|
||||
return (String) e.getValue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -288,7 +287,7 @@ public class HookImporter
|
||||
private Signature getObfuscatedMethodSignature(Method method)
|
||||
{
|
||||
String sig = getAnnotation(method.getAnnotations(), OBFUSCATED_SIGNATURE);
|
||||
if (sig.isEmpty() == false)
|
||||
if (!sig.isEmpty())
|
||||
{
|
||||
return toObSignature(new Signature(sig)); // if it is annoted, use that
|
||||
}
|
||||
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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.runeloader;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import java.lang.reflect.Field;
|
||||
import java.net.MalformedURLException;
|
||||
import java.net.URL;
|
||||
import java.net.URLClassLoader;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import net.runelite.mapping.Export;
|
||||
import net.runelite.mapping.ObfuscatedGetter;
|
||||
import net.runelite.mapping.ObfuscatedName;
|
||||
import net.runelite.runeloader.inject.GetterInjectInstruction;
|
||||
import net.runelite.runeloader.inject.Injection;
|
||||
import net.runelite.runeloader.inject.InjectionModscript;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
|
||||
public class CheckMappings
|
||||
{
|
||||
private static final File CLIENT = new File("d:/rs/07/adamout.jar");
|
||||
|
||||
private final List<Class> classes = new ArrayList<>();
|
||||
|
||||
@Before
|
||||
public void before() throws MalformedURLException, ClassNotFoundException
|
||||
{
|
||||
ClassLoader loader = new URLClassLoader(new URL[]{CLIENT.toURI().toURL()});
|
||||
|
||||
Class c = loader.loadClass("client");
|
||||
classes.add(c);
|
||||
|
||||
for (int i = 0; i < 230; ++i)
|
||||
{
|
||||
try
|
||||
{
|
||||
c = loader.loadClass("class" + i);
|
||||
classes.add(c);
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("unchecked")
|
||||
private Class<?> findClassWithObfuscatedName(String name)
|
||||
{
|
||||
for (Class c : classes)
|
||||
{
|
||||
if (c.getName().equals("net.runelite.rs.client.client") && name.equals("client"))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
|
||||
ObfuscatedName oc = (ObfuscatedName) c.getDeclaredAnnotation(ObfuscatedName.class);
|
||||
if (oc == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oc.value().equals(name))
|
||||
{
|
||||
return c;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Field findFieldWithObfuscatedName(Class c, String name)
|
||||
{
|
||||
for (Field f : c.getDeclaredFields())
|
||||
{
|
||||
ObfuscatedName oc = f.getDeclaredAnnotation(ObfuscatedName.class);
|
||||
if (oc == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
if (oc.value().equals(name))
|
||||
{
|
||||
return f;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private Integer getIntegerMultiplier(Field f)
|
||||
{
|
||||
ObfuscatedGetter getter = f.getDeclaredAnnotation(ObfuscatedGetter.class);
|
||||
if (getter == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return getter.intValue() == 0 ? null : getter.intValue();
|
||||
}
|
||||
|
||||
private String getExportedName(Field f)
|
||||
{
|
||||
Export e = f.getDeclaredAnnotation(Export.class);
|
||||
if (e == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
return e.value();
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void checkMappings() throws IOException
|
||||
{
|
||||
InjectionModscript mod = Injection.load(MappingImporter.class.getResourceAsStream(MappingImporter.RL_INJECTION));
|
||||
|
||||
for (int i = 0; i < mod.getGetterInjects().size(); ++i)
|
||||
{
|
||||
GetterInjectInstruction gii = mod.getGetterInjects().get(i);
|
||||
|
||||
Class c = this.findClassWithObfuscatedName(gii.getGetterClassName());
|
||||
Assert.assertNotNull(c);
|
||||
|
||||
Field f = this.findFieldWithObfuscatedName(c, gii.getGetterFieldName());
|
||||
Assert.assertNotNull(f);
|
||||
|
||||
String exportedName = this.getExportedName(f);
|
||||
String attrName = gii.getGetterName();
|
||||
attrName = Utils.toExportedName(attrName);
|
||||
|
||||
Integer mul = gii.getMultiplier(),
|
||||
myMul = this.getIntegerMultiplier(f);
|
||||
|
||||
// XXX Check @Export etc names
|
||||
|
||||
//Assert.assertEquals(exportedName, attrName);
|
||||
Assert.assertEquals(myMul, mul);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -3,4 +3,4 @@ org.gradle.warning.mode=all
|
||||
org.gradle.parallel=true
|
||||
org.gradle.console=rich
|
||||
org.gradle.configureondemand=true
|
||||
org.gradle.jvmargs=-Xmx4096m -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
org.gradle.jvmargs=-XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8
|
||||
|
||||
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
BIN
gradle/wrapper/gradle-wrapper.jar
vendored
Binary file not shown.
2
gradle/wrapper/gradle-wrapper.properties
vendored
2
gradle/wrapper/gradle-wrapper.properties
vendored
@@ -1,5 +1,5 @@
|
||||
distributionBase=GRADLE_USER_HOME
|
||||
distributionPath=wrapper/dists
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-5.6.2-all.zip
|
||||
distributionUrl=https\://services.gradle.org/distributions/gradle-6.0-all.zip
|
||||
zipStoreBase=GRADLE_USER_HOME
|
||||
zipStorePath=wrapper/dists
|
||||
|
||||
31
gradlew
vendored
31
gradlew
vendored
@@ -44,7 +44,7 @@ APP_NAME="Gradle"
|
||||
APP_BASE_NAME=`basename "$0"`
|
||||
|
||||
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
DEFAULT_JVM_OPTS='"-Xmx4g" "-Xms2g" "-Dfile.encoding=UTF-8"'
|
||||
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
|
||||
|
||||
# Use the maximum available, or set MAX_FD != -1 to use that value.
|
||||
MAX_FD="maximum"
|
||||
@@ -154,19 +154,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
|
||||
else
|
||||
eval `echo args$i`="\"$arg\""
|
||||
fi
|
||||
i=$((i+1))
|
||||
i=`expr $i + 1`
|
||||
done
|
||||
case $i in
|
||||
(0) set -- ;;
|
||||
(1) set -- "$args0" ;;
|
||||
(2) set -- "$args0" "$args1" ;;
|
||||
(3) set -- "$args0" "$args1" "$args2" ;;
|
||||
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
0) set -- ;;
|
||||
1) set -- "$args0" ;;
|
||||
2) set -- "$args0" "$args1" ;;
|
||||
3) set -- "$args0" "$args1" "$args2" ;;
|
||||
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
|
||||
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
|
||||
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
|
||||
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
|
||||
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
|
||||
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
|
||||
esac
|
||||
fi
|
||||
|
||||
@@ -175,14 +175,9 @@ save () {
|
||||
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
|
||||
echo " "
|
||||
}
|
||||
APP_ARGS=$(save "$@")
|
||||
APP_ARGS=`save "$@"`
|
||||
|
||||
# Collect all arguments for the java command, following the shell quoting and substitution rules
|
||||
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
|
||||
|
||||
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
|
||||
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
|
||||
cd "$(dirname "$0")"
|
||||
fi
|
||||
|
||||
exec "$JAVACMD" "$@"
|
||||
|
||||
2
gradlew.bat
vendored
2
gradlew.bat
vendored
@@ -30,7 +30,7 @@ set APP_BASE_NAME=%~n0
|
||||
set APP_HOME=%DIRNAME%
|
||||
|
||||
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
|
||||
set DEFAULT_JVM_OPTS="-Xmx4g" "-Xms2g" "-Dfile.encoding=UTF-8"
|
||||
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
|
||||
|
||||
@rem Find java.exe
|
||||
if defined JAVA_HOME goto findJavaFromJavaHome
|
||||
|
||||
@@ -1,33 +0,0 @@
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
description = 'Web API'
|
||||
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
compileOnly group: 'javax.inject', name: 'javax.inject', version: javaxInject
|
||||
compileOnly group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: gson
|
||||
implementation group: 'com.google.guava', name: 'guava', version: guava
|
||||
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: okhttp3
|
||||
implementation group: 'io.reactivex.rxjava2', name: 'rxjava', version: rxjava
|
||||
implementation group: 'org.apache.commons', name: 'commons-csv', version: apacheCommonsCsv
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4j
|
||||
implementation project(':runelite-api')
|
||||
|
||||
testImplementation group: 'com.squareup.okhttp3', name: 'mockwebserver', version: okhttp3
|
||||
testImplementation group: 'junit', name: 'junit', version: junit
|
||||
testImplementation group: 'org.slf4j', name: 'slf4j-simple', version: slf4j
|
||||
}
|
||||
|
||||
processResources {
|
||||
from file("src/main/resources/runelite.properties"), {
|
||||
filter(ReplaceTokens, tokens: [
|
||||
"projectver": project.version,
|
||||
"rsver": rsversion.toString(),
|
||||
"gitcommit": gitCommitShort,
|
||||
"gitdirty": gitDirty.toString()
|
||||
])
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,53 +22,50 @@
|
||||
* (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.injector;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.deob.DeobTestProperties;
|
||||
import net.runelite.deob.TemporyFolderLocation;
|
||||
import net.runelite.deob.util.JarUtil;
|
||||
import org.junit.After;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Rule;
|
||||
import org.junit.Test;
|
||||
import org.junit.rules.TemporaryFolder;
|
||||
import org.apache.tools.ant.filters.ReplaceTokens
|
||||
|
||||
public class InjectTest
|
||||
{
|
||||
@Rule
|
||||
public DeobTestProperties properties = new DeobTestProperties();
|
||||
description = "Web API"
|
||||
|
||||
@Rule
|
||||
public TemporaryFolder folder = TemporyFolderLocation.getTemporaryFolder();
|
||||
dependencies {
|
||||
annotationProcessor(Libraries.lombok)
|
||||
|
||||
private ClassGroup deob, vanilla;
|
||||
compileOnly(Libraries.javaxInject)
|
||||
compileOnly(Libraries.lombok)
|
||||
|
||||
@Before
|
||||
public void before() throws IOException
|
||||
{
|
||||
deob = JarUtil.loadJar(new File(properties.getRsClient()));
|
||||
vanilla = JarUtil.loadJar(new File(properties.getVanillaClient()));
|
||||
}
|
||||
|
||||
@After
|
||||
public void after() throws IOException
|
||||
{
|
||||
JarUtil.saveJar(vanilla, folder.newFile());
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void testRun() throws InjectionException
|
||||
{
|
||||
Inject instance = new Inject(deob, vanilla);
|
||||
instance.run();
|
||||
|
||||
InjectorValidator iv = new InjectorValidator(vanilla);
|
||||
iv.validate();
|
||||
}
|
||||
implementation(Libraries.gson)
|
||||
implementation(Libraries.guava)
|
||||
implementation(Libraries.okhttp3)
|
||||
implementation(Libraries.rxjava)
|
||||
implementation(Libraries.apacheCommonsCsv)
|
||||
implementation(Libraries.slf4jApi)
|
||||
implementation(project(":runelite-api"))
|
||||
|
||||
testImplementation(Libraries.okhttp3Webserver)
|
||||
testImplementation(Libraries.junit)
|
||||
testImplementation(Libraries.slf4jSimple)
|
||||
}
|
||||
|
||||
tasks {
|
||||
processResources {
|
||||
finalizedBy("filterResources")
|
||||
}
|
||||
|
||||
register<Copy>("filterResources") {
|
||||
val tokens = mapOf(
|
||||
"projectver" to ProjectVersions.rlVersion,
|
||||
"rsver" to ProjectVersions.rsversion.toString(),
|
||||
"gitcommit" to project.extra["gitCommit"]
|
||||
)
|
||||
|
||||
inputs.properties(tokens)
|
||||
|
||||
from("src/main/resources") {
|
||||
include("runelite.properties")
|
||||
}
|
||||
into("${buildDir}/resources/main")
|
||||
|
||||
filter(ReplaceTokens::class, "tokens" to tokens)
|
||||
filteringCharset = "UTF-8"
|
||||
}
|
||||
}
|
||||
@@ -25,13 +25,9 @@
|
||||
package net.runelite.http.api;
|
||||
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
import net.runelite.http.api.item.ItemEquipmentStats;
|
||||
import net.runelite.http.api.item.ItemPrice;
|
||||
import net.runelite.http.api.item.ItemStats;
|
||||
import net.runelite.http.api.util.TypeAdapters;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.Interceptor;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.OkHttpClient;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
@@ -60,12 +56,9 @@ public class RuneLiteAPI
|
||||
public static final String RUNELITE_AUTH = "RUNELITE-AUTH";
|
||||
|
||||
public static final OkHttpClient CLIENT;
|
||||
public static final Gson GSON = new GsonBuilder()
|
||||
.setPrettyPrinting()
|
||||
.registerTypeAdapter(ItemStats.class, TypeAdapters.ITEMSTATS)
|
||||
.registerTypeAdapter(ItemEquipmentStats.class, TypeAdapters.EQUIPMENTSTATS)
|
||||
.registerTypeAdapter(ItemPrice.class, TypeAdapters.ITEMPRICE)
|
||||
.create();
|
||||
public static final Gson GSON = new Gson();
|
||||
public static final MediaType JSON = MediaType.parse("application/json");
|
||||
public static String userAgent;
|
||||
|
||||
private static final String BASE = "https://api.runelite.net";
|
||||
private static final String WSBASE = "https://api.runelite.net/ws";
|
||||
@@ -76,8 +69,6 @@ public class RuneLiteAPI
|
||||
private static final String MAVEN_METADATA = "http://repo.runelite.net/net/runelite/runelite-parent/maven-metadata.xml";
|
||||
|
||||
private static final Properties properties = new Properties();
|
||||
private static String userAgent;
|
||||
|
||||
private static String version;
|
||||
private static String upstreamVersion;
|
||||
private static int rsVersion;
|
||||
|
||||
@@ -316,36 +316,6 @@ public class ChatClient
|
||||
}
|
||||
}
|
||||
|
||||
public String getLayout(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getOpenOSRSApiBase().newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("layout")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up layout!");
|
||||
}
|
||||
|
||||
final String layout = response.body().string();
|
||||
|
||||
if (!testLayout(layout))
|
||||
{
|
||||
throw new IOException("Layout " + layout + " is not valid!");
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
|
||||
public boolean testLayout(String layout)
|
||||
{
|
||||
return LAYOUT_VALIDATOR.test(layout);
|
||||
@@ -465,4 +435,51 @@ public class ChatClient
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public boolean submitLayout(String username, LayoutRoom[] rooms) throws IOException
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("layout")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.post(RequestBody.create(RuneLiteAPI.JSON, RuneLiteAPI.GSON.toJson(rooms)))
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
return response.isSuccessful();
|
||||
}
|
||||
}
|
||||
|
||||
public LayoutRoom[] getLayout(String username) throws IOException
|
||||
{
|
||||
HttpUrl url = RuneLiteAPI.getApiBase().newBuilder()
|
||||
.addPathSegment("chat")
|
||||
.addPathSegment("layout")
|
||||
.addQueryParameter("name", username)
|
||||
.build();
|
||||
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
if (!response.isSuccessful())
|
||||
{
|
||||
throw new IOException("Unable to look up layout!");
|
||||
}
|
||||
|
||||
InputStream in = response.body().byteStream();
|
||||
return RuneLiteAPI.GSON.fromJson(new InputStreamReader(in), LayoutRoom[].class);
|
||||
}
|
||||
catch (JsonParseException ex)
|
||||
{
|
||||
throw new IOException(ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2019, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,23 +22,29 @@
|
||||
* (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.injector;
|
||||
package net.runelite.http.api.chat;
|
||||
|
||||
public class InjectionException extends Exception
|
||||
public enum LayoutRoom
|
||||
{
|
||||
public InjectionException(String message)
|
||||
{
|
||||
super(message);
|
||||
}
|
||||
START,
|
||||
END,
|
||||
SCAVENGERS,
|
||||
FARMING,
|
||||
EMPTY,
|
||||
|
||||
public InjectionException(Throwable cause)
|
||||
{
|
||||
super(cause);
|
||||
}
|
||||
|
||||
public InjectionException(String message, Throwable cause)
|
||||
{
|
||||
super(message, cause);
|
||||
}
|
||||
TEKTON,
|
||||
MUTTADILES,
|
||||
GUARDIANS,
|
||||
VESPULA,
|
||||
SHAMANS,
|
||||
VASA,
|
||||
VANGUARDS,
|
||||
MYSTICS,
|
||||
UNKNOWN_COMBAT,
|
||||
|
||||
CRABS,
|
||||
ICE_DEMON,
|
||||
TIGHTROPE,
|
||||
THIEVING,
|
||||
UNKNOWN_PUZZLE;
|
||||
}
|
||||
@@ -30,10 +30,10 @@ import java.util.UUID;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import static net.runelite.http.api.RuneLiteAPI.JSON;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
@@ -42,7 +42,6 @@ import okhttp3.Response;
|
||||
@AllArgsConstructor
|
||||
public class GrandExchangeClient
|
||||
{
|
||||
private static final MediaType JSON = MediaType.parse("application/json");
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
|
||||
private final UUID uuid;
|
||||
|
||||
@@ -36,10 +36,10 @@ import java.util.UUID;
|
||||
import lombok.AllArgsConstructor;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import static net.runelite.http.api.RuneLiteAPI.JSON;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
@@ -48,7 +48,6 @@ import okhttp3.Response;
|
||||
@AllArgsConstructor
|
||||
public class LootTrackerClient
|
||||
{
|
||||
private static final MediaType JSON = MediaType.parse("application/json");
|
||||
private static final Gson GSON = RuneLiteAPI.GSON;
|
||||
|
||||
private final UUID uuid;
|
||||
|
||||
@@ -31,10 +31,10 @@ import java.io.InputStream;
|
||||
import java.io.InputStreamReader;
|
||||
import java.util.List;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import static net.runelite.http.api.RuneLiteAPI.JSON;
|
||||
import okhttp3.Call;
|
||||
import okhttp3.Callback;
|
||||
import okhttp3.HttpUrl;
|
||||
import okhttp3.MediaType;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.RequestBody;
|
||||
import okhttp3.Response;
|
||||
@@ -43,8 +43,6 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
public class XteaClient
|
||||
{
|
||||
private static final MediaType JSON = MediaType.parse("application/json");
|
||||
|
||||
private static final Logger logger = LoggerFactory.getLogger(XteaClient.class);
|
||||
|
||||
public void submit(XteaRequest xteaRequest)
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
runelite.version=@projectver@
|
||||
rs.version=@rsver@
|
||||
runelite.commit=@gitcommit@
|
||||
runelite.dirty=@gitdirty@
|
||||
runelite.commit=@gitcommit@
|
||||
@@ -1,26 +0,0 @@
|
||||
apply plugin: 'war'
|
||||
|
||||
description = 'Web Service OpenOSRS'
|
||||
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
api project(':cache')
|
||||
api project(':http-api')
|
||||
api project(':http-service')
|
||||
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: gson
|
||||
implementation group: 'com.google.guava', name: 'guava', version: guava
|
||||
implementation group: 'com.squareup.okhttp3', name: 'okhttp', version: okhttp3
|
||||
implementation group: 'org.springframework', name: 'spring-jdbc', version: springJdbc
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-devtools', version: springboot
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springboot
|
||||
implementation group: 'org.sql2o', name: 'sql2o', version: sql2o
|
||||
implementation(group: 'redis.clients', name: 'jedis', version: jedis) {
|
||||
exclude(module: 'commons-pool2')
|
||||
}
|
||||
|
||||
providedCompile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: mariadbJdbc
|
||||
providedCompile group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
providedCompile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: springboot
|
||||
}
|
||||
53
http-service-openosrs/http-service-openosrs.gradle.kts
Normal file
53
http-service-openosrs/http-service-openosrs.gradle.kts
Normal file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
plugins {
|
||||
war
|
||||
}
|
||||
|
||||
description = "Web Service OpenOSRS"
|
||||
|
||||
dependencies {
|
||||
annotationProcessor(Libraries.lombok)
|
||||
|
||||
api(project(":cache"))
|
||||
api(project(":http-api"))
|
||||
api(project(":http-service"))
|
||||
|
||||
implementation(Libraries.gson)
|
||||
implementation(Libraries.guava)
|
||||
implementation(Libraries.okhttp3)
|
||||
implementation(Libraries.springbootJdbc)
|
||||
implementation(Libraries.springbootDevtools)
|
||||
implementation(Libraries.springbootStarterWeb)
|
||||
implementation(Libraries.sql2o)
|
||||
implementation(Libraries.jedis) {
|
||||
exclude(module = "commons-pool2")
|
||||
}
|
||||
|
||||
providedCompile(Libraries.mariadbJdbc)
|
||||
providedCompile(Libraries.lombok)
|
||||
providedCompile(Libraries.springbootStarterTomcat)
|
||||
}
|
||||
@@ -1,37 +0,0 @@
|
||||
apply plugin: 'war'
|
||||
|
||||
description = 'Web Service'
|
||||
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.mapstruct', name: 'mapstruct-processor', version: mapstruct
|
||||
annotationProcessor group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
|
||||
api project(':cache')
|
||||
api project(':http-api')
|
||||
api project(':runelite-api')
|
||||
|
||||
implementation group: 'com.github.scribejava', name: 'scribejava-apis', version: scribejava
|
||||
implementation group: 'com.google.code.gson', name: 'gson', version: gson
|
||||
implementation group: 'com.google.guava', name: 'guava', version: guava
|
||||
implementation group: 'io.minio', name: 'minio', version: minio
|
||||
implementation group: 'org.mapstruct', name: 'mapstruct-jdk8', version: mapstruct
|
||||
implementation group: 'org.mongodb', name: 'mongodb-driver-sync', version: mongodbDriverSync
|
||||
implementation group: 'org.slf4j', name: 'slf4j-api', version: slf4j
|
||||
implementation group: 'org.springframework', name: 'spring-jdbc', version: springJdbc
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-devtools', version: springboot
|
||||
implementation group: 'org.springframework.boot', name: 'spring-boot-starter-web', version: springboot
|
||||
implementation group: 'org.sql2o', name: 'sql2o', version: sql2o
|
||||
implementation(group: 'redis.clients', name: 'jedis', version: jedis) {
|
||||
exclude(module: 'commons-pool2')
|
||||
}
|
||||
|
||||
providedCompile group: 'org.mariadb.jdbc', name: 'mariadb-java-client', version: mariadbJdbc
|
||||
providedCompile group: 'org.projectlombok', name: 'lombok', version: lombok
|
||||
providedCompile group: 'org.springframework.boot', name: 'spring-boot-starter-tomcat', version: springboot
|
||||
|
||||
testImplementation group: 'com.h2database', name: 'h2', version: '1.4.200'
|
||||
testImplementation group: 'com.squareup.okhttp3', name: 'mockwebserver', version: okhttp3
|
||||
testImplementation(group: 'org.springframework.boot', name: 'spring-boot-starter-test', version: springboot) {
|
||||
exclude(module: 'commons-logging')
|
||||
}
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,42 +22,43 @@
|
||||
* (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.injector;
|
||||
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import static org.junit.Assert.assertNotNull;
|
||||
import org.junit.Test;
|
||||
import org.mockito.Matchers;
|
||||
import static org.mockito.Mockito.mock;
|
||||
import static org.mockito.Mockito.when;
|
||||
|
||||
public class InjectConstructTest
|
||||
{
|
||||
@Test
|
||||
public void testInjectConstruct() throws Exception
|
||||
{
|
||||
ClassFile targetClass = new ClassFile();
|
||||
targetClass.setName("test");
|
||||
|
||||
ClassFile vanillaClass = new ClassFile();
|
||||
vanillaClass.setName("ab");
|
||||
Method constructor = new Method(vanillaClass, "<init>", new Signature("()V"));
|
||||
vanillaClass.addMethod(constructor);
|
||||
|
||||
Inject inject = mock(Inject.class);
|
||||
when(inject.findVanillaForInterface(Matchers.any(Class.class)))
|
||||
.thenReturn(vanillaClass);
|
||||
InjectConstruct injectConstruct = new InjectConstruct(inject);
|
||||
injectConstruct.injectConstruct(targetClass, APIClass.class.getDeclaredMethod("create"));
|
||||
|
||||
assertNotNull(targetClass.findMethod("create"));
|
||||
}
|
||||
|
||||
interface APIClass
|
||||
{
|
||||
APIClass create();
|
||||
}
|
||||
|
||||
plugins {
|
||||
war
|
||||
}
|
||||
|
||||
description = "Web Service"
|
||||
|
||||
dependencies {
|
||||
annotationProcessor(Libraries.mapstructProcessor)
|
||||
annotationProcessor(Libraries.lombok)
|
||||
|
||||
api(project(":cache"))
|
||||
api(project(":http-api"))
|
||||
api(project(":runelite-api"))
|
||||
|
||||
implementation(Libraries.scribejava)
|
||||
implementation(Libraries.gson)
|
||||
implementation(Libraries.guava)
|
||||
implementation(Libraries.minio)
|
||||
implementation(Libraries.mapstruct)
|
||||
implementation(Libraries.mongodbDriverSync)
|
||||
implementation(Libraries.slf4jApi)
|
||||
implementation(Libraries.springbootJdbc)
|
||||
implementation(Libraries.springbootDevtools)
|
||||
implementation(Libraries.springbootStarterWeb)
|
||||
implementation(Libraries.sql2o)
|
||||
implementation(Libraries.jedis) {
|
||||
exclude(module = "commons-pool2")
|
||||
}
|
||||
|
||||
providedCompile(Libraries.mariadbJdbc)
|
||||
providedCompile(Libraries.lombok)
|
||||
providedCompile(Libraries.springbootStarterTomcat)
|
||||
|
||||
testImplementation(Libraries.h2)
|
||||
testImplementation(Libraries.okhttp3Webserver)
|
||||
testImplementation(Libraries.springbootStarterTest) {
|
||||
exclude(module = "commons-logging")
|
||||
}
|
||||
}
|
||||
@@ -30,11 +30,13 @@ import java.util.concurrent.TimeUnit;
|
||||
import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import net.runelite.http.api.chat.Duels;
|
||||
import net.runelite.http.api.chat.LayoutRoom;
|
||||
import net.runelite.http.api.chat.Task;
|
||||
import net.runelite.http.service.util.exception.NotFoundException;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.web.bind.annotation.GetMapping;
|
||||
import org.springframework.web.bind.annotation.PostMapping;
|
||||
import org.springframework.web.bind.annotation.RequestBody;
|
||||
import org.springframework.web.bind.annotation.RequestMapping;
|
||||
import org.springframework.web.bind.annotation.RequestParam;
|
||||
import org.springframework.web.bind.annotation.RestController;
|
||||
@@ -208,4 +210,23 @@ public class ChatController
|
||||
}
|
||||
return duels;
|
||||
}
|
||||
|
||||
@PostMapping("/layout")
|
||||
public void submitLayout(@RequestParam String name, @RequestBody LayoutRoom[] rooms)
|
||||
{
|
||||
chatService.setLayout(name, rooms);
|
||||
}
|
||||
|
||||
@GetMapping("/layout")
|
||||
public LayoutRoom[] getLayout(@RequestParam String name)
|
||||
{
|
||||
LayoutRoom[] layout = chatService.getLayout(name);
|
||||
|
||||
if (layout == null)
|
||||
{
|
||||
throw new NotFoundException();
|
||||
}
|
||||
|
||||
return layout;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,13 @@
|
||||
*/
|
||||
package net.runelite.http.service.chat;
|
||||
|
||||
import com.google.common.base.Joiner;
|
||||
import com.google.common.base.Splitter;
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.time.Duration;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import net.runelite.http.api.chat.LayoutRoom;
|
||||
import net.runelite.http.api.chat.Task;
|
||||
import net.runelite.http.api.chat.Duels;
|
||||
import net.runelite.http.service.util.redis.RedisPool;
|
||||
@@ -198,4 +202,31 @@ public class ChatService
|
||||
jedis.expire(key, (int) EXPIRE.getSeconds());
|
||||
}
|
||||
}
|
||||
|
||||
public LayoutRoom[] getLayout(String name)
|
||||
{
|
||||
String layout;
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
layout = jedis.get("layout." + name);
|
||||
}
|
||||
|
||||
if (layout == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
List<String> roomList = Splitter.on(' ').splitToList(layout);
|
||||
return roomList.stream()
|
||||
.map(LayoutRoom::valueOf)
|
||||
.toArray(LayoutRoom[]::new);
|
||||
}
|
||||
|
||||
public void setLayout(String name, LayoutRoom[] rooms)
|
||||
{
|
||||
try (Jedis jedis = jedisPool.getResource())
|
||||
{
|
||||
jedis.setex("layout." + name, (int) EXPIRE.getSeconds(), Joiner.on(' ').join(rooms));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,6 +51,7 @@ import net.runelite.http.api.config.ConfigEntry;
|
||||
import net.runelite.http.api.config.Configuration;
|
||||
import org.bson.Document;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.stereotype.Service;
|
||||
|
||||
@Service
|
||||
@@ -66,11 +67,12 @@ public class ConfigService
|
||||
|
||||
@Autowired
|
||||
public ConfigService(
|
||||
MongoClient mongoClient
|
||||
MongoClient mongoClient,
|
||||
@Value("${mongo.database}") String databaseName
|
||||
)
|
||||
{
|
||||
|
||||
MongoDatabase database = mongoClient.getDatabase("config");
|
||||
MongoDatabase database = mongoClient.getDatabase(databaseName);
|
||||
MongoCollection<Document> collection = database.getCollection("config");
|
||||
this.mongoCollection = collection;
|
||||
|
||||
|
||||
@@ -98,6 +98,11 @@ public class OSBGrandExchangeService
|
||||
Integer itemId = entry.getKey();
|
||||
OsbuddySummaryItem item = entry.getValue();
|
||||
|
||||
if (item.getBuy_average() <= 0 || item.getSell_average() <= 0 || item.getOverall_average() <= 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
query
|
||||
.addParameter("itemId", itemId)
|
||||
.addParameter("buyAverage", item.getBuy_average())
|
||||
|
||||
@@ -32,10 +32,11 @@ redis:
|
||||
|
||||
mongo:
|
||||
jndiName: java:comp/env/mongodb/runelite
|
||||
database: runelite
|
||||
|
||||
# Twitter client for feed
|
||||
runelite:
|
||||
twitter:
|
||||
consumerkey:
|
||||
secretkey:
|
||||
listid: 968949795153948673
|
||||
listid: 1185897074786742273
|
||||
88
injected-client/injected-client.gradle.kts
Normal file
88
injected-client/injected-client.gradle.kts
Normal file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2019 ThatGamerBlue
|
||||
* Copyright (c) 2019 Owain van Brakel <https://github.com/Owain94>
|
||||
* 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.
|
||||
*/
|
||||
|
||||
apply<FernflowerPlugin>()
|
||||
|
||||
description = "Injected Client"
|
||||
|
||||
plugins {
|
||||
id("com.openosrs.injector")
|
||||
}
|
||||
|
||||
val vanillaDep by configurations.creating
|
||||
val rsapiDep by configurations.creating
|
||||
val rsclientDep by configurations.creating
|
||||
val mixinsDep by configurations.creating
|
||||
val combined by configurations.creating {
|
||||
extendsFrom(rsapiDep, rsclientDep, mixinsDep, vanillaDep)
|
||||
isCanBeResolved = true
|
||||
isCanBeConsumed = false
|
||||
}
|
||||
|
||||
configurations {
|
||||
all {
|
||||
isTransitive = false
|
||||
}
|
||||
}
|
||||
|
||||
dependencies {
|
||||
vanillaDep(Libraries.vanilla)
|
||||
rsapiDep(project(":runescape-api"))
|
||||
rsclientDep(project(":runescape-client"))
|
||||
mixinsDep(project(":runelite-mixins"))
|
||||
}
|
||||
|
||||
injector {
|
||||
mixins.set(mixinsDep.singleFile)
|
||||
rsapi.set(rsapiDep.singleFile)
|
||||
rsclient.set(rsclientDep.singleFile)
|
||||
vanilla.set(vanillaDep.singleFile)
|
||||
}
|
||||
|
||||
sourceSets {
|
||||
main {
|
||||
output.dir(tasks.inject.get().output.get().asFile.parentFile, "builtBy" to tasks.inject)
|
||||
}
|
||||
}
|
||||
|
||||
// keep the sourcesets etc but remove useless tasks
|
||||
tasks {
|
||||
inject {
|
||||
dependsOn(configurations["combined"])
|
||||
}
|
||||
classes {
|
||||
enabled = false
|
||||
}
|
||||
compileJava {
|
||||
enabled = false
|
||||
}
|
||||
jar {
|
||||
enabled = false
|
||||
}
|
||||
processResources {
|
||||
enabled = false
|
||||
}
|
||||
}
|
||||
@@ -1,63 +0,0 @@
|
||||
group = 'us.runelitepl.rs'
|
||||
description = 'Injector'
|
||||
|
||||
def buildPath = buildDir.toString().replace('\\', '/') // this doesnt work in an ext block for some reason
|
||||
def deobfuscatedJar = "${rootPath}/runescape-client/build/libs/rs-client-${project.version}.jar"
|
||||
def vanillaJar = "${buildPath}/vanilla-${rsversion}.jar"
|
||||
|
||||
configurations {
|
||||
vanilla
|
||||
}
|
||||
|
||||
dependencies {
|
||||
annotationProcessor group: 'org.eclipse.sisu', name: 'org.eclipse.sisu.inject', version: sisu
|
||||
|
||||
compileOnly group: 'org.apache.maven.plugin-tools', name: 'maven-plugin-annotations', version: mavenPluginAnnotations
|
||||
|
||||
implementation group: 'com.google.guava', name: 'guava', version: guava
|
||||
implementation group: 'org.apache.maven', name: 'maven-plugin-api', version: mavenPluginApi
|
||||
implementation group: 'org.ow2.asm', name: 'asm', version: asm
|
||||
implementation group: 'org.ow2.asm', name: 'asm-util', version: asm
|
||||
implementation project(':deobfuscator')
|
||||
implementation project(':mixins')
|
||||
implementation project(':runelite-api')
|
||||
implementation project(':runescape-api')
|
||||
|
||||
testImplementation group: 'junit', name: 'junit', version: junit
|
||||
testImplementation group: 'org.mockito', name: 'mockito-core', version: mockito
|
||||
testImplementation project(':deobfuscator')
|
||||
testImplementation project(path: ':deobfuscator', configuration: 'testArchives')
|
||||
|
||||
vanilla "net.runelite.rs:vanilla:${rsversion}"
|
||||
}
|
||||
|
||||
compileJava {
|
||||
dependsOn ":rs-client:build"
|
||||
|
||||
inputs.dir("${project.rootDir}/runescape-client/")
|
||||
inputs.dir("${project.rootDir}/runescape-api/")
|
||||
inputs.dir("${project.rootDir}/runelite-mixins/")
|
||||
}
|
||||
|
||||
compileJava.doLast() {
|
||||
copy {
|
||||
from configurations.vanilla
|
||||
into "$buildDir"
|
||||
}
|
||||
def path = sourceSets.main.runtimeClasspath
|
||||
def loader
|
||||
try {
|
||||
loader = new URLClassLoader(path.collect { f -> f.toURI().toURL() } as URL[])
|
||||
def inject = loader.loadClass('net.runelite.injector.Injector')
|
||||
String[] jarPaths = [
|
||||
deobfuscatedJar.toString(),
|
||||
vanillaJar.toString(),
|
||||
injectedClassesPath.toString()
|
||||
]
|
||||
inject.main(jarPaths)
|
||||
} finally {
|
||||
if (loader) {
|
||||
loader.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,582 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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.injector;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Field;
|
||||
import net.runelite.asm.Interfaces;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Annotations;
|
||||
import net.runelite.asm.attributes.annotation.Annotation;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.instructions.ALoad;
|
||||
import net.runelite.asm.attributes.code.instructions.DLoad;
|
||||
import net.runelite.asm.attributes.code.instructions.FLoad;
|
||||
import net.runelite.asm.attributes.code.instructions.ILoad;
|
||||
import net.runelite.asm.attributes.code.instructions.LLoad;
|
||||
import net.runelite.asm.pool.Class;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.deob.deobfuscators.arithmetic.DMath;
|
||||
import static net.runelite.injector.InjectUtil.getFieldType;
|
||||
import net.runelite.injector.raw.ClearColorBuffer;
|
||||
import net.runelite.injector.raw.DrawAfterWidgets;
|
||||
import net.runelite.injector.raw.Occluder;
|
||||
import net.runelite.injector.raw.RasterizerHook;
|
||||
import net.runelite.injector.raw.RenderDraw;
|
||||
import net.runelite.injector.raw.ScriptVM;
|
||||
import net.runelite.mapping.Import;
|
||||
import net.runelite.rs.api.RSClient;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import net.runelite.injector.raw.HidePlayerAttacks;
|
||||
|
||||
// import net.runelite.injector.raw.DrawMenu;
|
||||
|
||||
public class Inject
|
||||
{
|
||||
public static final java.lang.Class<?> CLIENT_CLASS = RSClient.class;
|
||||
public static final String API_PACKAGE_BASE = "net.runelite.rs.api.RS";
|
||||
public static final String RL_API_PACKAGE_BASE = "net.runelite.api.";
|
||||
private static final Logger logger = LoggerFactory.getLogger(Inject.class);
|
||||
private final InjectHookMethod hookMethod = new InjectHookMethod(this);
|
||||
|
||||
private final InjectGetter getters = new InjectGetter(this);
|
||||
private final InjectSetter setters = new InjectSetter(this);
|
||||
private final InjectInvoker invokes = new InjectInvoker(this);
|
||||
private final InjectConstruct construct = new InjectConstruct(this);
|
||||
|
||||
private final MixinInjector mixinInjector = new MixinInjector(this);
|
||||
|
||||
// deobfuscated contains exports etc to apply to vanilla
|
||||
private final ClassGroup deobfuscated, vanilla;
|
||||
|
||||
public Inject(ClassGroup deobfuscated, ClassGroup vanilla)
|
||||
{
|
||||
this.deobfuscated = deobfuscated;
|
||||
this.vanilla = vanilla;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert a java.lang.Class to a Type
|
||||
*
|
||||
* @param c
|
||||
* @return
|
||||
*/
|
||||
public static Type classToType(java.lang.Class<?> c)
|
||||
{
|
||||
int dimms = 0;
|
||||
while (c.isArray())
|
||||
{
|
||||
c = c.getComponentType();
|
||||
++dimms;
|
||||
}
|
||||
|
||||
if (c.isPrimitive())
|
||||
{
|
||||
String s;
|
||||
|
||||
switch (c.getName())
|
||||
{
|
||||
case "int":
|
||||
s = "I";
|
||||
break;
|
||||
case "long":
|
||||
s = "J";
|
||||
break;
|
||||
case "boolean":
|
||||
s = "Z";
|
||||
break;
|
||||
case "char":
|
||||
s = "C";
|
||||
break;
|
||||
case "short":
|
||||
s = "S";
|
||||
break;
|
||||
case "float":
|
||||
s = "F";
|
||||
break;
|
||||
case "double":
|
||||
s = "D";
|
||||
break;
|
||||
case "byte":
|
||||
s = "B";
|
||||
break;
|
||||
case "void":
|
||||
s = "V";
|
||||
break;
|
||||
default:
|
||||
throw new RuntimeException("unknown primitive type " + c.getName());
|
||||
}
|
||||
|
||||
return Type.getType(s, dimms);
|
||||
}
|
||||
|
||||
return Type.getType("L" + c.getName().replace('.', '/') + ";", dimms);
|
||||
}
|
||||
|
||||
public Signature getMethodSignature(Method m)
|
||||
{
|
||||
Signature signature = m.getDescriptor();
|
||||
|
||||
Annotation obfSignature = m.getAnnotations().find(DeobAnnotations.OBFUSCATED_SIGNATURE);
|
||||
if (obfSignature != null)
|
||||
{
|
||||
//Annotation exists. Signature was updated by us during deobfuscation
|
||||
signature = DeobAnnotations.getObfuscatedSignature(m);
|
||||
}
|
||||
|
||||
return signature;
|
||||
}
|
||||
|
||||
/**
|
||||
* Build a Signature from a java method
|
||||
*
|
||||
* @param method
|
||||
* @return
|
||||
*/
|
||||
public Signature javaMethodToSignature(java.lang.reflect.Method method)
|
||||
{
|
||||
Signature.Builder builder = new Signature.Builder()
|
||||
.setReturnType(classToType(method.getReturnType()));
|
||||
for (java.lang.Class<?> clazz : method.getParameterTypes())
|
||||
{
|
||||
builder.addArgument(classToType(clazz));
|
||||
}
|
||||
return builder.build();
|
||||
}
|
||||
|
||||
public void run() throws InjectionException
|
||||
{
|
||||
Map<ClassFile, java.lang.Class> implemented = new HashMap<>();
|
||||
|
||||
// inject interfaces first, so the validateTypeIsConvertibleTo
|
||||
// check below works
|
||||
for (ClassFile cf : deobfuscated.getClasses())
|
||||
{
|
||||
Annotations an = cf.getAnnotations();
|
||||
|
||||
if (an == null || an.size() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
|
||||
if (obfuscatedName == null)
|
||||
{
|
||||
obfuscatedName = cf.getName();
|
||||
}
|
||||
|
||||
ClassFile other = vanilla.findClass(obfuscatedName);
|
||||
assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
|
||||
|
||||
java.lang.Class implementingClass = injectInterface(cf, other);
|
||||
// it can not implement an interface but still have exported static fields, which are
|
||||
// moved to client
|
||||
|
||||
implemented.put(cf, implementingClass);
|
||||
}
|
||||
|
||||
// Has to be done before mixins
|
||||
// well, can be done after really
|
||||
// but why do that when you can do it before
|
||||
new RasterizerHook(this).inject();
|
||||
|
||||
// requires interfaces to be injected
|
||||
mixinInjector.inject();
|
||||
construct.inject(implemented);
|
||||
|
||||
for (ClassFile cf : deobfuscated.getClasses())
|
||||
{
|
||||
java.lang.Class implementingClass = implemented.get(cf);
|
||||
Annotations an = cf.getAnnotations();
|
||||
|
||||
if (an == null || an.size() == 0)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(an);
|
||||
if (obfuscatedName == null)
|
||||
{
|
||||
obfuscatedName = cf.getName();
|
||||
}
|
||||
|
||||
ClassFile other = vanilla.findClass(obfuscatedName);
|
||||
assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
|
||||
|
||||
for (Field f : cf.getFields())
|
||||
{
|
||||
an = f.getAnnotations();
|
||||
|
||||
if (an == null || an.find(DeobAnnotations.EXPORT) == null)
|
||||
{
|
||||
continue; // not an exported field
|
||||
}
|
||||
|
||||
Annotation exportAnnotation = an.find(DeobAnnotations.EXPORT);
|
||||
String exportedName = exportAnnotation.getElement().getString();
|
||||
|
||||
obfuscatedName = DeobAnnotations.getObfuscatedName(an);
|
||||
|
||||
Annotation getterAnnotation = an.find(DeobAnnotations.OBFUSCATED_GETTER);
|
||||
Number getter = null;
|
||||
if (getterAnnotation != null)
|
||||
{
|
||||
getter = (Number) getterAnnotation.getElement().getValue();
|
||||
}
|
||||
// the ob jar is the same as the vanilla so this field must exist in this class.
|
||||
|
||||
Type obType = getFieldType(f);
|
||||
Field otherf = other.findField(obfuscatedName, obType);
|
||||
assert otherf != null;
|
||||
|
||||
assert f.isStatic() == otherf.isStatic();
|
||||
|
||||
ClassFile targetClass = f.isStatic() ? vanilla.findClass("client") : other; // target class for getter
|
||||
java.lang.Class targetApiClass = f.isStatic() ? CLIENT_CLASS : implementingClass; // target api class for getter
|
||||
if (targetApiClass == null)
|
||||
{
|
||||
assert !f.isStatic();
|
||||
|
||||
// non static field exported on non exported interface
|
||||
// logger.debug("Non static exported field {} on non exported interface", exportedName);
|
||||
continue;
|
||||
}
|
||||
|
||||
java.lang.reflect.Method apiMethod = findImportMethodOnApi(targetApiClass, exportedName, true);
|
||||
if (apiMethod != null)
|
||||
{
|
||||
Number setter = null;
|
||||
if (getter != null)
|
||||
{
|
||||
setter = DMath.modInverse(getter); // inverse getter to get the setter
|
||||
}
|
||||
|
||||
setters.injectSetter(targetClass, targetApiClass, otherf, exportedName, setter);
|
||||
}
|
||||
|
||||
apiMethod = findImportMethodOnApi(targetApiClass, exportedName, false);
|
||||
if (apiMethod == null)
|
||||
{
|
||||
//logger.debug("Unable to find import method on api class {} with imported name {}, not injecting getter", targetApiClass, exportedName);
|
||||
continue;
|
||||
}
|
||||
|
||||
// check that otherf is converable to apiMethod's
|
||||
// return type
|
||||
Type fieldType = otherf.getType();
|
||||
Type returnType = classToType(apiMethod.getReturnType());
|
||||
if (!validateTypeIsConvertibleTo(fieldType, returnType))
|
||||
{
|
||||
throw new InjectionException("Type " + fieldType + " is not convertable to " + returnType + " for getter " + apiMethod);
|
||||
}
|
||||
|
||||
getters.injectGetter(targetClass, apiMethod, otherf, getter);
|
||||
}
|
||||
|
||||
for (Method m : cf.getMethods())
|
||||
{
|
||||
hookMethod.process(m);
|
||||
invokes.process(m, other, implementingClass);
|
||||
}
|
||||
}
|
||||
|
||||
logger.info("Injected {} getters, {} setters, {} invokers",
|
||||
getters.getInjectedGetters(),
|
||||
setters.getInjectedSetters(), invokes.getInjectedInvokers());
|
||||
|
||||
new DrawAfterWidgets(this).inject();
|
||||
new ScriptVM(this).inject();
|
||||
new ClearColorBuffer(this).inject();
|
||||
new RenderDraw(this).inject();
|
||||
// new DrawMenu(this).inject();
|
||||
new Occluder(this).inject();
|
||||
new HidePlayerAttacks(this).inject();
|
||||
}
|
||||
|
||||
private java.lang.Class injectInterface(ClassFile cf, ClassFile other)
|
||||
{
|
||||
Annotations an = cf.getAnnotations();
|
||||
if (an == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Annotation a = an.find(DeobAnnotations.IMPLEMENTS);
|
||||
if (a == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
String ifaceName = API_PACKAGE_BASE + a.getElement().getString();
|
||||
java.lang.Class<?> apiClass;
|
||||
|
||||
try
|
||||
{
|
||||
apiClass = java.lang.Class.forName(ifaceName);
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
logger.trace("Class {} implements nonexistent interface {}, skipping interface injection",
|
||||
cf.getName(),
|
||||
ifaceName);
|
||||
return null;
|
||||
}
|
||||
|
||||
String ifaceNameInternal = ifaceName.replace('.', '/'); // to internal name
|
||||
Class clazz = new Class(ifaceNameInternal);
|
||||
|
||||
Interfaces interfaces = other.getInterfaces();
|
||||
interfaces.addInterface(clazz);
|
||||
|
||||
return apiClass;
|
||||
}
|
||||
|
||||
public java.lang.reflect.Method findImportMethodOnApi(java.lang.Class<?> clazz, String name, Boolean setter)
|
||||
{
|
||||
for (java.lang.reflect.Method method : clazz.getDeclaredMethods())
|
||||
{
|
||||
if (method.isSynthetic())
|
||||
{
|
||||
/*
|
||||
* If you override an interface method in another interface
|
||||
* with a return type that is a child of the overriden methods
|
||||
* return type, both methods end up in the interface, and both
|
||||
* are *annotated*. But the base one is synthetic.
|
||||
*/
|
||||
continue;
|
||||
}
|
||||
|
||||
Import i = method.getAnnotation(Import.class);
|
||||
|
||||
if (i == null || !name.equals(i.value()) || (setter != null && (method.getParameterCount() > 0) != setter))
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
return method;
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* create a load instruction for a variable of type from a given index
|
||||
*
|
||||
* @param instructions
|
||||
* @param type
|
||||
* @param index
|
||||
* @return
|
||||
*/
|
||||
public Instruction createLoadForTypeIndex(Instructions instructions, Type type, int index)
|
||||
{
|
||||
if (type.getDimensions() > 0 || !type.isPrimitive())
|
||||
{
|
||||
return new ALoad(instructions, index);
|
||||
}
|
||||
|
||||
switch (type.toString())
|
||||
{
|
||||
case "B":
|
||||
case "C":
|
||||
case "I":
|
||||
case "S":
|
||||
case "Z":
|
||||
return new ILoad(instructions, index);
|
||||
case "D":
|
||||
return new DLoad(instructions, index);
|
||||
case "F":
|
||||
return new FLoad(instructions, index);
|
||||
case "J":
|
||||
return new LLoad(instructions, index);
|
||||
default:
|
||||
throw new RuntimeException("Unknown type");
|
||||
}
|
||||
}
|
||||
|
||||
ClassFile toDeobClass(ClassFile obClass)
|
||||
{
|
||||
for (ClassFile cf : deobfuscated.getClasses())
|
||||
{
|
||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(cf.getAnnotations());
|
||||
|
||||
if (obClass.getName().equalsIgnoreCase(obfuscatedName))
|
||||
{
|
||||
return cf;
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
Type deobfuscatedTypeToApiType(Type type) throws InjectionException
|
||||
{
|
||||
if (type.isPrimitive())
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
ClassFile cf = deobfuscated.findClass(type.getInternalName());
|
||||
if (cf == null)
|
||||
{
|
||||
return type; // not my type
|
||||
}
|
||||
|
||||
java.lang.Class<?> rsApiType;
|
||||
try
|
||||
{
|
||||
rsApiType = java.lang.Class.forName(API_PACKAGE_BASE + cf.getName().replace("/", "."));
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
throw new InjectionException("Deobfuscated type " + type.getInternalName() + " has no API type", ex);
|
||||
}
|
||||
|
||||
java.lang.Class<?> rlApiType = null;
|
||||
|
||||
for (java.lang.Class<?> inter : rsApiType.getInterfaces())
|
||||
{
|
||||
if (inter.getName().startsWith(RL_API_PACKAGE_BASE))
|
||||
{
|
||||
rlApiType = inter;
|
||||
}
|
||||
}
|
||||
|
||||
// if (rlApiType == null)
|
||||
// {
|
||||
// throw new InjectionException("RS API type " + rsApiType + " does not extend RL API interface");
|
||||
// }
|
||||
|
||||
final java.lang.Class<?> finalType = rlApiType == null ? rsApiType : rlApiType;
|
||||
|
||||
return Type.getType("L" + finalType.getName().replace('.', '/') + ";", type.getDimensions());
|
||||
}
|
||||
|
||||
Type apiTypeToDeobfuscatedType(Type type)
|
||||
{
|
||||
if (type.isPrimitive())
|
||||
{
|
||||
return type;
|
||||
}
|
||||
|
||||
String internalName = type.getInternalName().replace('/', '.');
|
||||
if (!internalName.startsWith(API_PACKAGE_BASE))
|
||||
{
|
||||
return type; // not an rs api type
|
||||
}
|
||||
|
||||
return Type.getType("L" + type.getInternalName().substring(API_PACKAGE_BASE.length()) + ";", type.getDimensions());
|
||||
}
|
||||
|
||||
ClassFile findVanillaForInterface(java.lang.Class<?> clazz)
|
||||
{
|
||||
String className = clazz.getName().replace('.', '/');
|
||||
for (ClassFile cf : getVanilla().getClasses())
|
||||
{
|
||||
for (net.runelite.asm.pool.Class cl : cf.getInterfaces().getInterfaces())
|
||||
{
|
||||
if (cl.getName().equals(className))
|
||||
{
|
||||
return cf;
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private boolean validateTypeIsConvertibleTo(Type from, Type to) throws InjectionException
|
||||
{
|
||||
if (from.getDimensions() != to.getDimensions())
|
||||
{
|
||||
throw new InjectionException("Array dimension mismatch");
|
||||
}
|
||||
|
||||
if (from.isPrimitive())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
ClassFile vanillaClass = vanilla.findClass(from.getInternalName());
|
||||
if (vanillaClass == null)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
boolean okay = false;
|
||||
for (Class inter : vanillaClass.getInterfaces().getInterfaces())
|
||||
{
|
||||
java.lang.Class c;
|
||||
|
||||
try
|
||||
{
|
||||
c = java.lang.Class.forName(inter.getName().replace('/', '.'));
|
||||
}
|
||||
catch (ClassNotFoundException ex)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
okay |= check(c, to);
|
||||
}
|
||||
|
||||
return okay;
|
||||
}
|
||||
|
||||
private boolean check(java.lang.Class c, Type type)
|
||||
{
|
||||
String s = type.getInternalName()
|
||||
.replace('/', '.');
|
||||
|
||||
if (c.getName().equals(s))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (java.lang.Class c2 : c.getInterfaces())
|
||||
{
|
||||
if (check(c2, type))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public final ClassGroup getDeobfuscated()
|
||||
{
|
||||
return deobfuscated;
|
||||
}
|
||||
|
||||
public final ClassGroup getVanilla()
|
||||
{
|
||||
return vanilla;
|
||||
}
|
||||
}
|
||||
@@ -1,171 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* 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.injector;
|
||||
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
import java.util.stream.Collectors;
|
||||
import java.util.stream.Stream;
|
||||
import net.runelite.asm.ClassFile;
|
||||
import net.runelite.asm.ClassGroup;
|
||||
import net.runelite.asm.Method;
|
||||
import net.runelite.asm.Type;
|
||||
import net.runelite.asm.attributes.Code;
|
||||
import net.runelite.asm.attributes.code.Instruction;
|
||||
import net.runelite.asm.attributes.code.Instructions;
|
||||
import net.runelite.asm.attributes.code.instructions.CheckCast;
|
||||
import net.runelite.asm.attributes.code.instructions.Dup;
|
||||
import net.runelite.asm.attributes.code.instructions.InvokeSpecial;
|
||||
import net.runelite.asm.attributes.code.instructions.New;
|
||||
import net.runelite.asm.attributes.code.instructions.Return;
|
||||
import net.runelite.asm.signature.Signature;
|
||||
import net.runelite.deob.DeobAnnotations;
|
||||
import net.runelite.mapping.Construct;
|
||||
import static org.objectweb.asm.Opcodes.ACC_PUBLIC;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class InjectConstruct
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(InjectConstruct.class);
|
||||
|
||||
private final Inject inject;
|
||||
|
||||
InjectConstruct(Inject inject)
|
||||
{
|
||||
this.inject = inject;
|
||||
}
|
||||
|
||||
public void inject(Map<ClassFile, java.lang.Class> implemented) throws InjectionException
|
||||
{
|
||||
for (Entry<ClassFile, java.lang.Class> entry : implemented.entrySet())
|
||||
{
|
||||
Class<?> clazz = entry.getValue();
|
||||
ClassFile cf = entry.getKey();
|
||||
|
||||
if (clazz == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
for (java.lang.reflect.Method method : clazz.getDeclaredMethods())
|
||||
{
|
||||
if (method.isSynthetic())
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Construct construct = method.getAnnotation(Construct.class);
|
||||
if (construct == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String obfuscatedName = DeobAnnotations.getObfuscatedName(cf.getAnnotations());
|
||||
if (obfuscatedName == null)
|
||||
{
|
||||
obfuscatedName = cf.getName();
|
||||
}
|
||||
|
||||
ClassGroup vanilla = inject.getVanilla();
|
||||
ClassFile other = vanilla.findClass(obfuscatedName);
|
||||
assert other != null : "unable to find vanilla class from obfuscated name: " + obfuscatedName;
|
||||
|
||||
injectConstruct(other, method);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void injectConstruct(ClassFile targetClass, java.lang.reflect.Method apiMethod) throws InjectionException
|
||||
{
|
||||
logger.info("Injecting construct for {}", apiMethod);
|
||||
|
||||
assert targetClass.findMethod(apiMethod.getName()) == null;
|
||||
|
||||
Class<?> typeToConstruct = apiMethod.getReturnType();
|
||||
ClassFile vanillaClass = inject.findVanillaForInterface(typeToConstruct);
|
||||
if (vanillaClass == null)
|
||||
{
|
||||
throw new InjectionException("Unable to find vanilla class which implements interface " + typeToConstruct);
|
||||
}
|
||||
|
||||
Signature sig = inject.javaMethodToSignature(apiMethod);
|
||||
|
||||
Signature constructorSig = new Signature.Builder()
|
||||
.addArguments(Stream.of(apiMethod.getParameterTypes())
|
||||
.map(arg ->
|
||||
{
|
||||
ClassFile vanilla = inject.findVanillaForInterface(arg);
|
||||
if (vanilla != null)
|
||||
{
|
||||
return new Type("L" + vanilla.getName() + ";");
|
||||
}
|
||||
return Inject.classToType(arg);
|
||||
})
|
||||
.collect(Collectors.toList()))
|
||||
.setReturnType(Type.VOID)
|
||||
.build();
|
||||
Method vanillaConstructor = vanillaClass.findMethod("<init>", constructorSig);
|
||||
if (vanillaConstructor == null)
|
||||
{
|
||||
throw new InjectionException("Unable to find constructor for " + vanillaClass.getName() + ".<init>" + constructorSig);
|
||||
}
|
||||
|
||||
Method setterMethod = new Method(targetClass, apiMethod.getName(), sig);
|
||||
setterMethod.setAccessFlags(ACC_PUBLIC);
|
||||
targetClass.addMethod(setterMethod);
|
||||
|
||||
Code code = new Code(setterMethod);
|
||||
setterMethod.setCode(code);
|
||||
|
||||
Instructions instructions = code.getInstructions();
|
||||
List<Instruction> ins = instructions.getInstructions();
|
||||
|
||||
ins.add(new New(instructions, vanillaClass.getPoolClass()));
|
||||
ins.add(new Dup(instructions));
|
||||
int idx = 1;
|
||||
int parameter = 0;
|
||||
for (Type type : vanillaConstructor.getDescriptor().getArguments())
|
||||
{
|
||||
Instruction load = inject.createLoadForTypeIndex(instructions, type, idx);
|
||||
idx += type.getSize();
|
||||
ins.add(load);
|
||||
|
||||
Type paramType = sig.getTypeOfArg(parameter);
|
||||
if (!type.equals(paramType))
|
||||
{
|
||||
CheckCast checkCast = new CheckCast(instructions);
|
||||
checkCast.setType(type);
|
||||
ins.add(checkCast);
|
||||
}
|
||||
|
||||
++parameter;
|
||||
}
|
||||
ins.add(new InvokeSpecial(instructions, vanillaConstructor.getPoolMethod()));
|
||||
ins.add(new Return(instructions));
|
||||
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user