2
.gitattributes
vendored
2
.gitattributes
vendored
@@ -1,2 +0,0 @@
|
||||
# Auto detect text files and perform LF normalization
|
||||
* text=auto
|
||||
134
.github/CONTRIBUTING.md
vendored
Normal file
134
.github/CONTRIBUTING.md
vendored
Normal file
@@ -0,0 +1,134 @@
|
||||
# Contributing to runelite
|
||||
|
||||
We'd love for you to contribute to our source code and to make runelite even better than it is
|
||||
today!
|
||||
|
||||
Check out the Developer's Guide on the [wiki](https://github.com/runelite/runelite/wiki) for setup instructions, and general tips and tricks.
|
||||
|
||||
Here are the guidelines we'd like you to follow:
|
||||
|
||||
- [Question or Problem?](#question)
|
||||
- [Issues and Bugs](#issue)
|
||||
- [Submission Guidelines](#submit)
|
||||
- [Coding Format](#format)
|
||||
|
||||
## <a name="question"></a> Got a Question or Problem?
|
||||
|
||||
If you have questions about how to contribute to runelite, please join our [Discord](https://discord.gg/HN5gf3m) server.
|
||||
|
||||
## <a name="issue"></a> Found an Issue?
|
||||
|
||||
If you find a bug in the source code or a mistake in the documentation, you can help us by
|
||||
submitting an issue to our [GitHub Repository][github]. Even better you can submit a Pull Request
|
||||
with a fix.
|
||||
|
||||
**Please see the [Submission Guidelines](#submit) below.**
|
||||
|
||||
## <a name="submit"></a> Submission Guidelines
|
||||
|
||||
### Submitting an Issue
|
||||
Before you submit your issue search the archive, maybe your question was already answered.
|
||||
|
||||
If your issue appears to be a bug and hasn't been reported, open a new issue. Help us to maximize
|
||||
the effort we can spend fixing issues and adding new features, by not reporting duplicate issues.
|
||||
Providing the following information will increase the chances of your issue being dealt with
|
||||
quickly:
|
||||
|
||||
* **Overview of the Issue** - if an error is being thrown a non-minified stack trace helps
|
||||
* **Java Version and Operating System** - is this a problem with a specific setup?
|
||||
* **Reproduce the Error** - provide details, if possible, on how to reproduce the error
|
||||
* **Related Issues** - has a similar issue been reported before?
|
||||
* **Suggest a Fix** - if you can't fix the bug yourself, perhaps you can point to what might be causing the problem (line of code or commit)
|
||||
|
||||
### Submitting a Pull Request
|
||||
Before you submit your pull request consider the following guidelines:
|
||||
|
||||
* Search [GitHub](https://github.com/runelite-extended/runelite/pulls) for an open or closed Pull Request
|
||||
that relates to your submission. You don't want to duplicate effort.
|
||||
* [Fork](https://help.github.com/articles/fork-a-repo/) this repo.
|
||||
* [Clone](https://help.github.com/articles/cloning-a-repository/) your copy.
|
||||
```shell
|
||||
git clone https://github.com/YOUR_USERNAME/runelite.git
|
||||
cd runelite/
|
||||
```
|
||||
* 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
|
||||
```
|
||||
|
||||
* Make your changes in a new git branch:
|
||||
|
||||
```shell
|
||||
git checkout -b my-fix-branch master
|
||||
```
|
||||
|
||||
* Create your patch and run appropriate tests.
|
||||
* Follow our [Coding Format](#format).
|
||||
* Commit your changes using a descriptive commit message that uses the imperative, present tense: "change" not "changed" nor "changes".
|
||||
|
||||
```shell
|
||||
git commit -a
|
||||
```
|
||||
Note: the optional commit `-a` command line option will automatically "add" and "rm" edited files.
|
||||
|
||||
* Push your branch to GitHub:
|
||||
|
||||
```shell
|
||||
git push origin my-fix-branch
|
||||
```
|
||||
|
||||
In GitHub, send a pull request to `runelite:master`.
|
||||
If we suggest changes, then:
|
||||
|
||||
* Make the required updates.
|
||||
* Re-run runelite and make sure any and all tests are still passing.
|
||||
* Commit your changes to your branch (e.g. `my-fix-branch`).
|
||||
* Push the changes to your GitHub repository (this will update your Pull Request).
|
||||
|
||||
If the PR gets too outdated we may ask you to rebase and force push to update the PR:
|
||||
|
||||
```shell
|
||||
git fetch upstream
|
||||
git rebase upstream/master
|
||||
git push origin my-fix-branch -f
|
||||
```
|
||||
|
||||
That's it! Thank you for your contribution!
|
||||
|
||||
#### After your pull request is merged
|
||||
|
||||
After your pull request is merged, you can safely delete your branch and pull the changes
|
||||
from the main (upstream) repository:
|
||||
|
||||
* Delete the remote branch on GitHub either through the GitHub web UI or your local shell as follows:
|
||||
|
||||
```shell
|
||||
git push origin --delete my-fix-branch
|
||||
```
|
||||
|
||||
* Check out the master branch:
|
||||
|
||||
```shell
|
||||
git checkout master -f
|
||||
```
|
||||
|
||||
* Delete the local branch:
|
||||
|
||||
```shell
|
||||
git branch -D my-fix-branch
|
||||
```
|
||||
|
||||
* Update your master with the latest upstream version:
|
||||
|
||||
```shell
|
||||
git pull --ff upstream master
|
||||
```
|
||||
|
||||
## <a name="format"></a> Coding Format
|
||||
|
||||
To ensure consistency throughout the source code, review our [code conventions](https://github.com/runelite/runelite/wiki/Code-Conventions).
|
||||
|
||||
|
||||
[github]: https://github.com/runelite-extended/runelite
|
||||
[discord]: https://discord.gg/HN5gf3m
|
||||
32
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
32
.github/ISSUE_TEMPLATE/Bug_report.md
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
---
|
||||
name: "\U0001F41B Bug report"
|
||||
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)
|
||||
|
||||
**Describe the bug**
|
||||
A clear and concise description of what the bug is.
|
||||
|
||||
**To Reproduce**
|
||||
Steps to reproduce the behavior:
|
||||
1. Go to '...'
|
||||
2. Click on '....'
|
||||
3. Scroll down to '....'
|
||||
4. See error
|
||||
|
||||
**Expected behavior**
|
||||
A clear and concise description of what you expected to happen.
|
||||
|
||||
**Screenshots**
|
||||
If applicable, add screenshots to help explain your problem.
|
||||
|
||||
**Environment (please complete the following information):**
|
||||
- OS: [e.g. Windows, Ubuntu, macOS]
|
||||
- RuneLite version: [e.g 1.4.6]
|
||||
- Launcher version: [e.g 1.5.2]
|
||||
|
||||
**Additional context**
|
||||
Add any other context about the problem here, e.g. logs. Your client logs can usually be found in
|
||||
`C:\Users\<your_user_name>\.runelite\logs` on Windows and `~/.runelite/logs` on Linux and macOS.
|
||||
19
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
19
.github/ISSUE_TEMPLATE/Feature_request.md
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
---
|
||||
name: "\U0001F680 Feature Request"
|
||||
about: Suggest an idea for this project
|
||||
|
||||
---
|
||||
|
||||
**Is your feature request related to a problem? Please describe.**
|
||||
A clear and concise description of what the problem is. Ex. I'm always
|
||||
frustrated when [...]
|
||||
|
||||
**Describe the solution you'd like**
|
||||
A clear and concise description of what you want to happen.
|
||||
|
||||
**Describe alternatives you've considered**
|
||||
A clear and concise description of any alternative solutions or features you've
|
||||
considered.
|
||||
|
||||
**Additional context**
|
||||
Add any other context or screenshots about the feature request here.
|
||||
17
.gitignore
vendored
17
.gitignore
vendored
@@ -1,6 +1,15 @@
|
||||
*.jar
|
||||
target
|
||||
nbactions.xml
|
||||
nb-configuration.xml
|
||||
/nbproject/
|
||||
project.properties
|
||||
*.iml
|
||||
|
||||
.idea/
|
||||
dependency-reduced-pom.xml
|
||||
**/target/*
|
||||
.project
|
||||
.settings/
|
||||
.classpath
|
||||
runelite-client/src/main/resources/META-INF/MANIFEST.MF
|
||||
git
|
||||
classes/artifacts/client_jar/run.bat
|
||||
classes/artifacts/client_jar/client.jar
|
||||
*.jar
|
||||
|
||||
1
.mvn/jvm.config
Normal file
1
.mvn/jvm.config
Normal file
@@ -0,0 +1 @@
|
||||
-Xmx512m
|
||||
13
.travis.yml
Normal file
13
.travis.yml
Normal file
@@ -0,0 +1,13 @@
|
||||
language: java
|
||||
sudo: false
|
||||
dist: trusty
|
||||
cache:
|
||||
directories:
|
||||
- $HOME/.m2
|
||||
jdk:
|
||||
- oraclejdk8
|
||||
install: true
|
||||
script: ./travis/build.sh
|
||||
before_install:
|
||||
- chmod +x ./travis/build.sh
|
||||
|
||||
686
LICENSE
686
LICENSE
@@ -1,661 +1,25 @@
|
||||
GNU AFFERO GENERAL PUBLIC LICENSE
|
||||
Version 3, 19 November 2007
|
||||
|
||||
Copyright (C) 2007 Free Software Foundation, Inc. <https://fsf.org/>
|
||||
Everyone is permitted to copy and distribute verbatim copies
|
||||
of this license document, but changing it is not allowed.
|
||||
|
||||
Preamble
|
||||
|
||||
The GNU Affero General Public License is a free, copyleft license for
|
||||
software and other kinds of works, specifically designed to ensure
|
||||
cooperation with the community in the case of network server software.
|
||||
|
||||
The licenses for most software and other practical works are designed
|
||||
to take away your freedom to share and change the works. By contrast,
|
||||
our General Public Licenses are intended to guarantee your freedom to
|
||||
share and change all versions of a program--to make sure it remains free
|
||||
software for all its users.
|
||||
|
||||
When we speak of free software, we are referring to freedom, not
|
||||
price. Our General Public Licenses are designed to make sure that you
|
||||
have the freedom to distribute copies of free software (and charge for
|
||||
them if you wish), that you receive source code or can get it if you
|
||||
want it, that you can change the software or use pieces of it in new
|
||||
free programs, and that you know you can do these things.
|
||||
|
||||
Developers that use our General Public Licenses protect your rights
|
||||
with two steps: (1) assert copyright on the software, and (2) offer
|
||||
you this License which gives you legal permission to copy, distribute
|
||||
and/or modify the software.
|
||||
|
||||
A secondary benefit of defending all users' freedom is that
|
||||
improvements made in alternate versions of the program, if they
|
||||
receive widespread use, become available for other developers to
|
||||
incorporate. Many developers of free software are heartened and
|
||||
encouraged by the resulting cooperation. However, in the case of
|
||||
software used on network servers, this result may fail to come about.
|
||||
The GNU General Public License permits making a modified version and
|
||||
letting the public access it on a server without ever releasing its
|
||||
source code to the public.
|
||||
|
||||
The GNU Affero General Public License is designed specifically to
|
||||
ensure that, in such cases, the modified source code becomes available
|
||||
to the community. It requires the operator of a network server to
|
||||
provide the source code of the modified version running there to the
|
||||
users of that server. Therefore, public use of a modified version, on
|
||||
a publicly accessible server, gives the public access to the source
|
||||
code of the modified version.
|
||||
|
||||
An older license, called the Affero General Public License and
|
||||
published by Affero, was designed to accomplish similar goals. This is
|
||||
a different license, not a version of the Affero GPL, but Affero has
|
||||
released a new version of the Affero GPL which permits relicensing under
|
||||
this license.
|
||||
|
||||
The precise terms and conditions for copying, distribution and
|
||||
modification follow.
|
||||
|
||||
TERMS AND CONDITIONS
|
||||
|
||||
0. Definitions.
|
||||
|
||||
"This License" refers to version 3 of the GNU Affero General Public License.
|
||||
|
||||
"Copyright" also means copyright-like laws that apply to other kinds of
|
||||
works, such as semiconductor masks.
|
||||
|
||||
"The Program" refers to any copyrightable work licensed under this
|
||||
License. Each licensee is addressed as "you". "Licensees" and
|
||||
"recipients" may be individuals or organizations.
|
||||
|
||||
To "modify" a work means to copy from or adapt all or part of the work
|
||||
in a fashion requiring copyright permission, other than the making of an
|
||||
exact copy. The resulting work is called a "modified version" of the
|
||||
earlier work or a work "based on" the earlier work.
|
||||
|
||||
A "covered work" means either the unmodified Program or a work based
|
||||
on the Program.
|
||||
|
||||
To "propagate" a work means to do anything with it that, without
|
||||
permission, would make you directly or secondarily liable for
|
||||
infringement under applicable copyright law, except executing it on a
|
||||
computer or modifying a private copy. Propagation includes copying,
|
||||
distribution (with or without modification), making available to the
|
||||
public, and in some countries other activities as well.
|
||||
|
||||
To "convey" a work means any kind of propagation that enables other
|
||||
parties to make or receive copies. Mere interaction with a user through
|
||||
a computer network, with no transfer of a copy, is not conveying.
|
||||
|
||||
An interactive user interface displays "Appropriate Legal Notices"
|
||||
to the extent that it includes a convenient and prominently visible
|
||||
feature that (1) displays an appropriate copyright notice, and (2)
|
||||
tells the user that there is no warranty for the work (except to the
|
||||
extent that warranties are provided), that licensees may convey the
|
||||
work under this License, and how to view a copy of this License. If
|
||||
the interface presents a list of user commands or options, such as a
|
||||
menu, a prominent item in the list meets this criterion.
|
||||
|
||||
1. Source Code.
|
||||
|
||||
The "source code" for a work means the preferred form of the work
|
||||
for making modifications to it. "Object code" means any non-source
|
||||
form of a work.
|
||||
|
||||
A "Standard Interface" means an interface that either is an official
|
||||
standard defined by a recognized standards body, or, in the case of
|
||||
interfaces specified for a particular programming language, one that
|
||||
is widely used among developers working in that language.
|
||||
|
||||
The "System Libraries" of an executable work include anything, other
|
||||
than the work as a whole, that (a) is included in the normal form of
|
||||
packaging a Major Component, but which is not part of that Major
|
||||
Component, and (b) serves only to enable use of the work with that
|
||||
Major Component, or to implement a Standard Interface for which an
|
||||
implementation is available to the public in source code form. A
|
||||
"Major Component", in this context, means a major essential component
|
||||
(kernel, window system, and so on) of the specific operating system
|
||||
(if any) on which the executable work runs, or a compiler used to
|
||||
produce the work, or an object code interpreter used to run it.
|
||||
|
||||
The "Corresponding Source" for a work in object code form means all
|
||||
the source code needed to generate, install, and (for an executable
|
||||
work) run the object code and to modify the work, including scripts to
|
||||
control those activities. However, it does not include the work's
|
||||
System Libraries, or general-purpose tools or generally available free
|
||||
programs which are used unmodified in performing those activities but
|
||||
which are not part of the work. For example, Corresponding Source
|
||||
includes interface definition files associated with source files for
|
||||
the work, and the source code for shared libraries and dynamically
|
||||
linked subprograms that the work is specifically designed to require,
|
||||
such as by intimate data communication or control flow between those
|
||||
subprograms and other parts of the work.
|
||||
|
||||
The Corresponding Source need not include anything that users
|
||||
can regenerate automatically from other parts of the Corresponding
|
||||
Source.
|
||||
|
||||
The Corresponding Source for a work in source code form is that
|
||||
same work.
|
||||
|
||||
2. Basic Permissions.
|
||||
|
||||
All rights granted under this License are granted for the term of
|
||||
copyright on the Program, and are irrevocable provided the stated
|
||||
conditions are met. This License explicitly affirms your unlimited
|
||||
permission to run the unmodified Program. The output from running a
|
||||
covered work is covered by this License only if the output, given its
|
||||
content, constitutes a covered work. This License acknowledges your
|
||||
rights of fair use or other equivalent, as provided by copyright law.
|
||||
|
||||
You may make, run and propagate covered works that you do not
|
||||
convey, without conditions so long as your license otherwise remains
|
||||
in force. You may convey covered works to others for the sole purpose
|
||||
of having them make modifications exclusively for you, or provide you
|
||||
with facilities for running those works, provided that you comply with
|
||||
the terms of this License in conveying all material for which you do
|
||||
not control copyright. Those thus making or running the covered works
|
||||
for you must do so exclusively on your behalf, under your direction
|
||||
and control, on terms that prohibit them from making any copies of
|
||||
your copyrighted material outside their relationship with you.
|
||||
|
||||
Conveying under any other circumstances is permitted solely under
|
||||
the conditions stated below. Sublicensing is not allowed; section 10
|
||||
makes it unnecessary.
|
||||
|
||||
3. Protecting Users' Legal Rights From Anti-Circumvention Law.
|
||||
|
||||
No covered work shall be deemed part of an effective technological
|
||||
measure under any applicable law fulfilling obligations under article
|
||||
11 of the WIPO copyright treaty adopted on 20 December 1996, or
|
||||
similar laws prohibiting or restricting circumvention of such
|
||||
measures.
|
||||
|
||||
When you convey a covered work, you waive any legal power to forbid
|
||||
circumvention of technological measures to the extent such circumvention
|
||||
is effected by exercising rights under this License with respect to
|
||||
the covered work, and you disclaim any intention to limit operation or
|
||||
modification of the work as a means of enforcing, against the work's
|
||||
users, your or third parties' legal rights to forbid circumvention of
|
||||
technological measures.
|
||||
|
||||
4. Conveying Verbatim Copies.
|
||||
|
||||
You may convey verbatim copies of the Program's source code as you
|
||||
receive it, in any medium, provided that you conspicuously and
|
||||
appropriately publish on each copy an appropriate copyright notice;
|
||||
keep intact all notices stating that this License and any
|
||||
non-permissive terms added in accord with section 7 apply to the code;
|
||||
keep intact all notices of the absence of any warranty; and give all
|
||||
recipients a copy of this License along with the Program.
|
||||
|
||||
You may charge any price or no price for each copy that you convey,
|
||||
and you may offer support or warranty protection for a fee.
|
||||
|
||||
5. Conveying Modified Source Versions.
|
||||
|
||||
You may convey a work based on the Program, or the modifications to
|
||||
produce it from the Program, in the form of source code under the
|
||||
terms of section 4, provided that you also meet all of these conditions:
|
||||
|
||||
a) The work must carry prominent notices stating that you modified
|
||||
it, and giving a relevant date.
|
||||
|
||||
b) The work must carry prominent notices stating that it is
|
||||
released under this License and any conditions added under section
|
||||
7. This requirement modifies the requirement in section 4 to
|
||||
"keep intact all notices".
|
||||
|
||||
c) You must license the entire work, as a whole, under this
|
||||
License to anyone who comes into possession of a copy. This
|
||||
License will therefore apply, along with any applicable section 7
|
||||
additional terms, to the whole of the work, and all its parts,
|
||||
regardless of how they are packaged. This License gives no
|
||||
permission to license the work in any other way, but it does not
|
||||
invalidate such permission if you have separately received it.
|
||||
|
||||
d) If the work has interactive user interfaces, each must display
|
||||
Appropriate Legal Notices; however, if the Program has interactive
|
||||
interfaces that do not display Appropriate Legal Notices, your
|
||||
work need not make them do so.
|
||||
|
||||
A compilation of a covered work with other separate and independent
|
||||
works, which are not by their nature extensions of the covered work,
|
||||
and which are not combined with it such as to form a larger program,
|
||||
in or on a volume of a storage or distribution medium, is called an
|
||||
"aggregate" if the compilation and its resulting copyright are not
|
||||
used to limit the access or legal rights of the compilation's users
|
||||
beyond what the individual works permit. Inclusion of a covered work
|
||||
in an aggregate does not cause this License to apply to the other
|
||||
parts of the aggregate.
|
||||
|
||||
6. Conveying Non-Source Forms.
|
||||
|
||||
You may convey a covered work in object code form under the terms
|
||||
of sections 4 and 5, provided that you also convey the
|
||||
machine-readable Corresponding Source under the terms of this License,
|
||||
in one of these ways:
|
||||
|
||||
a) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by the
|
||||
Corresponding Source fixed on a durable physical medium
|
||||
customarily used for software interchange.
|
||||
|
||||
b) Convey the object code in, or embodied in, a physical product
|
||||
(including a physical distribution medium), accompanied by a
|
||||
written offer, valid for at least three years and valid for as
|
||||
long as you offer spare parts or customer support for that product
|
||||
model, to give anyone who possesses the object code either (1) a
|
||||
copy of the Corresponding Source for all the software in the
|
||||
product that is covered by this License, on a durable physical
|
||||
medium customarily used for software interchange, for a price no
|
||||
more than your reasonable cost of physically performing this
|
||||
conveying of source, or (2) access to copy the
|
||||
Corresponding Source from a network server at no charge.
|
||||
|
||||
c) Convey individual copies of the object code with a copy of the
|
||||
written offer to provide the Corresponding Source. This
|
||||
alternative is allowed only occasionally and noncommercially, and
|
||||
only if you received the object code with such an offer, in accord
|
||||
with subsection 6b.
|
||||
|
||||
d) Convey the object code by offering access from a designated
|
||||
place (gratis or for a charge), and offer equivalent access to the
|
||||
Corresponding Source in the same way through the same place at no
|
||||
further charge. You need not require recipients to copy the
|
||||
Corresponding Source along with the object code. If the place to
|
||||
copy the object code is a network server, the Corresponding Source
|
||||
may be on a different server (operated by you or a third party)
|
||||
that supports equivalent copying facilities, provided you maintain
|
||||
clear directions next to the object code saying where to find the
|
||||
Corresponding Source. Regardless of what server hosts the
|
||||
Corresponding Source, you remain obligated to ensure that it is
|
||||
available for as long as needed to satisfy these requirements.
|
||||
|
||||
e) Convey the object code using peer-to-peer transmission, provided
|
||||
you inform other peers where the object code and Corresponding
|
||||
Source of the work are being offered to the general public at no
|
||||
charge under subsection 6d.
|
||||
|
||||
A separable portion of the object code, whose source code is excluded
|
||||
from the Corresponding Source as a System Library, need not be
|
||||
included in conveying the object code work.
|
||||
|
||||
A "User Product" is either (1) a "consumer product", which means any
|
||||
tangible personal property which is normally used for personal, family,
|
||||
or household purposes, or (2) anything designed or sold for incorporation
|
||||
into a dwelling. In determining whether a product is a consumer product,
|
||||
doubtful cases shall be resolved in favor of coverage. For a particular
|
||||
product received by a particular user, "normally used" refers to a
|
||||
typical or common use of that class of product, regardless of the status
|
||||
of the particular user or of the way in which the particular user
|
||||
actually uses, or expects or is expected to use, the product. A product
|
||||
is a consumer product regardless of whether the product has substantial
|
||||
commercial, industrial or non-consumer uses, unless such uses represent
|
||||
the only significant mode of use of the product.
|
||||
|
||||
"Installation Information" for a User Product means any methods,
|
||||
procedures, authorization keys, or other information required to install
|
||||
and execute modified versions of a covered work in that User Product from
|
||||
a modified version of its Corresponding Source. The information must
|
||||
suffice to ensure that the continued functioning of the modified object
|
||||
code is in no case prevented or interfered with solely because
|
||||
modification has been made.
|
||||
|
||||
If you convey an object code work under this section in, or with, or
|
||||
specifically for use in, a User Product, and the conveying occurs as
|
||||
part of a transaction in which the right of possession and use of the
|
||||
User Product is transferred to the recipient in perpetuity or for a
|
||||
fixed term (regardless of how the transaction is characterized), the
|
||||
Corresponding Source conveyed under this section must be accompanied
|
||||
by the Installation Information. But this requirement does not apply
|
||||
if neither you nor any third party retains the ability to install
|
||||
modified object code on the User Product (for example, the work has
|
||||
been installed in ROM).
|
||||
|
||||
The requirement to provide Installation Information does not include a
|
||||
requirement to continue to provide support service, warranty, or updates
|
||||
for a work that has been modified or installed by the recipient, or for
|
||||
the User Product in which it has been modified or installed. Access to a
|
||||
network may be denied when the modification itself materially and
|
||||
adversely affects the operation of the network or violates the rules and
|
||||
protocols for communication across the network.
|
||||
|
||||
Corresponding Source conveyed, and Installation Information provided,
|
||||
in accord with this section must be in a format that is publicly
|
||||
documented (and with an implementation available to the public in
|
||||
source code form), and must require no special password or key for
|
||||
unpacking, reading or copying.
|
||||
|
||||
7. Additional Terms.
|
||||
|
||||
"Additional permissions" are terms that supplement the terms of this
|
||||
License by making exceptions from one or more of its conditions.
|
||||
Additional permissions that are applicable to the entire Program shall
|
||||
be treated as though they were included in this License, to the extent
|
||||
that they are valid under applicable law. If additional permissions
|
||||
apply only to part of the Program, that part may be used separately
|
||||
under those permissions, but the entire Program remains governed by
|
||||
this License without regard to the additional permissions.
|
||||
|
||||
When you convey a copy of a covered work, you may at your option
|
||||
remove any additional permissions from that copy, or from any part of
|
||||
it. (Additional permissions may be written to require their own
|
||||
removal in certain cases when you modify the work.) You may place
|
||||
additional permissions on material, added by you to a covered work,
|
||||
for which you have or can give appropriate copyright permission.
|
||||
|
||||
Notwithstanding any other provision of this License, for material you
|
||||
add to a covered work, you may (if authorized by the copyright holders of
|
||||
that material) supplement the terms of this License with terms:
|
||||
|
||||
a) Disclaiming warranty or limiting liability differently from the
|
||||
terms of sections 15 and 16 of this License; or
|
||||
|
||||
b) Requiring preservation of specified reasonable legal notices or
|
||||
author attributions in that material or in the Appropriate Legal
|
||||
Notices displayed by works containing it; or
|
||||
|
||||
c) Prohibiting misrepresentation of the origin of that material, or
|
||||
requiring that modified versions of such material be marked in
|
||||
reasonable ways as different from the original version; or
|
||||
|
||||
d) Limiting the use for publicity purposes of names of licensors or
|
||||
authors of the material; or
|
||||
|
||||
e) Declining to grant rights under trademark law for use of some
|
||||
trade names, trademarks, or service marks; or
|
||||
|
||||
f) Requiring indemnification of licensors and authors of that
|
||||
material by anyone who conveys the material (or modified versions of
|
||||
it) with contractual assumptions of liability to the recipient, for
|
||||
any liability that these contractual assumptions directly impose on
|
||||
those licensors and authors.
|
||||
|
||||
All other non-permissive additional terms are considered "further
|
||||
restrictions" within the meaning of section 10. If the Program as you
|
||||
received it, or any part of it, contains a notice stating that it is
|
||||
governed by this License along with a term that is a further
|
||||
restriction, you may remove that term. If a license document contains
|
||||
a further restriction but permits relicensing or conveying under this
|
||||
License, you may add to a covered work material governed by the terms
|
||||
of that license document, provided that the further restriction does
|
||||
not survive such relicensing or conveying.
|
||||
|
||||
If you add terms to a covered work in accord with this section, you
|
||||
must place, in the relevant source files, a statement of the
|
||||
additional terms that apply to those files, or a notice indicating
|
||||
where to find the applicable terms.
|
||||
|
||||
Additional terms, permissive or non-permissive, may be stated in the
|
||||
form of a separately written license, or stated as exceptions;
|
||||
the above requirements apply either way.
|
||||
|
||||
8. Termination.
|
||||
|
||||
You may not propagate or modify a covered work except as expressly
|
||||
provided under this License. Any attempt otherwise to propagate or
|
||||
modify it is void, and will automatically terminate your rights under
|
||||
this License (including any patent licenses granted under the third
|
||||
paragraph of section 11).
|
||||
|
||||
However, if you cease all violation of this License, then your
|
||||
license from a particular copyright holder is reinstated (a)
|
||||
provisionally, unless and until the copyright holder explicitly and
|
||||
finally terminates your license, and (b) permanently, if the copyright
|
||||
holder fails to notify you of the violation by some reasonable means
|
||||
prior to 60 days after the cessation.
|
||||
|
||||
Moreover, your license from a particular copyright holder is
|
||||
reinstated permanently if the copyright holder notifies you of the
|
||||
violation by some reasonable means, this is the first time you have
|
||||
received notice of violation of this License (for any work) from that
|
||||
copyright holder, and you cure the violation prior to 30 days after
|
||||
your receipt of the notice.
|
||||
|
||||
Termination of your rights under this section does not terminate the
|
||||
licenses of parties who have received copies or rights from you under
|
||||
this License. If your rights have been terminated and not permanently
|
||||
reinstated, you do not qualify to receive new licenses for the same
|
||||
material under section 10.
|
||||
|
||||
9. Acceptance Not Required for Having Copies.
|
||||
|
||||
You are not required to accept this License in order to receive or
|
||||
run a copy of the Program. Ancillary propagation of a covered work
|
||||
occurring solely as a consequence of using peer-to-peer transmission
|
||||
to receive a copy likewise does not require acceptance. However,
|
||||
nothing other than this License grants you permission to propagate or
|
||||
modify any covered work. These actions infringe copyright if you do
|
||||
not accept this License. Therefore, by modifying or propagating a
|
||||
covered work, you indicate your acceptance of this License to do so.
|
||||
|
||||
10. Automatic Licensing of Downstream Recipients.
|
||||
|
||||
Each time you convey a covered work, the recipient automatically
|
||||
receives a license from the original licensors, to run, modify and
|
||||
propagate that work, subject to this License. You are not responsible
|
||||
for enforcing compliance by third parties with this License.
|
||||
|
||||
An "entity transaction" is a transaction transferring control of an
|
||||
organization, or substantially all assets of one, or subdividing an
|
||||
organization, or merging organizations. If propagation of a covered
|
||||
work results from an entity transaction, each party to that
|
||||
transaction who receives a copy of the work also receives whatever
|
||||
licenses to the work the party's predecessor in interest had or could
|
||||
give under the previous paragraph, plus a right to possession of the
|
||||
Corresponding Source of the work from the predecessor in interest, if
|
||||
the predecessor has it or can get it with reasonable efforts.
|
||||
|
||||
You may not impose any further restrictions on the exercise of the
|
||||
rights granted or affirmed under this License. For example, you may
|
||||
not impose a license fee, royalty, or other charge for exercise of
|
||||
rights granted under this License, and you may not initiate litigation
|
||||
(including a cross-claim or counterclaim in a lawsuit) alleging that
|
||||
any patent claim is infringed by making, using, selling, offering for
|
||||
sale, or importing the Program or any portion of it.
|
||||
|
||||
11. Patents.
|
||||
|
||||
A "contributor" is a copyright holder who authorizes use under this
|
||||
License of the Program or a work on which the Program is based. The
|
||||
work thus licensed is called the contributor's "contributor version".
|
||||
|
||||
A contributor's "essential patent claims" are all patent claims
|
||||
owned or controlled by the contributor, whether already acquired or
|
||||
hereafter acquired, that would be infringed by some manner, permitted
|
||||
by this License, of making, using, or selling its contributor version,
|
||||
but do not include claims that would be infringed only as a
|
||||
consequence of further modification of the contributor version. For
|
||||
purposes of this definition, "control" includes the right to grant
|
||||
patent sublicenses in a manner consistent with the requirements of
|
||||
this License.
|
||||
|
||||
Each contributor grants you a non-exclusive, worldwide, royalty-free
|
||||
patent license under the contributor's essential patent claims, to
|
||||
make, use, sell, offer for sale, import and otherwise run, modify and
|
||||
propagate the contents of its contributor version.
|
||||
|
||||
In the following three paragraphs, a "patent license" is any express
|
||||
agreement or commitment, however denominated, not to enforce a patent
|
||||
(such as an express permission to practice a patent or covenant not to
|
||||
sue for patent infringement). To "grant" such a patent license to a
|
||||
party means to make such an agreement or commitment not to enforce a
|
||||
patent against the party.
|
||||
|
||||
If you convey a covered work, knowingly relying on a patent license,
|
||||
and the Corresponding Source of the work is not available for anyone
|
||||
to copy, free of charge and under the terms of this License, through a
|
||||
publicly available network server or other readily accessible means,
|
||||
then you must either (1) cause the Corresponding Source to be so
|
||||
available, or (2) arrange to deprive yourself of the benefit of the
|
||||
patent license for this particular work, or (3) arrange, in a manner
|
||||
consistent with the requirements of this License, to extend the patent
|
||||
license to downstream recipients. "Knowingly relying" means you have
|
||||
actual knowledge that, but for the patent license, your conveying the
|
||||
covered work in a country, or your recipient's use of the covered work
|
||||
in a country, would infringe one or more identifiable patents in that
|
||||
country that you have reason to believe are valid.
|
||||
|
||||
If, pursuant to or in connection with a single transaction or
|
||||
arrangement, you convey, or propagate by procuring conveyance of, a
|
||||
covered work, and grant a patent license to some of the parties
|
||||
receiving the covered work authorizing them to use, propagate, modify
|
||||
or convey a specific copy of the covered work, then the patent license
|
||||
you grant is automatically extended to all recipients of the covered
|
||||
work and works based on it.
|
||||
|
||||
A patent license is "discriminatory" if it does not include within
|
||||
the scope of its coverage, prohibits the exercise of, or is
|
||||
conditioned on the non-exercise of one or more of the rights that are
|
||||
specifically granted under this License. You may not convey a covered
|
||||
work if you are a party to an arrangement with a third party that is
|
||||
in the business of distributing software, under which you make payment
|
||||
to the third party based on the extent of your activity of conveying
|
||||
the work, and under which the third party grants, to any of the
|
||||
parties who would receive the covered work from you, a discriminatory
|
||||
patent license (a) in connection with copies of the covered work
|
||||
conveyed by you (or copies made from those copies), or (b) primarily
|
||||
for and in connection with specific products or compilations that
|
||||
contain the covered work, unless you entered into that arrangement,
|
||||
or that patent license was granted, prior to 28 March 2007.
|
||||
|
||||
Nothing in this License shall be construed as excluding or limiting
|
||||
any implied license or other defenses to infringement that may
|
||||
otherwise be available to you under applicable patent law.
|
||||
|
||||
12. No Surrender of Others' Freedom.
|
||||
|
||||
If conditions are imposed on you (whether by court order, agreement or
|
||||
otherwise) that contradict the conditions of this License, they do not
|
||||
excuse you from the conditions of this License. If you cannot convey a
|
||||
covered work so as to satisfy simultaneously your obligations under this
|
||||
License and any other pertinent obligations, then as a consequence you may
|
||||
not convey it at all. For example, if you agree to terms that obligate you
|
||||
to collect a royalty for further conveying from those to whom you convey
|
||||
the Program, the only way you could satisfy both those terms and this
|
||||
License would be to refrain entirely from conveying the Program.
|
||||
|
||||
13. Remote Network Interaction; Use with the GNU General Public License.
|
||||
|
||||
Notwithstanding any other provision of this License, if you modify the
|
||||
Program, your modified version must prominently offer all users
|
||||
interacting with it remotely through a computer network (if your version
|
||||
supports such interaction) an opportunity to receive the Corresponding
|
||||
Source of your version by providing access to the Corresponding Source
|
||||
from a network server at no charge, through some standard or customary
|
||||
means of facilitating copying of software. This Corresponding Source
|
||||
shall include the Corresponding Source for any work covered by version 3
|
||||
of the GNU General Public License that is incorporated pursuant to the
|
||||
following paragraph.
|
||||
|
||||
Notwithstanding any other provision of this License, you have
|
||||
permission to link or combine any covered work with a work licensed
|
||||
under version 3 of the GNU General Public License into a single
|
||||
combined work, and to convey the resulting work. The terms of this
|
||||
License will continue to apply to the part which is the covered work,
|
||||
but the work with which it is combined will remain governed by version
|
||||
3 of the GNU General Public License.
|
||||
|
||||
14. Revised Versions of this License.
|
||||
|
||||
The Free Software Foundation may publish revised and/or new versions of
|
||||
the GNU Affero General Public License from time to time. Such new versions
|
||||
will be similar in spirit to the present version, but may differ in detail to
|
||||
address new problems or concerns.
|
||||
|
||||
Each version is given a distinguishing version number. If the
|
||||
Program specifies that a certain numbered version of the GNU Affero General
|
||||
Public License "or any later version" applies to it, you have the
|
||||
option of following the terms and conditions either of that numbered
|
||||
version or of any later version published by the Free Software
|
||||
Foundation. If the Program does not specify a version number of the
|
||||
GNU Affero General Public License, you may choose any version ever published
|
||||
by the Free Software Foundation.
|
||||
|
||||
If the Program specifies that a proxy can decide which future
|
||||
versions of the GNU Affero General Public License can be used, that proxy's
|
||||
public statement of acceptance of a version permanently authorizes you
|
||||
to choose that version for the Program.
|
||||
|
||||
Later license versions may give you additional or different
|
||||
permissions. However, no additional obligations are imposed on any
|
||||
author or copyright holder as a result of your choosing to follow a
|
||||
later version.
|
||||
|
||||
15. Disclaimer of Warranty.
|
||||
|
||||
THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY
|
||||
APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT
|
||||
HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY
|
||||
OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO,
|
||||
THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
|
||||
PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM
|
||||
IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF
|
||||
ALL NECESSARY SERVICING, REPAIR OR CORRECTION.
|
||||
|
||||
16. Limitation of Liability.
|
||||
|
||||
IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS
|
||||
THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY
|
||||
GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE
|
||||
USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF
|
||||
DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD
|
||||
PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS),
|
||||
EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF
|
||||
SUCH DAMAGES.
|
||||
|
||||
17. Interpretation of Sections 15 and 16.
|
||||
|
||||
If the disclaimer of warranty and limitation of liability provided
|
||||
above cannot be given local legal effect according to their terms,
|
||||
reviewing courts shall apply local law that most closely approximates
|
||||
an absolute waiver of all civil liability in connection with the
|
||||
Program, unless a warranty or assumption of liability accompanies a
|
||||
copy of the Program in return for a fee.
|
||||
|
||||
END OF TERMS AND CONDITIONS
|
||||
|
||||
How to Apply These Terms to Your New Programs
|
||||
|
||||
If you develop a new program, and you want it to be of the greatest
|
||||
possible use to the public, the best way to achieve this is to make it
|
||||
free software which everyone can redistribute and change under these terms.
|
||||
|
||||
To do so, attach the following notices to the program. It is safest
|
||||
to attach them to the start of each source file to most effectively
|
||||
state the exclusion of warranty; and each file should have at least
|
||||
the "copyright" line and a pointer to where the full notice is found.
|
||||
|
||||
<one line to give the program's name and a brief idea of what it does.>
|
||||
Copyright (C) <year> <name of author>
|
||||
|
||||
This program is free software: you can redistribute it and/or modify
|
||||
it under the terms of the GNU Affero General Public License as published
|
||||
by the Free Software Foundation, either version 3 of the License, or
|
||||
(at your option) any later version.
|
||||
|
||||
This program is distributed in the hope that it will be useful,
|
||||
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU Affero General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Affero General Public License
|
||||
along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
Also add information on how to contact you by electronic and paper mail.
|
||||
|
||||
If your software can interact with users remotely through a computer
|
||||
network, you should also make sure that it provides a way for users to
|
||||
get its source. For example, if your program is a web application, its
|
||||
interface could display a "Source" link that leads users to an archive
|
||||
of the code. There are many ways you could offer source, and different
|
||||
solutions will be better for different programs; see section 13 for the
|
||||
specific requirements.
|
||||
|
||||
You should also get your employer (if you work as a programmer) or school,
|
||||
if any, to sign a "copyright disclaimer" for the program, if necessary.
|
||||
For more information on this, and how to apply and follow the GNU AGPL, see
|
||||
<https://www.gnu.org/licenses/>.
|
||||
BSD 2-Clause License
|
||||
|
||||
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:
|
||||
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
list of conditions and the following disclaimer.
|
||||
|
||||
* 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 HOLDER 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.
|
||||
|
||||
33
README.md
Normal file
33
README.md
Normal file
@@ -0,0 +1,33 @@
|
||||

|
||||
|
||||
|
||||
|
||||
# RuneLitePlus
|
||||
[](https://forthebadge.com)
|
||||
|
||||
[](https://travis-ci.org/runelite-extended/runelite) [](http://makeapullrequest.com) [](http://hits.dwyl.io/runelite-extended/runelite) [](https://www.patreon.com/RuneLitePlus)
|
||||
|
||||
[RuneLitePlus](https://runelitepl.us) is a extended version of [RuneLite](https://github.com/runelite/runelite) that provides more functionality and less restrictions while staying more open-source.
|
||||
|
||||
|
||||
|
||||
## Discord
|
||||
![[Discord]](https://discordapp.com/api/guilds/373382904769675265/widget.png?style=banner2)
|
||||
|
||||
## Project Layout
|
||||
|
||||
- [cache](cache/src/main/java/net/runelite/cache) - Libraries used for reading/writing cache files, as well as the data in it
|
||||
- [http-api](http-api/src/main/java/net/runelite/http/api) - API for runelite and runeliteplus
|
||||
- [http-service](http-service/src/main/java/net/runelite/http/service) - Service for https://api.runelitepl.us
|
||||
- [runelite-api](runelite-api/src/main/java/net/runelite/api) - RuneLite API, interfaces for accessing the client
|
||||
- [runelite-mixins](runelite-mixins/src/main/java/net/runelite) - Mixins which are injected into the injected client's classes
|
||||
- [runescape-api](runescape-api/src/main/java/net/runelite) - Mappings correspond to these interfaces, runelite-api is a subset of this
|
||||
- [runelite-client](runelite-client/src/main/java/net/runelite/client) - Game client with plugins
|
||||
|
||||
## License
|
||||
|
||||
RuneLitePlus is licensed under the BSD 2-clause license. See the license header in the respective file to be sure.
|
||||
|
||||
## Contribute and Develop
|
||||
|
||||
We've set up a separate document for our [contribution guidelines](https://github.com/runelite-extended/runelite/blob/master/.github/CONTRIBUTING.md).
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* 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 com.runeswag.client.plugins;
|
||||
|
||||
import api.Client;
|
||||
import api.events.ChatMessage;
|
||||
import api.events.ClientTick;
|
||||
import api.events.GameTick;
|
||||
import api.events.MenuOpened;
|
||||
import api.events.VarbitChanged;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Binder;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import com.runeswag.client.config.ConfigManager;
|
||||
import com.runeswag.client.misc.Plugin;
|
||||
import com.runeswag.client.misc.PluginDescriptor;
|
||||
import com.runeswag.client.ui.OverlayManager;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
/**
|
||||
* Authors gazivodag longstreet
|
||||
*/
|
||||
@PluginDescriptor(
|
||||
name = "Test",
|
||||
description = "Testing plugin for building functionality",
|
||||
tags = {}
|
||||
)
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class Test extends Plugin
|
||||
{
|
||||
|
||||
@Provides
|
||||
TestConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(TestConfig.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private TestOverlay testOverlay;
|
||||
|
||||
@Inject
|
||||
private TestConfig config;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(testOverlay);
|
||||
System.out.println("Test Plugin started");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOpened(MenuOpened event)
|
||||
{
|
||||
System.out.println("[Test Plugin] Menu Opened");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
System.out.println("[Test Plugin] Chat Message");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
System.out.println("[Test Plugin] Varbit Changed");
|
||||
}
|
||||
}
|
||||
@@ -1,286 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Tyler <https://github.com/tylerthardy>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.config;
|
||||
|
||||
import api.config.Constants;
|
||||
import java.awt.Dimension;
|
||||
|
||||
@ConfigGroup("runelite")
|
||||
public interface RuneLiteConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "gameSize",
|
||||
name = "Game size",
|
||||
description = "The game will resize to this resolution upon starting the client",
|
||||
position = 10
|
||||
)
|
||||
default Dimension gameSize()
|
||||
{
|
||||
return Constants.GAME_FIXED_SIZE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "automaticResizeType",
|
||||
name = "Resize type",
|
||||
description = "Choose how the window should resize when opening and closing panels",
|
||||
position = 11
|
||||
)
|
||||
default ExpandResizeType automaticResizeType()
|
||||
{
|
||||
return ExpandResizeType.KEEP_GAME_SIZE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lockWindowSize",
|
||||
name = "Lock window size",
|
||||
description = "Determines if the window resizing is allowed or not",
|
||||
position = 12
|
||||
)
|
||||
default boolean lockWindowSize()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "enablePlugins",
|
||||
name = "Enable loading of external plugins",
|
||||
description = "Enable loading of external plugins",
|
||||
position = 10
|
||||
)
|
||||
default boolean enablePlugins()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "containInScreen",
|
||||
name = "Contain in screen",
|
||||
description = "Makes the client stay contained in the screen when attempted to move out of it.<br>Note: Only works if custom chrome is enabled.",
|
||||
position = 13
|
||||
)
|
||||
default boolean containInScreen()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "rememberScreenBounds",
|
||||
name = "Remember client position",
|
||||
description = "Save the position and size of the client after exiting",
|
||||
position = 14
|
||||
)
|
||||
default boolean rememberScreenBounds()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "uiEnableCustomChrome",
|
||||
name = "Enable custom window chrome",
|
||||
description = "Use Runelite's custom window title and borders.",
|
||||
warning = "Please restart your client after changing this setting",
|
||||
position = 15
|
||||
)
|
||||
default boolean enableCustomChrome()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gameAlwaysOnTop",
|
||||
name = "Enable client always on top",
|
||||
description = "The game will always be on the top of the screen",
|
||||
position = 16
|
||||
)
|
||||
default boolean gameAlwaysOnTop()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "warningOnExit",
|
||||
name = "Display warning on exit",
|
||||
description = "Toggles a warning popup when trying to exit the client",
|
||||
position = 17
|
||||
)
|
||||
default WarningOnExit warningOnExit()
|
||||
{
|
||||
return WarningOnExit.LOGGED_IN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "usernameInTitle",
|
||||
name = "Show display name in title",
|
||||
description = "Toggles displaying of local player's display name in client title",
|
||||
position = 18
|
||||
)
|
||||
default boolean usernameInTitle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationTray",
|
||||
name = "Enable tray notifications",
|
||||
description = "Enables tray notifications",
|
||||
position = 20
|
||||
)
|
||||
default boolean enableTrayNotifications()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationRequestFocus",
|
||||
name = "Request focus on notification",
|
||||
description = "Toggles window focus request",
|
||||
position = 21
|
||||
)
|
||||
default boolean requestFocusOnNotification()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationSound",
|
||||
name = "Enable sound on notifications",
|
||||
description = "Enables the playing of a beep sound when notifications are displayed",
|
||||
position = 22
|
||||
)
|
||||
default boolean enableNotificationSound()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationGameMessage",
|
||||
name = "Enable game message notifications",
|
||||
description = "Puts a notification message in the chatbox",
|
||||
position = 23
|
||||
)
|
||||
default boolean enableGameMessageNotification()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationFlash",
|
||||
name = "Enable flash notification",
|
||||
description = "Flashes the game frame as a notification",
|
||||
position = 24
|
||||
)
|
||||
default boolean enableFlashNotification()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "notificationFocused",
|
||||
name = "Send notifications when focused",
|
||||
description = "Toggles all notifications for when the client is focused",
|
||||
position = 25
|
||||
)
|
||||
default boolean sendNotificationsWhenFocused()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fontType",
|
||||
name = "Dynamic Overlay Font",
|
||||
description = "Configures what font type is used for in-game overlays such as player name, ground items, etc.",
|
||||
position = 30
|
||||
)
|
||||
default FontType fontType()
|
||||
{
|
||||
return FontType.SMALL;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tooltipFontType",
|
||||
name = "Tooltip Font",
|
||||
description = "Configures what font type is used for in-game tooltips such as food stats, NPC names, etc.",
|
||||
position = 31
|
||||
)
|
||||
default FontType tooltipFontType()
|
||||
{
|
||||
return FontType.SMALL;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "interfaceFontType",
|
||||
name = "Interface Overlay Font",
|
||||
description = "Configures what font type is used for in-game interface overlays such as panels, opponent info, clue scrolls etc.",
|
||||
position = 32
|
||||
)
|
||||
default FontType interfaceFontType()
|
||||
{
|
||||
return FontType.REGULAR;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "menuEntryShift",
|
||||
name = "Require Shift for overlay menu",
|
||||
description = "Overlay right-click menu will require shift to be added",
|
||||
position = 33
|
||||
)
|
||||
default boolean menuEntryShift()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "infoBoxVertical",
|
||||
name = "Display infoboxes vertically",
|
||||
description = "Toggles the infoboxes to display vertically",
|
||||
position = 40
|
||||
)
|
||||
default boolean infoBoxVertical()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "infoBoxWrap",
|
||||
name = "Infobox wrap count",
|
||||
description = "Configures the amount of infoboxes shown before wrapping",
|
||||
position = 41
|
||||
)
|
||||
default int infoBoxWrap()
|
||||
{
|
||||
return 4;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "infoBoxSize",
|
||||
name = "Infobox size (px)",
|
||||
description = "Configures the size of each infobox in pixels",
|
||||
position = 42
|
||||
)
|
||||
default int infoBoxSize()
|
||||
{
|
||||
return 35;
|
||||
}
|
||||
}
|
||||
@@ -1,333 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Modified by farhan1666
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.aoewarnings;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Stub;
|
||||
|
||||
@ConfigGroup("aoe")
|
||||
public interface AoeWarningConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "overlayStub",
|
||||
name = "Overlay",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
default Stub overlayStub()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "overlayColor",
|
||||
name = "Overlay Color",
|
||||
description = "Configures the color of the AoE Projectile Warnings overlay"
|
||||
)
|
||||
default Color overlayColor()
|
||||
{
|
||||
return new Color(0, 150, 200);
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "outline",
|
||||
name = "Display Outline",
|
||||
description = "Configures whether or not AoE Projectile Warnings have an outline",
|
||||
parent = "overlayStub",
|
||||
position = 3
|
||||
)
|
||||
default boolean isOutlineEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "delay",
|
||||
name = "Fade Delay",
|
||||
description = "Configures the amount of time in milliseconds that the warning lingers for after the projectile has touched the ground",
|
||||
parent = "overlayStub",
|
||||
position = 4
|
||||
)
|
||||
default int delay()
|
||||
{
|
||||
return 300;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "fade",
|
||||
name = "Fade Warnings",
|
||||
description = "Configures whether or not AoE Projectile Warnings fade over time",
|
||||
parent = "overlayStub",
|
||||
position = 5
|
||||
)
|
||||
default boolean isFadeEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "npcStub",
|
||||
name = "NPC's",
|
||||
description = "",
|
||||
position = 6
|
||||
)
|
||||
default Stub npcStub()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lizardmanaoe",
|
||||
name = "Lizardman Shamans",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Lizardman Shamans is displayed",
|
||||
parent = "npcStub",
|
||||
position = 7
|
||||
)
|
||||
default boolean isShamansEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "archaeologistaoe",
|
||||
name = "Crazy Archaeologist",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Archaeologist is displayed",
|
||||
parent = "npcStub",
|
||||
position = 8
|
||||
)
|
||||
default boolean isArchaeologistEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "icedemon",
|
||||
name = "Ice Demon",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Ice Demon is displayed",
|
||||
parent = "npcStub",
|
||||
position = 9
|
||||
)
|
||||
default boolean isIceDemonEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vasa",
|
||||
name = "Vasa",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vasa is displayed",
|
||||
parent = "npcStub",
|
||||
position = 10
|
||||
)
|
||||
default boolean isVasaEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "tekton",
|
||||
name = "Tekton",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Tekton is displayed",
|
||||
parent = "npcStub",
|
||||
position = 11
|
||||
)
|
||||
default boolean isTektonEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vorkath",
|
||||
name = "Vorkath",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vorkath are displayed",
|
||||
parent = "npcStub",
|
||||
position = 12
|
||||
)
|
||||
default boolean isVorkathEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "galvek",
|
||||
name = "Galvek",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Galvek are displayed",
|
||||
parent = "npcStub",
|
||||
position = 13
|
||||
)
|
||||
default boolean isGalvekEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gargboss",
|
||||
name = "Gargoyle Boss",
|
||||
description = "Configs whether or not AoE Projectile Warnings for Dawn/Dusk are displayed",
|
||||
parent = "npcStub",
|
||||
position = 14
|
||||
)
|
||||
default boolean isGargBossEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "vetion",
|
||||
name = "Vet'ion",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Vet'ion are displayed",
|
||||
parent = "npcStub",
|
||||
position = 15
|
||||
)
|
||||
default boolean isVetionEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "chaosfanatic",
|
||||
name = "Chaos Fanatic",
|
||||
description = "Configures whether or not AoE Projectile Warnings for Chaos Fanatic are displayed",
|
||||
parent = "npcStub",
|
||||
position = 16
|
||||
)
|
||||
default boolean isChaosFanaticEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "olm",
|
||||
name = "Olm",
|
||||
description = "Configures whether or not AoE Projectile Warnings for The Great Olm are displayed",
|
||||
parent = "npcStub",
|
||||
position = 17
|
||||
)
|
||||
default boolean isOlmEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "bombDisplay",
|
||||
name = "Olm Bombs",
|
||||
description = "Display a timer and colour-coded AoE for Olm's crystal-phase bombs.",
|
||||
parent = "npcStub",
|
||||
position = 18
|
||||
)
|
||||
default boolean bombDisplay()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "corp",
|
||||
name = "Corporeal Beast",
|
||||
description = "Configures whether or not AoE Projectile Warnings for the Corporeal Beast are displayed",
|
||||
parent = "npcStub",
|
||||
position = 19
|
||||
)
|
||||
default boolean isCorpEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "wintertodt",
|
||||
name = "Wintertodt Snow Fall",
|
||||
description = "Configures whether or not AOE Projectile Warnings for the Wintertodt snow fall are displayed",
|
||||
parent = "npcStub",
|
||||
position = 20
|
||||
)
|
||||
default boolean isWintertodtEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "isXarpusEnabled",
|
||||
name = "Xarpus",
|
||||
description = "Configures whether or not AOE Projectile Warnings for Xarpus are displayed",
|
||||
parent = "npcStub",
|
||||
position = 21
|
||||
)
|
||||
default boolean isXarpusEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "lightning",
|
||||
name = "Olm Lightning Trails",
|
||||
description = "Show Lightning Trails",
|
||||
parent = "npcStub",
|
||||
position = 22
|
||||
)
|
||||
default boolean LightningTrail()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "addyDrags",
|
||||
name = "Addy Drags",
|
||||
description = "Show Bad Areas",
|
||||
parent = "npcStub",
|
||||
position = 23
|
||||
)
|
||||
default boolean addyDrags()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "drake", name = "Drakes Breath",
|
||||
description = "Configures if Drakes Breath tile markers are displayed",
|
||||
parent = "npcStub",
|
||||
position = 24
|
||||
)
|
||||
default boolean isDrakeEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "cerbFire",
|
||||
name = "Cerberus Fire",
|
||||
description = "Configures if Cerberus fire tile markers are displayed",
|
||||
parent = "npcStub",
|
||||
position = 25
|
||||
)
|
||||
default boolean isCerbFireEnabled()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -1,166 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barbarianassault;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("barbarianAssault")
|
||||
public interface BarbarianAssaultConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "showTimer",
|
||||
name = "Show call change timer",
|
||||
description = "Show time to next call change",
|
||||
position = 0
|
||||
)
|
||||
default boolean showTimer()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "waveTimes",
|
||||
name = "Show wave and game duration",
|
||||
description = "Displays wave and game duration",
|
||||
position = 1
|
||||
)
|
||||
default boolean waveTimes()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showEggCountMessage",
|
||||
name = "Show count of eggs collected as collector.",
|
||||
description = "Display egg count as collector after each wave",
|
||||
position = 2
|
||||
)
|
||||
default boolean showEggCount()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showEggCountOverlay",
|
||||
name = "Overlay of eggs counted",
|
||||
description = "Display current egg count as collector",
|
||||
position = 3
|
||||
)
|
||||
default boolean showEggCountOverlay()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHpCountMessage",
|
||||
name = "Show count of Hp healed as healer.",
|
||||
description = "Display healed count as healer after each wave",
|
||||
position = 4
|
||||
)
|
||||
default boolean showHpCount()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHpCountOverlay",
|
||||
name = "Overlay of Hp counted",
|
||||
description = "Display current healed count as healer",
|
||||
position = 5
|
||||
)
|
||||
default boolean showHpCountOverlay()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightCollectorEggs",
|
||||
name = "Highlight collector eggs",
|
||||
description = "Highlight called egg colors",
|
||||
position = 6
|
||||
)
|
||||
default boolean highlightCollectorEggs()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showTotalRewards",
|
||||
name = "Summarize total reward points",
|
||||
description = "Displays total eggs/healed hp and missed attacks/lost runners",
|
||||
position = 7
|
||||
)
|
||||
default boolean showTotalRewards()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showSummaryOfPoints",
|
||||
name = "Display summary of advanced points",
|
||||
description = "Gives summary of advanced points breakdown in chat log",
|
||||
position = 8
|
||||
)
|
||||
default boolean showSummaryOfPoints()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "wrongPoisonFoodTextColor",
|
||||
name = "Change healer wrong poison pack color",
|
||||
description = "Change healer wrong poison pack color",
|
||||
position = 9
|
||||
)
|
||||
default Color wrongPoisonFoodTextColor()
|
||||
{
|
||||
return Color.BLACK;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightItems",
|
||||
name = "Highlight called poison/bait",
|
||||
description = "Highlights the poison or bait that was called by your teammate",
|
||||
position = 10
|
||||
)
|
||||
default boolean highlightItems()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "highlightColor",
|
||||
name = "Highlight color",
|
||||
description = "Configures the color to highlight the called poison/bait",
|
||||
position = 11
|
||||
)
|
||||
default Color highlightColor()
|
||||
{
|
||||
return Color.GREEN;
|
||||
}
|
||||
}
|
||||
@@ -1,247 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barbarianassault;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.Stroke;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import api.Client;
|
||||
import api.GameState;
|
||||
import static api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import api.Perspective;
|
||||
import api.Player;
|
||||
import api.Point;
|
||||
import api.coords.LocalPoint;
|
||||
import api.coords.WorldPoint;
|
||||
import api.widgets.Widget;
|
||||
import api.widgets.WidgetInfo;
|
||||
import api.widgets.WidgetItem;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
|
||||
class BarbarianAssaultOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_EGG_DISTANCE = 2500;
|
||||
private static final int HEALTH_BAR_HEIGHT = 20;
|
||||
private final Color HEALTH_BAR_COLOR = new Color(225, 35, 0, 125);
|
||||
private static final Color BACKGROUND = new Color(0, 0, 0, 150);
|
||||
private static final int OFFSET_Z = 20;
|
||||
|
||||
private final Client client;
|
||||
private final ItemManager itemManager;
|
||||
private final BarbarianAssaultPlugin plugin;
|
||||
private final BarbarianAssaultConfig config;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private Round currentRound;
|
||||
|
||||
|
||||
@Inject
|
||||
private BarbarianAssaultOverlay(Client client, ItemManager itemManager, BarbarianAssaultPlugin plugin, BarbarianAssaultConfig config)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.itemManager = itemManager;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "B.A. overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN || currentRound == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Role role = currentRound.getRoundRole();
|
||||
if (role == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Widget roleText = client.getWidget(role.getRoleText());
|
||||
Widget roleSprite = client.getWidget(role.getRoleSprite());
|
||||
|
||||
if (config.showTimer() && roleText != null && roleSprite != null)
|
||||
{
|
||||
if (config.showEggCountOverlay() && role.equals(Role.COLLECTOR))
|
||||
{
|
||||
roleText.setText(String.format("(%d) 00:%02d", plugin.getCollectedEggCount(), currentRound.getTimeToChange()));
|
||||
}
|
||||
else if (config.showHpCountOverlay() && role.equals(Role.HEALER))
|
||||
{
|
||||
roleText.setText(String.format("(%d) 00:%02d", plugin.getHpHealed(), currentRound.getTimeToChange()));
|
||||
}
|
||||
else
|
||||
{
|
||||
roleText.setText(String.format("00:%02d", currentRound.getTimeToChange()));
|
||||
}
|
||||
Rectangle spriteBounds = roleSprite.getBounds();
|
||||
roleSprite.setHidden(true);
|
||||
graphics.drawImage(plugin.getClockImage(), spriteBounds.x, spriteBounds.y, null);
|
||||
}
|
||||
|
||||
if (role == Role.COLLECTOR && config.highlightCollectorEggs())
|
||||
{
|
||||
String heardCall = plugin.getCollectorHeardCall();
|
||||
Color highlightColor = BarbarianAssaultPlugin.getEggColor(heardCall);
|
||||
Map<WorldPoint, Integer> calledEggMap = plugin.getCalledEggMap();
|
||||
Map<WorldPoint, Integer> yellowEggMap = plugin.getYellowEggs();
|
||||
|
||||
if (calledEggMap != null)
|
||||
{
|
||||
renderEggLocations(graphics, calledEggMap, highlightColor);
|
||||
}
|
||||
|
||||
// Always show yellow eggs
|
||||
renderEggLocations(graphics, yellowEggMap, Color.YELLOW);
|
||||
}
|
||||
Widget inventory = client.getWidget(WidgetInfo.INVENTORY);
|
||||
|
||||
if (config.highlightItems() && inventory != null && !inventory.isHidden() && ((role == Role.DEFENDER || role == Role.HEALER)))
|
||||
{
|
||||
int listenItemId = plugin.getListenItemId(role.getListen());
|
||||
|
||||
if (listenItemId != -1)
|
||||
{
|
||||
Color color = config.highlightColor();
|
||||
BufferedImage highlight = ImageUtil.fillImage(itemManager.getImage(listenItemId), new Color(color.getRed(), color.getGreen(), color.getBlue(), 150));
|
||||
|
||||
for (WidgetItem item : inventory.getWidgetItems())
|
||||
{
|
||||
if (item.getId() == listenItemId)
|
||||
{
|
||||
OverlayUtil.renderImageLocation(graphics, item.getCanvasLocation(), highlight);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (role == Role.HEALER)
|
||||
{
|
||||
for (HealerTeam teammate : HealerTeam.values())
|
||||
{
|
||||
Widget widget = client.getWidget(teammate.getTeammate());
|
||||
if (widget == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
String[] teammateHealth = widget.getText().split(" / ");
|
||||
final int curHealth = Integer.parseInt(teammateHealth[0]);
|
||||
final int maxHealth = Integer.parseInt(teammateHealth[1]);
|
||||
|
||||
int width = teammate.getWidth();
|
||||
final int filledWidth = getBarWidth(maxHealth, curHealth, width);
|
||||
|
||||
int offsetX = teammate.getOffset().getX();
|
||||
int offsetY = teammate.getOffset().getY();
|
||||
int x = widget.getCanvasLocation().getX() - offsetX;
|
||||
int y = widget.getCanvasLocation().getY() - offsetY;
|
||||
|
||||
graphics.setColor(HEALTH_BAR_COLOR);
|
||||
graphics.fillRect(x, y, filledWidth, HEALTH_BAR_HEIGHT);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static int getBarWidth(int base, int current, int size)
|
||||
{
|
||||
final double ratio = (double) current / base;
|
||||
|
||||
if (ratio >= 1)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
return (int) Math.round(ratio * size);
|
||||
}
|
||||
|
||||
private void renderEggLocations(Graphics2D graphics, Map<WorldPoint, Integer> eggMap, Color color)
|
||||
{
|
||||
Player player = client.getLocalPlayer();
|
||||
|
||||
if (player == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final Stroke originalStroke = graphics.getStroke();
|
||||
|
||||
for (WorldPoint worldPoint : eggMap.keySet())
|
||||
{
|
||||
LocalPoint groundPoint = LocalPoint.fromWorld(client, worldPoint);
|
||||
|
||||
if (groundPoint == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if (player.getLocalLocation().distanceTo(groundPoint) > MAX_EGG_DISTANCE)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, groundPoint);
|
||||
|
||||
if (poly == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
int quantity = eggMap.get(worldPoint);
|
||||
String quantityText = "x" + quantity;
|
||||
Point textPoint = Perspective.getCanvasTextLocation(client, graphics, groundPoint, quantityText, OFFSET_Z);
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.drawPolygon(poly);
|
||||
OverlayUtil.renderTextLocation(graphics, textPoint, quantityText, Color.WHITE);
|
||||
}
|
||||
|
||||
graphics.setStroke(originalStroke);
|
||||
}
|
||||
}
|
||||
@@ -1,628 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barbarianassault;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Image;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import api.ChatMessageType;
|
||||
import api.Client;
|
||||
import api.GameState;
|
||||
import api.ItemID;
|
||||
import api.MenuEntry;
|
||||
import api.MessageNode;
|
||||
import api.Player;
|
||||
import api.Tile;
|
||||
import api.Varbits;
|
||||
import api.coords.WorldPoint;
|
||||
import api.events.ChatMessage;
|
||||
import api.events.GameStateChanged;
|
||||
import api.events.ItemDespawned;
|
||||
import api.events.ItemSpawned;
|
||||
import api.events.MenuEntryAdded;
|
||||
import api.events.VarbitChanged;
|
||||
import api.events.WidgetLoaded;
|
||||
import api.kit.KitType;
|
||||
import api.widgets.Widget;
|
||||
import api.widgets.WidgetID;
|
||||
import api.widgets.WidgetInfo;
|
||||
import net.runelite.client.chat.ChatColorType;
|
||||
import net.runelite.client.chat.ChatMessageBuilder;
|
||||
import net.runelite.client.chat.ChatMessageManager;
|
||||
import net.runelite.client.chat.QueuedMessage;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
import net.runelite.client.util.Text;
|
||||
|
||||
@Slf4j
|
||||
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Barbarian Assault+",
|
||||
description = "Custom barbarian assault plugin, use along with BA Tools",
|
||||
tags = {"minigame", "overlay", "timer"},
|
||||
type = PluginType.PVM // don't remove this, added this because our barbarian assault plugin is big time modified
|
||||
)
|
||||
public class BarbarianAssaultPlugin extends Plugin
|
||||
{
|
||||
private static final int BA_WAVE_NUM_INDEX = 2;
|
||||
private static final String START_WAVE = "1";
|
||||
private static final String ENDGAME_REWARD_NEEDLE_TEXT = "<br>5";
|
||||
|
||||
@Getter
|
||||
private int collectedEggCount = 0;
|
||||
|
||||
@Getter
|
||||
private int positiveEggCount = 0;
|
||||
|
||||
@Getter
|
||||
private int wrongEggs = 0;
|
||||
|
||||
@Getter
|
||||
private int HpHealed = 0;
|
||||
|
||||
@Getter
|
||||
private int totalCollectedEggCount = 0;
|
||||
|
||||
@Getter
|
||||
private int totalHpHealed = 0;
|
||||
|
||||
private boolean hasAnnounced;
|
||||
private Font font;
|
||||
private final Image clockImage = ImageUtil.getResourceStreamFromClass(getClass(), "clock.png");
|
||||
private int inGameBit = 0;
|
||||
private String currentWave = START_WAVE;
|
||||
private GameTimer gameTime;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final HashMap<WorldPoint, Integer> redEggs = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final HashMap<WorldPoint, Integer> greenEggs = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final HashMap<WorldPoint, Integer> blueEggs = new HashMap<>();
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final HashMap<WorldPoint, Integer> yellowEggs = new HashMap<>();
|
||||
|
||||
@Inject
|
||||
@Getter
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ChatMessageManager chatMessageManager;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private BarbarianAssaultConfig config;
|
||||
|
||||
@Inject
|
||||
private BarbarianAssaultOverlay overlay;
|
||||
|
||||
@Provides
|
||||
BarbarianAssaultConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BarbarianAssaultConfig.class);
|
||||
}
|
||||
|
||||
private Game game;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
font = FontManager.getRunescapeFont()
|
||||
.deriveFont(Font.BOLD, 24);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
gameTime = null;
|
||||
currentWave = START_WAVE;
|
||||
inGameBit = 0;
|
||||
collectedEggCount = 0;
|
||||
positiveEggCount = 0;
|
||||
wrongEggs = 0;
|
||||
HpHealed = 0;
|
||||
clearAllEggMaps();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(final GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOADING)
|
||||
{
|
||||
clearAllEggMaps();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
switch (event.getGroupId())
|
||||
{
|
||||
case WidgetID.BA_REWARD_GROUP_ID:
|
||||
{
|
||||
Wave wave = new Wave(client);
|
||||
Widget rewardWidget = client.getWidget(WidgetInfo.BA_REWARD_TEXT);
|
||||
if (rewardWidget != null && rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && gameTime != null)
|
||||
{
|
||||
if (config.waveTimes())
|
||||
{
|
||||
announceTime("Game finished, duration: ", gameTime.getTime(false));
|
||||
}
|
||||
if (config.showTotalRewards())
|
||||
{
|
||||
announceSomething(game.getGameSummary());
|
||||
}
|
||||
}
|
||||
Widget pointsWidget = client.getWidget(WidgetInfo.BA_RUNNERS_PASSED);
|
||||
if (rewardWidget != null && !rewardWidget.getText().contains(ENDGAME_REWARD_NEEDLE_TEXT) && pointsWidget != null
|
||||
&& config.showSummaryOfPoints() && !hasAnnounced && client.getVar(Varbits.IN_GAME_BA) == 0)
|
||||
{
|
||||
wave.setWaveAmounts();
|
||||
wave.setWavePoints();
|
||||
game.getWaves().add(wave);
|
||||
announceSomething(wave.getWaveSummary());
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
case WidgetID.BA_ATTACKER_GROUP_ID:
|
||||
{
|
||||
setOverlayRound(Role.ATTACKER);
|
||||
break;
|
||||
}
|
||||
case WidgetID.BA_DEFENDER_GROUP_ID:
|
||||
{
|
||||
setOverlayRound(Role.DEFENDER);
|
||||
break;
|
||||
}
|
||||
case WidgetID.BA_HEALER_GROUP_ID:
|
||||
{
|
||||
setOverlayRound(Role.HEALER);
|
||||
break;
|
||||
}
|
||||
case WidgetID.BA_COLLECTOR_GROUP_ID:
|
||||
{
|
||||
setOverlayRound(Role.COLLECTOR);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
if (chatMessage.getMessage().toLowerCase().contains("testing"))
|
||||
{
|
||||
ArrayList<Wave> waves = new ArrayList<>();
|
||||
for (int i = 0; i < 1; i++)
|
||||
{
|
||||
Wave wave1 = new Wave(client);
|
||||
int[] amounts = {4, 0, 30, 10, 1, 38};
|
||||
int[] points = {-3, -2, 6, -4, -8, -11};
|
||||
int[] otherPoints = {38, 35, 33, 30};
|
||||
wave1.setWaveAmounts(amounts);
|
||||
wave1.setWavePoints(points, otherPoints);
|
||||
waves.add(wave1);
|
||||
announceSomething(wave1.getWaveSummary());
|
||||
}
|
||||
Game game1 = new Game(client, waves);
|
||||
announceSomething(game1.getGameSummary());
|
||||
}
|
||||
if (chatMessage.getMessage().toLowerCase().startsWith("wave points"))
|
||||
{
|
||||
hasAnnounced = true;
|
||||
}
|
||||
if (!chatMessage.getType().equals(ChatMessageType.GAMEMESSAGE))
|
||||
{
|
||||
return;
|
||||
}
|
||||
int inGame = client.getVar(Varbits.IN_GAME_BA);
|
||||
if (inGameBit != inGame)
|
||||
{
|
||||
return;
|
||||
}
|
||||
final String message = chatMessage.getMessage().toLowerCase();
|
||||
final MessageNode messageNode = chatMessage.getMessageNode();
|
||||
final String nodeValue = Text.removeTags(messageNode.getValue());
|
||||
String recolored = null;
|
||||
if (chatMessage.getMessage().startsWith("---- Wave:"))
|
||||
{
|
||||
String[] tempMessage = chatMessage.getMessage().split(" ");
|
||||
currentWave = tempMessage[BA_WAVE_NUM_INDEX];
|
||||
collectedEggCount = 0;
|
||||
HpHealed = 0;
|
||||
positiveEggCount = 0;
|
||||
wrongEggs = 0;
|
||||
if (currentWave.equals(START_WAVE))
|
||||
{
|
||||
gameTime = new GameTimer();
|
||||
totalHpHealed = 0;
|
||||
totalCollectedEggCount = 0;
|
||||
game = new Game(client);
|
||||
}
|
||||
else if (gameTime != null)
|
||||
{
|
||||
gameTime.setWaveStartTime();
|
||||
}
|
||||
}
|
||||
if (chatMessage.getMessage().contains("exploded"))
|
||||
{
|
||||
wrongEggs++;
|
||||
positiveEggCount--;
|
||||
}
|
||||
if (chatMessage.getMessage().contains("You healed"))
|
||||
{
|
||||
String[] tokens = message.split(" ");
|
||||
if (Integer.parseInt(tokens[2]) > 0)
|
||||
{
|
||||
int Hp = Integer.parseInt(tokens[2]);
|
||||
HpHealed += Hp;
|
||||
}
|
||||
}
|
||||
|
||||
if (message.contains("the wrong type of poisoned food to use"))
|
||||
{
|
||||
recolored = ColorUtil.wrapWithColorTag(nodeValue, config.wrongPoisonFoodTextColor());
|
||||
}
|
||||
if (recolored != null)
|
||||
{
|
||||
messageNode.setValue(recolored);
|
||||
chatMessageManager.update(messageNode);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
int inGame = client.getVar(Varbits.IN_GAME_BA);
|
||||
|
||||
if (inGameBit != inGame)
|
||||
{
|
||||
if (inGameBit == 1)
|
||||
{
|
||||
overlay.setCurrentRound(null);
|
||||
|
||||
if (config.waveTimes() && gameTime != null)
|
||||
{
|
||||
announceTime("Wave " + currentWave + " duration: ", gameTime.getTime(true));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
hasAnnounced = false;
|
||||
}
|
||||
}
|
||||
|
||||
inGameBit = inGame;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemSpawned(ItemSpawned itemSpawned)
|
||||
{
|
||||
int itemId = itemSpawned.getItem().getId();
|
||||
WorldPoint worldPoint = itemSpawned.getTile().getWorldLocation();
|
||||
HashMap<WorldPoint, Integer> eggMap = getEggMap(itemId);
|
||||
if (eggMap != null)
|
||||
{
|
||||
Integer existingQuantity = eggMap.putIfAbsent(worldPoint, 1);
|
||||
if (existingQuantity != null)
|
||||
{
|
||||
eggMap.put(worldPoint, existingQuantity + 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onItemDespawned(ItemDespawned itemDespawned)
|
||||
{
|
||||
int itemId = itemDespawned.getItem().getId();
|
||||
WorldPoint worldPoint = itemDespawned.getTile().getWorldLocation();
|
||||
HashMap<WorldPoint, Integer> eggMap = getEggMap(itemId);
|
||||
|
||||
if (eggMap != null && eggMap.containsKey(worldPoint))
|
||||
{
|
||||
int quantity = eggMap.get(worldPoint);
|
||||
if (quantity > 1)
|
||||
{
|
||||
eggMap.put(worldPoint, quantity - 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
eggMap.remove(worldPoint);
|
||||
}
|
||||
}
|
||||
if (client.getVar(Varbits.IN_GAME_BA) == 0 || !isEgg(itemDespawned.getItem().getId()))
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (isUnderPlayer(itemDespawned.getTile()))
|
||||
{
|
||||
if (client.getLocalPlayer().getPlayerAppearance().getEquipmentId(KitType.CAPE) == ItemID.COLLECTOR_ICON)
|
||||
{
|
||||
positiveEggCount++;
|
||||
if (positiveEggCount > 60)
|
||||
{
|
||||
positiveEggCount = 60;
|
||||
}
|
||||
collectedEggCount = positiveEggCount - wrongEggs; //true positive - negative egg count
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (!config.highlightCollectorEggs())
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (overlay.getCurrentRound() == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
if (overlay.getCurrentRound().getRoundRole() != Role.COLLECTOR)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String calledEgg = getCollectorHeardCall();
|
||||
String target = event.getTarget();
|
||||
String option = event.getOption();
|
||||
String targetClean = target.substring(target.indexOf('>') + 1);
|
||||
String optionClean = option.substring(option.indexOf('>') + 1);
|
||||
|
||||
if ("Take".equals(optionClean))
|
||||
{
|
||||
Color highlightColor = null;
|
||||
|
||||
if (calledEgg != null && calledEgg.startsWith(targetClean))
|
||||
{
|
||||
highlightColor = getEggColor(targetClean);
|
||||
}
|
||||
else if ("Yellow egg".equals(targetClean))
|
||||
{
|
||||
// Always show yellow egg
|
||||
highlightColor = Color.YELLOW;
|
||||
}
|
||||
|
||||
if (highlightColor != null)
|
||||
{
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry last = menuEntries[menuEntries.length - 1];
|
||||
last.setTarget(ColorUtil.prependColorTag(targetClean, highlightColor));
|
||||
client.setMenuEntries(menuEntries);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void setOverlayRound(Role role)
|
||||
{
|
||||
if (overlay.getCurrentRound() != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
overlay.setCurrentRound(new Round(role));
|
||||
}
|
||||
|
||||
private void announceSomething(final ChatMessageBuilder chatMessage)
|
||||
{
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(chatMessage.build())
|
||||
.build());
|
||||
}
|
||||
|
||||
String getCollectorHeardCall()
|
||||
{
|
||||
Widget widget = client.getWidget(WidgetInfo.BA_COLL_LISTEN_TEXT);
|
||||
String call = null;
|
||||
|
||||
if (widget != null)
|
||||
{
|
||||
call = widget.getText();
|
||||
}
|
||||
|
||||
return call;
|
||||
}
|
||||
|
||||
Map<WorldPoint, Integer> getCalledEggMap()
|
||||
{
|
||||
Map<WorldPoint, Integer> map;
|
||||
String calledEgg = getCollectorHeardCall();
|
||||
|
||||
if (calledEgg == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
switch (calledEgg)
|
||||
{
|
||||
case "Red eggs":
|
||||
map = redEggs;
|
||||
break;
|
||||
case "Green eggs":
|
||||
map = greenEggs;
|
||||
break;
|
||||
case "Blue eggs":
|
||||
map = blueEggs;
|
||||
break;
|
||||
default:
|
||||
map = null;
|
||||
}
|
||||
|
||||
return map;
|
||||
}
|
||||
|
||||
static Color getEggColor(String str)
|
||||
{
|
||||
Color color;
|
||||
|
||||
if (str == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (str.startsWith("Red"))
|
||||
{
|
||||
color = Color.RED;
|
||||
}
|
||||
else if (str.startsWith("Green"))
|
||||
{
|
||||
color = Color.GREEN;
|
||||
}
|
||||
else if (str.startsWith("Blue"))
|
||||
{
|
||||
color = Color.CYAN;
|
||||
}
|
||||
else if (str.startsWith("Yellow"))
|
||||
{
|
||||
color = Color.YELLOW;
|
||||
}
|
||||
else
|
||||
{
|
||||
color = null;
|
||||
}
|
||||
|
||||
return color;
|
||||
}
|
||||
|
||||
private HashMap<WorldPoint, Integer> getEggMap(int itemID)
|
||||
{
|
||||
switch (itemID)
|
||||
{
|
||||
case ItemID.RED_EGG:
|
||||
return redEggs;
|
||||
case ItemID.GREEN_EGG:
|
||||
return greenEggs;
|
||||
case ItemID.BLUE_EGG:
|
||||
return blueEggs;
|
||||
case ItemID.YELLOW_EGG:
|
||||
return yellowEggs;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void announceTime(String preText, String time)
|
||||
{
|
||||
final String chatMessage = new ChatMessageBuilder()
|
||||
.append(ChatColorType.NORMAL)
|
||||
.append(preText)
|
||||
.append(ChatColorType.HIGHLIGHT)
|
||||
.append(time)
|
||||
.build();
|
||||
|
||||
chatMessageManager.queue(QueuedMessage.builder()
|
||||
.type(ChatMessageType.CONSOLE)
|
||||
.runeLiteFormattedMessage(chatMessage)
|
||||
.build());
|
||||
}
|
||||
|
||||
private boolean isEgg(int itemID)
|
||||
{
|
||||
return itemID == ItemID.RED_EGG || itemID == ItemID.GREEN_EGG
|
||||
|| itemID == ItemID.BLUE_EGG || itemID == ItemID.YELLOW_EGG;
|
||||
}
|
||||
|
||||
private boolean isUnderPlayer(Tile tile)
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
if (local == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
return (tile.getWorldLocation().equals(local.getWorldLocation()));
|
||||
}
|
||||
|
||||
private void clearAllEggMaps()
|
||||
{
|
||||
redEggs.clear();
|
||||
greenEggs.clear();
|
||||
blueEggs.clear();
|
||||
yellowEggs.clear();
|
||||
}
|
||||
|
||||
public Font getFont()
|
||||
{
|
||||
return font;
|
||||
}
|
||||
|
||||
Image getClockImage()
|
||||
{
|
||||
return clockImage;
|
||||
}
|
||||
|
||||
int getListenItemId(WidgetInfo listenInfo)
|
||||
{
|
||||
Widget listenWidget = client.getWidget(listenInfo);
|
||||
|
||||
if (listenWidget != null)
|
||||
{
|
||||
switch (listenWidget.getText())
|
||||
{
|
||||
case "Tofu":
|
||||
return ItemID.TOFU;
|
||||
case "Crackers":
|
||||
return ItemID.CRACKERS;
|
||||
case "Worms":
|
||||
return ItemID.WORMS;
|
||||
case "Pois. Worms":
|
||||
return ItemID.POISONED_WORMS;
|
||||
case "Pois. Tofu":
|
||||
return ItemID.POISONED_TOFU;
|
||||
case "Pois. Meat":
|
||||
return ItemID.POISONED_MEAT;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
@@ -1,164 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("BATools")
|
||||
public interface BAToolsConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "defTimer",
|
||||
name = "Defender Tick Timer",
|
||||
description = "Shows the current cycle tick of runners."
|
||||
)
|
||||
default boolean defTimer()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "calls",
|
||||
name = "Remove Incorrect Calls",
|
||||
description = "Remove incorrect calls."
|
||||
)
|
||||
default boolean calls()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "swapLadder",
|
||||
name = "Swap ladder option",
|
||||
description = "Swap Climb-down with Quick-start in the wave lobbies"
|
||||
)
|
||||
default boolean swapLadder()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerCodes",
|
||||
name = "Healer Codes",
|
||||
description = "Overlay to show healer codes"
|
||||
)
|
||||
default boolean healerCodes()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "healerMenuOption",
|
||||
name = "Healer menu options",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean healerMenuOption()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "eggBoi",
|
||||
name = "Collector helper",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean eggBoi()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "osHelp",
|
||||
name = "Shift OS",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean osHelp()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "prayerMetronome",
|
||||
name = "Prayer Metronome",
|
||||
description = "asd"
|
||||
)
|
||||
default boolean prayerMetronome()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "prayerMetronomeVolume",
|
||||
name = "Prayer Metronome Volume",
|
||||
description = "asd"
|
||||
)
|
||||
default int prayerMetronomeVolume()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "attackStyles",
|
||||
name = "Attack Styles",
|
||||
description = "Hide attack styles depending on weapon."
|
||||
)
|
||||
default boolean attackStyles()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeBA",
|
||||
name = "*Barbarian Assault Helper*",
|
||||
description = "Remove unnecessary menu options in Barbarian Assault depending on role<br>Examples: Remove attack options when not attacker<br>Remove take options when not collector"
|
||||
)
|
||||
default boolean removeBA()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeWrongEggs",
|
||||
name = "Remove wrong eggs - *Barbarian Assault Helper*",
|
||||
description = "Remove unnecessary menu options in Barbarian Assault depending on role<br>Examples: Remove attack options when not attacker<br>Remove take options when not collector"
|
||||
)
|
||||
default boolean removeWrongEggs()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "removeWrongHealFood",
|
||||
name = "Remove wrong Heal Food - *Barbarian Assault Helper*",
|
||||
description = "Remove unnecessary menu options in Barbarian Assault depending on role<br>Examples: Remove attack options when not attacker<br>Remove take options when not collector"
|
||||
)
|
||||
default boolean removeHealWrongFood()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,806 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import com.google.inject.Provides;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import api.Actor;
|
||||
import api.ChatMessageType;
|
||||
import api.Client;
|
||||
import api.ItemID;
|
||||
import api.MenuEntry;
|
||||
import api.NPC;
|
||||
import api.NpcID;
|
||||
import api.Prayer;
|
||||
import api.SoundEffectID;
|
||||
import api.Varbits;
|
||||
import api.coords.WorldPoint;
|
||||
import api.events.ChatMessage;
|
||||
import api.events.ConfigChanged;
|
||||
import api.events.GameTick;
|
||||
import api.events.HitsplatApplied;
|
||||
import api.events.InteractingChanged;
|
||||
import api.events.MenuEntryAdded;
|
||||
import api.events.MenuOptionClicked;
|
||||
import api.events.NpcDespawned;
|
||||
import api.events.NpcSpawned;
|
||||
import api.events.VarbitChanged;
|
||||
import api.events.WidgetLoaded;
|
||||
import api.widgets.Widget;
|
||||
import static api.widgets.WidgetID.BA_REWARD_GROUP_ID;
|
||||
import api.widgets.WidgetInfo;
|
||||
import static api.widgets.WidgetInfo.BA_ATK_CALL_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_ATK_LISTEN_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_ATK_ROLE_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_COLL_CALL_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_COLL_LISTEN_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_COLL_ROLE_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_DEF_CALL_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_DEF_ROLE_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_HEAL_CALL_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_HEAL_LISTEN_TEXT;
|
||||
import static api.widgets.WidgetInfo.BA_REWARD_TEXT;
|
||||
import static api.widgets.WidgetInfo.COMBAT_STYLE_FOUR;
|
||||
import static api.widgets.WidgetInfo.COMBAT_STYLE_ONE;
|
||||
import static api.widgets.WidgetInfo.COMBAT_STYLE_THREE;
|
||||
import static api.widgets.WidgetInfo.COMBAT_STYLE_TWO;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.ui.overlay.infobox.InfoBoxManager;
|
||||
import static net.runelite.client.util.MenuUtil.swap;
|
||||
import net.runelite.client.util.Text;
|
||||
import org.apache.commons.lang3.ArrayUtils;
|
||||
|
||||
@Slf4j
|
||||
@PluginDescriptor(
|
||||
name = "BA Tools",
|
||||
description = "Custom tools for Barbarian Assault",
|
||||
tags = {"minigame", "overlay", "timer"},
|
||||
type = PluginType.PVM
|
||||
)
|
||||
public class BAToolsPlugin extends Plugin implements KeyListener
|
||||
{
|
||||
private boolean inGame;
|
||||
private int tickNum;
|
||||
private int pastCall = 0;
|
||||
private int currentWave = 1;
|
||||
private static final int BA_WAVE_NUM_INDEX = 2;
|
||||
private static final WorldPoint healerSpawnPoint = new WorldPoint(1898, 1586, 0);
|
||||
private final List<MenuEntry> entries = new ArrayList<>();
|
||||
private ImmutableMap<WidgetInfo, Boolean> originalAttackStyles;
|
||||
private HashMap<Integer, Instant> foodPressed = new HashMap<>();
|
||||
private CycleCounter counter;
|
||||
private Actor lastInteracted;
|
||||
|
||||
private boolean shiftDown;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private BAToolsConfig config;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Inject
|
||||
private InfoBoxManager infoBoxManager;
|
||||
|
||||
@Inject
|
||||
private BAToolsOverlay overlay;
|
||||
|
||||
@Getter
|
||||
private Map<NPC, Healer> healers;
|
||||
|
||||
@Getter
|
||||
private Instant wave_start;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
|
||||
@Provides
|
||||
BAToolsConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(BAToolsConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
healers = new HashMap<>();
|
||||
wave_start = Instant.now();
|
||||
lastInteracted = null;
|
||||
foodPressed.clear();
|
||||
keyManager.registerKeyListener(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
removeCounter();
|
||||
healers.clear();
|
||||
inGame = false;
|
||||
lastInteracted = null;
|
||||
overlayManager.remove(overlay);
|
||||
keyManager.unregisterKeyListener(this);
|
||||
shiftDown = false;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onWidgetLoaded(WidgetLoaded event)
|
||||
{
|
||||
if (event.getGroupId() == BA_REWARD_GROUP_ID)
|
||||
{
|
||||
Widget rewardWidget = client.getWidget(BA_REWARD_TEXT);
|
||||
if (rewardWidget != null && rewardWidget.getText().contains("<br>5"))
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
Widget callWidget = getWidget();
|
||||
|
||||
if (callWidget != null)
|
||||
{
|
||||
if (callWidget.getTextColor() != pastCall && callWidget.getTextColor() == 16316664)
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
pastCall = callWidget.getTextColor();
|
||||
}
|
||||
if (inGame && config.defTimer())
|
||||
{
|
||||
if (tickNum > 9)
|
||||
{
|
||||
tickNum = 0;
|
||||
}
|
||||
|
||||
if (counter == null)
|
||||
{
|
||||
addCounter();
|
||||
}
|
||||
counter.setCount(tickNum);
|
||||
|
||||
tickNum++;
|
||||
}
|
||||
|
||||
Widget weapon = client.getWidget(593, 1);
|
||||
|
||||
if (config.attackStyles()
|
||||
&& weapon != null
|
||||
&& inGame
|
||||
&& weapon.getText().contains("Crystal halberd") || weapon.getText().contains("Dragon claws")
|
||||
&& client.getWidget(BA_ATK_LISTEN_TEXT) != null)
|
||||
{
|
||||
if (originalAttackStyles == null)
|
||||
{
|
||||
ImmutableMap.Builder<WidgetInfo, Boolean> builder = new ImmutableMap.Builder<>();
|
||||
|
||||
builder.put(COMBAT_STYLE_ONE, client.getWidget(COMBAT_STYLE_ONE).isHidden());
|
||||
builder.put(COMBAT_STYLE_TWO, client.getWidget(COMBAT_STYLE_TWO).isHidden());
|
||||
builder.put(COMBAT_STYLE_THREE, client.getWidget(COMBAT_STYLE_THREE).isHidden());
|
||||
builder.put(COMBAT_STYLE_FOUR, client.getWidget(COMBAT_STYLE_FOUR).isHidden());
|
||||
|
||||
originalAttackStyles = builder.build();
|
||||
}
|
||||
|
||||
String style = client.getWidget(BA_ATK_LISTEN_TEXT).getText();
|
||||
|
||||
if (style.contains("Defensive"))
|
||||
{
|
||||
client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_FOUR).setHidden(false);
|
||||
}
|
||||
else if (style.contains("Aggressive"))
|
||||
{
|
||||
client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_TWO).setHidden(false);
|
||||
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
|
||||
}
|
||||
else if (style.contains("Controlled"))
|
||||
{
|
||||
if (weapon.getText().contains("Crystal halberd"))
|
||||
{
|
||||
client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
|
||||
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.getWidget(COMBAT_STYLE_ONE).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_THREE).setHidden(false);
|
||||
}
|
||||
client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
|
||||
}
|
||||
else if (style.contains("Accurate") && weapon.getText().contains("Dragon claws"))
|
||||
{
|
||||
client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
|
||||
client.getWidget(COMBAT_STYLE_TWO).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_THREE).setHidden(true);
|
||||
client.getWidget(COMBAT_STYLE_FOUR).setHidden(true);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.getWidget(COMBAT_STYLE_ONE).setHidden(false);
|
||||
client.getWidget(COMBAT_STYLE_TWO).setHidden(false);
|
||||
client.getWidget(COMBAT_STYLE_THREE).setHidden(false);
|
||||
client.getWidget(COMBAT_STYLE_FOUR).setHidden(false);
|
||||
}
|
||||
|
||||
}
|
||||
else if (originalAttackStyles != null)
|
||||
{
|
||||
originalAttackStyles.forEach((w, b) -> client.getWidget(w).setHidden(b));
|
||||
}
|
||||
|
||||
if (config.prayerMetronome() && isAnyPrayerActive())
|
||||
{
|
||||
for (int i = 0; i < config.prayerMetronomeVolume(); i++)
|
||||
{
|
||||
client.playSoundEffect(SoundEffectID.GE_INCREMENT_PLOP);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private Widget getWidget()
|
||||
{
|
||||
if (client.getWidget(BA_DEF_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(BA_DEF_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(BA_ATK_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(BA_ATK_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(BA_COLL_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(BA_COLL_CALL_TEXT);
|
||||
}
|
||||
else if (client.getWidget(BA_HEAL_CALL_TEXT) != null)
|
||||
{
|
||||
return client.getWidget(BA_HEAL_CALL_TEXT);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
int inGameBit = client.getVar(Varbits.IN_GAME_BA);
|
||||
|
||||
if (inGameBit == 1 && !inGame ||
|
||||
inGameBit == 0 && inGame)
|
||||
{
|
||||
inGame = inGameBit == 1;
|
||||
|
||||
if (!inGame)
|
||||
{
|
||||
pastCall = 0;
|
||||
removeCounter();
|
||||
foodPressed.clear();
|
||||
}
|
||||
else
|
||||
{
|
||||
addCounter();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage event)
|
||||
{
|
||||
if (event.getType() == ChatMessageType.GAMEMESSAGE
|
||||
&& event.getMessage().startsWith("---- Wave:"))
|
||||
{
|
||||
String[] message = event.getMessage().split(" ");
|
||||
currentWave = Integer.parseInt(message[BA_WAVE_NUM_INDEX]);
|
||||
wave_start = Instant.now();
|
||||
healers.clear();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
NPC npc = event.getNpc();
|
||||
|
||||
if (inGame && isNpcHealer(npc.getId()))
|
||||
{
|
||||
if (checkNewSpawn(npc) || Duration.between(wave_start, Instant.now()).getSeconds() < 16)
|
||||
{
|
||||
int spawnNumber = healers.size();
|
||||
healers.put(npc, new Healer(npc, spawnNumber, currentWave));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onHitsplatApplied(HitsplatApplied hitsplatApplied)
|
||||
{
|
||||
Actor actor = hitsplatApplied.getActor();
|
||||
|
||||
if (healers.isEmpty() && !(actor instanceof NPC) && lastInteracted == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
for (Healer healer : healers.values())
|
||||
{
|
||||
if (healer.getNpc() == actor && actor == lastInteracted)
|
||||
{
|
||||
healer.setFoodRemaining(healer.getFoodRemaining() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned event)
|
||||
{
|
||||
healers.remove(event.getNpc());
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onInteractingChanged(InteractingChanged event)
|
||||
{
|
||||
Actor opponent = event.getTarget();
|
||||
|
||||
if (opponent instanceof NPC && isNpcHealer(((NPC) opponent).getId()) && event.getSource() != client.getLocalPlayer())
|
||||
{
|
||||
lastInteracted = opponent;
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isNpcHealer(int npcId)
|
||||
{
|
||||
return npcId == NpcID.PENANCE_HEALER ||
|
||||
npcId == NpcID.PENANCE_HEALER_5766 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5767 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5768 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5769 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5770 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5771 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5772 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5773 ||
|
||||
npcId == NpcID.PENANCE_HEALER_5774;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
if (config.calls() && getWidget() != null && event.getTarget().endsWith("horn") && !event.getTarget().contains("Unicorn"))
|
||||
{
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
Widget callWidget = getWidget();
|
||||
String call = Calls.getOption(callWidget.getText());
|
||||
MenuEntry correctCall = null;
|
||||
|
||||
entries.clear();
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
String option = entry.getOption();
|
||||
if (option.equals(call))
|
||||
{
|
||||
correctCall = entry;
|
||||
}
|
||||
else if (!option.startsWith("Tell-"))
|
||||
{
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
|
||||
if (correctCall != null) //&& callWidget.getTextColor()==16316664)
|
||||
{
|
||||
entries.add(correctCall);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[0]));
|
||||
}
|
||||
}
|
||||
|
||||
final int itemId = event.getIdentifier();
|
||||
String option = Text.removeTags(event.getOption()).toLowerCase();
|
||||
String target = Text.removeTags(event.getTarget()).toLowerCase();
|
||||
|
||||
|
||||
if (config.swapLadder() && option.equals("climb-down") && target.equals("ladder"))
|
||||
{
|
||||
swap(client, "quick-start", option, target);
|
||||
}
|
||||
else if (config.removeBA() && client.getVar(Varbits.IN_GAME_BA) == 1 && !option.contains("tell-"))//if in barbarian assault and menu isnt from a horn
|
||||
{
|
||||
if (itemId == ItemID.LOGS && !target.contains("healing vial"))
|
||||
{
|
||||
if (client.getWidget(BA_DEF_ROLE_TEXT) == null)
|
||||
{
|
||||
remove(new String[]{"take", "light"}, target);
|
||||
}
|
||||
else //remove "Light" option (and "Take" option if not defender).
|
||||
{
|
||||
remove("light", target);
|
||||
}
|
||||
}
|
||||
else if (option.equals("use"))
|
||||
{
|
||||
if (config.removeHealWrongFood())
|
||||
{
|
||||
Widget healer = client.getWidget(BA_HEAL_LISTEN_TEXT);
|
||||
if (healer != null)
|
||||
{
|
||||
String item = target.split("-")[0].trim();
|
||||
List<String> poison = Arrays.asList("poisoned tofu", "poisoned meat", "poisoned worms");
|
||||
List<String> vials = Arrays.asList("healing vial", "healing vial(1)", "healing vial(2)", "healing vial(3)", "healing vial(4)");//"healing vial(4)"
|
||||
if (poison.contains(item))
|
||||
{
|
||||
//if item is a poison item
|
||||
int calledPoison = 0;
|
||||
switch (healer.getText())//choose which poison to hide the use/destroy option for
|
||||
{
|
||||
case "Pois. Tofu":
|
||||
calledPoison = ItemID.POISONED_TOFU;
|
||||
break;
|
||||
case "Pois. Meat":
|
||||
calledPoison = ItemID.POISONED_MEAT;
|
||||
break;
|
||||
case "Pois. Worms":
|
||||
calledPoison = ItemID.POISONED_WORMS;
|
||||
break;
|
||||
}
|
||||
if (target.equals(item))//if targeting the item itself
|
||||
{
|
||||
if (calledPoison != 0 && itemId != calledPoison)//if no call or chosen item is not the called one
|
||||
{
|
||||
remove(new String[]{"use", "destroy", "examine"}, target);//remove options
|
||||
}
|
||||
}
|
||||
else if (!target.contains("penance healer"))
|
||||
{
|
||||
remove(option, target);
|
||||
}
|
||||
}
|
||||
else if (vials.contains(item))//if item is the healer's healing vial
|
||||
{
|
||||
|
||||
if (!target.equals(item))//if target is not the vial itself
|
||||
{
|
||||
|
||||
if (!target.contains("level") || target.contains("penance") || target.contains("queen spawn"))//if someone has "penance" or "queen spawn" in their name, gg...
|
||||
{
|
||||
remove(option, target);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (option.equals("attack") && client.getWidget(BA_ATK_ROLE_TEXT) == null && !target.equals("queen spawn"))//if not attacker
|
||||
{
|
||||
//remove attack option from everything but queen spawns
|
||||
remove(option, target);
|
||||
}
|
||||
else if ((option.equals("fix") || (option.equals("block") && target.equals("penance cave"))) && client.getWidget(BA_DEF_ROLE_TEXT) == null)//if not defender
|
||||
{
|
||||
//the check for option requires checking target as well because defensive attack style option is also called "block".
|
||||
remove(option, target);
|
||||
}
|
||||
else if ((option.equals("load")) && client.getWidget(BA_COLL_ROLE_TEXT) == null)//if not collector, remove hopper options
|
||||
{
|
||||
remove(new String[]{option, "look-in"}, target);
|
||||
}
|
||||
else if (config.removeWrongEggs() && option.equals("take"))
|
||||
{
|
||||
Widget eggToColl = client.getWidget(BA_COLL_LISTEN_TEXT);
|
||||
if (eggToColl != null)//if we're a collector
|
||||
{
|
||||
List<Integer> eggsToHide = new ArrayList<>();
|
||||
eggsToHide.add(ItemID.HAMMER);
|
||||
switch (eggToColl.getText())//choose which eggs to hide take option for
|
||||
{
|
||||
case "Red eggs":
|
||||
eggsToHide.add(ItemID.BLUE_EGG);
|
||||
eggsToHide.add(ItemID.GREEN_EGG);
|
||||
break;
|
||||
case "Blue eggs":
|
||||
eggsToHide.add(ItemID.RED_EGG);
|
||||
eggsToHide.add(ItemID.GREEN_EGG);
|
||||
break;
|
||||
case "Green eggs":
|
||||
eggsToHide.add(ItemID.RED_EGG);
|
||||
eggsToHide.add(ItemID.BLUE_EGG);
|
||||
break;
|
||||
}
|
||||
if (eggsToHide.contains(itemId))
|
||||
{
|
||||
remove(option, target);//hide wrong eggs
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
List<Integer> defenderItems = Arrays.asList(ItemID.HAMMER, ItemID.TOFU, ItemID.CRACKERS, ItemID.WORMS);//logs are handled separately due to hiding "light" option too.
|
||||
if (client.getWidget(BA_DEF_ROLE_TEXT) == null || !defenderItems.contains(itemId))//if not defender, or item is not a defenderItem
|
||||
{
|
||||
remove(option, target);//hide everything except hammer/logs and bait if Defender
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (inGame && config.healerMenuOption() && event.getTarget().contains("Penance Healer"))
|
||||
{
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry lastEntry = menuEntries[menuEntries.length - 1];
|
||||
String targett = lastEntry.getTarget();
|
||||
|
||||
if (foodPressed.containsKey(lastEntry.getIdentifier()))
|
||||
{
|
||||
lastEntry.setTarget(lastEntry.getTarget().split("\\(")[0] + "(" + Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() + ")");
|
||||
if (Duration.between(foodPressed.get(lastEntry.getIdentifier()), Instant.now()).getSeconds() > 20)
|
||||
{
|
||||
lastEntry.setTarget(lastEntry.getTarget().replace("<col=ffff00>", "<col=2bff63>"));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lastEntry.setTarget(targett.replace("<col=ffff00>", "<col=2bff63>"));
|
||||
|
||||
}
|
||||
|
||||
client.setMenuEntries(menuEntries);
|
||||
}
|
||||
|
||||
if (client.getWidget(BA_COLL_LISTEN_TEXT) != null && inGame && config.eggBoi() && event.getTarget().endsWith("egg") && shiftDown)
|
||||
{
|
||||
String[] currentCall = client.getWidget(BA_COLL_LISTEN_TEXT).getText().split(" ");
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry correctEgg = null;
|
||||
entries.clear();
|
||||
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
if (entry.getTarget().contains(currentCall[0]) && entry.getOption().equals("Take"))
|
||||
{
|
||||
correctEgg = entry;
|
||||
}
|
||||
else if (!entry.getOption().startsWith("Take"))
|
||||
{
|
||||
entries.add(entry);
|
||||
}
|
||||
}
|
||||
if (correctEgg != null)
|
||||
{
|
||||
entries.add(correctEgg);
|
||||
}
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[0]));
|
||||
}
|
||||
|
||||
if (client.getWidget(BA_HEAL_LISTEN_TEXT) != null && inGame && config.osHelp() && event.getTarget().equals("<col=ffff>Healer item machine") && shiftDown)
|
||||
{
|
||||
String[] currentCall = client.getWidget(BA_HEAL_LISTEN_TEXT).getText().split(" ");
|
||||
|
||||
if (!currentCall[0].contains("Pois."))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
MenuEntry[] menuEntries = client.getMenuEntries();
|
||||
MenuEntry correctEgg = null;
|
||||
entries.clear();
|
||||
|
||||
for (MenuEntry entry : menuEntries)
|
||||
{
|
||||
if (entry.getOption().equals("Take-" + currentCall[1]))
|
||||
{
|
||||
correctEgg = entry;
|
||||
}
|
||||
}
|
||||
if (correctEgg != null)
|
||||
{
|
||||
entries.add(correctEgg);
|
||||
client.setMenuEntries(entries.toArray(new MenuEntry[0]));
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOptionClicked(MenuOptionClicked event)
|
||||
{
|
||||
if (!config.healerMenuOption() || !event.getMenuTarget().contains("Penance Healer") || client.getWidget(BA_HEAL_CALL_TEXT) == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
String currentCall = client.getWidget(BA_HEAL_CALL_TEXT).getText();
|
||||
String target = event.getMenuTarget();
|
||||
|
||||
if ((currentCall.equals("Pois. Worms") && (target.contains("Poisoned worms") && target.contains("->") && target.contains("Penance Healer")))
|
||||
|| (currentCall.equals("Pois. Meat") && (target.contains("Poisoned meat") && target.contains("->") && target.contains("Penance Healer")))
|
||||
|| (currentCall.equals("Pois. Tofu") && (target.contains("Poisoned tofu") && target.contains("->") && target.contains("Penance Healer"))))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
}
|
||||
|
||||
if (target.contains("->") && target.contains("Penance Healer"))
|
||||
{
|
||||
foodPressed.put(event.getId(), Instant.now());
|
||||
}
|
||||
}
|
||||
|
||||
public void onConfigChanged(ConfigChanged event)
|
||||
{
|
||||
if (counter != null && !config.defTimer())
|
||||
{
|
||||
removeCounter();
|
||||
}
|
||||
}
|
||||
|
||||
private void addCounter()
|
||||
{
|
||||
if (!config.defTimer() || counter != null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
int itemSpriteId = ItemID.FIGHTER_TORSO;
|
||||
|
||||
BufferedImage taskImg = itemManager.getImage(itemSpriteId);
|
||||
counter = new CycleCounter(taskImg, this, tickNum);
|
||||
|
||||
infoBoxManager.addInfoBox(counter);
|
||||
}
|
||||
|
||||
private void removeCounter()
|
||||
{
|
||||
if (counter == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
infoBoxManager.removeInfoBox(counter);
|
||||
counter = null;
|
||||
}
|
||||
|
||||
private void remove(String option, String target)
|
||||
{
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
int idx = searchIndex(entries, option, target);
|
||||
if (idx >= 0 && entries[idx] != null)
|
||||
{
|
||||
entries = ArrayUtils.removeElement(entries, entries[idx]);
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
}
|
||||
|
||||
private void remove(String[] options, String target)
|
||||
{
|
||||
MenuEntry[] entries = client.getMenuEntries();
|
||||
for (String option : options)
|
||||
{
|
||||
int idx = searchIndex(entries, option, target);
|
||||
if (idx >= 0 && entries[idx] != null)
|
||||
{
|
||||
entries = ArrayUtils.removeElement(entries, entries[idx]);
|
||||
}
|
||||
}
|
||||
|
||||
client.setMenuEntries(entries);
|
||||
}
|
||||
|
||||
private int searchIndex(MenuEntry[] entries, String option, String target)
|
||||
{
|
||||
for (int i = entries.length - 1; i >= 0; i--)
|
||||
{
|
||||
MenuEntry entry = entries[i];
|
||||
String entryOption = Text.removeTags(entry.getOption()).toLowerCase();
|
||||
String entryTarget = Text.removeTags(entry.getTarget()).toLowerCase();
|
||||
|
||||
if (entryOption.equals(option) && entryTarget.equals(target))
|
||||
{
|
||||
return i;
|
||||
}
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
private boolean checkNewSpawn(NPC npc)
|
||||
{
|
||||
for (WorldPoint p : WorldPoint.toLocalInstance(client, healerSpawnPoint))
|
||||
{
|
||||
if (p.distanceTo(npc.getWorldLocation()) < 5)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftDown = true;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (e.getKeyCode() == KeyEvent.VK_SHIFT)
|
||||
{
|
||||
shiftDown = false;
|
||||
}
|
||||
}
|
||||
|
||||
private boolean isAnyPrayerActive()
|
||||
{
|
||||
for (Prayer pray : Prayer.values())//Check if any prayers are active
|
||||
{
|
||||
if (client.isPrayerActive(pray))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,102 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import api.NPC;
|
||||
|
||||
|
||||
class Healer
|
||||
{
|
||||
|
||||
@Getter
|
||||
private NPC npc;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int wave;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int spawnNumber;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int foodRemaining;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int lastFoodTime;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int firstCallFood;
|
||||
|
||||
@Getter
|
||||
@Setter
|
||||
private int secondCallFood;
|
||||
|
||||
Healer(NPC npc, int spawnNumber, int wave)
|
||||
{
|
||||
this.npc = npc;
|
||||
this.wave = wave;
|
||||
this.spawnNumber = spawnNumber;
|
||||
this.firstCallFood = getCode(wave).getFirstCallFood()[spawnNumber];
|
||||
this.secondCallFood = getCode(wave).getSecondCallFood()[spawnNumber];
|
||||
this.foodRemaining = firstCallFood + secondCallFood;
|
||||
this.lastFoodTime = getCode(wave).getSpacing()[spawnNumber];
|
||||
}
|
||||
|
||||
private HealerCode getCode(int wave)
|
||||
{
|
||||
switch (wave)
|
||||
{
|
||||
case 1:
|
||||
return HealerCode.WAVEONE;
|
||||
case 2:
|
||||
return HealerCode.WAVETWO;
|
||||
case 3:
|
||||
return HealerCode.WAVETHREE;
|
||||
case 4:
|
||||
return HealerCode.WAVEFOUR;
|
||||
case 5:
|
||||
return HealerCode.WAVEFIVE;
|
||||
case 6:
|
||||
return HealerCode.WAVESIX;
|
||||
case 7:
|
||||
return HealerCode.WAVESEVEN;
|
||||
case 8:
|
||||
return HealerCode.WAVEEIGHT;
|
||||
case 9:
|
||||
return HealerCode.WAVENINE;
|
||||
case 10:
|
||||
return HealerCode.WAVETEN;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.batools;
|
||||
|
||||
import lombok.Getter;
|
||||
|
||||
|
||||
enum HealerCode
|
||||
{
|
||||
|
||||
WAVEONE(new int[]{1, 1}, new int[]{0, 0}, new int[]{0, 0}),
|
||||
WAVETWO(new int[]{1, 1, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 21}),
|
||||
WAVETHREE(new int[]{1, 6, 2}, new int[]{0, 0, 0}, new int[]{0, 0, 0}),
|
||||
WAVEFOUR(new int[]{2, 5, 2, 0}, new int[]{0, 0, 7, 10}, new int[]{0, 0, 0, 0}),
|
||||
WAVEFIVE(new int[]{2, 5, 2, 3, 0}, new int[]{0, 0, 0, 0, 7}, new int[]{0, 0, 21, 30, 0}),
|
||||
WAVESIX(new int[]{3, 5, 2, 2, 0, 0}, new int[]{0, 0, 0, 2, 9, 10}, new int[]{12, 18, 21, 0, 0, 0}),
|
||||
WAVESEVEN(new int[]{3, 7, 1, 1, 0, 0, 0}, new int[]{2, 0, 1, 1, 2, 4, 10}, new int[]{0, 21, 0, 0, 30, 45, 0}),
|
||||
WAVEEIGHT(new int[]{1, 9, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 2, 10}, new int[]{0, 0, 0, 0, 33, 42, 0}),
|
||||
WAVENINE(new int[]{2, 8, 1, 1, 0, 0, 0, 0}, new int[]{1, 0, 1, 1, 2, 1, 1, 10}, new int[]{0, 21, 0, 0, 0, 0, 0, 0, 0}),
|
||||
WAVETEN(new int[]{2, 5, 1, 1, 0, 0, 0}, new int[]{1, 0, 1, 1, 4, 4, 8}, new int[]{21, 33, 0, 33, 30, 45, 0});
|
||||
|
||||
|
||||
@Getter
|
||||
private final int[] firstCallFood;
|
||||
@Getter
|
||||
private final int[] secondCallFood;
|
||||
@Getter
|
||||
private final int[] spacing;
|
||||
|
||||
HealerCode(int[] firstCallFood, int[] secondCallFood, int[] spacing)
|
||||
{
|
||||
this.firstCallFood = firstCallFood;
|
||||
this.secondCallFood = secondCallFood;
|
||||
this.spacing = spacing;
|
||||
}
|
||||
}
|
||||
@@ -1,165 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.blackjack;
|
||||
|
||||
import com.google.inject.Binder;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import api.ChatMessageType;
|
||||
import api.Client;
|
||||
import static api.Varbits.QUEST_THE_FEUD;
|
||||
import api.events.ChatMessage;
|
||||
import api.events.GameTick;
|
||||
import api.events.MenuEntryAdded;
|
||||
import api.events.VarbitChanged;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.menus.MenuManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import static net.runelite.client.util.MenuUtil.swap;
|
||||
|
||||
/**
|
||||
* Authors gazivodag longstreet
|
||||
*/
|
||||
@PluginDescriptor(
|
||||
name = "Blackjack",
|
||||
description = "Uses chat messages and tick timers instead of animations to read",
|
||||
tags = {"blackjack", "thieving"},
|
||||
type = PluginType.SKILLING
|
||||
)
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class BlackjackPlugin extends Plugin
|
||||
{
|
||||
private static final String PICKPOCKET = "Pickpocket";
|
||||
private static final String KNOCK_OUT = "Knock-out";
|
||||
private static final String LURE = "Lure";
|
||||
private static final String BANDIT = "Bandit";
|
||||
private static final String MENAPHITE = "Menaphite Thug";
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private MenuManager menuManager;
|
||||
|
||||
private int lastKnockout;
|
||||
private boolean pickpocketing;
|
||||
private boolean ableToBlackJack;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
menuManager.addPriorityEntry(LURE, BANDIT);
|
||||
menuManager.addPriorityEntry(LURE, MENAPHITE);
|
||||
|
||||
menuManager.addPriorityEntry(KNOCK_OUT, BANDIT);
|
||||
menuManager.addPriorityEntry(KNOCK_OUT, MENAPHITE);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
menuManager.removePriorityEntry(LURE, BANDIT);
|
||||
menuManager.removePriorityEntry(LURE, MENAPHITE);
|
||||
|
||||
menuManager.removePriorityEntry(PICKPOCKET, BANDIT);
|
||||
menuManager.removePriorityEntry(PICKPOCKET, MENAPHITE);
|
||||
|
||||
menuManager.removePriorityEntry(KNOCK_OUT, BANDIT);
|
||||
menuManager.removePriorityEntry(KNOCK_OUT, MENAPHITE);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick gameTick)
|
||||
{
|
||||
if (ableToBlackJack && pickpocketing && client.getTickCount() >= lastKnockout + 4)
|
||||
{
|
||||
pickpocketing = false;
|
||||
|
||||
menuManager.removePriorityEntry(PICKPOCKET, BANDIT);
|
||||
menuManager.removePriorityEntry(PICKPOCKET, MENAPHITE);
|
||||
|
||||
menuManager.addPriorityEntry(KNOCK_OUT, BANDIT);
|
||||
menuManager.addPriorityEntry(KNOCK_OUT, MENAPHITE);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuEntryAdded(MenuEntryAdded event)
|
||||
{
|
||||
// Lure has higher priority than knock-out
|
||||
if (event.getTarget().contains(MENAPHITE) || event.getTarget().contains(BANDIT)
|
||||
&& event.getOption().equals(LURE))
|
||||
{
|
||||
swap(client, KNOCK_OUT, LURE, event.getTarget(), false);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
if (chatMessage.getType() == ChatMessageType.SPAM)
|
||||
{
|
||||
if (chatMessage.getMessage().equals("You smack the bandit over the head and render them unconscious.")
|
||||
|| chatMessage.getMessage().equals("Your blow only glances off the bandit's head."))
|
||||
{
|
||||
menuManager.removePriorityEntry(KNOCK_OUT, BANDIT);
|
||||
menuManager.removePriorityEntry(KNOCK_OUT, MENAPHITE);
|
||||
|
||||
menuManager.addPriorityEntry(PICKPOCKET, BANDIT);
|
||||
menuManager.addPriorityEntry(PICKPOCKET, MENAPHITE);
|
||||
|
||||
lastKnockout = client.getTickCount();
|
||||
pickpocketing = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
ableToBlackJack = client.getVar(QUEST_THE_FEUD) >= 13;
|
||||
|
||||
if (!ableToBlackJack)
|
||||
{
|
||||
menuManager.removePriorityEntry(LURE, BANDIT);
|
||||
menuManager.removePriorityEntry(LURE, MENAPHITE);
|
||||
|
||||
menuManager.removePriorityEntry(KNOCK_OUT, BANDIT);
|
||||
menuManager.removePriorityEntry(KNOCK_OUT, MENAPHITE);
|
||||
|
||||
menuManager.removePriorityEntry(PICKPOCKET, BANDIT);
|
||||
menuManager.removePriorityEntry(PICKPOCKET, MENAPHITE);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,101 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Lucas C <lucas1757@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.cooking;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import static api.AnimationID.COOKING_WINE;
|
||||
import api.Client;
|
||||
import static api.MenuAction.RUNELITE_OVERLAY_CONFIG;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import static net.runelite.client.ui.overlay.OverlayManager.OPTION_CONFIGURE;
|
||||
import net.runelite.client.ui.overlay.OverlayMenuEntry;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
@Slf4j
|
||||
class FermentTimerOverlay extends Overlay
|
||||
{
|
||||
private static final int INITIAL_TIME = 12;
|
||||
|
||||
private final Client client;
|
||||
private final CookingPlugin plugin;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
private FermentTimerOverlay(final Client client, final CookingPlugin plugin)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
getMenuEntries().add(new OverlayMenuEntry(RUNELITE_OVERLAY_CONFIG, OPTION_CONFIGURE, "Fermenting Timer overlay"));
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
FermentTimerSession session = plugin.getFermentTimerSession();
|
||||
if (session == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (isMakingWine() || Duration.between(session.getLastWineMakingAction(), Instant.now()).getSeconds() < INITIAL_TIME)
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Making Wine")
|
||||
.color(Color.GREEN)
|
||||
.build());
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Ferments in: ")
|
||||
.right(String.valueOf(INITIAL_TIME - Duration.between(session.getLastWineMakingAction(), Instant.now()).getSeconds()))
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Wine Fermented")
|
||||
.color(Color.ORANGE)
|
||||
.build());
|
||||
}
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
|
||||
private boolean isMakingWine()
|
||||
{
|
||||
return (client.getLocalPlayer().getAnimation() == COOKING_WINE);
|
||||
}
|
||||
}
|
||||
@@ -1,333 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, xzact <https://github.com/xzact>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.coxhelper;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.NPC;
|
||||
import api.NPCDefinition;
|
||||
import api.Perspective;
|
||||
import api.Point;
|
||||
import api.coords.LocalPoint;
|
||||
import api.coords.WorldArea;
|
||||
import api.coords.WorldPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class CoxOverlay extends Overlay
|
||||
{
|
||||
private final Client client;
|
||||
|
||||
|
||||
private final CoxPlugin plugin;
|
||||
private final CoxConfig config;
|
||||
|
||||
@Inject
|
||||
private CoxOverlay(Client client, CoxPlugin plugin, CoxConfig config)
|
||||
{
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGH);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (WorldPoint point : plugin.getOlm_Heal())
|
||||
{
|
||||
client.setHintArrow(point);
|
||||
drawTile(graphics, point, config.tpColor(), 2, 150, 50);
|
||||
}
|
||||
|
||||
for (WorldPoint point : plugin.getOlm_TP())
|
||||
{
|
||||
client.setHintArrow(point);
|
||||
drawTile(graphics, point, config.tpColor(), 2, 150, 50);
|
||||
}
|
||||
|
||||
if (plugin.isRunMutta())
|
||||
{
|
||||
if (config.Muttadile())
|
||||
{
|
||||
NPC boss = plugin.getMomma_NPC();
|
||||
NPC baby = plugin.getMutta_NPC();
|
||||
if (boss != null)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition composition = boss.getTransformedDefinition();
|
||||
{
|
||||
size = composition.getSize();
|
||||
}
|
||||
List<WorldPoint> meleeRangeMom = getHitSquares(boss.getWorldLocation(), size, 1, false);
|
||||
for (WorldPoint p : meleeRangeMom)
|
||||
{
|
||||
drawTile(graphics, p, config.muttaColor(), 0, 0, 50);
|
||||
}
|
||||
}
|
||||
if (baby != null)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition compositionbaby = baby.getTransformedDefinition();
|
||||
{
|
||||
size = compositionbaby.getSize();
|
||||
}
|
||||
List<WorldPoint> meleeRange = getHitSquares(baby.getWorldLocation(), size, 1, false);
|
||||
for (WorldPoint p : meleeRange)
|
||||
{
|
||||
drawTile(graphics, p, config.muttaColor(), 0, 0, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.isRunGuard())
|
||||
{
|
||||
if (config.Guardians())
|
||||
{
|
||||
NPC G1 = plugin.getGuard1_NPC();
|
||||
NPC G2 = plugin.getGuard2_NPC();
|
||||
int tick = plugin.getGuardTick();
|
||||
if (tick == 5)
|
||||
{
|
||||
if (G1 != null)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition composition = G1.getTransformedDefinition();
|
||||
{
|
||||
size = composition.getSize();
|
||||
}
|
||||
List<WorldPoint> meleeRange = getHitSquares(G1.getWorldLocation(), size, 1, true);
|
||||
for (WorldPoint p : meleeRange)
|
||||
{
|
||||
drawTile(graphics, p, config.guardColor(), 0, 0, 50);
|
||||
}
|
||||
}
|
||||
if (G2 != null)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition composition = G2.getTransformedDefinition();
|
||||
{
|
||||
size = composition.getSize();
|
||||
}
|
||||
List<WorldPoint> meleeRange = getHitSquares(G2.getWorldLocation(), size, 1, true);
|
||||
for (WorldPoint p : meleeRange)
|
||||
{
|
||||
drawTile(graphics, p, config.guardColor(), 0, 0, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (plugin.isRunTekton())
|
||||
{
|
||||
if (config.Tekton())
|
||||
{
|
||||
NPC boss = plugin.getTekton_NPC();
|
||||
if (boss != null)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition composition = boss.getTransformedDefinition();
|
||||
{
|
||||
size = composition.getSize();
|
||||
}
|
||||
List<WorldPoint> meleeRange = getHitSquares(boss.getWorldLocation(), size, 1, false);
|
||||
for (WorldPoint p : meleeRange)
|
||||
{
|
||||
drawTile(graphics, p, config.tektonColor(), 0, 0, 50);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.isRunOlm())
|
||||
{
|
||||
NPC boss = plugin.getOlm_NPC();
|
||||
|
||||
if (config.OlmTick())
|
||||
{
|
||||
if (boss != null)
|
||||
{
|
||||
int tick = plugin.getOlm_TicksUntilAction();
|
||||
int cycle = plugin.getOlm_ActionCycle();
|
||||
int spec = plugin.getOlm_NextSpec();
|
||||
final String tickStr = String.valueOf(tick);
|
||||
String cycleStr = "?";
|
||||
switch (cycle)
|
||||
{
|
||||
case 1:
|
||||
switch (spec)
|
||||
{
|
||||
case 1:
|
||||
cycleStr = "Portals";
|
||||
break;
|
||||
case 2:
|
||||
cycleStr = "lightning";
|
||||
break;
|
||||
case 3:
|
||||
cycleStr = "Crystals";
|
||||
break;
|
||||
case 4:
|
||||
cycleStr = "Heal";
|
||||
break;
|
||||
case -1:
|
||||
cycleStr = "??";
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case 2:
|
||||
cycleStr = "Sauto";
|
||||
break;
|
||||
case 3:
|
||||
cycleStr = "Null";
|
||||
break;
|
||||
case 4:
|
||||
cycleStr = "Nauto";
|
||||
break;
|
||||
case -1:
|
||||
cycleStr = "??";
|
||||
break;
|
||||
}
|
||||
final String combinedStr = cycleStr + ":" + tickStr;
|
||||
Point canvasPoint = boss.getCanvasTextLocation(graphics, combinedStr, 130);
|
||||
renderTextLocation(graphics, combinedStr, config.textSize(), config.fontStyle().getFont(), Color.WHITE, canvasPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private void drawTile(Graphics2D graphics, WorldPoint point, Color color, int strokeWidth, int outlineAlpha, int fillAlpha)
|
||||
{
|
||||
WorldPoint playerLocation = client.getLocalPlayer().getWorldLocation();
|
||||
if (point.distanceTo(playerLocation) >= 32)
|
||||
{
|
||||
return;
|
||||
}
|
||||
LocalPoint lp = LocalPoint.fromWorld(client, point);
|
||||
if (lp == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
Polygon poly = Perspective.getCanvasTilePoly(client, lp);
|
||||
if (poly == null)
|
||||
{
|
||||
return;
|
||||
}
|
||||
//OverlayUtil.renderPolygon(graphics, poly, color);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
|
||||
graphics.setStroke(new BasicStroke(strokeWidth));
|
||||
graphics.draw(poly);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
|
||||
graphics.fill(poly);
|
||||
}
|
||||
|
||||
private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition composition = actor.getTransformedDefinition();
|
||||
if (composition != null)
|
||||
{
|
||||
size = composition.getSize();
|
||||
}
|
||||
LocalPoint lp = actor.getLocalLocation();
|
||||
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size);
|
||||
|
||||
if (tilePoly != null)
|
||||
{
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
|
||||
graphics.setStroke(new BasicStroke(outlineWidth));
|
||||
graphics.draw(tilePoly);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
|
||||
graphics.fill(tilePoly);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", fontStyle, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX(),
|
||||
canvasPoint.getY());
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() + 1,
|
||||
canvasPoint.getY() + 1);
|
||||
if (config.shadows())
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
private List<WorldPoint> getHitSquares(WorldPoint npcLoc, int npcSize, int thickness, boolean includeUnder)
|
||||
{
|
||||
List<WorldPoint> little = new WorldArea(npcLoc, npcSize, npcSize).toWorldPointList();
|
||||
List<WorldPoint> big = new WorldArea(npcLoc.getX() - thickness, npcLoc.getY() - thickness, npcSize + (thickness * 2), npcSize + (thickness * 2), npcLoc.getPlane()).toWorldPointList();
|
||||
if (!includeUnder)
|
||||
{
|
||||
for (Iterator<WorldPoint> it = big.iterator(); it.hasNext(); )
|
||||
{
|
||||
WorldPoint p = it.next();
|
||||
if (little.contains(p))
|
||||
{
|
||||
it.remove();
|
||||
}
|
||||
}
|
||||
}
|
||||
return big;
|
||||
}
|
||||
|
||||
private void renderPoly(Graphics2D graphics, Color color, Polygon polygon)
|
||||
{
|
||||
if (polygon != null)
|
||||
{
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.draw(polygon);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20));
|
||||
graphics.fill(polygon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,231 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.coxhelper;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import api.Actor;
|
||||
import api.Client;
|
||||
import api.Perspective;
|
||||
import api.Point;
|
||||
import api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class TimersOverlay extends Overlay
|
||||
{
|
||||
|
||||
private CoxPlugin plugin;
|
||||
private CoxConfig config;
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
TimersOverlay(CoxPlugin plugin, CoxConfig config, Client client)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (config.tektonTickCounter())
|
||||
{
|
||||
Actor actor = plugin.getTekton_NPC();
|
||||
final int ticksLeft = plugin.getTektonTicks();
|
||||
final int attackTicksleft = plugin.getTektonAttackTicks();
|
||||
String attacksLeftStr;
|
||||
Color tickcolor;
|
||||
Color attackcolor;
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
{
|
||||
tickcolor = new Color(255, 0, 0, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = actor.getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, config.textSize(), config.fontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
if (attackTicksleft >= 0 && plugin.getTektonAttacks() > 0)
|
||||
{
|
||||
if (attackTicksleft <= 1)
|
||||
{
|
||||
attackcolor = new Color(255, 0, 0, 255);
|
||||
attacksLeftStr = "Phase Over";
|
||||
}
|
||||
else
|
||||
{
|
||||
attackcolor = new Color(255, 255, 255, 255);
|
||||
attacksLeftStr = String.valueOf(attackTicksleft);
|
||||
}
|
||||
|
||||
if (actor != null)
|
||||
{
|
||||
Point canvasPoint = actor.getCanvasTextLocation(graphics, attacksLeftStr, 0);
|
||||
renderTextLocationAbove(graphics, attacksLeftStr, config.textSize(), config.fontStyle().getFont(), attackcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.timers())
|
||||
{
|
||||
if (plugin.getBurnTarget().size() > 0)
|
||||
{
|
||||
for (Actor actor : plugin.getBurnTarget())
|
||||
{
|
||||
renderNpcOverlay(graphics, actor, config.burnColor(), 2, 100, 10);
|
||||
final int ticksLeft = plugin.getBurnTicks();
|
||||
String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Color tickcolor = new Color(255, 255, 255, 255);
|
||||
if (ticksLeft >= 0)
|
||||
{
|
||||
if (ticksLeft == 34 ||
|
||||
ticksLeft == 33 ||
|
||||
ticksLeft == 26 ||
|
||||
ticksLeft == 25 ||
|
||||
ticksLeft == 18 ||
|
||||
ticksLeft == 17 ||
|
||||
ticksLeft == 10 ||
|
||||
ticksLeft == 9 ||
|
||||
ticksLeft == 2 ||
|
||||
ticksLeft == 1)
|
||||
{
|
||||
tickcolor = new Color(255, 0, 0, 255);
|
||||
ticksLeftStr = "GAP";
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
Point canvasPoint = actor.getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, config.textSize(), config.fontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (plugin.getAcidTarget() != null)
|
||||
{
|
||||
Actor actor = plugin.getAcidTarget();
|
||||
renderNpcOverlay(graphics, actor, config.acidColor(), 2, 100, 10);
|
||||
final int ticksLeft = plugin.getAcidTicks();
|
||||
Color tickcolor = new Color(255, 255, 255, 255);
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft > 1)
|
||||
{
|
||||
tickcolor = new Color(69, 241, 44, 255);
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = new Color(255, 255, 255, 255);
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = actor.getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, config.textSize(), config.fontStyle().getFont(), tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (config.tpOverlay())
|
||||
{
|
||||
if (plugin.getTeleportTarget() != null)
|
||||
{
|
||||
renderNpcOverlay(graphics, plugin.getTeleportTarget(), new Color(193, 255, 245, 255), 2, 100, 10);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderNpcOverlay(Graphics2D graphics, Actor actor, Color color, int outlineWidth, int outlineAlpha, int fillAlpha)
|
||||
{
|
||||
int size = 1;
|
||||
LocalPoint lp = actor.getLocalLocation();
|
||||
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size);
|
||||
|
||||
if (tilePoly != null)
|
||||
{
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
|
||||
graphics.setStroke(new BasicStroke(outlineWidth));
|
||||
graphics.draw(tilePoly);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
|
||||
graphics.fill(tilePoly);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", fontStyle, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX(),
|
||||
canvasPoint.getY());
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() + 1,
|
||||
canvasPoint.getY() + 1);
|
||||
if (config.shadows())
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTextLocationAbove(Graphics2D graphics, String txtString, int fontSize, int fontStyle, Color fontColor, Point canvasPoint)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", fontStyle, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX(),
|
||||
canvasPoint.getY() + 20);
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() + 1,
|
||||
canvasPoint.getY() + 21);
|
||||
if (config.shadows())
|
||||
{
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
}
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,97 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, lyzrds <https://discord.gg/5eb9Fe>
|
||||
* Copyright (c) 2019, ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.coxhelper;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.NPC;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
|
||||
public class VanguardsHighlight extends Overlay
|
||||
{
|
||||
|
||||
private final Client client;
|
||||
private final CoxPlugin plugin;
|
||||
private final CoxConfig config;
|
||||
|
||||
@Inject
|
||||
VanguardsHighlight(Client client, CoxPlugin plugin, CoxConfig config)
|
||||
{
|
||||
super(plugin);
|
||||
setLayer(OverlayLayer.ABOVE_MAP);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (plugin.isRunVanguards())
|
||||
{
|
||||
if (config.vangHighlight())
|
||||
{
|
||||
if (plugin.getRangeVang() != null)
|
||||
{
|
||||
renderNpcOverlay(graphics, plugin.getRangeVang(), "Range", Color.GREEN);
|
||||
}
|
||||
if (plugin.getMageVang() != null)
|
||||
{
|
||||
renderNpcOverlay(graphics, plugin.getMageVang(), "Mage", Color.BLUE);
|
||||
}
|
||||
if (plugin.getMeleeVang() != null)
|
||||
{
|
||||
renderNpcOverlay(graphics, plugin.getMeleeVang(), "Melee", Color.RED);
|
||||
}
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
|
||||
private void renderNpcOverlay(Graphics2D graphics, NPC actor, String name, Color color)
|
||||
{
|
||||
Polygon objectClickbox = actor.getConvexHull();
|
||||
renderPoly(graphics, color, objectClickbox);
|
||||
}
|
||||
|
||||
private void renderPoly(Graphics2D graphics, Color color, Polygon polygon)
|
||||
{
|
||||
if (polygon != null)
|
||||
{
|
||||
graphics.setColor(color);
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.draw(polygon);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), 20));
|
||||
graphics.fill(polygon);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,135 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Abexlry <abexlry@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.entertochat;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.GameState;
|
||||
import api.VarClientStr;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.MouseAdapter;
|
||||
|
||||
class EnterToChatListener extends MouseAdapter implements KeyListener
|
||||
{
|
||||
@Inject
|
||||
private EnterToChatPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
private final Map<Integer, Integer> modified = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN || !plugin.chatboxFocused())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.isTyping())
|
||||
{
|
||||
switch (e.getKeyCode())
|
||||
{
|
||||
case KeyEvent.VK_ENTER:
|
||||
case KeyEvent.VK_SLASH:
|
||||
case KeyEvent.VK_COLON:
|
||||
// refocus chatbox
|
||||
plugin.setTyping(true);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
plugin.unlockChat();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (e.getKeyCode())
|
||||
{
|
||||
case KeyEvent.VK_ENTER:
|
||||
plugin.setTyping(false);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
plugin.lockChat();
|
||||
});
|
||||
break;
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
plugin.setTyping(false);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
|
||||
plugin.lockChat();
|
||||
});
|
||||
break;
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
if (Strings.isNullOrEmpty(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)))
|
||||
{
|
||||
plugin.setTyping(false);
|
||||
clientThread.invoke(() -> plugin.lockChat());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.chatboxFocused() && !plugin.isTyping())
|
||||
{
|
||||
modified.remove(e.getKeyCode());
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
// press d + enter + release d - causes the right arrow to never be released
|
||||
Integer m = modified.get(e.getKeyCode());
|
||||
if (m != null)
|
||||
{
|
||||
modified.remove(e.getKeyCode());
|
||||
e.setKeyCode(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,206 +0,0 @@
|
||||
/*'
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Abexlry <abexlry@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.entertochat;
|
||||
|
||||
import java.awt.Color;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import api.Client;
|
||||
import api.GameState;
|
||||
import api.IconID;
|
||||
import api.VarClientInt;
|
||||
import api.VarClientStr;
|
||||
import api.Varbits;
|
||||
import api.events.ScriptCallbackEvent;
|
||||
import api.widgets.Widget;
|
||||
import api.widgets.WidgetInfo;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.input.KeyManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.JagexColors;
|
||||
import net.runelite.client.util.ColorUtil;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Press Enter to Chat",
|
||||
description = "'Press Enter to Chat'",
|
||||
tags = {"enter", "chat"},
|
||||
enabledByDefault = false,
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
public class EnterToChatPlugin extends Plugin
|
||||
{
|
||||
private static final String PRESS_ENTER_TO_CHAT = "Press Enter to Chat...";
|
||||
private static final String SCRIPT_EVENT_SET_CHATBOX_INPUT = "setChatboxInput";
|
||||
private static final String SCRIPT_EVENT_BLOCK_CHAT_INPUT = "blockChatInput";
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Inject
|
||||
private ConfigManager configManager;
|
||||
|
||||
@Inject
|
||||
private KeyManager keyManager;
|
||||
|
||||
@Inject
|
||||
private EnterToChatListener inputListener;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean typing;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
configManager.setConfiguration("runelite", "wasdcameraplugin", false);
|
||||
typing = false;
|
||||
keyManager.registerKeyListener(inputListener);
|
||||
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
lockChat();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
unlockChat();
|
||||
}
|
||||
});
|
||||
|
||||
keyManager.unregisterKeyListener(inputListener);
|
||||
}
|
||||
|
||||
|
||||
boolean chatboxFocused()
|
||||
{
|
||||
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
|
||||
if (chatboxParent == null || chatboxParent.getOnKeyListener() == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// the search box on the world map can be focused, and chat input goes there, even
|
||||
// though the chatbox still has its key listener.
|
||||
Widget worldMapSearch = client.getWidget(WidgetInfo.WORLD_MAP_SEARCH);
|
||||
return worldMapSearch == null || client.getVar(VarClientInt.WORLD_MAP_SEARCH_FOCUSED) != 1;
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onScriptCallbackEvent(ScriptCallbackEvent scriptCallbackEvent)
|
||||
{
|
||||
switch (scriptCallbackEvent.getEventName())
|
||||
{
|
||||
case SCRIPT_EVENT_SET_CHATBOX_INPUT:
|
||||
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
|
||||
if (chatboxInput != null)
|
||||
{
|
||||
if (chatboxFocused() && !typing)
|
||||
{
|
||||
chatboxInput.setText(PRESS_ENTER_TO_CHAT);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case SCRIPT_EVENT_BLOCK_CHAT_INPUT:
|
||||
if (!typing)
|
||||
{
|
||||
int[] intStack = client.getIntStack();
|
||||
int intStackSize = client.getIntStackSize();
|
||||
intStack[intStackSize - 1] = 1;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void lockChat()
|
||||
{
|
||||
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
|
||||
if (chatboxParent != null && chatboxParent.getOnKeyListener() != null)
|
||||
{
|
||||
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
|
||||
if (chatboxInput != null)
|
||||
{
|
||||
chatboxInput.setText(PRESS_ENTER_TO_CHAT);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void unlockChat()
|
||||
{
|
||||
Widget chatboxParent = client.getWidget(WidgetInfo.CHATBOX_PARENT);
|
||||
if (chatboxParent != null)
|
||||
{
|
||||
Widget chatboxInput = client.getWidget(WidgetInfo.CHATBOX_INPUT);
|
||||
if (chatboxInput != null)
|
||||
{
|
||||
if (client.getGameState() == GameState.LOGGED_IN)
|
||||
{
|
||||
final boolean isChatboxTransparent = client.isResized() && client.getVar(Varbits.TRANSPARENT_CHATBOX) == 1;
|
||||
final Color textColor = isChatboxTransparent ? JagexColors.CHAT_TYPED_TEXT_TRANSPARENT_BACKGROUND : JagexColors.CHAT_TYPED_TEXT_OPAQUE_BACKGROUND;
|
||||
chatboxInput.setText(getPlayerNameWithIcon() + ": " + ColorUtil.wrapWithColorTag(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT) + "*", textColor));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private String getPlayerNameWithIcon()
|
||||
{
|
||||
IconID icon;
|
||||
switch (client.getAccountType())
|
||||
{
|
||||
case IRONMAN:
|
||||
icon = IconID.IRONMAN;
|
||||
break;
|
||||
case ULTIMATE_IRONMAN:
|
||||
icon = IconID.ULTIMATE_IRONMAN;
|
||||
break;
|
||||
case HARDCORE_IRONMAN:
|
||||
icon = IconID.HARDCORE_IRONMAN;
|
||||
break;
|
||||
default:
|
||||
return client.getLocalPlayer().getName();
|
||||
}
|
||||
return icon + client.getLocalPlayer().getName();
|
||||
}
|
||||
}
|
||||
@@ -1,184 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2019, Ganom <https://github.com/Ganom>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
package net.runelite.client.plugins.fightcave;
|
||||
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Polygon;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.NPC;
|
||||
import api.NPCDefinition;
|
||||
import api.Perspective;
|
||||
import api.Point;
|
||||
import api.coords.LocalPoint;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.OverlayPriority;
|
||||
import net.runelite.client.ui.overlay.OverlayUtil;
|
||||
|
||||
public class TimersOverlay extends Overlay
|
||||
{
|
||||
private FightCavePlugin plugin;
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
TimersOverlay(FightCavePlugin plugin, Client client)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPriority(OverlayPriority.HIGHEST);
|
||||
setLayer(OverlayLayer.ALWAYS_ON_TOP);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
for (NPCContainer npc : plugin.getDrainers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.RED, 255, 20);
|
||||
String str = "drainer";
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, str, 0);
|
||||
renderTextLocation(graphics, str, 12, Color.WHITE, canvasPoint);
|
||||
}
|
||||
|
||||
for (NPCContainer npc : plugin.getIgnore().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.BLACK, 50, 5);
|
||||
String str = "ignore";
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, str, 0);
|
||||
renderTextLocation(graphics, str, 10, Color.WHITE, canvasPoint);
|
||||
}
|
||||
|
||||
Color tickcolor;
|
||||
|
||||
for (NPCContainer npc : plugin.getRangers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.GREEN, 100, 10);
|
||||
final int ticksLeft = npc.getTicksUntilAttack();
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
{
|
||||
tickcolor = Color.GREEN;
|
||||
}
|
||||
else
|
||||
{
|
||||
tickcolor = Color.WHITE;
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
|
||||
for (NPCContainer npc : plugin.getMagers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.CYAN, 100, 10);
|
||||
final int ticksLeft = npc.getTicksUntilAttack();
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
{
|
||||
tickcolor = Color.CYAN;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tickcolor = Color.WHITE;
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
|
||||
for (NPCContainer npc : plugin.getMeleers().values())
|
||||
{
|
||||
renderNpcOverlay(graphics, npc.getNpc(), Color.RED, 100, 10);
|
||||
final int ticksLeft = npc.getTicksUntilAttack();
|
||||
if (ticksLeft > 0)
|
||||
{
|
||||
if (ticksLeft == 1)
|
||||
{
|
||||
tickcolor = Color.RED;
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
tickcolor = Color.WHITE;
|
||||
}
|
||||
final String ticksLeftStr = String.valueOf(ticksLeft);
|
||||
Point canvasPoint = npc.getNpc().getCanvasTextLocation(graphics, ticksLeftStr, 0);
|
||||
renderTextLocation(graphics, ticksLeftStr, 32, tickcolor, canvasPoint);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderNpcOverlay(Graphics2D graphics, NPC actor, Color color, int outlineAlpha, int fillAlpha)
|
||||
{
|
||||
int size = 1;
|
||||
NPCDefinition composition = actor.getTransformedDefinition();
|
||||
if (composition != null)
|
||||
{
|
||||
size = composition.getSize();
|
||||
}
|
||||
LocalPoint lp = actor.getLocalLocation();
|
||||
Polygon tilePoly = Perspective.getCanvasTileAreaPoly(client, lp, size);
|
||||
|
||||
if (tilePoly != null)
|
||||
{
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), outlineAlpha));
|
||||
graphics.setStroke(new BasicStroke(2));
|
||||
graphics.draw(tilePoly);
|
||||
graphics.setColor(new Color(color.getRed(), color.getGreen(), color.getBlue(), fillAlpha));
|
||||
graphics.fill(tilePoly);
|
||||
}
|
||||
}
|
||||
|
||||
private void renderTextLocation(Graphics2D graphics, String txtString, int fontSize, Color fontColor, Point canvasPoint)
|
||||
{
|
||||
graphics.setFont(new Font("Arial", Font.BOLD, fontSize));
|
||||
if (canvasPoint != null)
|
||||
{
|
||||
final Point canvasCenterPoint = new Point(
|
||||
canvasPoint.getX(),
|
||||
canvasPoint.getY());
|
||||
final Point canvasCenterPoint_shadow = new Point(
|
||||
canvasPoint.getX() + 1,
|
||||
canvasPoint.getY() + 1);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint_shadow, txtString, Color.BLACK);
|
||||
OverlayUtil.renderTextLocation(graphics, canvasCenterPoint, txtString, fontColor);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,157 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2017, Devin French <https://github.com/devinfrench>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.idlenotifier;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("idlenotifier")
|
||||
public interface IdleNotifierConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "animationidle",
|
||||
name = "Idle Animation Notifications",
|
||||
description = "Configures if idle animation notifications are enabled",
|
||||
position = 1
|
||||
)
|
||||
default boolean animationIdle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "interactionidle",
|
||||
name = "Idle Interaction Notifications",
|
||||
description = "Configures if idle interaction notifications are enabled e.g. combat, fishing",
|
||||
position = 2
|
||||
)
|
||||
default boolean interactionIdle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "logoutidle",
|
||||
name = "Idle Logout Notifications",
|
||||
description = "Configures if the idle logout notifications are enabled",
|
||||
position = 3
|
||||
)
|
||||
default boolean logoutIdle()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "skullNotification",
|
||||
name = "Skull Notification",
|
||||
description = "Receive a notification when you skull."
|
||||
)
|
||||
default boolean showSkullNotification()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "unskullNotification",
|
||||
name = "Unskull Notification",
|
||||
description = "Receive a notification when you unskull."
|
||||
)
|
||||
default boolean showUnskullNotification()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "timeout",
|
||||
name = "Idle Notification Delay (ms)",
|
||||
description = "The notification delay after the player is idle",
|
||||
position = 6
|
||||
)
|
||||
default int getIdleNotificationDelay()
|
||||
{
|
||||
return 5000;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "hitpoints",
|
||||
name = "Hitpoints Notification Threshold",
|
||||
description = "The amount of hitpoints to send a notification at. A value of 0 will disable notification.",
|
||||
position = 7
|
||||
)
|
||||
default int getHitpointsThreshold()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "prayer",
|
||||
name = "Prayer Notification Threshold",
|
||||
description = "The amount of prayer points to send a notification at. A value of 0 will disable notification.",
|
||||
position = 8
|
||||
)
|
||||
default int getPrayerThreshold()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "oxygen",
|
||||
name = "Oxygen Notification Threshold",
|
||||
position = 9,
|
||||
description = "The amount of remaining oxygen to send a notification at. A value of 0 will disable notification."
|
||||
)
|
||||
default int getOxygenThreshold()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "spec",
|
||||
name = "Special Attack Energy Notification Threshold",
|
||||
position = 10,
|
||||
description = "The amount of spec energy reached to send a notification at. A value of 0 will disable notification."
|
||||
)
|
||||
default int getSpecEnergyThreshold()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "pkers",
|
||||
name = "PKer Notifier",
|
||||
position = 9,
|
||||
description = "Notifies if an attackable player based on your level range appears on screen.",
|
||||
group = "PvP",
|
||||
warning = "This will not notify you if the player is in your cc or is online on your friends list."
|
||||
)
|
||||
default boolean notifyPkers()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,53 +0,0 @@
|
||||
package net.runelite.client.plugins.inventoryhighlight;
|
||||
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
import net.runelite.client.config.Stub;
|
||||
|
||||
@ConfigGroup("inventoryHighlight")
|
||||
public interface InventoryHighlightConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "showItem",
|
||||
name = "Show the item",
|
||||
description = "Show a preview of the item in the new slot"
|
||||
)
|
||||
default boolean showItem()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "gridStub",
|
||||
name = "Grid",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
default Stub gridStub()
|
||||
{
|
||||
return new Stub();
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showGrid",
|
||||
name = "Show a grid",
|
||||
description = "Show a grid on the inventory while dragging",
|
||||
parent = "gridStub"
|
||||
)
|
||||
default boolean showGrid()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
keyName = "showHighlight",
|
||||
name = "Show background highlight",
|
||||
description = "Show a green background highlight in the new slot",
|
||||
parent = "gridStub"
|
||||
)
|
||||
default boolean showHighlight()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jeremy Plsek <https://github.com/jplsek>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.inventoryhighlight;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.event.MouseEvent;
|
||||
import api.Client;
|
||||
import api.GameState;
|
||||
import api.Point;
|
||||
import api.widgets.Widget;
|
||||
import api.widgets.WidgetInfo;
|
||||
import api.widgets.WidgetItem;
|
||||
import net.runelite.client.input.MouseListener;
|
||||
|
||||
public class InventoryHighlightInputListener implements MouseListener
|
||||
{
|
||||
private final InventoryHighlightPlugin plugin;
|
||||
private final Client client;
|
||||
|
||||
@Inject
|
||||
public InventoryHighlightInputListener(InventoryHighlightPlugin plugin, Client client)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseDragged(MouseEvent mouseEvent)
|
||||
{
|
||||
plugin.setDragging(true);
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseMoved(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseClicked(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mousePressed(MouseEvent mouseEvent)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY);
|
||||
final Widget bankInventoryWidget = client.getWidget(WidgetInfo.BANK_INVENTORY_ITEMS_CONTAINER);
|
||||
|
||||
if ((inventoryWidget == null || inventoryWidget.isSelfHidden()) &&
|
||||
(inventoryWidget == null || bankInventoryWidget == null || bankInventoryWidget.isSelfHidden()))
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
final Point mouse = client.getMouseCanvasPosition();
|
||||
|
||||
for (WidgetItem item : inventoryWidget.getWidgetItems())
|
||||
{
|
||||
if (item.getCanvasBounds().contains(mouse.getX(), mouse.getY()))
|
||||
{
|
||||
plugin.setDraggingItem(item.getId());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseReleased(MouseEvent mouseEvent)
|
||||
{
|
||||
plugin.setDragging(false);
|
||||
plugin.setDraggingItem(-1);
|
||||
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseEntered(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
|
||||
@Override
|
||||
public MouseEvent mouseExited(MouseEvent mouseEvent)
|
||||
{
|
||||
return mouseEvent;
|
||||
}
|
||||
}
|
||||
@@ -1,140 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jeremy Plsek <https://github.com/jplsek>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.inventoryhighlight;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Point;
|
||||
import java.awt.Rectangle;
|
||||
import java.awt.image.BufferedImage;
|
||||
import api.Client;
|
||||
import api.widgets.Widget;
|
||||
import api.widgets.WidgetInfo;
|
||||
import net.runelite.client.game.ItemManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
|
||||
public class InventoryHighlightOverlay extends Overlay
|
||||
{
|
||||
private final InventoryHighlightPlugin plugin;
|
||||
private final InventoryHighlightConfig config;
|
||||
private final Client client;
|
||||
private final ItemManager itemManager;
|
||||
|
||||
// the inventory widget location is slightly off
|
||||
private static final int FIXED_MARGIN_X = -10;
|
||||
private static final int FIXED_MARGIN_Y = -25;
|
||||
private static final int RESIZEABLE_MARGIN_X = -6;
|
||||
private static final int RESIZEABLE_MARGIN_Y = -21;
|
||||
|
||||
private static final int ITEM_WIDTH = 32;
|
||||
private static final int ITEM_HEIGHT = 32;
|
||||
private static final int ITEM_MARGIN_X = 10;
|
||||
private static final int ITEM_MARGIN_Y = 4;
|
||||
|
||||
private static final Color HIGHLIGHT = new Color(0, 255, 0, 45);
|
||||
private static final Color GRID = new Color(255, 255, 255, 45);
|
||||
|
||||
@Inject
|
||||
public InventoryHighlightOverlay(InventoryHighlightPlugin plugin, InventoryHighlightConfig config, Client client, ItemManager itemManager)
|
||||
{
|
||||
this.plugin = plugin;
|
||||
this.itemManager = itemManager;
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (plugin.getDraggingItem() == -1 || !plugin.isDragging())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
int marginX, marginY;
|
||||
if (client.isResized())
|
||||
{
|
||||
marginX = RESIZEABLE_MARGIN_X;
|
||||
marginY = RESIZEABLE_MARGIN_Y;
|
||||
}
|
||||
else
|
||||
{
|
||||
marginX = FIXED_MARGIN_X;
|
||||
marginY = FIXED_MARGIN_Y;
|
||||
}
|
||||
|
||||
final api.Point mouse = client.getMouseCanvasPosition();
|
||||
final Point updatedMouse = new Point(mouse.getX() + marginX, mouse.getY() + marginY);
|
||||
|
||||
// null checks for inventory are checked during dragging events
|
||||
final Widget inventoryWidget = client.getWidget(WidgetInfo.INVENTORY);
|
||||
|
||||
final int inventoryX = inventoryWidget.getCanvasLocation().getX() + marginX;
|
||||
final int inventoryY = inventoryWidget.getCanvasLocation().getY() + marginY;
|
||||
|
||||
final BufferedImage draggedItemImage = itemManager.getImage(plugin.getDraggingItem());
|
||||
|
||||
for (int i = 0; i < 4; i++)
|
||||
{
|
||||
for (int j = 0; j < 7; j++)
|
||||
{
|
||||
final int x = (ITEM_WIDTH + ITEM_MARGIN_X) * i + inventoryX;
|
||||
final int y = (ITEM_HEIGHT + ITEM_MARGIN_Y) * j + inventoryY;
|
||||
final Rectangle bounds = new Rectangle(x, y, ITEM_WIDTH, ITEM_HEIGHT);
|
||||
|
||||
if (config.showItem() && bounds.contains(updatedMouse))
|
||||
{
|
||||
graphics.setComposite(AlphaComposite.SrcOver.derive(0.3f));
|
||||
graphics.drawImage(draggedItemImage, x, y, null);
|
||||
graphics.setComposite(AlphaComposite.SrcOver);
|
||||
}
|
||||
|
||||
if (config.showHighlight() && bounds.contains(updatedMouse))
|
||||
{
|
||||
graphics.setColor(HIGHLIGHT);
|
||||
graphics.fill(bounds);
|
||||
}
|
||||
|
||||
if (config.showGrid())
|
||||
{
|
||||
// don't set color on highlighted slot
|
||||
if (!config.showHighlight() || !(config.showHighlight() && bounds.contains(updatedMouse)))
|
||||
{
|
||||
graphics.setColor(GRID);
|
||||
graphics.fill(bounds);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -1,99 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jeremy Plsek <https://github.com/jplsek>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.inventoryhighlight;
|
||||
|
||||
import com.google.inject.Inject;
|
||||
import com.google.inject.Provides;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.Setter;
|
||||
import api.events.FocusChanged;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.input.MouseManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Inventory Highlight",
|
||||
description = "Shows a preview of where items will be dragged",
|
||||
tags = {"items", "overlay"},
|
||||
enabledByDefault = false,
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
public class InventoryHighlightPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private InventoryHighlightOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private InventoryHighlightInputListener inputListener;
|
||||
|
||||
@Inject
|
||||
private MouseManager mouseManager;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private int draggingItem = -1;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
@Setter(AccessLevel.PACKAGE)
|
||||
private boolean dragging = false;
|
||||
|
||||
@Override
|
||||
public void startUp()
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
mouseManager.registerMouseListener(inputListener);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void shutDown()
|
||||
{
|
||||
mouseManager.unregisterMouseListener(inputListener);
|
||||
overlayManager.remove(overlay);
|
||||
}
|
||||
|
||||
@Provides
|
||||
InventoryHighlightConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(InventoryHighlightConfig.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onFocusChanged(FocusChanged focusChanged)
|
||||
{
|
||||
if (!focusChanged.isFocused())
|
||||
{
|
||||
dragging = false;
|
||||
draggingItem = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,628 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Jordan Atwood <jordan.atwood423@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.itemstats;
|
||||
|
||||
import com.google.inject.Singleton;
|
||||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Map;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import static api.ItemID.ADMIRAL_PIE;
|
||||
import static api.ItemID.AGILITY_POTION1;
|
||||
import static api.ItemID.AGILITY_POTION2;
|
||||
import static api.ItemID.AGILITY_POTION3;
|
||||
import static api.ItemID.AGILITY_POTION4;
|
||||
import static api.ItemID.ANCHOVIES;
|
||||
import static api.ItemID.ANCHOVY_PIZZA;
|
||||
import static api.ItemID.ANGLERFISH;
|
||||
import static api.ItemID.APPLE_PIE;
|
||||
import static api.ItemID.ATTACK_POTION1;
|
||||
import static api.ItemID.ATTACK_POTION2;
|
||||
import static api.ItemID.ATTACK_POTION3;
|
||||
import static api.ItemID.ATTACK_POTION4;
|
||||
import static api.ItemID.AUTUMN_SQIRKJUICE;
|
||||
import static api.ItemID.BAGUETTE;
|
||||
import static api.ItemID.BAKED_POTATO;
|
||||
import static api.ItemID.BANANA;
|
||||
import static api.ItemID.BANDAGES;
|
||||
import static api.ItemID.BASS;
|
||||
import static api.ItemID.BASTION_POTION1;
|
||||
import static api.ItemID.BASTION_POTION2;
|
||||
import static api.ItemID.BASTION_POTION3;
|
||||
import static api.ItemID.BASTION_POTION4;
|
||||
import static api.ItemID.BATTLEMAGE_POTION1;
|
||||
import static api.ItemID.BATTLEMAGE_POTION2;
|
||||
import static api.ItemID.BATTLEMAGE_POTION3;
|
||||
import static api.ItemID.BATTLEMAGE_POTION4;
|
||||
import static api.ItemID.BAT_SHISH;
|
||||
import static api.ItemID.BOTANICAL_PIE;
|
||||
import static api.ItemID.BOTTLE_OF_WINE;
|
||||
import static api.ItemID.BRAWK_FISH_3;
|
||||
import static api.ItemID.BREAD;
|
||||
import static api.ItemID.CABBAGE;
|
||||
import static api.ItemID.CABBAGE_1967;
|
||||
import static api.ItemID.CAKE;
|
||||
import static api.ItemID.CAVE_EEL;
|
||||
import static api.ItemID.CAVIAR;
|
||||
import static api.ItemID.CHEESE;
|
||||
import static api.ItemID.CHEESETOM_BATTA;
|
||||
import static api.ItemID.CHILLI_CON_CARNE;
|
||||
import static api.ItemID.CHILLI_POTATO;
|
||||
import static api.ItemID.CHOCCHIP_CRUNCHIES;
|
||||
import static api.ItemID.CHOCICE;
|
||||
import static api.ItemID.CHOCOLATEY_MILK;
|
||||
import static api.ItemID.CHOCOLATE_BAR;
|
||||
import static api.ItemID.CHOCOLATE_BOMB;
|
||||
import static api.ItemID.CHOCOLATE_CAKE;
|
||||
import static api.ItemID.CHOCOLATE_SLICE;
|
||||
import static api.ItemID.CHOC_SATURDAY;
|
||||
import static api.ItemID.CHOPPED_ONION;
|
||||
import static api.ItemID.CHOPPED_TOMATO;
|
||||
import static api.ItemID.CHOPPED_TUNA;
|
||||
import static api.ItemID.COATED_FROGS_LEGS;
|
||||
import static api.ItemID.COD;
|
||||
import static api.ItemID.COMBAT_POTION1;
|
||||
import static api.ItemID.COMBAT_POTION2;
|
||||
import static api.ItemID.COMBAT_POTION3;
|
||||
import static api.ItemID.COMBAT_POTION4;
|
||||
import static api.ItemID.COOKED_CHICKEN;
|
||||
import static api.ItemID.COOKED_CHOMPY;
|
||||
import static api.ItemID.COOKED_CRAB_MEAT;
|
||||
import static api.ItemID.COOKED_FISHCAKE;
|
||||
import static api.ItemID.COOKED_JUBBLY;
|
||||
import static api.ItemID.COOKED_KARAMBWAN;
|
||||
import static api.ItemID.COOKED_MEAT;
|
||||
import static api.ItemID.COOKED_RABBIT;
|
||||
import static api.ItemID.COOKED_SLIMY_EEL;
|
||||
import static api.ItemID.COOKED_SWEETCORN;
|
||||
import static api.ItemID.CURRY;
|
||||
import static api.ItemID.DARK_CRAB;
|
||||
import static api.ItemID.DEFENCE_POTION1;
|
||||
import static api.ItemID.DEFENCE_POTION2;
|
||||
import static api.ItemID.DEFENCE_POTION3;
|
||||
import static api.ItemID.DEFENCE_POTION4;
|
||||
import static api.ItemID.DRUNK_DRAGON;
|
||||
import static api.ItemID.DWELLBERRIES;
|
||||
import static api.ItemID.EASTER_EGG;
|
||||
import static api.ItemID.EDIBLE_SEAWEED;
|
||||
import static api.ItemID.EEL_SUSHI;
|
||||
import static api.ItemID.EGG_AND_TOMATO;
|
||||
import static api.ItemID.EGG_POTATO;
|
||||
import static api.ItemID.ELDER_1;
|
||||
import static api.ItemID.ELDER_1_20921;
|
||||
import static api.ItemID.ELDER_2;
|
||||
import static api.ItemID.ELDER_2_20922;
|
||||
import static api.ItemID.ELDER_3;
|
||||
import static api.ItemID.ELDER_3_20923;
|
||||
import static api.ItemID.ELDER_4;
|
||||
import static api.ItemID.ELDER_4_20924;
|
||||
import static api.ItemID.ELDER_POTION_1;
|
||||
import static api.ItemID.ELDER_POTION_2;
|
||||
import static api.ItemID.ELDER_POTION_3;
|
||||
import static api.ItemID.ELDER_POTION_4;
|
||||
import static api.ItemID.ENERGY_POTION1;
|
||||
import static api.ItemID.ENERGY_POTION2;
|
||||
import static api.ItemID.ENERGY_POTION3;
|
||||
import static api.ItemID.ENERGY_POTION4;
|
||||
import static api.ItemID.FAT_SNAIL_MEAT;
|
||||
import static api.ItemID.FIELD_RATION;
|
||||
import static api.ItemID.FILLETS;
|
||||
import static api.ItemID.FINGERS;
|
||||
import static api.ItemID.FISHING_POTION1;
|
||||
import static api.ItemID.FISHING_POTION2;
|
||||
import static api.ItemID.FISHING_POTION3;
|
||||
import static api.ItemID.FISHING_POTION4;
|
||||
import static api.ItemID.FISH_PIE;
|
||||
import static api.ItemID.FRIED_MUSHROOMS;
|
||||
import static api.ItemID.FRIED_ONIONS;
|
||||
import static api.ItemID.FROGBURGER;
|
||||
import static api.ItemID.FROGSPAWN_GUMBO;
|
||||
import static api.ItemID.FROG_SPAWN;
|
||||
import static api.ItemID.FRUIT_BATTA;
|
||||
import static api.ItemID.FRUIT_BLAST;
|
||||
import static api.ItemID.GARDEN_PIE;
|
||||
import static api.ItemID.GIANT_CARP;
|
||||
import static api.ItemID.GIRAL_BAT_2;
|
||||
import static api.ItemID.GOUT_TUBER;
|
||||
import static api.ItemID.GREEN_GLOOP_SOUP;
|
||||
import static api.ItemID.GRUBS__LA_MODE;
|
||||
import static api.ItemID.GUANIC_BAT_0;
|
||||
import static api.ItemID.GUTHIX_REST1;
|
||||
import static api.ItemID.GUTHIX_REST2;
|
||||
import static api.ItemID.GUTHIX_REST3;
|
||||
import static api.ItemID.GUTHIX_REST4;
|
||||
import static api.ItemID.HALF_AN_ADMIRAL_PIE;
|
||||
import static api.ItemID.HALF_AN_APPLE_PIE;
|
||||
import static api.ItemID.HALF_A_BOTANICAL_PIE;
|
||||
import static api.ItemID.HALF_A_FISH_PIE;
|
||||
import static api.ItemID.HALF_A_GARDEN_PIE;
|
||||
import static api.ItemID.HALF_A_MEAT_PIE;
|
||||
import static api.ItemID.HALF_A_MUSHROOM_PIE;
|
||||
import static api.ItemID.HALF_A_REDBERRY_PIE;
|
||||
import static api.ItemID.HALF_A_SUMMER_PIE;
|
||||
import static api.ItemID.HALF_A_WILD_PIE;
|
||||
import static api.ItemID.HERRING;
|
||||
import static api.ItemID.HUNTER_POTION1;
|
||||
import static api.ItemID.HUNTER_POTION2;
|
||||
import static api.ItemID.HUNTER_POTION3;
|
||||
import static api.ItemID.HUNTER_POTION4;
|
||||
import static api.ItemID.IMBUED_HEART;
|
||||
import static api.ItemID.JANGERBERRIES;
|
||||
import static api.ItemID.JUG_OF_WINE;
|
||||
import static api.ItemID.KODAI_1;
|
||||
import static api.ItemID.KODAI_1_20945;
|
||||
import static api.ItemID.KODAI_2;
|
||||
import static api.ItemID.KODAI_2_20946;
|
||||
import static api.ItemID.KODAI_3;
|
||||
import static api.ItemID.KODAI_3_20947;
|
||||
import static api.ItemID.KODAI_4;
|
||||
import static api.ItemID.KODAI_4_20948;
|
||||
import static api.ItemID.KODAI_POTION_1;
|
||||
import static api.ItemID.KODAI_POTION_2;
|
||||
import static api.ItemID.KODAI_POTION_3;
|
||||
import static api.ItemID.KODAI_POTION_4;
|
||||
import static api.ItemID.KRYKET_BAT_4;
|
||||
import static api.ItemID.KYREN_FISH_6;
|
||||
import static api.ItemID.LAVA_EEL;
|
||||
import static api.ItemID.LECKISH_FISH_2;
|
||||
import static api.ItemID.LEMON;
|
||||
import static api.ItemID.LEMON_CHUNKS;
|
||||
import static api.ItemID.LEMON_SLICES;
|
||||
import static api.ItemID.LIME;
|
||||
import static api.ItemID.LIME_CHUNKS;
|
||||
import static api.ItemID.LIME_SLICES;
|
||||
import static api.ItemID.LOACH;
|
||||
import static api.ItemID.LOBSTER;
|
||||
import static api.ItemID.MACKEREL;
|
||||
import static api.ItemID.MAGIC_ESSENCE1;
|
||||
import static api.ItemID.MAGIC_ESSENCE2;
|
||||
import static api.ItemID.MAGIC_ESSENCE3;
|
||||
import static api.ItemID.MAGIC_ESSENCE4;
|
||||
import static api.ItemID.MAGIC_POTION1;
|
||||
import static api.ItemID.MAGIC_POTION2;
|
||||
import static api.ItemID.MAGIC_POTION3;
|
||||
import static api.ItemID.MAGIC_POTION4;
|
||||
import static api.ItemID.MANTA_RAY;
|
||||
import static api.ItemID.MEAT_PIE;
|
||||
import static api.ItemID.MEAT_PIZZA;
|
||||
import static api.ItemID.MINT_CAKE;
|
||||
import static api.ItemID.MONKFISH;
|
||||
import static api.ItemID.MOONLIGHT_MEAD;
|
||||
import static api.ItemID.MURNG_BAT_5;
|
||||
import static api.ItemID.MUSHROOMS;
|
||||
import static api.ItemID.MUSHROOM_PIE;
|
||||
import static api.ItemID.MUSHROOM_POTATO;
|
||||
import static api.ItemID.MUSHROOM__ONION;
|
||||
import static api.ItemID.MYCIL_FISH_4;
|
||||
import static api.ItemID.ONION;
|
||||
import static api.ItemID.ORANGE;
|
||||
import static api.ItemID.ORANGE_CHUNKS;
|
||||
import static api.ItemID.ORANGE_SLICES;
|
||||
import static api.ItemID.OVERLOAD_1;
|
||||
import static api.ItemID.OVERLOAD_1_20985;
|
||||
import static api.ItemID.OVERLOAD_1_20989;
|
||||
import static api.ItemID.OVERLOAD_1_20993;
|
||||
import static api.ItemID.OVERLOAD_2;
|
||||
import static api.ItemID.OVERLOAD_2_20986;
|
||||
import static api.ItemID.OVERLOAD_2_20990;
|
||||
import static api.ItemID.OVERLOAD_2_20994;
|
||||
import static api.ItemID.OVERLOAD_3;
|
||||
import static api.ItemID.OVERLOAD_3_20987;
|
||||
import static api.ItemID.OVERLOAD_3_20991;
|
||||
import static api.ItemID.OVERLOAD_3_20995;
|
||||
import static api.ItemID.OVERLOAD_4;
|
||||
import static api.ItemID.OVERLOAD_4_20988;
|
||||
import static api.ItemID.OVERLOAD_4_20992;
|
||||
import static api.ItemID.OVERLOAD_4_20996;
|
||||
import static api.ItemID.PAPAYA_FRUIT;
|
||||
import static api.ItemID.PEACH;
|
||||
import static api.ItemID.PHLUXIA_BAT_3;
|
||||
import static api.ItemID.PIKE;
|
||||
import static api.ItemID.PINEAPPLE_CHUNKS;
|
||||
import static api.ItemID.PINEAPPLE_PIZZA;
|
||||
import static api.ItemID.PINEAPPLE_PUNCH;
|
||||
import static api.ItemID.PINEAPPLE_RING;
|
||||
import static api.ItemID.PLAIN_PIZZA;
|
||||
import static api.ItemID.POISON_KARAMBWAN;
|
||||
import static api.ItemID.POTATO;
|
||||
import static api.ItemID.POTATO_WITH_BUTTER;
|
||||
import static api.ItemID.POTATO_WITH_CHEESE;
|
||||
import static api.ItemID.POT_OF_CREAM;
|
||||
import static api.ItemID.PRAEL_BAT_1;
|
||||
import static api.ItemID.PRAYER_POTION1;
|
||||
import static api.ItemID.PRAYER_POTION2;
|
||||
import static api.ItemID.PRAYER_POTION3;
|
||||
import static api.ItemID.PRAYER_POTION4;
|
||||
import static api.ItemID.PREMADE_CHOC_BOMB;
|
||||
import static api.ItemID.PREMADE_CHOC_SDY;
|
||||
import static api.ItemID.PREMADE_CH_CRUNCH;
|
||||
import static api.ItemID.PREMADE_CT_BATTA;
|
||||
import static api.ItemID.PREMADE_DR_DRAGON;
|
||||
import static api.ItemID.PREMADE_FRT_BATTA;
|
||||
import static api.ItemID.PREMADE_FR_BLAST;
|
||||
import static api.ItemID.PREMADE_P_PUNCH;
|
||||
import static api.ItemID.PREMADE_SGG;
|
||||
import static api.ItemID.PREMADE_SY_CRUNCH;
|
||||
import static api.ItemID.PREMADE_TD_BATTA;
|
||||
import static api.ItemID.PREMADE_TD_CRUNCH;
|
||||
import static api.ItemID.PREMADE_TTL;
|
||||
import static api.ItemID.PREMADE_VEG_BALL;
|
||||
import static api.ItemID.PREMADE_VEG_BATTA;
|
||||
import static api.ItemID.PREMADE_WIZ_BLZD;
|
||||
import static api.ItemID.PREMADE_WM_BATTA;
|
||||
import static api.ItemID.PREMADE_WM_CRUN;
|
||||
import static api.ItemID.PREMADE_WORM_HOLE;
|
||||
import static api.ItemID.PSYKK_BAT_6;
|
||||
import static api.ItemID.PUMPKIN;
|
||||
import static api.ItemID.PURPLE_SWEETS_10476;
|
||||
import static api.ItemID.PYSK_FISH_0;
|
||||
import static api.ItemID.RAINBOW_FISH;
|
||||
import static api.ItemID.RANGING_POTION1;
|
||||
import static api.ItemID.RANGING_POTION2;
|
||||
import static api.ItemID.RANGING_POTION3;
|
||||
import static api.ItemID.RANGING_POTION4;
|
||||
import static api.ItemID.REDBERRY_PIE;
|
||||
import static api.ItemID.RESTORE_POTION1;
|
||||
import static api.ItemID.RESTORE_POTION2;
|
||||
import static api.ItemID.RESTORE_POTION3;
|
||||
import static api.ItemID.RESTORE_POTION4;
|
||||
import static api.ItemID.REVITALISATION_1_20957;
|
||||
import static api.ItemID.REVITALISATION_2_20958;
|
||||
import static api.ItemID.REVITALISATION_3_20959;
|
||||
import static api.ItemID.REVITALISATION_4_20960;
|
||||
import static api.ItemID.ROAST_BEAST_MEAT;
|
||||
import static api.ItemID.ROAST_BIRD_MEAT;
|
||||
import static api.ItemID.ROAST_FROG;
|
||||
import static api.ItemID.ROAST_RABBIT;
|
||||
import static api.ItemID.ROE;
|
||||
import static api.ItemID.ROLL;
|
||||
import static api.ItemID.ROQED_FISH_5;
|
||||
import static api.ItemID.SALMON;
|
||||
import static api.ItemID.SANFEW_SERUM1;
|
||||
import static api.ItemID.SANFEW_SERUM2;
|
||||
import static api.ItemID.SANFEW_SERUM3;
|
||||
import static api.ItemID.SANFEW_SERUM4;
|
||||
import static api.ItemID.SARADOMIN_BREW1;
|
||||
import static api.ItemID.SARADOMIN_BREW2;
|
||||
import static api.ItemID.SARADOMIN_BREW3;
|
||||
import static api.ItemID.SARADOMIN_BREW4;
|
||||
import static api.ItemID.SARDINE;
|
||||
import static api.ItemID.SEA_TURTLE;
|
||||
import static api.ItemID.SHARK;
|
||||
import static api.ItemID.SHORT_GREEN_GUY;
|
||||
import static api.ItemID.SHRIMPS;
|
||||
import static api.ItemID.SLICED_BANANA;
|
||||
import static api.ItemID.SLICE_OF_CAKE;
|
||||
import static api.ItemID.SPICY_CRUNCHIES;
|
||||
import static api.ItemID.SPICY_SAUCE;
|
||||
import static api.ItemID.SPICY_STEW;
|
||||
import static api.ItemID.SPINACH_ROLL;
|
||||
import static api.ItemID.SPRING_SQIRKJUICE;
|
||||
import static api.ItemID.SQUARE_SANDWICH;
|
||||
import static api.ItemID.STAMINA_POTION1;
|
||||
import static api.ItemID.STAMINA_POTION2;
|
||||
import static api.ItemID.STAMINA_POTION3;
|
||||
import static api.ItemID.STAMINA_POTION4;
|
||||
import static api.ItemID.STEW;
|
||||
import static api.ItemID.STRANGE_FRUIT;
|
||||
import static api.ItemID.STRAWBERRY;
|
||||
import static api.ItemID.STRENGTH_POTION1;
|
||||
import static api.ItemID.STRENGTH_POTION2;
|
||||
import static api.ItemID.STRENGTH_POTION3;
|
||||
import static api.ItemID.STRENGTH_POTION4;
|
||||
import static api.ItemID.STUFFED_SNAKE;
|
||||
import static api.ItemID.SUMMER_PIE;
|
||||
import static api.ItemID.SUMMER_SQIRKJUICE;
|
||||
import static api.ItemID.SUPER_ATTACK1;
|
||||
import static api.ItemID.SUPER_ATTACK2;
|
||||
import static api.ItemID.SUPER_ATTACK3;
|
||||
import static api.ItemID.SUPER_ATTACK4;
|
||||
import static api.ItemID.SUPER_COMBAT_POTION1;
|
||||
import static api.ItemID.SUPER_COMBAT_POTION2;
|
||||
import static api.ItemID.SUPER_COMBAT_POTION3;
|
||||
import static api.ItemID.SUPER_COMBAT_POTION4;
|
||||
import static api.ItemID.SUPER_DEFENCE1;
|
||||
import static api.ItemID.SUPER_DEFENCE2;
|
||||
import static api.ItemID.SUPER_DEFENCE3;
|
||||
import static api.ItemID.SUPER_DEFENCE4;
|
||||
import static api.ItemID.SUPER_ENERGY1;
|
||||
import static api.ItemID.SUPER_ENERGY2;
|
||||
import static api.ItemID.SUPER_ENERGY3;
|
||||
import static api.ItemID.SUPER_ENERGY4;
|
||||
import static api.ItemID.SUPER_MAGIC_POTION_1;
|
||||
import static api.ItemID.SUPER_MAGIC_POTION_2;
|
||||
import static api.ItemID.SUPER_MAGIC_POTION_3;
|
||||
import static api.ItemID.SUPER_MAGIC_POTION_4;
|
||||
import static api.ItemID.SUPER_RANGING_1;
|
||||
import static api.ItemID.SUPER_RANGING_2;
|
||||
import static api.ItemID.SUPER_RANGING_3;
|
||||
import static api.ItemID.SUPER_RANGING_4;
|
||||
import static api.ItemID.SUPER_RESTORE1;
|
||||
import static api.ItemID.SUPER_RESTORE2;
|
||||
import static api.ItemID.SUPER_RESTORE3;
|
||||
import static api.ItemID.SUPER_RESTORE4;
|
||||
import static api.ItemID.SUPER_STRENGTH1;
|
||||
import static api.ItemID.SUPER_STRENGTH2;
|
||||
import static api.ItemID.SUPER_STRENGTH3;
|
||||
import static api.ItemID.SUPER_STRENGTH4;
|
||||
import static api.ItemID.SUPHI_FISH_1;
|
||||
import static api.ItemID.SWEETCORN_7088;
|
||||
import static api.ItemID.SWORDFISH;
|
||||
import static api.ItemID.TANGLED_TOADS_LEGS;
|
||||
import static api.ItemID.THIN_SNAIL_MEAT;
|
||||
import static api.ItemID.TOAD_BATTA;
|
||||
import static api.ItemID.TOAD_CRUNCHIES;
|
||||
import static api.ItemID.TOMATO;
|
||||
import static api.ItemID.TRIANGLE_SANDWICH;
|
||||
import static api.ItemID.TROUT;
|
||||
import static api.ItemID.TUNA;
|
||||
import static api.ItemID.TUNA_AND_CORN;
|
||||
import static api.ItemID.TUNA_POTATO;
|
||||
import static api.ItemID.TWISTED_1;
|
||||
import static api.ItemID.TWISTED_1_20933;
|
||||
import static api.ItemID.TWISTED_2;
|
||||
import static api.ItemID.TWISTED_2_20934;
|
||||
import static api.ItemID.TWISTED_3;
|
||||
import static api.ItemID.TWISTED_3_20935;
|
||||
import static api.ItemID.TWISTED_4;
|
||||
import static api.ItemID.TWISTED_4_20936;
|
||||
import static api.ItemID.TWISTED_POTION_1;
|
||||
import static api.ItemID.TWISTED_POTION_2;
|
||||
import static api.ItemID.TWISTED_POTION_3;
|
||||
import static api.ItemID.TWISTED_POTION_4;
|
||||
import static api.ItemID.UGTHANKI_KEBAB;
|
||||
import static api.ItemID.UGTHANKI_KEBAB_1885;
|
||||
import static api.ItemID.VEGETABLE_BATTA;
|
||||
import static api.ItemID.VEG_BALL;
|
||||
import static api.ItemID.WATERMELON_SLICE;
|
||||
import static api.ItemID.WHITE_TREE_FRUIT;
|
||||
import static api.ItemID.WILD_PIE;
|
||||
import static api.ItemID.WINTER_SQIRKJUICE;
|
||||
import static api.ItemID.WIZARD_BLIZZARD;
|
||||
import static api.ItemID.WORM_BATTA;
|
||||
import static api.ItemID.WORM_CRUNCHIES;
|
||||
import static api.ItemID.WORM_HOLE;
|
||||
import static api.ItemID.XERICS_AID_1_20981;
|
||||
import static api.ItemID.XERICS_AID_2_20982;
|
||||
import static api.ItemID.XERICS_AID_3_20983;
|
||||
import static api.ItemID.XERICS_AID_4_20984;
|
||||
import static api.ItemID.ZAMORAK_BREW1;
|
||||
import static api.ItemID.ZAMORAK_BREW2;
|
||||
import static api.ItemID.ZAMORAK_BREW3;
|
||||
import static api.ItemID.ZAMORAK_BREW4;
|
||||
import static api.ItemID._12_ANCHOVY_PIZZA;
|
||||
import static api.ItemID._12_MEAT_PIZZA;
|
||||
import static api.ItemID._12_PINEAPPLE_PIZZA;
|
||||
import static api.ItemID._12_PLAIN_PIZZA;
|
||||
import static api.ItemID._23_CAKE;
|
||||
import static api.ItemID._23_CHOCOLATE_CAKE;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.boost;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.combo;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.dec;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.food;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.heal;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.perc;
|
||||
import static net.runelite.client.plugins.itemstats.Builders.range;
|
||||
import net.runelite.client.plugins.itemstats.food.Anglerfish;
|
||||
import net.runelite.client.plugins.itemstats.potions.PrayerPotion;
|
||||
import net.runelite.client.plugins.itemstats.potions.SaradominBrew;
|
||||
import net.runelite.client.plugins.itemstats.potions.SuperRestore;
|
||||
import net.runelite.client.plugins.itemstats.special.CastleWarsBandage;
|
||||
import net.runelite.client.plugins.itemstats.special.SpicyStew;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.AGILITY;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.ATTACK;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.CRAFTING;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.DEFENCE;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.FARMING;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.FISHING;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.HERBLORE;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.HITPOINTS;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.HUNTER;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.MAGIC;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.PRAYER;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.RANGED;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.RUN_ENERGY;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.SLAYER;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.STRENGTH;
|
||||
import static net.runelite.client.plugins.itemstats.stats.Stats.THIEVING;
|
||||
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class ItemStatChanges
|
||||
{
|
||||
ItemStatChanges()
|
||||
{
|
||||
init();
|
||||
}
|
||||
|
||||
private void init()
|
||||
{
|
||||
add(food(-5), POISON_KARAMBWAN);
|
||||
add(food(1), POTATO, ONION, CABBAGE, POT_OF_CREAM, CHOPPED_ONION, ANCHOVIES);
|
||||
add(food(2), TOMATO, CHOPPED_TOMATO, BANANA, SLICED_BANANA, ORANGE, ORANGE_SLICES, ORANGE_CHUNKS,
|
||||
PINEAPPLE_RING, PINEAPPLE_CHUNKS, SPICY_SAUCE, CHEESE, SPINACH_ROLL, LEMON, LEMON_CHUNKS, LEMON_SLICES,
|
||||
LIME, LIME_CHUNKS, LIME_SLICES, DWELLBERRIES);
|
||||
add(food(3), SHRIMPS, COOKED_MEAT, COOKED_CHICKEN, ROE, CHOCOLATE_BAR);
|
||||
add(food(4), SARDINE, CAKE, _23_CAKE, SLICE_OF_CAKE, CHOCOLATEY_MILK, BAKED_POTATO, EDIBLE_SEAWEED, MOONLIGHT_MEAD);
|
||||
add(food(5), BREAD, HERRING, CHOCOLATE_CAKE, _23_CHOCOLATE_CAKE, CHOCOLATE_SLICE, COOKED_RABBIT, CHILLI_CON_CARNE,
|
||||
FRIED_MUSHROOMS, FRIED_ONIONS, REDBERRY_PIE, HALF_A_REDBERRY_PIE, CAVIAR, PYSK_FISH_0);
|
||||
add(food(6), CHOCICE, MACKEREL, MEAT_PIE, HALF_A_MEAT_PIE, GUANIC_BAT_0, ROAST_BIRD_MEAT,
|
||||
SQUARE_SANDWICH, ROLL, BAGUETTE, TRIANGLE_SANDWICH, GIANT_CARP);
|
||||
add(food(7), TROUT, COD, PLAIN_PIZZA, _12_PLAIN_PIZZA, APPLE_PIE, HALF_AN_APPLE_PIE, ROAST_RABBIT,
|
||||
PREMADE_CH_CRUNCH, CHOCCHIP_CRUNCHIES, PREMADE_SY_CRUNCH, SPICY_CRUNCHIES);
|
||||
add(food(8), PIKE, ROAST_BEAST_MEAT, MEAT_PIZZA, _12_MEAT_PIZZA, PREMADE_WM_CRUN, WORM_CRUNCHIES, PREMADE_TD_CRUNCH,
|
||||
TOAD_CRUNCHIES, EGG_AND_TOMATO, PRAEL_BAT_1, PEACH, SUPHI_FISH_1);
|
||||
add(food(9), PREMADE_P_PUNCH, PINEAPPLE_PUNCH, PREMADE_FR_BLAST, FRUIT_BLAST, SALMON, ANCHOVY_PIZZA,
|
||||
_12_ANCHOVY_PIZZA);
|
||||
add(food(10), TUNA, COOKED_CRAB_MEAT, CHOPPED_TUNA, COOKED_CHOMPY, FIELD_RATION);
|
||||
add(food(11), RAINBOW_FISH, STEW, PINEAPPLE_PIZZA, _12_PINEAPPLE_PIZZA, COOKED_FISHCAKE,
|
||||
PREMADE_VEG_BATTA, VEGETABLE_BATTA, PREMADE_WM_BATTA, WORM_BATTA, PREMADE_TD_BATTA, TOAD_BATTA, PREMADE_CT_BATTA,
|
||||
CHEESETOM_BATTA, PREMADE_FRT_BATTA, FRUIT_BATTA, MUSHROOM__ONION, GIRAL_BAT_2, LAVA_EEL, LECKISH_FISH_2);
|
||||
add(food(12), LOBSTER, PREMADE_WORM_HOLE, WORM_HOLE, PREMADE_VEG_BALL, VEG_BALL);
|
||||
add(food(13), BASS, TUNA_AND_CORN);
|
||||
add(food(14), POTATO_WITH_BUTTER, CHILLI_POTATO, SWORDFISH, PHLUXIA_BAT_3, PUMPKIN, EASTER_EGG, BRAWK_FISH_3);
|
||||
add(food(15), PREMADE_TTL, TANGLED_TOADS_LEGS, PREMADE_CHOC_BOMB, CHOCOLATE_BOMB, COOKED_JUBBLY);
|
||||
add(food(16), MONKFISH, POTATO_WITH_CHEESE, EGG_POTATO);
|
||||
add(food(17), MYCIL_FISH_4, KRYKET_BAT_4);
|
||||
add(food(18), COOKED_KARAMBWAN);
|
||||
add(food(19), CURRY, UGTHANKI_KEBAB, UGTHANKI_KEBAB_1885);
|
||||
add(food(20), MUSHROOM_POTATO, SHARK, ROQED_FISH_5, MURNG_BAT_5, STUFFED_SNAKE);
|
||||
add(food(21), SEA_TURTLE);
|
||||
add(food(22), MANTA_RAY, DARK_CRAB, TUNA_POTATO);
|
||||
add(food(23), KYREN_FISH_6, PSYKK_BAT_6);
|
||||
add(new Anglerfish(), ANGLERFISH);
|
||||
add(food(maxHP -> (int) Math.ceil(maxHP * .06)), STRAWBERRY);
|
||||
add(food(maxHP -> (int) Math.ceil(maxHP * .05)), WATERMELON_SLICE);
|
||||
add(food(perc(.1, 1)), COOKED_SWEETCORN, SWEETCORN_7088 /* Bowl of cooked sweetcorn */);
|
||||
add(combo(food(1), boost(DEFENCE, perc(.02, 1))), CABBAGE_1967 /* Draynor Manor */);
|
||||
add(combo(2, food(8), heal(RUN_ENERGY, 5)), PAPAYA_FRUIT);
|
||||
add(range(food(5), food(7)), THIN_SNAIL_MEAT);
|
||||
add(range(food(7), food(9)), FAT_SNAIL_MEAT);
|
||||
|
||||
// Dorgeshuun Cuisine
|
||||
add(food(2), BAT_SHISH, COATED_FROGS_LEGS, FILLETS, FINGERS, FROGBURGER, FROGSPAWN_GUMBO, GREEN_GLOOP_SOUP,
|
||||
GRUBS__LA_MODE, MUSHROOMS, ROAST_FROG);
|
||||
add(food(3), LOACH);
|
||||
add(range(food(3), food(6)), FROG_SPAWN);
|
||||
add(range(food(6), food(10)), COOKED_SLIMY_EEL);
|
||||
add(range(food(8), food(12)), CAVE_EEL);
|
||||
add(food(10), EEL_SUSHI);
|
||||
|
||||
// Alcoholic Beverages
|
||||
add(combo(food(11), dec(ATTACK, 2)), JUG_OF_WINE);
|
||||
add(combo(food(14), dec(ATTACK, 3)), BOTTLE_OF_WINE);
|
||||
add(combo(2, food(5), boost(STRENGTH, 6), heal(ATTACK, -4)), PREMADE_WIZ_BLZD, WIZARD_BLIZZARD);
|
||||
add(combo(2, food(5), boost(STRENGTH, 4), heal(ATTACK, -3)), PREMADE_SGG, SHORT_GREEN_GUY);
|
||||
add(combo(2, food(5), boost(STRENGTH, 7), heal(ATTACK, -4)), PREMADE_DR_DRAGON, DRUNK_DRAGON);
|
||||
add(combo(2, food(5), boost(STRENGTH, 7), heal(ATTACK, -4)), PREMADE_CHOC_SDY, CHOC_SATURDAY);
|
||||
|
||||
// Sq'irk Juice
|
||||
add(heal(RUN_ENERGY, 5), WINTER_SQIRKJUICE);
|
||||
add(combo(heal(RUN_ENERGY, 10), boost(THIEVING, 1)), SPRING_SQIRKJUICE);
|
||||
add(combo(heal(RUN_ENERGY, 15), boost(THIEVING, 2)), AUTUMN_SQIRKJUICE);
|
||||
add(combo(heal(RUN_ENERGY, 20), boost(THIEVING, 3)), SUMMER_SQIRKJUICE);
|
||||
|
||||
// Combat potions
|
||||
add(boost(ATTACK, perc(.10, 3)), ATTACK_POTION1, ATTACK_POTION2, ATTACK_POTION3, ATTACK_POTION4);
|
||||
add(boost(STRENGTH, perc(.10, 3)), STRENGTH_POTION1, STRENGTH_POTION2, STRENGTH_POTION3, STRENGTH_POTION4);
|
||||
add(boost(DEFENCE, perc(.10, 3)), DEFENCE_POTION1, DEFENCE_POTION2, DEFENCE_POTION3, DEFENCE_POTION4);
|
||||
add(boost(MAGIC, 4), MAGIC_POTION1, MAGIC_POTION2, MAGIC_POTION3, MAGIC_POTION4);
|
||||
add(boost(RANGED, perc(.10, 4)), RANGING_POTION1, RANGING_POTION2, RANGING_POTION3, RANGING_POTION4);
|
||||
add(combo(2, boost(ATTACK, perc(.10, 3)), boost(STRENGTH, perc(.10, 3))), COMBAT_POTION1, COMBAT_POTION2, COMBAT_POTION3, COMBAT_POTION4);
|
||||
add(boost(ATTACK, perc(.15, 5)), SUPER_ATTACK1, SUPER_ATTACK2, SUPER_ATTACK3, SUPER_ATTACK4);
|
||||
add(boost(STRENGTH, perc(.15, 5)), SUPER_STRENGTH1, SUPER_STRENGTH2, SUPER_STRENGTH3, SUPER_STRENGTH4);
|
||||
add(boost(DEFENCE, perc(.15, 5)), SUPER_DEFENCE1, SUPER_DEFENCE2, SUPER_DEFENCE3, SUPER_DEFENCE4);
|
||||
add(boost(MAGIC, 3), MAGIC_ESSENCE1, MAGIC_ESSENCE2, MAGIC_ESSENCE3, MAGIC_ESSENCE4);
|
||||
add(combo(3, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5))), SUPER_COMBAT_POTION1, SUPER_COMBAT_POTION2, SUPER_COMBAT_POTION3, SUPER_COMBAT_POTION4);
|
||||
add(combo(3, boost(ATTACK, perc(.20, 2)), boost(STRENGTH, perc(.12, 2)), heal(PRAYER, perc(.10, 0)), heal(DEFENCE, perc(.10, -2)), new BoostedStatBoost(HITPOINTS, false, perc(-.12, 0))), ZAMORAK_BREW1, ZAMORAK_BREW2, ZAMORAK_BREW3, ZAMORAK_BREW4);
|
||||
add(new SaradominBrew(0.15, 0.2, 0.1, 2, 2), SARADOMIN_BREW1, SARADOMIN_BREW2, SARADOMIN_BREW3, SARADOMIN_BREW4);
|
||||
add(boost(RANGED, perc(.15, 5)), SUPER_RANGING_1, SUPER_RANGING_2, SUPER_RANGING_3, SUPER_RANGING_4);
|
||||
add(boost(MAGIC, perc(.15, 5)), SUPER_MAGIC_POTION_1, SUPER_MAGIC_POTION_2, SUPER_MAGIC_POTION_3, SUPER_MAGIC_POTION_4);
|
||||
add(combo(2, boost(RANGED, perc(0.1, 4)), boost(DEFENCE, perc(0.15, 5))), BASTION_POTION1, BASTION_POTION2, BASTION_POTION3, BASTION_POTION4);
|
||||
add(combo(2, boost(MAGIC, 4), boost(DEFENCE, perc(0.15, 5))), BATTLEMAGE_POTION1, BATTLEMAGE_POTION2, BATTLEMAGE_POTION3, BATTLEMAGE_POTION4);
|
||||
|
||||
// Regular overload (NMZ)
|
||||
add(combo(5, boost(ATTACK, perc(.15, 5)), boost(STRENGTH, perc(.15, 5)), boost(DEFENCE, perc(.15, 5)), boost(RANGED, perc(.15, 5)), boost(MAGIC, perc(.15, 5)), heal(HITPOINTS, -50)), OVERLOAD_1, OVERLOAD_2, OVERLOAD_3, OVERLOAD_4);
|
||||
|
||||
// Bandages (Castle Wars)
|
||||
add(new CastleWarsBandage(), BANDAGES);
|
||||
|
||||
// Recovery potions
|
||||
add(combo(5, heal(ATTACK, perc(.30, 10)), heal(STRENGTH, perc(.30, 10)), heal(DEFENCE, perc(.30, 10)), heal(RANGED, perc(.30, 10)), heal(MAGIC, perc(.30, 10))), RESTORE_POTION1, RESTORE_POTION2, RESTORE_POTION3, RESTORE_POTION4);
|
||||
add(heal(RUN_ENERGY, 10), ENERGY_POTION1, ENERGY_POTION2, ENERGY_POTION3, ENERGY_POTION4);
|
||||
add(new PrayerPotion(7), PRAYER_POTION1, PRAYER_POTION2, PRAYER_POTION3, PRAYER_POTION4);
|
||||
add(heal(RUN_ENERGY, 20), SUPER_ENERGY1, SUPER_ENERGY2, SUPER_ENERGY3, SUPER_ENERGY4);
|
||||
add(new SuperRestore(.25, 8), SUPER_RESTORE1, SUPER_RESTORE2, SUPER_RESTORE3, SUPER_RESTORE4);
|
||||
add(new SuperRestore(.25, 9), SANFEW_SERUM1, SANFEW_SERUM2, SANFEW_SERUM3, SANFEW_SERUM4);
|
||||
add(heal(RUN_ENERGY, 20), STAMINA_POTION1, STAMINA_POTION2, STAMINA_POTION3, STAMINA_POTION4);
|
||||
|
||||
// Raids potions (+)
|
||||
add(combo(5, boost(ATTACK, perc(.16, 6)), boost(STRENGTH, perc(.16, 6)), boost(DEFENCE, perc(.16, 6)), boost(RANGED, perc(.16, 6)), boost(MAGIC, perc(.16, 6)), heal(HITPOINTS, -50)), OVERLOAD_1_20993, OVERLOAD_2_20994, OVERLOAD_3_20995, OVERLOAD_4_20996);
|
||||
add(combo(3, boost(ATTACK, perc(.16, 6)), boost(STRENGTH, perc(.16, 6)), boost(DEFENCE, perc(.16, 6))), ELDER_1_20921, ELDER_2_20922, ELDER_3_20923, ELDER_4_20924);
|
||||
add(combo(2, boost(RANGED, perc(.16, 6)), boost(DEFENCE, perc(.16, 6))), TWISTED_1_20933, TWISTED_2_20934, TWISTED_3_20935, TWISTED_4_20936);
|
||||
add(combo(2, boost(MAGIC, perc(.16, 6)), boost(DEFENCE, perc(.16, 6))), KODAI_1_20945, KODAI_2_20946, KODAI_3_20947, KODAI_4_20948);
|
||||
add(new SuperRestore(.30, 11), REVITALISATION_1_20957, REVITALISATION_2_20958, REVITALISATION_3_20959, REVITALISATION_4_20960);
|
||||
add(new SaradominBrew(0.15, 0.2, 0.1, 5, 4), XERICS_AID_1_20981, XERICS_AID_2_20982, XERICS_AID_3_20983, XERICS_AID_4_20984);
|
||||
|
||||
// Raids potions
|
||||
add(combo(5, boost(ATTACK, perc(.13, 5)), boost(STRENGTH, perc(.13, 5)), boost(DEFENCE, perc(.13, 5)), boost(RANGED, perc(.13, 5)), boost(MAGIC, perc(.13, 5)), heal(HITPOINTS, -50)), OVERLOAD_1_20989, OVERLOAD_2_20990, OVERLOAD_3_20991, OVERLOAD_4_20992);
|
||||
add(combo(3, boost(ATTACK, perc(.13, 5)), boost(STRENGTH, perc(.13, 5)), boost(DEFENCE, perc(.13, 5))), ELDER_POTION_1, ELDER_POTION_2, ELDER_POTION_3, ELDER_POTION_4);
|
||||
add(combo(2, boost(RANGED, perc(.13, 5)), boost(DEFENCE, perc(.13, 5))), TWISTED_POTION_1, TWISTED_POTION_2, TWISTED_POTION_3, TWISTED_POTION_4);
|
||||
add(combo(2, boost(MAGIC, perc(.13, 5)), boost(DEFENCE, perc(.13, 5))), KODAI_POTION_1, KODAI_POTION_2, KODAI_POTION_3, KODAI_POTION_4);
|
||||
|
||||
// Raids potions (-)
|
||||
add(combo(5, boost(ATTACK, perc(.10, 4)), boost(STRENGTH, perc(.10, 4)), boost(DEFENCE, perc(.10, 4)), boost(RANGED, perc(.10, 4)), boost(MAGIC, perc(.10, 4)), heal(HITPOINTS, -50)), OVERLOAD_1_20985, OVERLOAD_2_20986, OVERLOAD_3_20987, OVERLOAD_4_20988);
|
||||
add(combo(3, boost(ATTACK, perc(.10, 4)), boost(STRENGTH, perc(.10, 4)), boost(DEFENCE, perc(.10, 4))), ELDER_1, ELDER_2, ELDER_3, ELDER_4);
|
||||
add(combo(3, boost(RANGED, perc(.10, 4)), boost(DEFENCE, perc(.10, 4))), TWISTED_1, TWISTED_2, TWISTED_3, TWISTED_4);
|
||||
add(combo(3, boost(MAGIC, perc(.10, 4)), boost(DEFENCE, perc(.10, 4))), KODAI_1, KODAI_2, KODAI_3, KODAI_4);
|
||||
|
||||
// Skill potions
|
||||
add(boost(AGILITY, 3), AGILITY_POTION1, AGILITY_POTION2, AGILITY_POTION3, AGILITY_POTION4);
|
||||
add(boost(FISHING, 3), FISHING_POTION1, FISHING_POTION2, FISHING_POTION3, FISHING_POTION4);
|
||||
add(boost(HUNTER, 3), HUNTER_POTION1, HUNTER_POTION2, HUNTER_POTION3, HUNTER_POTION4);
|
||||
add(combo(2, boost(HITPOINTS, 5), heal(RUN_ENERGY, 5)), GUTHIX_REST1, GUTHIX_REST2, GUTHIX_REST3, GUTHIX_REST4);
|
||||
|
||||
// Misc/run energy
|
||||
add(heal(RUN_ENERGY, 10), WHITE_TREE_FRUIT);
|
||||
add(heal(RUN_ENERGY, 30), STRANGE_FRUIT);
|
||||
add(heal(RUN_ENERGY, 50), MINT_CAKE);
|
||||
add(combo(food(12), heal(RUN_ENERGY, 50)), GOUT_TUBER);
|
||||
|
||||
// Pies
|
||||
add(combo(2, heal(HITPOINTS, 6), boost(FARMING, 3)), GARDEN_PIE, HALF_A_GARDEN_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 6), boost(FISHING, 3)), FISH_PIE, HALF_A_FISH_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 7), boost(HERBLORE, 4)), BOTANICAL_PIE, HALF_A_BOTANICAL_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 8), boost(CRAFTING, 4)), MUSHROOM_PIE, HALF_A_MUSHROOM_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 8), boost(FISHING, 5)), ADMIRAL_PIE, HALF_AN_ADMIRAL_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 11), boost(SLAYER, 5), boost(RANGED, 4)), WILD_PIE, HALF_A_WILD_PIE);
|
||||
add(combo(2, heal(HITPOINTS, 11), boost(AGILITY, 5), heal(RUN_ENERGY, 10)), SUMMER_PIE, HALF_A_SUMMER_PIE);
|
||||
|
||||
// Other
|
||||
add(combo(range(food(1), food(3)), heal(RUN_ENERGY, 10)), PURPLE_SWEETS_10476);
|
||||
add(new SpicyStew(), SPICY_STEW);
|
||||
add(boost(MAGIC, perc(.10, 1)), IMBUED_HEART);
|
||||
add(combo(boost(ATTACK, 2), boost(STRENGTH, 1), heal(DEFENCE, -1)), JANGERBERRIES);
|
||||
|
||||
log.debug("{} items; {} behaviours loaded", effects.size(), new HashSet<>(effects.values()).size());
|
||||
}
|
||||
|
||||
private final Map<Integer, Effect> effects = new HashMap<>();
|
||||
|
||||
private void add(Effect effect, int... items)
|
||||
{
|
||||
assert items.length > 0;
|
||||
for (int item : items)
|
||||
{
|
||||
Effect prev = effects.put(item, effect);
|
||||
assert prev == null : "Item already added";
|
||||
}
|
||||
}
|
||||
|
||||
public Effect get(int id)
|
||||
{
|
||||
return effects.get(id);
|
||||
}
|
||||
}
|
||||
@@ -1,221 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.keptondeath;
|
||||
|
||||
import java.util.HashSet;
|
||||
import static api.ItemID.ADAMANT_FIRE_ARROWS;
|
||||
import static api.ItemID.ADAMANT_FIRE_ARROWS_2539;
|
||||
import static api.ItemID.AIR_RUNE_PACK;
|
||||
import static api.ItemID.AMETHYST_FIRE_ARROWS;
|
||||
import static api.ItemID.AMETHYST_FIRE_ARROWS_21330;
|
||||
import static api.ItemID.AMULET_OF_GLORY1;
|
||||
import static api.ItemID.AMULET_OF_GLORY2;
|
||||
import static api.ItemID.AMULET_OF_GLORY3;
|
||||
import static api.ItemID.AMULET_OF_GLORY5;
|
||||
import static api.ItemID.AMULET_OF_GLORY_T1;
|
||||
import static api.ItemID.AMULET_OF_GLORY_T2;
|
||||
import static api.ItemID.AMULET_OF_GLORY_T3;
|
||||
import static api.ItemID.AMULET_OF_GLORY_T5;
|
||||
import static api.ItemID.APPLES1;
|
||||
import static api.ItemID.APPLES2;
|
||||
import static api.ItemID.APPLES3;
|
||||
import static api.ItemID.APPLES4;
|
||||
import static api.ItemID.BANANAS1;
|
||||
import static api.ItemID.BANANAS2;
|
||||
import static api.ItemID.BANANAS3;
|
||||
import static api.ItemID.BANANAS4;
|
||||
import static api.ItemID.BASKET_PACK;
|
||||
import static api.ItemID.BLACK_MASK_1;
|
||||
import static api.ItemID.BLACK_MASK_2;
|
||||
import static api.ItemID.BLACK_MASK_3;
|
||||
import static api.ItemID.BLACK_MASK_4;
|
||||
import static api.ItemID.BLACK_MASK_5;
|
||||
import static api.ItemID.BLACK_MASK_6;
|
||||
import static api.ItemID.BLACK_MASK_7;
|
||||
import static api.ItemID.BLACK_MASK_8;
|
||||
import static api.ItemID.BLACK_MASK_9;
|
||||
import static api.ItemID.BLACK_SATCHEL;
|
||||
import static api.ItemID.BRONZE_FIRE_ARROWS;
|
||||
import static api.ItemID.BRONZE_FIRE_ARROWS_942;
|
||||
import static api.ItemID.BURNING_AMULET1;
|
||||
import static api.ItemID.BURNING_AMULET2;
|
||||
import static api.ItemID.BURNING_AMULET3;
|
||||
import static api.ItemID.BURNING_AMULET4;
|
||||
import static api.ItemID.CAKE;
|
||||
import static api.ItemID.CHAOS_RUNE_PACK;
|
||||
import static api.ItemID.CHOCOLATE_CAKE;
|
||||
import static api.ItemID.CHOCOLATE_SLICE;
|
||||
import static api.ItemID.COMBAT_BRACELET1;
|
||||
import static api.ItemID.COMBAT_BRACELET2;
|
||||
import static api.ItemID.COMBAT_BRACELET3;
|
||||
import static api.ItemID.COMBAT_BRACELET5;
|
||||
import static api.ItemID.DRAGON_FIRE_ARROWS;
|
||||
import static api.ItemID.DRAGON_FIRE_ARROWS_11222;
|
||||
import static api.ItemID.EARTH_RUNE_PACK;
|
||||
import static api.ItemID.FEATHER_PACK;
|
||||
import static api.ItemID.FIRE_RUNE_PACK;
|
||||
import static api.ItemID.GAMES_NECKLACE1;
|
||||
import static api.ItemID.GAMES_NECKLACE2;
|
||||
import static api.ItemID.GAMES_NECKLACE3;
|
||||
import static api.ItemID.GAMES_NECKLACE4;
|
||||
import static api.ItemID.GAMES_NECKLACE5;
|
||||
import static api.ItemID.GAMES_NECKLACE6;
|
||||
import static api.ItemID.GAMES_NECKLACE7;
|
||||
import static api.ItemID.GOLD_SATCHEL;
|
||||
import static api.ItemID.GREEN_SATCHEL;
|
||||
import static api.ItemID.HALF_AN_ADMIRAL_PIE;
|
||||
import static api.ItemID.HALF_AN_APPLE_PIE;
|
||||
import static api.ItemID.HALF_A_BOTANICAL_PIE;
|
||||
import static api.ItemID.HALF_A_FISH_PIE;
|
||||
import static api.ItemID.HALF_A_GARDEN_PIE;
|
||||
import static api.ItemID.HALF_A_MEAT_PIE;
|
||||
import static api.ItemID.HALF_A_MUSHROOM_PIE;
|
||||
import static api.ItemID.HALF_A_REDBERRY_PIE;
|
||||
import static api.ItemID.HALF_A_SUMMER_PIE;
|
||||
import static api.ItemID.HALF_A_WILD_PIE;
|
||||
import static api.ItemID.IRON_FIRE_ARROWS;
|
||||
import static api.ItemID.IRON_FIRE_ARROWS_2533;
|
||||
import static api.ItemID.MIND_RUNE_PACK;
|
||||
import static api.ItemID.MITHRIL_FIRE_ARROWS;
|
||||
import static api.ItemID.MITHRIL_FIRE_ARROWS_2537;
|
||||
import static api.ItemID.NECKLACE_OF_PASSAGE1;
|
||||
import static api.ItemID.NECKLACE_OF_PASSAGE2;
|
||||
import static api.ItemID.NECKLACE_OF_PASSAGE3;
|
||||
import static api.ItemID.NECKLACE_OF_PASSAGE4;
|
||||
import static api.ItemID.ORANGES1;
|
||||
import static api.ItemID.ORANGES2;
|
||||
import static api.ItemID.ORANGES3;
|
||||
import static api.ItemID.ORANGES4;
|
||||
import static api.ItemID.PLAIN_SATCHEL;
|
||||
import static api.ItemID.PLANT_POT_PACK;
|
||||
import static api.ItemID.RED_SATCHEL;
|
||||
import static api.ItemID.RING_OF_DUELING1;
|
||||
import static api.ItemID.RING_OF_DUELING2;
|
||||
import static api.ItemID.RING_OF_DUELING3;
|
||||
import static api.ItemID.RING_OF_DUELING4;
|
||||
import static api.ItemID.RING_OF_DUELING5;
|
||||
import static api.ItemID.RING_OF_DUELING6;
|
||||
import static api.ItemID.RING_OF_DUELING7;
|
||||
import static api.ItemID.RING_OF_WEALTH_1;
|
||||
import static api.ItemID.RING_OF_WEALTH_2;
|
||||
import static api.ItemID.RING_OF_WEALTH_3;
|
||||
import static api.ItemID.RING_OF_WEALTH_4;
|
||||
import static api.ItemID.RING_OF_WEALTH_I;
|
||||
import static api.ItemID.RING_OF_WEALTH_I1;
|
||||
import static api.ItemID.RING_OF_WEALTH_I2;
|
||||
import static api.ItemID.RING_OF_WEALTH_I3;
|
||||
import static api.ItemID.RING_OF_WEALTH_I4;
|
||||
import static api.ItemID.RING_OF_WEALTH_I5;
|
||||
import static api.ItemID.RUNE_FIRE_ARROWS;
|
||||
import static api.ItemID.RUNE_FIRE_ARROWS_2541;
|
||||
import static api.ItemID.RUNE_SATCHEL;
|
||||
import static api.ItemID.SACK_PACK;
|
||||
import static api.ItemID.SKILLS_NECKLACE1;
|
||||
import static api.ItemID.SKILLS_NECKLACE2;
|
||||
import static api.ItemID.SKILLS_NECKLACE3;
|
||||
import static api.ItemID.SKILLS_NECKLACE5;
|
||||
import static api.ItemID.SLICE_OF_CAKE;
|
||||
import static api.ItemID.STEEL_FIRE_ARROWS;
|
||||
import static api.ItemID.STEEL_FIRE_ARROWS_2535;
|
||||
import static api.ItemID.STRAWBERRIES1;
|
||||
import static api.ItemID.STRAWBERRIES2;
|
||||
import static api.ItemID.STRAWBERRIES3;
|
||||
import static api.ItemID.STRAWBERRIES4;
|
||||
import static api.ItemID.TOMATOES1;
|
||||
import static api.ItemID.TOMATOES2;
|
||||
import static api.ItemID.TOMATOES3;
|
||||
import static api.ItemID.TOMATOES4;
|
||||
import static api.ItemID.TZHAAR_AIR_RUNE_PACK;
|
||||
import static api.ItemID.TZHAAR_EARTH_RUNE_PACK;
|
||||
import static api.ItemID.TZHAAR_FIRE_RUNE_PACK;
|
||||
import static api.ItemID.TZHAAR_WATER_RUNE_PACK;
|
||||
import static api.ItemID.UNFINISHED_BROAD_BOLT_PACK;
|
||||
import static api.ItemID.WATER_RUNE_PACK;
|
||||
import static api.ItemID._12_ANCHOVY_PIZZA;
|
||||
import static api.ItemID._12_MEAT_PIZZA;
|
||||
import static api.ItemID._12_PINEAPPLE_PIZZA;
|
||||
import static api.ItemID._12_PLAIN_PIZZA;
|
||||
import static api.ItemID._23_CAKE;
|
||||
import static api.ItemID._23_CHOCOLATE_CAKE;
|
||||
|
||||
/**
|
||||
* Certain items aren't tradeable via the GE but can be traded between players.
|
||||
* The {@link api.ItemDefinition}'s `isTradeable` value is based on GE trade-ability so we need
|
||||
* to account for these items. These items should only be kept if protected based on item value.
|
||||
*/
|
||||
public enum ActuallyTradeableItem
|
||||
{
|
||||
// Item Packs
|
||||
RUNE_PACKS(AIR_RUNE_PACK, WATER_RUNE_PACK, EARTH_RUNE_PACK, FIRE_RUNE_PACK, CHAOS_RUNE_PACK, MIND_RUNE_PACK),
|
||||
TZHAAR_PACKS(TZHAAR_AIR_RUNE_PACK, TZHAAR_WATER_RUNE_PACK, TZHAAR_EARTH_RUNE_PACK, TZHAAR_FIRE_RUNE_PACK),
|
||||
OTHER_PACKS(BASKET_PACK, FEATHER_PACK, PLANT_POT_PACK, SACK_PACK, UNFINISHED_BROAD_BOLT_PACK),
|
||||
// Equipment
|
||||
BLACK_MASK(BLACK_MASK_1, BLACK_MASK_2, BLACK_MASK_3, BLACK_MASK_4, BLACK_MASK_5, BLACK_MASK_6, BLACK_MASK_7, BLACK_MASK_8, BLACK_MASK_9),
|
||||
SATCHELS(BLACK_SATCHEL, GOLD_SATCHEL, GREEN_SATCHEL, PLAIN_SATCHEL, RED_SATCHEL, RUNE_SATCHEL),
|
||||
FIRE_ARROWS(BRONZE_FIRE_ARROWS, IRON_FIRE_ARROWS, STEEL_FIRE_ARROWS, MITHRIL_FIRE_ARROWS, ADAMANT_FIRE_ARROWS, RUNE_FIRE_ARROWS, AMETHYST_FIRE_ARROWS, DRAGON_FIRE_ARROWS),
|
||||
FIRE_ARROWS_2(BRONZE_FIRE_ARROWS_942, IRON_FIRE_ARROWS_2533, STEEL_FIRE_ARROWS_2535, MITHRIL_FIRE_ARROWS_2537, ADAMANT_FIRE_ARROWS_2539, RUNE_FIRE_ARROWS_2541, AMETHYST_FIRE_ARROWS_21330, DRAGON_FIRE_ARROWS_11222),
|
||||
// Food Items
|
||||
HALF_A(HALF_A_GARDEN_PIE, HALF_A_MEAT_PIE, HALF_A_MUSHROOM_PIE, HALF_A_REDBERRY_PIE, HALF_A_BOTANICAL_PIE, HALF_A_FISH_PIE, HALF_A_SUMMER_PIE, HALF_A_WILD_PIE, HALF_AN_ADMIRAL_PIE, HALF_AN_APPLE_PIE),
|
||||
PIZZA(_12_ANCHOVY_PIZZA, _12_MEAT_PIZZA, _12_PINEAPPLE_PIZZA, _12_PLAIN_PIZZA),
|
||||
CAKES(CAKE, _23_CAKE, SLICE_OF_CAKE, CHOCOLATE_CAKE, _23_CHOCOLATE_CAKE, CHOCOLATE_SLICE),
|
||||
BASKETS(APPLES1, APPLES2, APPLES3, APPLES4, BANANAS1, BANANAS2, BANANAS3, BANANAS4, ORANGES1, ORANGES2, ORANGES3, ORANGES4, STRAWBERRIES1, STRAWBERRIES2, STRAWBERRIES3, STRAWBERRIES4, TOMATOES1, TOMATOES2, TOMATOES3, TOMATOES4),
|
||||
// Charged Jewelery
|
||||
BURNING_AMULET(BURNING_AMULET1, BURNING_AMULET2, BURNING_AMULET3, BURNING_AMULET4),
|
||||
NECKLACE_OF_PASSAGE(NECKLACE_OF_PASSAGE1, NECKLACE_OF_PASSAGE2, NECKLACE_OF_PASSAGE3, NECKLACE_OF_PASSAGE4),
|
||||
RING_OF_DUELING(RING_OF_DUELING1, RING_OF_DUELING2, RING_OF_DUELING3, RING_OF_DUELING4, RING_OF_DUELING5, RING_OF_DUELING6, RING_OF_DUELING7),
|
||||
GAMES_NECKLACE(GAMES_NECKLACE1, GAMES_NECKLACE2, GAMES_NECKLACE3, GAMES_NECKLACE4, GAMES_NECKLACE5, GAMES_NECKLACE6, GAMES_NECKLACE7),
|
||||
COMBAT_BRACELET(COMBAT_BRACELET1, COMBAT_BRACELET2, COMBAT_BRACELET3, COMBAT_BRACELET5),
|
||||
RING_OF_WEALTH(RING_OF_WEALTH_I, RING_OF_WEALTH_1, RING_OF_WEALTH_I1, RING_OF_WEALTH_2, RING_OF_WEALTH_I2, RING_OF_WEALTH_3, RING_OF_WEALTH_I3, RING_OF_WEALTH_4, RING_OF_WEALTH_I4, RING_OF_WEALTH_I5),
|
||||
AMULET_OF_GLORY(AMULET_OF_GLORY1, AMULET_OF_GLORY2, AMULET_OF_GLORY3, AMULET_OF_GLORY5),
|
||||
AMULET_OF_GLORY_T(AMULET_OF_GLORY_T1, AMULET_OF_GLORY_T2, AMULET_OF_GLORY_T3, AMULET_OF_GLORY_T5),
|
||||
SKILLS_NECKLACE(SKILLS_NECKLACE1, SKILLS_NECKLACE2, SKILLS_NECKLACE3, SKILLS_NECKLACE5),
|
||||
;
|
||||
|
||||
private final int[] ids;
|
||||
|
||||
private static final HashSet<Integer> ID_SET;
|
||||
|
||||
static
|
||||
{
|
||||
ID_SET = new HashSet<>();
|
||||
for (ActuallyTradeableItem p : values())
|
||||
{
|
||||
for (int id : p.ids)
|
||||
{
|
||||
ID_SET.add(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ActuallyTradeableItem(int... ids)
|
||||
{
|
||||
this.ids = ids;
|
||||
}
|
||||
|
||||
public static Boolean check(int id)
|
||||
{
|
||||
return ID_SET.contains(id);
|
||||
}
|
||||
}
|
||||
@@ -1,591 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, TheStonedTurtle <https://github.com/TheStonedTurtle>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.keptondeath;
|
||||
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Kept on Death",
|
||||
description = "Reworks the Items Kept on Death interface to be more accurate",
|
||||
enabledByDefault = false,
|
||||
type = PluginType.UTILITY
|
||||
)
|
||||
@Slf4j
|
||||
public class KeptOnDeathPlugin extends Plugin
|
||||
{
|
||||
}
|
||||
//todo once bytecodes work again, re-enable
|
||||
/*
|
||||
{
|
||||
// Handles Clicking on items in Kept on Death Interface
|
||||
private static final int SCRIPT_ID = ScriptID.KEPT_LOST_ITEM_EXAMINE;
|
||||
private static final double HIGH_ALCH = 0.6;
|
||||
|
||||
// Item Container helpers
|
||||
private static final int MAX_ROW_ITEMS = 8;
|
||||
private static final int STARTING_X = 5;
|
||||
private static final int STARTING_Y = 25;
|
||||
private static final int X_INCREMENT = 40;
|
||||
private static final int Y_INCREMENT = 38;
|
||||
private static final int ORIGINAL_WIDTH = 36;
|
||||
private static final int ORIGINAL_HEIGHT = 32;
|
||||
private static final int ORIGINAL_LOST_HEIGHT = 209;
|
||||
private static final int ORIGINAL_LOST_Y = 107;
|
||||
|
||||
// Information panel text helpers
|
||||
private static final DecimalFormat NUMBER_FORMAT = new DecimalFormat("#,###");
|
||||
private static final String MAX_KEPT_ITEMS_FORMAT = "<col=ffcc33>Max items kept on death :<br><br><col=ffcc33>~ %s ~";
|
||||
private static final String ACTION_TEXT = "Item: <col=ff981f>%s";
|
||||
private static final String DEFAULT = "<col=FFFFFF>3<col=FF981F> items protected by default";
|
||||
private static final String IS_SKULLED = "<col=ff3333>PK skull<col=ff981f> -3";
|
||||
private static final String PROTECTING_ITEM = "<col=ff3333>Protect Item prayer<col=ff981f> +1";
|
||||
private static final String ACTUAL = "Actually protecting <col=FFFFFF>%s<col=FF981F> items";
|
||||
private static final String WHITE_OUTLINE = "Items with a <col=ffffff>white outline<col=ff981f> will always be lost.";
|
||||
private static final String CHANGED_MECHANICS = "Untradeable items are kept on death in non-pvp scenarios.";
|
||||
private static final String NON_PVP = "You will have 1 hour to retrieve your lost items.";
|
||||
private static final String LINE_BREAK = "<br>";
|
||||
private static final String UIM_DEFAULT = "You are an <col=FFFFFF>UIM<col=FF981F> which means <col=FFFFFF>0<col=FF981F> items are protected by default";
|
||||
private static final int ORIGINAL_INFO_HEIGHT = 183;
|
||||
private static final int FONT_COLOR = 0xFF981F;
|
||||
|
||||
// Button Names and Images
|
||||
private static final String PROTECT_ITEM_BUTTON_NAME = "Protect Item Prayer";
|
||||
private static final String SKULLED_BUTTON_NAME = "Skulled";
|
||||
private static final String LOW_WILDY_BUTTON_NAME = "Low Wildy (1-20)";
|
||||
private static final String DEEP_WILDY_BUTTON_NAME = "Deep Wildy (21+)";
|
||||
private static final int PROTECT_ITEM_SPRITE_ID = SpriteID.PRAYER_PROTECT_ITEM;
|
||||
private static final int SKULL_SPRITE_ID = SpriteID.PLAYER_KILLER_SKULL_523;
|
||||
private static final int SWORD_SPRITE_ID = SpriteID.MULTI_COMBAT_ZONE_CROSSED_SWORDS;
|
||||
private static final int SKULL_2_SPRITE_ID = SpriteID.FIGHT_PITS_WINNER_SKULL_RED;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ItemManager itemManager;
|
||||
|
||||
@Getter
|
||||
private boolean widgetVisible = false;
|
||||
|
||||
private LinkedHashMap<String, WidgetButton> buttonMap = new LinkedHashMap<>();
|
||||
private boolean isSkulled = false;
|
||||
private boolean protectingItem = false;
|
||||
private boolean hasAlwaysLost = false;
|
||||
private int wildyLevel = -1;
|
||||
|
||||
@Subscribe
|
||||
protected void onScriptCallbackEvent(ScriptCallbackEvent event)
|
||||
{
|
||||
if (event.getEventName().equals("deathKeepBuild"))
|
||||
{
|
||||
// The script in charge of building the Items Kept on Death interface has finished running.
|
||||
// Make all necessary changes now.
|
||||
|
||||
// Players inside Safe Areas (POH/Clan Wars) & playing DMM see the default interface
|
||||
if (isInSafeArea() || client.getWorldType().contains(WorldType.DEADMAN))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
syncSettings();
|
||||
createWidgetButtons();
|
||||
recreateItemsKeptOnDeathWidget();
|
||||
}
|
||||
}
|
||||
|
||||
// Sync user settings
|
||||
private void syncSettings()
|
||||
{
|
||||
SkullIcon s = client.getLocalPlayer().getSkullIcon();
|
||||
// Ultimate iron men deaths are treated like they are always skulled
|
||||
isSkulled = (s != null && s.equals(SkullIcon.SKULL)) || isUltimateIronman();
|
||||
protectingItem = client.getVar(Varbits.PRAYER_PROTECT_ITEM) == 1;
|
||||
syncCurrentWildyLevel();
|
||||
}
|
||||
|
||||
private void syncCurrentWildyLevel()
|
||||
{
|
||||
if (client.getVar(Varbits.IN_WILDERNESS) != 1)
|
||||
{
|
||||
// if they are in a PvP world and not in a safe zone act like in lvl 1 wildy
|
||||
if (isInPvpWorld() && !isInPvPSafeZone())
|
||||
{
|
||||
wildyLevel = 1;
|
||||
return;
|
||||
}
|
||||
wildyLevel = -1;
|
||||
return;
|
||||
}
|
||||
|
||||
int y = client.getLocalPlayer().getWorldLocation().getY();
|
||||
|
||||
// Credits to atomicint_#5069 (Discord)
|
||||
int underLevel = ((y - 9920) / 8) + 1;
|
||||
int upperLevel = ((y - 3520) / 8) + 1;
|
||||
wildyLevel = (y > 6400 ? underLevel : upperLevel);
|
||||
}
|
||||
|
||||
private boolean isInPvpWorld()
|
||||
{
|
||||
EnumSet<WorldType> world = client.getWorldType();
|
||||
return world.contains(WorldType.PVP) || world.contains(WorldType.HIGH_RISK);
|
||||
}
|
||||
|
||||
private boolean isInPvPSafeZone()
|
||||
{
|
||||
Widget w = client.getWidget(WidgetInfo.PVP_WORLD_SAFE_ZONE);
|
||||
return w != null && !w.isHidden();
|
||||
}
|
||||
|
||||
private boolean isInSafeArea()
|
||||
{
|
||||
Widget w = client.getWidget(WidgetInfo.ITEMS_KEPT_SAFE_ZONE_CONTAINER);
|
||||
return w != null && !w.isHidden();
|
||||
}
|
||||
|
||||
private boolean isUltimateIronman()
|
||||
{
|
||||
return client.getAccountType().equals(AccountType.ULTIMATE_IRONMAN);
|
||||
}
|
||||
|
||||
private int getDefaultItemsKept()
|
||||
{
|
||||
int count = isSkulled ? 0 : 3;
|
||||
|
||||
if (protectingItem)
|
||||
{
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
private void recreateItemsKeptOnDeathWidget()
|
||||
{
|
||||
// Text flags based on items should be reset everytime the widget is recreated
|
||||
hasAlwaysLost = false;
|
||||
|
||||
Widget lost = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_CONTAINER);
|
||||
Widget kept = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_CONTAINER);
|
||||
if (lost != null && kept != null)
|
||||
{
|
||||
// Grab all items on player and sort by price.
|
||||
List<Item> items = new ArrayList<>();
|
||||
ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
|
||||
Item[] inv = inventory == null ? new Item[0] : inventory.getItems();
|
||||
ItemContainer equipment = client.getItemContainer(InventoryID.EQUIPMENT);
|
||||
Item[] equip = equipment == null ? new Item[0] : equipment.getItems();
|
||||
Collections.addAll(items, inv);
|
||||
Collections.addAll(items, equip);
|
||||
// Sort by item price
|
||||
items.sort((o1, o2) ->
|
||||
{
|
||||
int o1ID = ItemVariationMapping.map(itemManager.canonicalize(o1.getId()));
|
||||
int o2ID = ItemVariationMapping.map(itemManager.canonicalize(o2.getId()));
|
||||
ItemDefinition c1 = itemManager.getItemDefinition(o1ID);
|
||||
ItemDefinition c2 = itemManager.getItemDefinition(o2ID);
|
||||
int exchangePrice1 = c1.isTradeable() ? itemManager.getItemPrice(c1.getId()) : c1.getPrice();
|
||||
int exchangePrice2 = c2.isTradeable() ? itemManager.getItemPrice(c2.getId()) : c2.getPrice();
|
||||
return exchangePrice2 - exchangePrice1;
|
||||
});
|
||||
|
||||
int keepCount = getDefaultItemsKept();
|
||||
|
||||
List<Widget> keptItems = new ArrayList<>();
|
||||
List<Widget> lostItems = new ArrayList<>();
|
||||
for (Item i : items)
|
||||
{
|
||||
int id = i.getId();
|
||||
if (id == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
ItemDefinition c = itemManager.getItemDefinition(i.getId());
|
||||
Widget itemWidget = createItemWidget(i.getQuantity(), c);
|
||||
|
||||
// Bonds are always kept and do not count towards the limit.
|
||||
if (id == ItemID.OLD_SCHOOL_BOND || id == ItemID.OLD_SCHOOL_BOND_UNTRADEABLE)
|
||||
{
|
||||
keptItems.add(itemWidget);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Certain items are always lost on death and have a white outline which we need to readd
|
||||
AlwaysLostItem item = AlwaysLostItem.getByItemID(i.getId());
|
||||
if (item != null)
|
||||
{
|
||||
// Some of these items are kept on death (outside wildy), like the Rune pouch. Ignore them
|
||||
if (!item.isKept() || wildyLevel > 0)
|
||||
{
|
||||
itemWidget.setOnOpListener(SCRIPT_ID, 0, i.getQuantity(), c.getName());
|
||||
itemWidget.setBorderType(2);
|
||||
lostItems.add(itemWidget);
|
||||
hasAlwaysLost = true;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
// Keep most valuable items regardless of trade-ability.
|
||||
if (keepCount > 0)
|
||||
{
|
||||
if (i.getQuantity() > keepCount)
|
||||
{
|
||||
keptItems.add(createItemWidget(keepCount, c));
|
||||
itemWidget.setItemQuantity(i.getQuantity() - keepCount);
|
||||
keepCount = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
keptItems.add(itemWidget);
|
||||
keepCount -= i.getQuantity();
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (!checkTradeable(i.getId(), c) && wildyLevel < 21)
|
||||
{
|
||||
// Certain items are turned into broken variants inside the wilderness.
|
||||
if (BrokenOnDeathItem.check(i.getId()))
|
||||
{
|
||||
keptItems.add(itemWidget);
|
||||
continue;
|
||||
}
|
||||
|
||||
// Ignore all non tradeables in wildy except for the above case(s).
|
||||
if (wildyLevel > 0)
|
||||
{
|
||||
lostItems.add(itemWidget);
|
||||
continue;
|
||||
}
|
||||
|
||||
keptItems.add(itemWidget);
|
||||
}
|
||||
else
|
||||
{
|
||||
itemWidget.setOnOpListener(SCRIPT_ID, 0, i.getQuantity(), c.getName());
|
||||
lostItems.add(itemWidget);
|
||||
}
|
||||
}
|
||||
|
||||
int rows = keptItems.size() > MAX_ROW_ITEMS ? keptItems.size() / MAX_ROW_ITEMS : 0;
|
||||
// Adjust items lost container position if new rows were added to kept items container
|
||||
lost.setOriginalY(ORIGINAL_LOST_Y + (rows * Y_INCREMENT));
|
||||
lost.setOriginalHeight(ORIGINAL_LOST_HEIGHT - (rows * Y_INCREMENT));
|
||||
setWidgetChildren(kept, keptItems);
|
||||
setWidgetChildren(lost, lostItems);
|
||||
|
||||
updateKeptWidgetInfoText();
|
||||
}
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Wrapper for widget.setChildren() but updates the child index and original positions
|
||||
* Used for Items Kept and Lost containers
|
||||
*
|
||||
* @param parent Widget to override children
|
||||
* @param widgets Children to set on parent
|
||||
* <p>
|
||||
* Creates the text to be displayed in the right side of the interface based on current selections
|
||||
* <p>
|
||||
* Corrects the Information panel based on the item containers
|
||||
* <p>
|
||||
* Creates an Item Widget for use inside the Kept on Death Interface
|
||||
* @param qty Amount of item
|
||||
* @param c Items Composition
|
||||
* @return
|
||||
*//*
|
||||
|
||||
private void setWidgetChildren(Widget parent, List<Widget> widgets)
|
||||
{
|
||||
Widget[] children = parent.getChildren();
|
||||
if (children == null)
|
||||
{
|
||||
// Create a child so we can copy the returned Widget[] and avoid hn casting issues from creating a new Widget[]
|
||||
parent.createChild(0, WidgetType.GRAPHIC);
|
||||
children = parent.getChildren();
|
||||
}
|
||||
Widget[] itemsArray = Arrays.copyOf(children, widgets.size());
|
||||
|
||||
int parentId = parent.getId();
|
||||
int startingIndex = 0;
|
||||
for (Widget w : widgets)
|
||||
{
|
||||
int originalX = STARTING_X + ((startingIndex % MAX_ROW_ITEMS) * X_INCREMENT);
|
||||
int originalY = STARTING_Y + ((startingIndex / MAX_ROW_ITEMS) * Y_INCREMENT);
|
||||
|
||||
w.setParentId(parentId);
|
||||
w.setId(parentId);
|
||||
w.setIndex(startingIndex);
|
||||
|
||||
w.setOriginalX(originalX);
|
||||
w.setOriginalY(originalY);
|
||||
w.revalidate();
|
||||
|
||||
itemsArray[startingIndex] = w;
|
||||
startingIndex++;
|
||||
}
|
||||
|
||||
parent.setChildren(itemsArray);
|
||||
parent.revalidate();
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Creates the text to be displayed in the right side of the interface based on current selections
|
||||
*//*
|
||||
|
||||
private String getUpdatedInfoText()
|
||||
{
|
||||
String textToAdd = DEFAULT;
|
||||
|
||||
if (isUltimateIronman())
|
||||
{
|
||||
textToAdd = UIM_DEFAULT;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (isSkulled)
|
||||
{
|
||||
textToAdd += LINE_BREAK + IS_SKULLED;
|
||||
}
|
||||
|
||||
if (protectingItem)
|
||||
{
|
||||
textToAdd += LINE_BREAK + PROTECTING_ITEM;
|
||||
}
|
||||
|
||||
textToAdd += LINE_BREAK + String.format(ACTUAL, getDefaultItemsKept());
|
||||
}
|
||||
|
||||
|
||||
if (wildyLevel < 1)
|
||||
{
|
||||
textToAdd += LINE_BREAK + LINE_BREAK + NON_PVP;
|
||||
}
|
||||
|
||||
if (hasAlwaysLost)
|
||||
{
|
||||
textToAdd += LINE_BREAK + LINE_BREAK + WHITE_OUTLINE;
|
||||
}
|
||||
|
||||
textToAdd += LINE_BREAK + LINE_BREAK + CHANGED_MECHANICS;
|
||||
|
||||
return textToAdd;
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Corrects the Information panel based on the item containers
|
||||
*//*
|
||||
|
||||
private void updateKeptWidgetInfoText()
|
||||
{
|
||||
// Add Information text widget
|
||||
createNewTextWidget();
|
||||
|
||||
// Update Items lost total value
|
||||
Widget lost = client.getWidget(WidgetInfo.ITEMS_LOST_ON_DEATH_CONTAINER);
|
||||
double total = 0;
|
||||
for (Widget w : lost.getChildren())
|
||||
{
|
||||
if (w.getItemId() == -1)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
double price = itemManager.getItemPrice(w.getItemId());
|
||||
if (price == 0)
|
||||
{
|
||||
// Default to alch price
|
||||
price = itemManager.getItemDefinition(w.getItemId()).getPrice() * HIGH_ALCH;
|
||||
}
|
||||
total += price;
|
||||
}
|
||||
Widget lostValue = client.getWidget(WidgetInfo.ITEMS_LOST_VALUE);
|
||||
lostValue.setText(NUMBER_FORMAT.format(total) + " gp");
|
||||
|
||||
// Update Max items kept
|
||||
Widget kept = client.getWidget(WidgetInfo.ITEMS_KEPT_ON_DEATH_CONTAINER);
|
||||
Widget max = client.getWidget(WidgetInfo.ITEMS_KEPT_MAX);
|
||||
max.setText(String.format(MAX_KEPT_ITEMS_FORMAT, kept.getChildren().length));
|
||||
}
|
||||
|
||||
// isTradeable checks if they are traded on the grand exchange, some items are trade-able but not via GE
|
||||
private boolean checkTradeable(int id, ItemDefinition c)
|
||||
{
|
||||
// If the item is a note check the unnoted variants trade ability
|
||||
if (c.getNote() != -1)
|
||||
{
|
||||
return checkTradeable(c.getLinkedNoteId(), itemManager.getItemDefinition(c.getLinkedNoteId()));
|
||||
}
|
||||
|
||||
switch (id)
|
||||
{
|
||||
case ItemID.COINS_995:
|
||||
case ItemID.PLATINUM_TOKEN:
|
||||
return true;
|
||||
default:
|
||||
if (ActuallyTradeableItem.check(id))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return c.isTradeable();
|
||||
}
|
||||
|
||||
private void createNewTextWidget()
|
||||
{
|
||||
// The text use to be put inside this container but since we can't create LAYER widgets
|
||||
// We needed to edit this to be a layer for adding buttons
|
||||
Widget old = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
|
||||
|
||||
// Update the existing TEXT container if it exists. It should be the last child of the old text widget
|
||||
// client.getWidget() seems to not find indexed child widgets
|
||||
Widget[] children = old.getChildren();
|
||||
if (children != null && children.length > 0)
|
||||
{
|
||||
Widget x = old.getChild(children.length - 1);
|
||||
if (x.getId() == WidgetInfo.ITEMS_KEPT_CUSTOM_TEXT_CONTAINER.getId())
|
||||
{
|
||||
x.setText(getUpdatedInfoText());
|
||||
x.revalidate();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Widget w = old.createChild(-1, WidgetType.TEXT);
|
||||
// Position under buttons taking remaining space
|
||||
w.setOriginalWidth(old.getOriginalWidth());
|
||||
w.setOriginalHeight(ORIGINAL_INFO_HEIGHT - old.getOriginalHeight());
|
||||
w.setOriginalY(old.getOriginalHeight());
|
||||
|
||||
w.setFontId(FontID.PLAIN_11);
|
||||
w.setTextShadowed(true);
|
||||
w.setTextColor(FONT_COLOR);
|
||||
|
||||
w.setText(getUpdatedInfoText());
|
||||
w.setId(WidgetInfo.ITEMS_KEPT_CUSTOM_TEXT_CONTAINER.getId());
|
||||
w.revalidate();
|
||||
|
||||
// Need to reset height so text is visible?
|
||||
old.setOriginalHeight(ORIGINAL_INFO_HEIGHT);
|
||||
old.revalidate();
|
||||
}
|
||||
|
||||
private void createWidgetButtons()
|
||||
{
|
||||
buttonMap.clear();
|
||||
|
||||
// Ultimate Iron men are always skulled and can't use the protect item prayer
|
||||
if (!isUltimateIronman())
|
||||
{
|
||||
createButton(PROTECT_ITEM_BUTTON_NAME, PROTECT_ITEM_SPRITE_ID, protectingItem);
|
||||
createButton(SKULLED_BUTTON_NAME, SKULL_SPRITE_ID, isSkulled);
|
||||
}
|
||||
createButton(LOW_WILDY_BUTTON_NAME, SWORD_SPRITE_ID, wildyLevel > 0 && wildyLevel <= 20);
|
||||
createButton(DEEP_WILDY_BUTTON_NAME, SKULL_2_SPRITE_ID, wildyLevel > 20);
|
||||
|
||||
Widget parent = client.getWidget(WidgetInfo.ITEMS_KEPT_INFORMATION_CONTAINER);
|
||||
parent.setType(WidgetType.LAYER);
|
||||
parent.revalidate();
|
||||
WidgetButton.addButtonsToContainerWidget(parent, buttonMap.values());
|
||||
}
|
||||
|
||||
private void createButton(String name, int spriteID, boolean startingFlag)
|
||||
{
|
||||
WidgetButton button = new WidgetButton(name, spriteID, startingFlag, this::buttonCallback, client);
|
||||
buttonMap.put(name, button);
|
||||
}
|
||||
|
||||
private void buttonCallback(String name, boolean selected)
|
||||
{
|
||||
log.debug("Clicked Widget Button {}. New value: {}", name, selected);
|
||||
switch (name)
|
||||
{
|
||||
case PROTECT_ITEM_BUTTON_NAME:
|
||||
protectingItem = selected;
|
||||
break;
|
||||
case SKULLED_BUTTON_NAME:
|
||||
isSkulled = selected;
|
||||
break;
|
||||
case LOW_WILDY_BUTTON_NAME:
|
||||
if (!selected)
|
||||
{
|
||||
syncCurrentWildyLevel();
|
||||
break;
|
||||
}
|
||||
wildyLevel = 1;
|
||||
buttonMap.get(DEEP_WILDY_BUTTON_NAME).setSelected(false);
|
||||
break;
|
||||
case DEEP_WILDY_BUTTON_NAME:
|
||||
if (!selected)
|
||||
{
|
||||
syncCurrentWildyLevel();
|
||||
break;
|
||||
}
|
||||
wildyLevel = 21;
|
||||
buttonMap.get(LOW_WILDY_BUTTON_NAME).setSelected(false);
|
||||
break;
|
||||
default:
|
||||
log.warn("Unhandled Button Name: {}", name);
|
||||
return;
|
||||
}
|
||||
|
||||
recreateItemsKeptOnDeathWidget();
|
||||
}
|
||||
|
||||
*/
|
||||
/**
|
||||
* Creates an Item Widget for use inside the Kept on Death Interface
|
||||
*
|
||||
* @param qty Amount of item
|
||||
* @param c Items Composition
|
||||
* @return
|
||||
*//*
|
||||
|
||||
private Widget createItemWidget(int qty, ItemDefinition c)
|
||||
{
|
||||
Widget itemWidget = client.createWidget();
|
||||
itemWidget.setType(WidgetType.GRAPHIC);
|
||||
itemWidget.setItemId(c.getId());
|
||||
itemWidget.setItemQuantity(qty);
|
||||
itemWidget.setHasListener(true);
|
||||
itemWidget.setIsIf3(true);
|
||||
itemWidget.setOriginalWidth(ORIGINAL_WIDTH);
|
||||
itemWidget.setOriginalHeight(ORIGINAL_HEIGHT);
|
||||
itemWidget.setBorderType(1);
|
||||
|
||||
itemWidget.setAction(1, String.format(ACTION_TEXT, c.getName()));
|
||||
itemWidget.setOnOpListener(SCRIPT_ID, 1, qty, c.getName());
|
||||
|
||||
return itemWidget;
|
||||
}
|
||||
}*/
|
||||
@@ -1,24 +0,0 @@
|
||||
package net.runelite.client.plugins.menuentryswapper;
|
||||
|
||||
import com.google.common.base.Splitter;
|
||||
|
||||
public class Parse
|
||||
{
|
||||
public static boolean parse(String value)
|
||||
{
|
||||
try
|
||||
{
|
||||
Splitter NEWLINE_SPLITTER = Splitter
|
||||
.on("\n")
|
||||
.omitEmptyStrings()
|
||||
.trimResults();
|
||||
|
||||
NEWLINE_SPLITTER.withKeyValueSeparator(':').split(value);
|
||||
return true;
|
||||
}
|
||||
catch (IllegalArgumentException ex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,82 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, SomeoneWithAnInternetConnection
|
||||
* Copyright (c) 2018, oplosthee <https://github.com/oplosthee>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.metronome;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.SoundEffectID;
|
||||
import api.events.GameTick;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Metronome",
|
||||
description = "Play a sound on a specified tick to aid in efficient skilling",
|
||||
tags = {"skilling", "tick", "timers"},
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class MetronomePlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private MetronomePluginConfiguration config;
|
||||
|
||||
private int tickCounter = 0;
|
||||
private boolean shouldTock = false;
|
||||
|
||||
@Provides
|
||||
MetronomePluginConfiguration provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(MetronomePluginConfiguration.class);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick tick)
|
||||
{
|
||||
if (config.tickCount() == 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (++tickCounter % config.tickCount() == 0)
|
||||
{
|
||||
if (config.enableTock() && shouldTock)
|
||||
{
|
||||
client.playSoundEffect(SoundEffectID.GE_DECREMENT_PLOP);
|
||||
}
|
||||
else
|
||||
{
|
||||
client.playSoundEffect(SoundEffectID.GE_INCREMENT_PLOP);
|
||||
}
|
||||
shouldTock = !shouldTock;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,130 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.mining;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_ADAMANT;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_BLACK;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_BRONZE;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_DRAGON;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_DRAGON_ORN;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_INFERNAL;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_IRON;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_MITHRIL;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_RUNE;
|
||||
import static api.AnimationID.MINING_MOTHERLODE_STEEL;
|
||||
import api.Client;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.LineComponent;
|
||||
import net.runelite.client.ui.overlay.components.PanelComponent;
|
||||
import net.runelite.client.ui.overlay.components.TitleComponent;
|
||||
|
||||
class MiningOverlay extends Overlay
|
||||
{
|
||||
private static final Set<Integer> MINING_ANIMATION_IDS = ImmutableSet.of(
|
||||
MINING_MOTHERLODE_BRONZE, MINING_MOTHERLODE_IRON, MINING_MOTHERLODE_STEEL,
|
||||
MINING_MOTHERLODE_BLACK, MINING_MOTHERLODE_MITHRIL, MINING_MOTHERLODE_ADAMANT,
|
||||
MINING_MOTHERLODE_RUNE, MINING_MOTHERLODE_DRAGON, MINING_MOTHERLODE_DRAGON_ORN,
|
||||
MINING_MOTHERLODE_INFERNAL
|
||||
);
|
||||
|
||||
private final Client client;
|
||||
private final MiningPlugin plugin;
|
||||
private final MiningConfig config;
|
||||
private final PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
MiningOverlay(Client client, MiningPlugin plugin, MiningConfig config)
|
||||
{
|
||||
setPosition(OverlayPosition.TOP_LEFT);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
if (!plugin.isInMlm() || !config.showMiningStats())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
MiningSession session = plugin.getSession();
|
||||
|
||||
if (session.getLastPayDirtMined() == null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Duration statTimeout = Duration.ofMinutes(config.statTimeout());
|
||||
Duration sinceCut = Duration.between(session.getLastPayDirtMined(), Instant.now());
|
||||
|
||||
if (sinceCut.compareTo(statTimeout) >= 0)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
panelComponent.getChildren().clear();
|
||||
|
||||
if (config.showMiningState())
|
||||
{
|
||||
if (MINING_ANIMATION_IDS.contains(client.getLocalPlayer().getAnimation()))
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("Mining")
|
||||
.color(Color.GREEN)
|
||||
.build());
|
||||
}
|
||||
else
|
||||
{
|
||||
panelComponent.getChildren().add(TitleComponent.builder()
|
||||
.text("NOT mining")
|
||||
.color(Color.RED)
|
||||
.build());
|
||||
}
|
||||
}
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Pay-dirt mined:")
|
||||
.right(Integer.toString(session.getTotalMined()))
|
||||
.build());
|
||||
|
||||
panelComponent.getChildren().add(LineComponent.builder()
|
||||
.left("Pay-dirt/hr:")
|
||||
.right(session.getRecentMined() > 2 ? Integer.toString(session.getPerHour()) : "")
|
||||
.build());
|
||||
|
||||
return panelComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -1,366 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Lars <lars.oernlo@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.mining;
|
||||
|
||||
import com.google.common.collect.ImmutableSet;
|
||||
import com.google.inject.Provides;
|
||||
import java.time.temporal.ChronoUnit;
|
||||
import java.util.HashSet;
|
||||
import java.util.Set;
|
||||
import javax.inject.Inject;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import api.Client;
|
||||
import api.GameObject;
|
||||
import api.GameState;
|
||||
import api.ItemID;
|
||||
import static api.ObjectID.ORE_VEIN_26661;
|
||||
import static api.ObjectID.ORE_VEIN_26662;
|
||||
import static api.ObjectID.ORE_VEIN_26663;
|
||||
import static api.ObjectID.ORE_VEIN_26664;
|
||||
import api.WallObject;
|
||||
import api.events.GameObjectChanged;
|
||||
import api.events.GameObjectDespawned;
|
||||
import api.events.GameObjectSpawned;
|
||||
import api.events.GameStateChanged;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.task.Schedule;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Mining",
|
||||
description = "Show helpful information about Mining",
|
||||
tags = {"mining", "skilling", "overlay"},
|
||||
type = PluginType.SKILLING,
|
||||
enabledByDefault = false
|
||||
)
|
||||
public class MiningPlugin extends Plugin
|
||||
{
|
||||
private static final Set<Integer> MOTHERLODE_MAP_REGIONS = ImmutableSet.of(14679, 14680, 14681, 14935, 14936, 14937, 15191, 15192, 15193);
|
||||
private static final Set<Integer> MINE_SPOTS = ImmutableSet.of(ORE_VEIN_26661, ORE_VEIN_26662, ORE_VEIN_26663, ORE_VEIN_26664);
|
||||
private static final Set<Integer> MLM_ORE_TYPES = ImmutableSet.of(ItemID.RUNITE_ORE, ItemID.ADAMANTITE_ORE,
|
||||
ItemID.MITHRIL_ORE, ItemID.GOLD_ORE, ItemID.COAL, ItemID.GOLDEN_NUGGET);
|
||||
private static final Set<Integer> MINING_ROCKS = ImmutableSet.of(
|
||||
// another website says depleted rocks are 7468, 7469
|
||||
// website says stoney 2902, 2962, 2963, 2964,
|
||||
2231, 2257, 2584, 2704, 3722, 3723, 3748, 3790, 3791, 3803, 3804, 3805, 3806, 3807, 3808, 4437, 4438, 4676, 6669, 6670, 6671, 6672, 6673, 7453, 7454, 7455, 7456, 7457, 7458, 7459, 7460, 7461, 7462, 7463, 7464, 7467, 7470, 7484, 7485, 7486, 7487, 7488, 7489, 7490, 7491, 7492, 7493, 7494, 7495, 8727, 8828, 8829, 8830, 10079, 10080, 10081, 11441, 11924, 12590, 15127, 15128, 15213, 16464, 16514, 16515, 16521, 16522, 16523, 16524, 16534, 16535, 16545, 16549, 16550, 16998, 16999, 17042, 17043, 17064, 17065, 18817, 18840, 18952, 18953, 18954, 18961, 19849, 19969, 19970, 19971, 19972, 19973, 22665, 22667, 23280, 23281, 23640, 24146, 24147, 24148, 24557, 26873, 26874, 27984, 27985, 27987, 27988, 28596, 28597, 28752, 28753, 28890
|
||||
//2090, 2091, 2092, 2093, 2094, 2095, 2096, 2097, 2098, 2099, 2100, 2101, 2102, 2103, 2104, 2105, 2106, 2107, 2108, 2109, 2110, 2111, 2119, 2120, 2121, 2122, 2123, 2124, 2125, 2126, 2127, 2128, 2129, 2130, 2131, 2132, 2133, 2134, 2135, 2136, 2137, 2138, 2139, 2140, 2231, 2257, 2328, 3042, 3043, 3722, 3723, 3748, 3790, 3791, 3803, 3804, 4676, 6943, 6944, 6945, 6946, 6947, 6948, 9296, 9297, 9303, 9304, 9305, 9306, 9316, 9317, 9331, 9332, 9335, 9336, 9708, 9709, 9710, 9711, 9712, 9713, 9714, 9715, 9716, 9717, 9718, 9719, 9720, 9721, 9722, 9723, 9724, 9725, 9726, 9727, 9728, 9729, 9730, 9731, 9732, 9733, 9734, 9735, 9736, 9737, 10583, 10584, 10585, 10586, 10587, 10944, 10945, 10946, 10947, 10948, 10949, 11165, 11166, 11167, 11168, 11169, 11170, 11171, 11172, 11173, 11174, 11175, 11176, 11177, 11178, 11179, 11180, 11181, 11182, 11183, 11184, 11185, 11186, 11187, 11188, 11189, 11190, 11191, 11192, 11193, 11194, 11195, 11424, 11425, 11426, 11427, 11428, 11429, 11430, 11431, 11432, 11433, 11434, 11435, 11436, 11437, 11438, 11439, 11440, 11441, 11442, 11443, 11444, 11552, 11553, 11554, 11555, 11556, 11557, 11915, 11916, 11917, 11918, 11919, 11920, 11921, 11922, 11923, 11924, 11925, 11926, 11927, 11928, 11929, 11930, 11931, 11932, 11933, 11934, 11935, 11936, 11937, 11938, 11939, 11940, 11941, 11942, 11943, 11944, 11945, 11946, 11947, 11948, 11949, 11950, 11951, 11952, 11953, 11954, 11955, 11956, 11957, 11958, 11959, 11960, 11961, 11962, 11963, 11964, 11965
|
||||
//968, 1480, 1855, 4043, 4487, 7533, 9716, 21250, 1997, 2581, 2582, 2694, 2695, 2696, 2697, 2835, 2836, 2837, 2901, 2965, 3339, 3364, 4526, 4552, 4553, 4554, 4555, 4556, 4557, 4558, 4887, 5604, 5605, 5606, 5844, 5845, 5896, 5985, 5987, 6622, 6623, 6707, 6708, 6709, 7466, 8725, 8726, 8950, 8951, 8952, 9031, 9032, 10036, 10782, 10783, 10784, 10785, 10786, 10787, 10788, 11097, 11098, 11182, 11183, 11424, 11425, 12564, 12565, 12566, 12567, 12588, 12589, 12774, 14814, 14815, 14816, 14817, 15198, 15199, 15217, 15218, 15219, 15410, 15536, 15537, 16077, 16078, 16079, 16080, 16115, 16136, 16284, 16303, 17350, 17351, 17352, 17353, 17354, 17355, 17356, 17357, 17358, 17364, 17365, 17366, 17679, 17958, 17959, 17960, 17970, 17971, 17972, 18871, 18872, 18873, 19131, 21571, 21572, 21573, 22549, 22550, 22551, 23124, 23125, 23126, 23127, 23165, 23976, 23977, 23978, 23979, 23980, 23981, 24693, 24694, 24695, 24696, 24697, 24698, 24699, 24700, 24701, 24781, 25158, 25159, 25160, 25422, 25423, 26372, 26373, 26376, 26377, 26850, 26856, 28580, 29102, 29883, 29884, 29885, 30344, 30519, 30521, 30522, 30857, 30858, 31045, 31781, 31782, 31783, 31784, 31785, 31786, 31787, 31788, 31789
|
||||
);
|
||||
private static final int MAX_INVENTORY_SIZE = 28;
|
||||
|
||||
// private static final int SACK_LARGE_SIZE = 162;
|
||||
// private static final int SACK_SIZE = 81;
|
||||
//
|
||||
// private static final int UPPER_FLOOR_HEIGHT = -500;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private MiningOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private MiningRocksOverlay rocksOverlay;
|
||||
|
||||
@Inject
|
||||
private MiningConfig config;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private boolean inMlm;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int curSackSize;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int maxSackSize;
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Integer depositsLeft;
|
||||
|
||||
private MiningSession session;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<WallObject> veins = new HashSet<>();
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private final Set<GameObject> rocks = new HashSet<>();
|
||||
|
||||
@Provides
|
||||
MiningConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(MiningConfig.class);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
overlayManager.add(rocksOverlay);
|
||||
// overlayManager.add(motherlodeGemOverlay);
|
||||
// overlayManager.add(motherlodeSackOverlay);
|
||||
|
||||
session = new MiningSession();
|
||||
//inMlm = checkInMlm();
|
||||
|
||||
// if (inMlm)
|
||||
// {
|
||||
// clientThread.invokeLater(this::refreshSackValues);
|
||||
// }
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(rocksOverlay);
|
||||
// overlayManager.remove(motherlodeGemOverlay);
|
||||
// overlayManager.remove(motherlodeSackOverlay);
|
||||
session = null;
|
||||
// veins.clear();
|
||||
rocks.clear();
|
||||
|
||||
// Widget sack = client.getWidget(WidgetInfo.MOTHERLODE_MINE);
|
||||
|
||||
// clientThread.invokeLater(() ->
|
||||
// {
|
||||
// if (sack != null && sack.isHidden())
|
||||
// {
|
||||
// sack.setHidden(false);
|
||||
// }
|
||||
// });
|
||||
}
|
||||
|
||||
public MiningSession getSession()
|
||||
{
|
||||
return session;
|
||||
}
|
||||
|
||||
// @Subscribe
|
||||
// public void onVarbitChanged(VarbitChanged event)
|
||||
// {
|
||||
// if (inMlm)
|
||||
// {
|
||||
// refreshSackValues();
|
||||
// }
|
||||
// }
|
||||
|
||||
// @Subscribe
|
||||
// public void onChatMessage(ChatMessage event)
|
||||
// {
|
||||
// if (!inMlm || event.getType() != ChatMessageType.FILTERED)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// String chatMessage = event.getMessage();
|
||||
//
|
||||
// switch (chatMessage)
|
||||
// {
|
||||
// case "You manage to mine some pay-dirt.":
|
||||
// session.incrementPayDirtMined();
|
||||
// break;
|
||||
//
|
||||
// case "You just found a Diamond!":
|
||||
// session.incrementGemFound(ItemID.UNCUT_DIAMOND);
|
||||
// break;
|
||||
//
|
||||
// case "You just found a Ruby!":
|
||||
// session.incrementGemFound(ItemID.UNCUT_RUBY);
|
||||
// break;
|
||||
//
|
||||
// case "You just found an Emerald!":
|
||||
// session.incrementGemFound(ItemID.UNCUT_EMERALD);
|
||||
// break;
|
||||
//
|
||||
// case "You just found a Sapphire!":
|
||||
// session.incrementGemFound(ItemID.UNCUT_SAPPHIRE);
|
||||
// break;
|
||||
// }
|
||||
// }
|
||||
|
||||
@Schedule(
|
||||
period = 1,
|
||||
unit = ChronoUnit.SECONDS
|
||||
)
|
||||
// public void checkMining()
|
||||
// {
|
||||
// if (!inMlm)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// depositsLeft = calculateDepositsLeft();
|
||||
//
|
||||
// Instant lastPayDirtMined = session.getLastPayDirtMined();
|
||||
// if (lastPayDirtMined == null)
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
//
|
||||
// // reset recentPayDirtMined if you haven't mined anything recently
|
||||
// Duration statTimeout = Duration.ofMinutes(config.statTimeout());
|
||||
// Duration sinceMined = Duration.between(lastPayDirtMined, Instant.now());
|
||||
//
|
||||
// if (sinceMined.compareTo(statTimeout) >= 0)
|
||||
// {
|
||||
// session.resetRecent();
|
||||
// }
|
||||
// }
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectSpawned(GameObjectSpawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
if (MINING_ROCKS.contains(gameObject.getId()))
|
||||
{
|
||||
rocks.add(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectChanged(GameObjectChanged event)
|
||||
{
|
||||
GameObject previous = event.getPrevious();
|
||||
GameObject gameObject = event.getGameObject();
|
||||
rocks.remove(previous);
|
||||
if (MINING_ROCKS.contains(gameObject.getId()))
|
||||
{
|
||||
rocks.add(gameObject);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameObjectDespawned(GameObjectDespawned event)
|
||||
{
|
||||
GameObject gameObject = event.getGameObject();
|
||||
rocks.remove(gameObject);
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
if (event.getGameState() == GameState.LOADING)
|
||||
{
|
||||
// on region changes the tiles get set to null
|
||||
rocks.clear();
|
||||
}
|
||||
}
|
||||
|
||||
// private Integer calculateDepositsLeft()
|
||||
// {
|
||||
// if (maxSackSize == 0) // check if maxSackSize has been initialized
|
||||
// {
|
||||
// refreshSackValues();
|
||||
// }
|
||||
//
|
||||
// double depositsLeft = 0;
|
||||
// int nonPayDirtItems = 0;
|
||||
//
|
||||
// ItemContainer inventory = client.getItemContainer(InventoryID.INVENTORY);
|
||||
// if (inventory == null)
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// Item[] result = inventory.getItems();
|
||||
// assert result != null;
|
||||
//
|
||||
// for (Item item : result)
|
||||
// {
|
||||
// // Assume that MLM ores are being banked and exclude them from the check,
|
||||
// // so the user doesn't see the Overlay switch between deposits left and N/A.
|
||||
// //
|
||||
// // Count other items at nonPayDirtItems so depositsLeft is calculated accordingly.
|
||||
// if (item.getId() != ItemID.PAYDIRT && item.getId() != -1 && !MLM_ORE_TYPES.contains(item.getId()))
|
||||
// {
|
||||
// nonPayDirtItems += 1;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// double inventorySpace = MAX_INVENTORY_SIZE - nonPayDirtItems;
|
||||
// double sackSizeRemaining = maxSackSize - curSackSize;
|
||||
//
|
||||
// if (inventorySpace > 0 && sackSizeRemaining > 0)
|
||||
// {
|
||||
// depositsLeft = Math.ceil(sackSizeRemaining / inventorySpace);
|
||||
// }
|
||||
// else if (inventorySpace == 0)
|
||||
// {
|
||||
// return null;
|
||||
// }
|
||||
//
|
||||
// return (int) depositsLeft;
|
||||
// }
|
||||
//
|
||||
// private boolean checkInMlm()
|
||||
// {
|
||||
// if (client.getGameState() != GameState.LOGGED_IN)
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
//
|
||||
// int[] currentMapRegions = client.getMapRegions();
|
||||
//
|
||||
// // Verify that all regions exist in MOTHERLODE_MAP_REGIONS
|
||||
// for (int region : currentMapRegions)
|
||||
// {
|
||||
// if (!MOTHERLODE_MAP_REGIONS.contains(region))
|
||||
// {
|
||||
// return false;
|
||||
// }
|
||||
// }
|
||||
//
|
||||
// return true;
|
||||
// }
|
||||
//
|
||||
// private void refreshSackValues()
|
||||
// {
|
||||
// curSackSize = client.getVar(Varbits.SACK_NUMBER);
|
||||
// boolean sackUpgraded = client.getVar(Varbits.SACK_UPGRADED) == 1;
|
||||
// maxSackSize = sackUpgraded ? SACK_LARGE_SIZE : SACK_SIZE;
|
||||
// }
|
||||
//
|
||||
// /**
|
||||
// * Checks if the given point is "upstairs" in the mlm.
|
||||
// * The upper floor is actually on z=0.
|
||||
// * @param localPoint
|
||||
// * @return
|
||||
// */
|
||||
// boolean isUpstairs(LocalPoint localPoint)
|
||||
// {
|
||||
// return Perspective.getTileHeight(client, localPoint, 0) < UPPER_FLOOR_HEIGHT;
|
||||
// }
|
||||
}
|
||||
@@ -1,115 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Lars <lars.oernlo@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.mining;
|
||||
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.GameObject;
|
||||
import api.Perspective;
|
||||
import api.Player;
|
||||
import api.Point;
|
||||
import api.Skill;
|
||||
import api.coords.LocalPoint;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
|
||||
class MiningRocksOverlay extends Overlay
|
||||
{
|
||||
private static final int MAX_DISTANCE = 2350;
|
||||
|
||||
private final Client client;
|
||||
private final MiningPlugin plugin;
|
||||
private final MiningConfig config;
|
||||
|
||||
private final BufferedImage miningIcon;
|
||||
|
||||
@Inject
|
||||
MiningRocksOverlay(Client client, MiningPlugin plugin, MiningConfig config, SkillIconManager iconManager)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_SCENE);
|
||||
this.client = client;
|
||||
this.plugin = plugin;
|
||||
this.config = config;
|
||||
|
||||
miningIcon = iconManager.getSkillImage(Skill.MINING);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D graphics)
|
||||
{
|
||||
Player local = client.getLocalPlayer();
|
||||
|
||||
renderTiles(graphics, local);
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private void renderTiles(Graphics2D graphics, Player local)
|
||||
{
|
||||
LocalPoint localLocation = local.getLocalLocation();
|
||||
|
||||
if (config.showMiningRocks())
|
||||
{
|
||||
for (GameObject rock : plugin.getRocks())
|
||||
{
|
||||
|
||||
LocalPoint location = rock.getLocalLocation();
|
||||
if (localLocation.distanceTo(location) <= MAX_DISTANCE)
|
||||
{
|
||||
renderMiningRock(graphics, rock);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
private void renderMiningRock(Graphics2D graphics, GameObject rock)
|
||||
{
|
||||
Point canvasLoc = Perspective.getCanvasImageLocation(client, rock.getLocalLocation(), miningIcon, 0);
|
||||
if (canvasLoc != null)
|
||||
{
|
||||
graphics.drawImage(miningIcon, canvasLoc.getX(), canvasLoc.getY(), null);
|
||||
}
|
||||
}
|
||||
|
||||
// private void renderMiningRockSquare(Graphics2D graphics, GameObject rock)
|
||||
// {
|
||||
// Polygon poly = Perspective.getCanvasTilePoly(client, rock.getLocalLocation());
|
||||
//
|
||||
// if (poly != null)
|
||||
// {
|
||||
// OverlayUtil.renderPolygon(graphics, poly, Color.red);
|
||||
// }
|
||||
// }
|
||||
|
||||
}
|
||||
@@ -1,139 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.mining;
|
||||
|
||||
import java.time.Duration;
|
||||
import java.time.Instant;
|
||||
import lombok.AccessLevel;
|
||||
import lombok.Getter;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import api.ItemID;
|
||||
|
||||
@Slf4j
|
||||
public class MiningSession
|
||||
{
|
||||
private static final Duration HOUR = Duration.ofHours(1);
|
||||
|
||||
private int perHour;
|
||||
|
||||
private Instant lastPayDirtMined;
|
||||
private int totalMined;
|
||||
|
||||
private Instant recentPayDirtMined;
|
||||
private int recentMined;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private Instant lastGemFound;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int diamondsFound;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int rubiesFound;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int emeraldsFound;
|
||||
|
||||
@Getter(AccessLevel.PACKAGE)
|
||||
private int sapphiresFound;
|
||||
|
||||
public void incrementGemFound(int gemID)
|
||||
{
|
||||
lastGemFound = Instant.now();
|
||||
|
||||
switch (gemID)
|
||||
{
|
||||
case ItemID.UNCUT_DIAMOND:
|
||||
diamondsFound++;
|
||||
break;
|
||||
|
||||
case ItemID.UNCUT_RUBY:
|
||||
rubiesFound++;
|
||||
break;
|
||||
|
||||
case ItemID.UNCUT_EMERALD:
|
||||
emeraldsFound++;
|
||||
break;
|
||||
|
||||
case ItemID.UNCUT_SAPPHIRE:
|
||||
sapphiresFound++;
|
||||
break;
|
||||
|
||||
default:
|
||||
log.error("Invalid gem type specified. The gem count will not be incremented.");
|
||||
}
|
||||
}
|
||||
|
||||
public void incrementPayDirtMined()
|
||||
{
|
||||
Instant now = Instant.now();
|
||||
|
||||
lastPayDirtMined = now;
|
||||
++totalMined;
|
||||
|
||||
if (recentMined == 0)
|
||||
{
|
||||
recentPayDirtMined = now;
|
||||
}
|
||||
++recentMined;
|
||||
|
||||
Duration timeSinceStart = Duration.between(recentPayDirtMined, now);
|
||||
if (!timeSinceStart.isZero())
|
||||
{
|
||||
perHour = (int) ((double) recentMined * (double) HOUR.toMillis() / (double) timeSinceStart.toMillis());
|
||||
}
|
||||
}
|
||||
|
||||
public void resetRecent()
|
||||
{
|
||||
recentPayDirtMined = null;
|
||||
recentMined = 0;
|
||||
}
|
||||
|
||||
public int getPerHour()
|
||||
{
|
||||
return perHour;
|
||||
}
|
||||
|
||||
public Instant getLastPayDirtMined()
|
||||
{
|
||||
return lastPayDirtMined;
|
||||
}
|
||||
|
||||
public int getTotalMined()
|
||||
{
|
||||
return totalMined;
|
||||
}
|
||||
|
||||
public Instant getRecentPayDirtMined()
|
||||
{
|
||||
return recentPayDirtMined;
|
||||
}
|
||||
|
||||
public int getRecentMined()
|
||||
{
|
||||
return recentMined;
|
||||
}
|
||||
}
|
||||
@@ -1,299 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Seth <Sethtroll3@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.poh;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.Map;
|
||||
import lombok.Getter;
|
||||
import static api.NullObjectID.NULL_13615;
|
||||
import static api.NullObjectID.NULL_13618;
|
||||
import static api.NullObjectID.NULL_13620;
|
||||
import static api.NullObjectID.NULL_13622;
|
||||
import static api.NullObjectID.NULL_13625;
|
||||
import static api.NullObjectID.NULL_13627;
|
||||
import static api.NullObjectID.NULL_13629;
|
||||
import static api.NullObjectID.NULL_13632;
|
||||
import static api.NullObjectID.NULL_13634;
|
||||
import static api.NullObjectID.NULL_29228;
|
||||
import static api.NullObjectID.NULL_29229;
|
||||
import static api.ObjectID.ALTAR_13179;
|
||||
import static api.ObjectID.ALTAR_13180;
|
||||
import static api.ObjectID.ALTAR_13181;
|
||||
import static api.ObjectID.ALTAR_13182;
|
||||
import static api.ObjectID.ALTAR_13183;
|
||||
import static api.ObjectID.ALTAR_13184;
|
||||
import static api.ObjectID.ALTAR_13185;
|
||||
import static api.ObjectID.ALTAR_13186;
|
||||
import static api.ObjectID.ALTAR_13187;
|
||||
import static api.ObjectID.ALTAR_13188;
|
||||
import static api.ObjectID.ALTAR_13189;
|
||||
import static api.ObjectID.ALTAR_13190;
|
||||
import static api.ObjectID.ALTAR_13191;
|
||||
import static api.ObjectID.ALTAR_13192;
|
||||
import static api.ObjectID.ALTAR_13193;
|
||||
import static api.ObjectID.ALTAR_13194;
|
||||
import static api.ObjectID.ALTAR_13196;
|
||||
import static api.ObjectID.ALTAR_13197;
|
||||
import static api.ObjectID.ALTAR_13198;
|
||||
import static api.ObjectID.ALTAR_13199;
|
||||
import static api.ObjectID.ALTAR_OF_THE_OCCULT;
|
||||
import static api.ObjectID.AMULET_OF_GLORY;
|
||||
import static api.ObjectID.ANCIENT_ALTAR;
|
||||
import static api.ObjectID.ANNAKARL_PORTAL;
|
||||
import static api.ObjectID.ANNAKARL_PORTAL_29349;
|
||||
import static api.ObjectID.ANNAKARL_PORTAL_29357;
|
||||
import static api.ObjectID.ARDOUGNE_PORTAL;
|
||||
import static api.ObjectID.ARDOUGNE_PORTAL_13626;
|
||||
import static api.ObjectID.ARDOUGNE_PORTAL_13633;
|
||||
import static api.ObjectID.ARMOUR_REPAIR_STAND;
|
||||
import static api.ObjectID.BASIC_JEWELLERY_BOX;
|
||||
import static api.ObjectID.CARRALLANGAR_PORTAL;
|
||||
import static api.ObjectID.CARRALLANGAR_PORTAL_33437;
|
||||
import static api.ObjectID.CARRALLANGAR_PORTAL_33440;
|
||||
import static api.ObjectID.CATHERBY_PORTAL;
|
||||
import static api.ObjectID.CATHERBY_PORTAL_33435;
|
||||
import static api.ObjectID.CATHERBY_PORTAL_33438;
|
||||
import static api.ObjectID.DARK_ALTAR;
|
||||
import static api.ObjectID.DIGSITE_PENDANT;
|
||||
import static api.ObjectID.DIGSITE_PENDANT_33417;
|
||||
import static api.ObjectID.DIGSITE_PENDANT_33418;
|
||||
import static api.ObjectID.DIGSITE_PENDANT_33420;
|
||||
import static api.ObjectID.FALADOR_PORTAL;
|
||||
import static api.ObjectID.FALADOR_PORTAL_13624;
|
||||
import static api.ObjectID.FALADOR_PORTAL_13631;
|
||||
import static api.ObjectID.FANCY_JEWELLERY_BOX;
|
||||
import static api.ObjectID.FANCY_REJUVENATION_POOL;
|
||||
import static api.ObjectID.FISHING_GUILD_PORTAL;
|
||||
import static api.ObjectID.FISHING_GUILD_PORTAL_29351;
|
||||
import static api.ObjectID.FISHING_GUILD_PORTAL_29359;
|
||||
import static api.ObjectID.GHORROCK_PORTAL;
|
||||
import static api.ObjectID.GHORROCK_PORTAL_33436;
|
||||
import static api.ObjectID.GHORROCK_PORTAL_33439;
|
||||
import static api.ObjectID.KHARYRLL_PORTAL;
|
||||
import static api.ObjectID.KHARYRLL_PORTAL_29346;
|
||||
import static api.ObjectID.KHARYRLL_PORTAL_29354;
|
||||
import static api.ObjectID.KOUREND_PORTAL;
|
||||
import static api.ObjectID.KOUREND_PORTAL_29353;
|
||||
import static api.ObjectID.KOUREND_PORTAL_29361;
|
||||
import static api.ObjectID.LUMBRIDGE_PORTAL;
|
||||
import static api.ObjectID.LUMBRIDGE_PORTAL_13623;
|
||||
import static api.ObjectID.LUMBRIDGE_PORTAL_13630;
|
||||
import static api.ObjectID.LUNAR_ALTAR;
|
||||
import static api.ObjectID.LUNAR_ISLE_PORTAL;
|
||||
import static api.ObjectID.LUNAR_ISLE_PORTAL_29347;
|
||||
import static api.ObjectID.LUNAR_ISLE_PORTAL_29355;
|
||||
import static api.ObjectID.MARIM_PORTAL;
|
||||
import static api.ObjectID.MARIM_PORTAL_29352;
|
||||
import static api.ObjectID.MARIM_PORTAL_29360;
|
||||
import static api.ObjectID.OBELISK_31554;
|
||||
import static api.ObjectID.ORNATE_JEWELLERY_BOX;
|
||||
import static api.ObjectID.ORNATE_REJUVENATION_POOL;
|
||||
import static api.ObjectID.POOL_OF_REJUVENATION;
|
||||
import static api.ObjectID.POOL_OF_RESTORATION;
|
||||
import static api.ObjectID.POOL_OF_REVITALISATION;
|
||||
import static api.ObjectID.PORTAL_4525;
|
||||
import static api.ObjectID.PORTAL_NEXUS;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33355;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33356;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33357;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33358;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33359;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33360;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33361;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33362;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33363;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33364;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33365;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33366;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33367;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33368;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33369;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33370;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33371;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33372;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33373;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33374;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33375;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33376;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33377;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33378;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33379;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33380;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33381;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33382;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33383;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33384;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33385;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33386;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33387;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33388;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33389;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33390;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33391;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33392;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33393;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33394;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33395;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33396;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33397;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33398;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33399;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33400;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33401;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33402;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33403;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33404;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33405;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33406;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33407;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33408;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33409;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33410;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33423;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33424;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33425;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33426;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33427;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33428;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33429;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33430;
|
||||
import static api.ObjectID.PORTAL_NEXUS_33431;
|
||||
import static api.ObjectID.SENNTISTEN_PORTAL;
|
||||
import static api.ObjectID.SENNTISTEN_PORTAL_29348;
|
||||
import static api.ObjectID.SENNTISTEN_PORTAL_29356;
|
||||
import static api.ObjectID.SPIRIT_TREE_29227;
|
||||
import static api.ObjectID.TROLL_STRONGHOLD_PORTAL;
|
||||
import static api.ObjectID.TROLL_STRONGHOLD_PORTAL_33180;
|
||||
import static api.ObjectID.TROLL_STRONGHOLD_PORTAL_33181;
|
||||
import static api.ObjectID.WATERBIRTH_ISLAND_PORTAL;
|
||||
import static api.ObjectID.WATERBIRTH_ISLAND_PORTAL_29350;
|
||||
import static api.ObjectID.WATERBIRTH_ISLAND_PORTAL_29358;
|
||||
import static api.ObjectID.XERICS_TALISMAN;
|
||||
import static api.ObjectID.XERICS_TALISMAN_33412;
|
||||
import static api.ObjectID.XERICS_TALISMAN_33413;
|
||||
import static api.ObjectID.XERICS_TALISMAN_33414;
|
||||
import static api.ObjectID.XERICS_TALISMAN_33415;
|
||||
import static api.ObjectID.XERICS_TALISMAN_33419;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
public enum PohIcons
|
||||
{
|
||||
EXITPORTAL("exitportal", PORTAL_4525),
|
||||
VARROCK("varrock", NULL_13615, NULL_13622, NULL_13629),
|
||||
FALADOR("falador", FALADOR_PORTAL, FALADOR_PORTAL_13624, FALADOR_PORTAL_13631),
|
||||
LUMBRIDGE("lumbridge", LUMBRIDGE_PORTAL, LUMBRIDGE_PORTAL_13623, LUMBRIDGE_PORTAL_13630),
|
||||
ARDOUGNE("ardougne", ARDOUGNE_PORTAL, ARDOUGNE_PORTAL_13626, ARDOUGNE_PORTAL_13633),
|
||||
YANILLE("yanille", NULL_13620, NULL_13627, NULL_13634),
|
||||
CAMELOT("camelot", NULL_13618, NULL_13625, NULL_13632),
|
||||
LUNARISLE("lunarisle", LUNAR_ISLE_PORTAL, LUNAR_ISLE_PORTAL_29347, LUNAR_ISLE_PORTAL_29355),
|
||||
WATERBIRTH("waterbirth", WATERBIRTH_ISLAND_PORTAL, WATERBIRTH_ISLAND_PORTAL_29350, WATERBIRTH_ISLAND_PORTAL_29358),
|
||||
FISHINGGUILD("fishingguild", FISHING_GUILD_PORTAL, FISHING_GUILD_PORTAL_29351, FISHING_GUILD_PORTAL_29359),
|
||||
SENNTISTEN("senntisten", SENNTISTEN_PORTAL, SENNTISTEN_PORTAL_29348, SENNTISTEN_PORTAL_29356),
|
||||
KHARYLL("kharyll", KHARYRLL_PORTAL, KHARYRLL_PORTAL_29346, KHARYRLL_PORTAL_29354),
|
||||
ANNAKARL("annakarl", ANNAKARL_PORTAL, ANNAKARL_PORTAL_29349, ANNAKARL_PORTAL_29357),
|
||||
KOUREND("kourend", KOUREND_PORTAL, KOUREND_PORTAL_29353, KOUREND_PORTAL_29361),
|
||||
MARIM("marim", MARIM_PORTAL, MARIM_PORTAL_29352, MARIM_PORTAL_29360),
|
||||
TROLLSTRONGHOLD("trollheim", TROLL_STRONGHOLD_PORTAL, TROLL_STRONGHOLD_PORTAL_33180, TROLL_STRONGHOLD_PORTAL_33181),
|
||||
GHORROCK("ghorrock", GHORROCK_PORTAL, GHORROCK_PORTAL_33436, GHORROCK_PORTAL_33439),
|
||||
CARRALLANGAR("carrallangar", CARRALLANGAR_PORTAL, CARRALLANGAR_PORTAL_33437, CARRALLANGAR_PORTAL_33440),
|
||||
CATHERBY("catherby", CATHERBY_PORTAL, CATHERBY_PORTAL_33435, CATHERBY_PORTAL_33438),
|
||||
ALTAR("altar",
|
||||
ALTAR_13179, ALTAR_13180, ALTAR_13181, ALTAR_13182, ALTAR_13183, ALTAR_13184, ALTAR_13185, ALTAR_13186,
|
||||
ALTAR_13187, ALTAR_13188, ALTAR_13189, ALTAR_13190, ALTAR_13191, ALTAR_13192, ALTAR_13193, ALTAR_13194,
|
||||
ALTAR_13196, ALTAR_13197, ALTAR_13198, ALTAR_13199
|
||||
),
|
||||
POOLS("pool", POOL_OF_RESTORATION, POOL_OF_REVITALISATION, POOL_OF_REJUVENATION, FANCY_REJUVENATION_POOL, ORNATE_REJUVENATION_POOL),
|
||||
GLORY("glory", AMULET_OF_GLORY),
|
||||
REPAIR("repair", ARMOUR_REPAIR_STAND),
|
||||
SPELLBOOKALTAR("spellbook", ANCIENT_ALTAR, LUNAR_ALTAR, DARK_ALTAR, ALTAR_OF_THE_OCCULT),
|
||||
JEWELLERYBOX("jewellery", BASIC_JEWELLERY_BOX, FANCY_JEWELLERY_BOX, ORNATE_JEWELLERY_BOX),
|
||||
MAGICTRAVEL("transportation", SPIRIT_TREE_29227, NULL_29228, NULL_29229, OBELISK_31554),
|
||||
PORTALNEXUS("portalnexus",
|
||||
PORTAL_NEXUS, PORTAL_NEXUS_33355, PORTAL_NEXUS_33356, PORTAL_NEXUS_33357, PORTAL_NEXUS_33358, PORTAL_NEXUS_33359, PORTAL_NEXUS_33360,
|
||||
PORTAL_NEXUS_33361, PORTAL_NEXUS_33362, PORTAL_NEXUS_33363, PORTAL_NEXUS_33364, PORTAL_NEXUS_33365, PORTAL_NEXUS_33366, PORTAL_NEXUS_33367,
|
||||
PORTAL_NEXUS_33368, PORTAL_NEXUS_33369, PORTAL_NEXUS_33370, PORTAL_NEXUS_33371, PORTAL_NEXUS_33372, PORTAL_NEXUS_33373, PORTAL_NEXUS_33374,
|
||||
PORTAL_NEXUS_33375, PORTAL_NEXUS_33376, PORTAL_NEXUS_33377, PORTAL_NEXUS_33378, PORTAL_NEXUS_33379, PORTAL_NEXUS_33380, PORTAL_NEXUS_33381,
|
||||
PORTAL_NEXUS_33382, PORTAL_NEXUS_33383, PORTAL_NEXUS_33384, PORTAL_NEXUS_33385, PORTAL_NEXUS_33386, PORTAL_NEXUS_33387, PORTAL_NEXUS_33388,
|
||||
PORTAL_NEXUS_33389, PORTAL_NEXUS_33390, PORTAL_NEXUS_33391, PORTAL_NEXUS_33392, PORTAL_NEXUS_33393, PORTAL_NEXUS_33394, PORTAL_NEXUS_33395,
|
||||
PORTAL_NEXUS_33396, PORTAL_NEXUS_33397, PORTAL_NEXUS_33398, PORTAL_NEXUS_33399, PORTAL_NEXUS_33400, PORTAL_NEXUS_33401, PORTAL_NEXUS_33402,
|
||||
PORTAL_NEXUS_33403, PORTAL_NEXUS_33404, PORTAL_NEXUS_33405, PORTAL_NEXUS_33406, PORTAL_NEXUS_33407, PORTAL_NEXUS_33408, PORTAL_NEXUS_33409,
|
||||
PORTAL_NEXUS_33410, PORTAL_NEXUS_33423, PORTAL_NEXUS_33424, PORTAL_NEXUS_33425, PORTAL_NEXUS_33426, PORTAL_NEXUS_33427, PORTAL_NEXUS_33428,
|
||||
PORTAL_NEXUS_33429, PORTAL_NEXUS_33430, PORTAL_NEXUS_33431
|
||||
),
|
||||
XERICSTALISMAN("xericstalisman",
|
||||
XERICS_TALISMAN, XERICS_TALISMAN_33412, XERICS_TALISMAN_33413, XERICS_TALISMAN_33414, XERICS_TALISMAN_33415, XERICS_TALISMAN_33419
|
||||
),
|
||||
DIGSITEPENDANT("digsitependant",
|
||||
DIGSITE_PENDANT, DIGSITE_PENDANT_33417, DIGSITE_PENDANT_33418, DIGSITE_PENDANT_33420
|
||||
);
|
||||
|
||||
private static final Map<Integer, PohIcons> minimapIcons;
|
||||
|
||||
@Getter
|
||||
private final String imageResource;
|
||||
@Getter
|
||||
private final int[] Ids;
|
||||
|
||||
private BufferedImage image;
|
||||
|
||||
static
|
||||
{
|
||||
ImmutableMap.Builder<Integer, PohIcons> builder = new ImmutableMap.Builder<>();
|
||||
|
||||
for (PohIcons icon : values())
|
||||
{
|
||||
for (Integer spotId : icon.getIds())
|
||||
{
|
||||
builder.put(spotId, icon);
|
||||
}
|
||||
}
|
||||
|
||||
minimapIcons = builder.build();
|
||||
}
|
||||
|
||||
PohIcons(String imageResource, int... ids)
|
||||
{
|
||||
this.imageResource = imageResource;
|
||||
this.Ids = ids;
|
||||
}
|
||||
|
||||
public static PohIcons getIcon(int id)
|
||||
{
|
||||
return minimapIcons.get(id);
|
||||
}
|
||||
|
||||
public BufferedImage getImage()
|
||||
{
|
||||
if (image != null)
|
||||
{
|
||||
return image;
|
||||
}
|
||||
|
||||
image = ImageUtil.getResourceStreamFromClass(getClass(), getImageResource() + ".png");
|
||||
|
||||
return image;
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
package net.runelite.client.plugins.runedoku;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("runedoku")
|
||||
public interface RunedokuConfig extends Config
|
||||
{
|
||||
|
||||
@ConfigItem(
|
||||
position = 0,
|
||||
keyName = "mindRuneColor",
|
||||
name = "Mind Rune Color",
|
||||
description = "Color used to highlight Mind runes."
|
||||
)
|
||||
default Color mindRuneColor()
|
||||
{
|
||||
return Color.PINK;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 1,
|
||||
keyName = "fireRuneColor",
|
||||
name = "Fire Rune Color",
|
||||
description = "Color used to highlight Fire runes."
|
||||
)
|
||||
default Color fireRuneColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 2,
|
||||
keyName = "bodyRuneColor",
|
||||
name = "Body Rune Color",
|
||||
description = "Color used to highlight Body runes."
|
||||
)
|
||||
default Color bodyRuneColor()
|
||||
{
|
||||
return Color.MAGENTA;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 3,
|
||||
keyName = "airRuneColor",
|
||||
name = "Air Rune Color",
|
||||
description = "Color used to highlight Air runes."
|
||||
)
|
||||
default Color airRuneColor()
|
||||
{
|
||||
return Color.WHITE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 4,
|
||||
keyName = "deathRuneColor",
|
||||
name = "Death Rune Color",
|
||||
description = "Color used to highlight Death runes."
|
||||
)
|
||||
default Color deathRuneColor()
|
||||
{
|
||||
return Color.BLACK;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 5,
|
||||
keyName = "waterRuneColor",
|
||||
name = "Water Rune Color",
|
||||
description = "Color used to highlight Water runes."
|
||||
)
|
||||
default Color waterRuneColor()
|
||||
{
|
||||
return Color.BLUE;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 6,
|
||||
keyName = "chaosRuneColor",
|
||||
name = "Chaos Rune Color",
|
||||
description = "Color used to highlight Chaos runes."
|
||||
)
|
||||
default Color chaosRuneColor()
|
||||
{
|
||||
return Color.YELLOW;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 7,
|
||||
keyName = "earthRuneColor",
|
||||
name = "Earth Rune Color",
|
||||
description = "Color used to highlight Earth runes."
|
||||
)
|
||||
default Color earthRuneColor()
|
||||
{
|
||||
return Color.GREEN;
|
||||
}
|
||||
|
||||
@ConfigItem(
|
||||
position = 8,
|
||||
keyName = "lawRuneColor",
|
||||
name = "Law Rune Color",
|
||||
description = "Color used to highlight Law runes."
|
||||
)
|
||||
default Color lawRuneColor()
|
||||
{
|
||||
return Color.CYAN;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,322 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Jos <Malevolentdev@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.statusbars;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Dimension;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.Image;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.MenuEntry;
|
||||
import api.Point;
|
||||
import api.Skill;
|
||||
import api.VarPlayer;
|
||||
import api.Varbits;
|
||||
import api.widgets.Widget;
|
||||
import api.widgets.WidgetInfo;
|
||||
import net.runelite.client.game.SkillIconManager;
|
||||
import net.runelite.client.plugins.itemstats.Effect;
|
||||
import net.runelite.client.plugins.itemstats.ItemStatChangesService;
|
||||
import net.runelite.client.plugins.itemstats.StatChange;
|
||||
import net.runelite.client.plugins.itemstats.StatsChanges;
|
||||
import net.runelite.client.ui.FontManager;
|
||||
import net.runelite.client.ui.overlay.Overlay;
|
||||
import net.runelite.client.ui.overlay.OverlayLayer;
|
||||
import net.runelite.client.ui.overlay.OverlayPosition;
|
||||
import net.runelite.client.ui.overlay.components.TextComponent;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
class StatusBarsOverlay extends Overlay
|
||||
{
|
||||
private static final Color PRAYER_COLOR = new Color(50, 200, 200, 175);
|
||||
private static final Color QUICK_PRAYER_COLOR = new Color(57, 255, 186, 225);
|
||||
private static final Color BACKGROUND = new Color(0, 0, 0, 150);
|
||||
private static final Color HEALTH_COLOR = new Color(225, 35, 0, 125);
|
||||
private static final Color POISONED_COLOR = new Color(0, 145, 0, 150);
|
||||
private static final Color VENOMED_COLOR = new Color(0, 65, 0, 150);
|
||||
private static final Color HEAL_COLOR = new Color(255, 112, 6, 150);
|
||||
private static final Color PRAYER_HEAL_COLOR = new Color(57, 255, 186, 75);
|
||||
private static final Color OVERHEAL_COLOR = new Color(216, 255, 139, 150);
|
||||
private static final int HEIGHT = 252;
|
||||
private static final int RESIZED_BOTTOM_HEIGHT = 272;
|
||||
private static final int WIDTH = 20;
|
||||
private static final int PADDING = 1;
|
||||
private static final int IMAGE_SIZE = 17;
|
||||
private static final int HEALTH_LOCATION_X = 0;
|
||||
private static final int PRAYER_LOCATION_X = 1;
|
||||
private static final int RESIZED_BOTTOM_OFFSET_Y = 12;
|
||||
private static final int RESIZED_BOTTOM_OFFSET_X = 10;
|
||||
private static final int OVERHEAL_OFFSET = 2;
|
||||
private static final int HEAL_OFFSET = 3;
|
||||
private static final int ICON_AND_COUNTER_OFFSET_X = 1;
|
||||
private static final int ICON_AND_COUNTER_OFFSET_Y = 21;
|
||||
private static final int SKILL_ICON_HEIGHT = 35;
|
||||
private static final int COUNTER_ICON_HEIGHT = 18;
|
||||
private static final int OFFSET = 2;
|
||||
|
||||
private final Client client;
|
||||
private final StatusBarsConfig config;
|
||||
private final SkillIconManager skillIconManager;
|
||||
private final TextComponent textComponent = new TextComponent();
|
||||
private final ItemStatChangesService itemStatService;
|
||||
|
||||
private final Image prayerImage;
|
||||
|
||||
@Inject
|
||||
private StatusBarsOverlay(Client client, StatusBarsConfig config, SkillIconManager skillIconManager, ItemStatChangesService itemstatservice)
|
||||
{
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setLayer(OverlayLayer.ABOVE_WIDGETS);
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
this.skillIconManager = skillIconManager;
|
||||
this.itemStatService = itemstatservice;
|
||||
|
||||
prayerImage = ImageUtil.resizeImage(skillIconManager.getSkillImage(Skill.PRAYER, true), IMAGE_SIZE, IMAGE_SIZE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
final Widget widgetBankTitleBar = client.getWidget(WidgetInfo.BANK_TITLE_BAR);
|
||||
if (widgetBankTitleBar != null && !widgetBankTitleBar.isHidden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
Viewport curViewport = null;
|
||||
Widget curWidget = null;
|
||||
|
||||
for (Viewport viewport : Viewport.values())
|
||||
{
|
||||
final Widget viewportWidget = client.getWidget(viewport.getViewport());
|
||||
if (viewportWidget != null && !viewportWidget.isHidden())
|
||||
{
|
||||
curViewport = viewport;
|
||||
curWidget = viewportWidget;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (curViewport == null || curWidget.isHidden())
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
final Point offsetLeft = curViewport.getOffsetLeft();
|
||||
final Point offsetRight = curViewport.getOffsetRight();
|
||||
final Point location = curWidget.getCanvasLocation();
|
||||
final int height, offsetHealthX, offsetHealthY, offsetPrayerX, offsetPrayerY;
|
||||
|
||||
if (curViewport == Viewport.RESIZED_BOTTOM)
|
||||
{
|
||||
height = RESIZED_BOTTOM_HEIGHT;
|
||||
offsetHealthX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetLeft.getX());
|
||||
offsetHealthY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY());
|
||||
offsetPrayerX = (location.getX() + RESIZED_BOTTOM_OFFSET_X - offsetRight.getX());
|
||||
offsetPrayerY = (location.getY() - RESIZED_BOTTOM_OFFSET_Y - offsetRight.getY());
|
||||
}
|
||||
else
|
||||
{
|
||||
height = HEIGHT;
|
||||
offsetHealthX = (location.getX() - offsetLeft.getX());
|
||||
offsetHealthY = (location.getY() - offsetLeft.getY());
|
||||
offsetPrayerX = (location.getX() - offsetRight.getX()) + curWidget.getWidth();
|
||||
offsetPrayerY = (location.getY() - offsetRight.getY());
|
||||
}
|
||||
|
||||
final int poisonState = client.getVar(VarPlayer.IS_POISONED);
|
||||
final Color healthBar;
|
||||
|
||||
if (poisonState >= 1000000)
|
||||
{
|
||||
healthBar = VENOMED_COLOR;
|
||||
}
|
||||
else if (poisonState > 0)
|
||||
{
|
||||
healthBar = POISONED_COLOR;
|
||||
}
|
||||
else
|
||||
{
|
||||
healthBar = HEALTH_COLOR;
|
||||
}
|
||||
|
||||
final int maxHealth = client.getRealSkillLevel(Skill.HITPOINTS);
|
||||
final int maxPrayer = client.getRealSkillLevel(Skill.PRAYER);
|
||||
final int currentHealth = client.getBoostedSkillLevel(Skill.HITPOINTS);
|
||||
final int currentPrayer = client.getBoostedSkillLevel(Skill.PRAYER);
|
||||
final int quickPrayerState = client.getVar(Varbits.QUICK_PRAYER);
|
||||
final Color prayerBar = quickPrayerState == 1 ? QUICK_PRAYER_COLOR : PRAYER_COLOR;
|
||||
|
||||
renderBar(g, offsetHealthX, offsetHealthY,
|
||||
maxHealth, currentHealth, height, healthBar);
|
||||
|
||||
renderBar(g, offsetPrayerX, offsetPrayerY,
|
||||
maxPrayer, currentPrayer, height, prayerBar);
|
||||
|
||||
if (config.enableRestorationBars())
|
||||
{
|
||||
final MenuEntry[] menu = client.getMenuEntries();
|
||||
final int menuSize = menu.length;
|
||||
final MenuEntry entry = menuSize > 0 ? menu[menuSize - 1] : null;
|
||||
int prayerHealValue = 0;
|
||||
int foodHealValue = 0;
|
||||
if (entry != null && entry.getParam1() == WidgetInfo.INVENTORY.getId())
|
||||
{
|
||||
final Effect change = itemStatService.getItemStatChanges(entry.getIdentifier());
|
||||
|
||||
if (change != null)
|
||||
{
|
||||
final StatsChanges statsChanges = change.calculate(client);
|
||||
|
||||
for (final StatChange c : statsChanges.getStatChanges())
|
||||
{
|
||||
final int theoreticalBoost = c.getTheoretical();
|
||||
|
||||
if (c.getStat().getName().equals(Skill.HITPOINTS.getName()))
|
||||
{
|
||||
foodHealValue = theoreticalBoost;
|
||||
}
|
||||
|
||||
if (c.getStat().getName().equals(Skill.PRAYER.getName()))
|
||||
{
|
||||
prayerHealValue = theoreticalBoost;
|
||||
}
|
||||
|
||||
if (foodHealValue != 0 && prayerHealValue != 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
renderHealingBar(g, offsetHealthX, offsetHealthY,
|
||||
maxHealth, currentHealth, height,
|
||||
foodHealValue, HEAL_COLOR);
|
||||
|
||||
renderHealingBar(g, offsetPrayerX, offsetPrayerY,
|
||||
maxPrayer, currentPrayer, height,
|
||||
prayerHealValue, PRAYER_HEAL_COLOR);
|
||||
}
|
||||
|
||||
if (config.enableSkillIcon() || config.enableCounter())
|
||||
{
|
||||
final Image healthImage = skillIconManager.getSkillImage(Skill.HITPOINTS, true);
|
||||
final int counterHealth = client.getBoostedSkillLevel(Skill.HITPOINTS);
|
||||
final int counterPrayer = client.getBoostedSkillLevel(Skill.PRAYER);
|
||||
final String counterHealthText = Integer.toString(counterHealth);
|
||||
final String counterPrayerText = Integer.toString(counterPrayer);
|
||||
|
||||
renderIconsAndCounters(g, offsetPrayerX, offsetPrayerY, prayerImage, counterPrayerText, PRAYER_LOCATION_X);
|
||||
renderIconsAndCounters(g, offsetHealthX, offsetHealthY, healthImage, counterHealthText, HEALTH_LOCATION_X);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
private static void renderBar(Graphics2D graphics, int x, int y, int max, int current, int height, Color filled)
|
||||
{
|
||||
graphics.setColor(BACKGROUND);
|
||||
graphics.drawRect(x, y, WIDTH - PADDING, height - PADDING);
|
||||
graphics.fillRect(x, y, WIDTH, height);
|
||||
|
||||
final int filledHeight = getBarHeight(max, current, height);
|
||||
graphics.setColor(filled);
|
||||
graphics.fillRect(x + PADDING,
|
||||
y + PADDING + (height - filledHeight),
|
||||
WIDTH - PADDING * OFFSET,
|
||||
filledHeight - PADDING * OFFSET);
|
||||
}
|
||||
|
||||
private static void renderHealingBar(Graphics2D graphics, int x, int y, int max, int current, int height, int heal, Color color)
|
||||
{
|
||||
if (heal <= 0)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
final int filledCurrentHeight = getBarHeight(max, current, height);
|
||||
int filledHeight = getBarHeight(max, heal, height);
|
||||
graphics.setColor(color);
|
||||
|
||||
if (filledHeight + filledCurrentHeight > height)
|
||||
{
|
||||
final int overHeal = filledHeight + filledCurrentHeight - height;
|
||||
filledHeight = filledHeight - overHeal + OVERHEAL_OFFSET;
|
||||
graphics.setColor(OVERHEAL_COLOR);
|
||||
graphics.fillRect(x + PADDING,
|
||||
y - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET,
|
||||
WIDTH - PADDING * OVERHEAL_OFFSET,
|
||||
filledHeight - PADDING * OVERHEAL_OFFSET);
|
||||
}
|
||||
else
|
||||
{
|
||||
graphics.fillRect(x + PADDING,
|
||||
y - OVERHEAL_OFFSET - filledCurrentHeight + (height - filledHeight) + HEAL_OFFSET,
|
||||
WIDTH - PADDING * OVERHEAL_OFFSET,
|
||||
filledHeight + OVERHEAL_OFFSET - PADDING * OVERHEAL_OFFSET);
|
||||
}
|
||||
}
|
||||
|
||||
private static int getBarHeight(int base, int current, int size)
|
||||
{
|
||||
final double ratio = (double) current / base;
|
||||
|
||||
if (ratio >= 1)
|
||||
{
|
||||
return size;
|
||||
}
|
||||
|
||||
return (int) Math.round(ratio * size);
|
||||
}
|
||||
|
||||
private void renderIconsAndCounters(Graphics2D graphics, int x, int y, Image image, String counterText, int counterPadding)
|
||||
{
|
||||
final int widthOfCounter = graphics.getFontMetrics().stringWidth(counterText);
|
||||
final int centerText = (WIDTH - PADDING) / 2 - (widthOfCounter / 2);
|
||||
|
||||
if (config.enableCounter())
|
||||
{
|
||||
graphics.setFont(FontManager.getRunescapeSmallFont());
|
||||
textComponent.setColor(Color.WHITE);
|
||||
textComponent.setText(counterText);
|
||||
textComponent.setPosition(new java.awt.Point(x + centerText + counterPadding, y + COUNTER_ICON_HEIGHT));
|
||||
}
|
||||
else
|
||||
{
|
||||
textComponent.setText("");
|
||||
}
|
||||
|
||||
if (config.enableSkillIcon())
|
||||
{
|
||||
graphics.drawImage(image, x + ICON_AND_COUNTER_OFFSET_X + PADDING, y + ICON_AND_COUNTER_OFFSET_Y - image.getWidth(null), null);
|
||||
textComponent.setPosition(new java.awt.Point(x + centerText + counterPadding, y + SKILL_ICON_HEIGHT));
|
||||
}
|
||||
|
||||
textComponent.render(graphics);
|
||||
}
|
||||
}
|
||||
@@ -1,111 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.test;
|
||||
|
||||
import api.Client;
|
||||
import api.events.ChatMessage;
|
||||
import api.events.ClientTick;
|
||||
import api.events.GameTick;
|
||||
import api.events.MenuOpened;
|
||||
import api.events.VarbitChanged;
|
||||
import com.google.common.eventbus.Subscribe;
|
||||
import com.google.inject.Binder;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Singleton;
|
||||
|
||||
import com.google.inject.Provides;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import net.runelite.client.config.ConfigManager;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
|
||||
/**
|
||||
* Authors gazivodag longstreet
|
||||
*/
|
||||
@PluginDescriptor(
|
||||
name = "Test",
|
||||
description = "Testing plugin for building functionality",
|
||||
tags = {}
|
||||
)
|
||||
@Singleton
|
||||
@Slf4j
|
||||
public class Test extends Plugin
|
||||
{
|
||||
|
||||
@Provides
|
||||
TestConfig getConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(TestConfig.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private TestOverlay testOverlay;
|
||||
|
||||
@Inject
|
||||
private TestConfig config;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Override
|
||||
public void configure(Binder binder)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(testOverlay);
|
||||
System.out.println("Test Plugin started");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onMenuOpened(MenuOpened event)
|
||||
{
|
||||
System.out.println("[Test Plugin] Menu Opened");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onChatMessage(ChatMessage chatMessage)
|
||||
{
|
||||
System.out.println("[Test Plugin] Chat Message");
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onVarbitChanged(VarbitChanged event)
|
||||
{
|
||||
System.out.println("[Test Plugin] Varbit Changed");
|
||||
}
|
||||
}
|
||||
@@ -1,107 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, James Munson <https://github.com/james-munson>
|
||||
* 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 HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.tickcounter;
|
||||
|
||||
import java.awt.Color;
|
||||
import net.runelite.client.config.Alpha;
|
||||
import net.runelite.client.config.Config;
|
||||
import net.runelite.client.config.ConfigGroup;
|
||||
import net.runelite.client.config.ConfigItem;
|
||||
|
||||
@ConfigGroup("tickcounter")
|
||||
public interface TickCounterConfig extends Config
|
||||
{
|
||||
@ConfigItem(
|
||||
keyName = "resetInstance",
|
||||
name = "Reset on new instances",
|
||||
description = "",
|
||||
position = 1
|
||||
)
|
||||
default boolean instance()
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "selfColor",
|
||||
name = "Your color",
|
||||
description = "",
|
||||
position = 4
|
||||
)
|
||||
default Color selfColor()
|
||||
{
|
||||
return Color.green;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "totalColor",
|
||||
name = "Total color",
|
||||
description = "",
|
||||
position = 6
|
||||
)
|
||||
default Color totalColor()
|
||||
{
|
||||
return Color.RED;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "otherColor",
|
||||
name = "Other players color",
|
||||
description = "",
|
||||
position = 5
|
||||
)
|
||||
default Color otherColor()
|
||||
{
|
||||
return Color.white;
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "bgColor",
|
||||
name = "Background color",
|
||||
description = "",
|
||||
position = 3
|
||||
)
|
||||
default Color bgColor()
|
||||
{
|
||||
return new Color(70, 61, 50, 156);
|
||||
}
|
||||
|
||||
@Alpha
|
||||
@ConfigItem(
|
||||
keyName = "titleColor",
|
||||
name = "Title color",
|
||||
description = "",
|
||||
position = 2
|
||||
)
|
||||
default Color titleColor()
|
||||
{
|
||||
return Color.white;
|
||||
}
|
||||
}
|
||||
@@ -1,83 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, James Munson <https://github.com/james-munson>
|
||||
* 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 HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.tickcounter;
|
||||
|
||||
/*public class TickCounterOverlay extends Overlay
|
||||
{
|
||||
|
||||
private TickCounterPlugin plugin;
|
||||
private TickCounterConfig config;
|
||||
private Client client;
|
||||
private PanelComponent panelComponent = new PanelComponent();
|
||||
|
||||
@Inject
|
||||
public TickCounterOverlay(TickCounterPlugin plugin, Client client, TickCounterConfig config)
|
||||
{
|
||||
super(plugin);
|
||||
setPosition(OverlayPosition.DYNAMIC);
|
||||
setPosition(OverlayPosition.DETACHED);
|
||||
setPosition(OverlayPosition.BOTTOM_RIGHT);
|
||||
this.plugin = plugin;
|
||||
this.client = client;
|
||||
this.config = config;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Dimension render(Graphics2D g)
|
||||
{
|
||||
List<LayoutableRenderableEntity> elems = panelComponent.getChildren();
|
||||
elems.clear();
|
||||
panelComponent.setBackgroundColor(config.bgColor());
|
||||
elems.add(TitleComponent.builder().text("Combat counter").color(config.titleColor()).build());
|
||||
List<Entry<String, Integer>> list = new ArrayList<>(plugin.activity.entrySet());
|
||||
list.sort((o1, o2) ->
|
||||
{
|
||||
int value = -Integer.compare(o1.getValue(), o2.getValue());
|
||||
if (value == 0)
|
||||
{
|
||||
value = o1.getKey().compareTo(o2.getKey());
|
||||
}
|
||||
return value;
|
||||
});
|
||||
int total = 0;
|
||||
for (Entry<String, Integer> e : list)
|
||||
{
|
||||
total += e.getValue();
|
||||
if (e.getKey().equals(client.getLocalPlayer().getName()))
|
||||
{
|
||||
elems.add(LineComponent.builder().leftColor(config.selfColor()).rightColor(config.selfColor()).left(e.getKey()).right(e.getValue().toString()).build());
|
||||
}
|
||||
else
|
||||
{
|
||||
elems.add(LineComponent.builder().left(e.getKey()).right(e.getValue().toString()).leftColor(config.otherColor()).rightColor(config.otherColor()).build());
|
||||
|
||||
}
|
||||
}
|
||||
elems.add(LineComponent.builder().left("Total").leftColor(config.totalColor()).rightColor(config.totalColor()).right(String.valueOf(total)).build());
|
||||
return this.panelComponent.render(g);
|
||||
}
|
||||
|
||||
}*/
|
||||
@@ -1,233 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, James Munson <https://github.com/james-munson>
|
||||
* 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 HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.tickcounter;
|
||||
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
|
||||
@PluginDescriptor(name = "Tick Counter",
|
||||
description = "Counts combat activity for nearby players",
|
||||
enabledByDefault = false,
|
||||
type = PluginType.PVP
|
||||
)
|
||||
public class TickCounterPlugin extends Plugin
|
||||
{
|
||||
//todo once bytecodes work again, re-enable
|
||||
/*
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private TickCounterConfig config;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Provides
|
||||
TickCounterConfig provideConfig(ConfigManager configManager)
|
||||
{
|
||||
return configManager.getConfig(TickCounterConfig.class);
|
||||
}
|
||||
|
||||
@Inject
|
||||
private TickCounterOverlay overlay;
|
||||
|
||||
Map<String, Integer> activity = new HashMap<>();
|
||||
|
||||
private List<Player> blowpiping = new ArrayList<>();
|
||||
private boolean instanced = false;
|
||||
|
||||
@Override
|
||||
protected void startUp() throws Exception
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown() throws Exception
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
activity.clear();
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onAnimationChanged(AnimationChanged e)
|
||||
{
|
||||
if (!(e.getActor() instanceof Player))
|
||||
{
|
||||
return;
|
||||
}
|
||||
Player p = (Player) e.getActor();
|
||||
int weapon = -1;
|
||||
if (p.getPlayerAppearance() != null)
|
||||
{
|
||||
weapon = p.getPlayerAppearance().getEquipmentId(KitType.WEAPON);
|
||||
}
|
||||
int delta = 0;
|
||||
switch (p.getAnimation())
|
||||
{
|
||||
case 7617: // rune knife
|
||||
case 8194: // dragon knife
|
||||
case 8291: // dragon knife spec
|
||||
case 5061: // blowpipe
|
||||
if (weapon == 12926)
|
||||
{
|
||||
blowpiping.add(p);
|
||||
}
|
||||
else
|
||||
{
|
||||
delta = 2;
|
||||
}
|
||||
break;
|
||||
case 2323: // rpg
|
||||
case 7618: // chin
|
||||
delta = 3;
|
||||
break;
|
||||
case 426: // bow shoot
|
||||
if (weapon == 20997) // twisted bow
|
||||
{
|
||||
delta = 5;
|
||||
}
|
||||
else // shortbow
|
||||
{
|
||||
delta = 3;
|
||||
}
|
||||
break;
|
||||
case 376: // dds poke
|
||||
case 377: // dds slash
|
||||
case 422: // punch
|
||||
case 423: // kick
|
||||
case 386: // lunge
|
||||
case 390: // generic slash
|
||||
case 1062: // dds spec
|
||||
case 1067: // claw stab
|
||||
case 1074: // msb spec
|
||||
case 1167: // trident cast
|
||||
case 1658: // whip
|
||||
case 2890: // arclight spec
|
||||
case 3294: // abby dagger slash
|
||||
case 3297: // abby dagger poke
|
||||
case 3298: // bludgeon attack
|
||||
case 3299: // bludgeon spec
|
||||
case 3300: // abby dagger spec
|
||||
case 7514: // claw spec
|
||||
case 7515: // d sword spec
|
||||
case 8145: // rapier stab
|
||||
case 8288: // dhl stab
|
||||
case 8289: // dhl slash
|
||||
case 8290: // dhl crush
|
||||
delta = 4;
|
||||
break;
|
||||
case 393: // staff bash
|
||||
if (weapon == 13652)
|
||||
{ // claw scratch
|
||||
delta = 4;
|
||||
break;
|
||||
}
|
||||
case 395: // axe autos
|
||||
case 400: // pick smash
|
||||
case 1379: //burst or blitz
|
||||
case 1979: // barrage spell cast
|
||||
case 1162: // strike/bolt spells
|
||||
case 7552: // generic crossbow
|
||||
case 7855: // surge spells
|
||||
case 8056: // scythe swing
|
||||
delta = 5;
|
||||
break;
|
||||
case 401:
|
||||
if (weapon == 13576) // dwh bop
|
||||
{
|
||||
delta = 6;
|
||||
}
|
||||
else // used by pickaxe and axe
|
||||
{
|
||||
delta = 5;
|
||||
}
|
||||
break;
|
||||
case 1378:
|
||||
case 7045:
|
||||
case 7054:
|
||||
case 7055: // godsword autos
|
||||
case 7511: // dinh's attack
|
||||
case 7516: // maul attack
|
||||
case 7555: // ballista attack
|
||||
case 7638: // zgs spec
|
||||
case 7640: // sgs spec
|
||||
case 7642: // bgs spec
|
||||
case 7643: // bgs spec
|
||||
case 7644: // ags spec
|
||||
delta = 6;
|
||||
break;
|
||||
case 428: // chally swipe
|
||||
case 440: // chally jab
|
||||
case 1203: // chally spec
|
||||
delta = 7;
|
||||
break;
|
||||
case -1:
|
||||
blowpiping.remove(p);
|
||||
break;
|
||||
}
|
||||
if (delta > 0)
|
||||
{
|
||||
String name = p.getName();
|
||||
this.activity.put(name, this.activity.getOrDefault(name, 0) + delta);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onClientTick(ClientTick e)
|
||||
{
|
||||
*//*
|
||||
* Hack for blowpipe since the AnimationChanged event doesn't fire when using a
|
||||
* blowpipe because of its speed. If blowpipe animation restarts, then add 2
|
||||
*//*
|
||||
for (Player p : blowpiping)
|
||||
{
|
||||
if (p.getActionFrame() == 0 && p.getActionFrameCycle() == 1)
|
||||
{
|
||||
String name = p.getName();
|
||||
int activity = this.activity.getOrDefault(name, 0);
|
||||
this.activity.put(name, activity + 2);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick tick)
|
||||
{
|
||||
if (!config.instance())
|
||||
{
|
||||
return;
|
||||
}
|
||||
boolean prevInstance = instanced;
|
||||
instanced = client.isInInstancedRegion();
|
||||
if (!prevInstance && instanced)
|
||||
{
|
||||
activity.clear();
|
||||
}
|
||||
}*/
|
||||
}
|
||||
@@ -1,219 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.vorkath;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import javax.inject.Inject;
|
||||
import lombok.Getter;
|
||||
import api.AnimationID;
|
||||
import api.Client;
|
||||
import api.GameState;
|
||||
import api.NPC;
|
||||
import api.NpcID;
|
||||
import api.events.GameStateChanged;
|
||||
import api.events.GameTick;
|
||||
import api.events.NpcDespawned;
|
||||
import api.events.NpcSpawned;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.eventbus.Subscribe;
|
||||
import net.runelite.client.plugins.Plugin;
|
||||
import net.runelite.client.plugins.PluginDescriptor;
|
||||
import net.runelite.client.plugins.PluginType;
|
||||
import net.runelite.client.ui.overlay.OverlayManager;
|
||||
import net.runelite.client.util.ImageUtil;
|
||||
|
||||
@PluginDescriptor(
|
||||
name = "Vorkath Helper",
|
||||
description = "Count vorkath attacks, and which phase is coming next",
|
||||
tags = {"combat", "overlay", "pve", "pvm"},
|
||||
type = PluginType.PVM
|
||||
)
|
||||
public class VorkathPlugin extends Plugin
|
||||
{
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private OverlayManager overlayManager;
|
||||
|
||||
@Inject
|
||||
private VorkathOverlay overlay;
|
||||
|
||||
@Inject
|
||||
private ZombifiedSpawnOverlay SpawnOverlay;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
@Getter
|
||||
private Vorkath vorkath;
|
||||
|
||||
@Getter
|
||||
private ZombifiedSpawn spawn;
|
||||
|
||||
static final BufferedImage ACID;
|
||||
static final BufferedImage ICE;
|
||||
static final BufferedImage MAGERANGE;
|
||||
|
||||
static
|
||||
{
|
||||
ACID = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "acid.png");
|
||||
ICE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "ice.png");
|
||||
MAGERANGE = ImageUtil.getResourceStreamFromClass(VorkathPlugin.class, "magerange.png");
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void startUp()
|
||||
{
|
||||
overlayManager.add(overlay);
|
||||
overlayManager.add(SpawnOverlay);
|
||||
clientThread.invoke(this::reset);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void shutDown()
|
||||
{
|
||||
overlayManager.remove(overlay);
|
||||
overlayManager.remove(SpawnOverlay);
|
||||
}
|
||||
|
||||
private void reset()
|
||||
{
|
||||
this.vorkath = null;
|
||||
for (NPC npc : client.getNpcs())
|
||||
{
|
||||
if (isNpcVorkath(npc.getId()))
|
||||
{
|
||||
this.vorkath = new Vorkath(npc);
|
||||
}
|
||||
else if (isNpcZombifiedSpawn(npc.getId()))
|
||||
{
|
||||
this.spawn = new ZombifiedSpawn(npc);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private static boolean isNpcVorkath(int npcId)
|
||||
{
|
||||
return npcId == NpcID.VORKATH ||
|
||||
npcId == NpcID.VORKATH_8058 ||
|
||||
npcId == NpcID.VORKATH_8059 ||
|
||||
npcId == NpcID.VORKATH_8060 ||
|
||||
npcId == NpcID.VORKATH_8061;
|
||||
}
|
||||
|
||||
private static boolean isNpcZombifiedSpawn(int id)
|
||||
{
|
||||
return id == NpcID.ZOMBIFIED_SPAWN ||
|
||||
id == NpcID.ZOMBIFIED_SPAWN_8063;
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcSpawned(NpcSpawned event)
|
||||
{
|
||||
NPC npc = event.getNpc();
|
||||
if (isNpcVorkath(npc.getId()))
|
||||
{
|
||||
this.vorkath = new Vorkath(npc);
|
||||
}
|
||||
else if (isNpcZombifiedSpawn(npc.getId()))
|
||||
{
|
||||
this.spawn = new ZombifiedSpawn(npc);
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onNpcDespawned(NpcDespawned npcDespawned)
|
||||
{
|
||||
final NPC npc = npcDespawned.getNpc();
|
||||
if (this.vorkath != null)
|
||||
{
|
||||
if (npc.getId() == this.vorkath.getNpc().getId())
|
||||
{
|
||||
this.vorkath = null;
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
if (this.spawn != null)
|
||||
{
|
||||
if (npc.getId() == this.spawn.getNpc().getId())
|
||||
{
|
||||
this.spawn = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@Subscribe
|
||||
public void onGameStateChanged(GameStateChanged event)
|
||||
{
|
||||
GameState gs = event.getGameState();
|
||||
if (gs == GameState.LOGGING_IN ||
|
||||
gs == GameState.CONNECTION_LOST ||
|
||||
gs == GameState.HOPPING)
|
||||
{
|
||||
reset();
|
||||
}
|
||||
}
|
||||
|
||||
@Subscribe
|
||||
public void onGameTick(GameTick event)
|
||||
{
|
||||
if (vorkath != null)
|
||||
{
|
||||
int animationId = vorkath.getNpc().getAnimation();
|
||||
|
||||
if (animationId != vorkath.getLastTickAnimation())
|
||||
{
|
||||
if (animationId == AnimationID.VORKATH_ACID_ATTACK)
|
||||
{
|
||||
vorkath.setPhase(2);
|
||||
vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
|
||||
}
|
||||
else if (animationId == AnimationID.VORKATH_ATTACK && vorkath.getAttacksUntilSwitch() == 0)
|
||||
{
|
||||
vorkath.setPhase(1);
|
||||
vorkath.setAttacksUntilSwitch(Vorkath.ATTACKS_PER_SWITCH);
|
||||
//Vorkath does a bomb animation after the ice dragon breathe, we need to account for it
|
||||
vorkath.setIcePhaseAttack(true);
|
||||
}
|
||||
else if (animationId == AnimationID.VORKATH_ATTACK || animationId == AnimationID.VORKATH_FIRE_BOMB_ATTACK)
|
||||
{
|
||||
if (vorkath.isIcePhaseAttack())
|
||||
{
|
||||
vorkath.setIcePhaseAttack(false);
|
||||
}
|
||||
else
|
||||
{
|
||||
vorkath.setAttacksUntilSwitch(vorkath.getAttacksUntilSwitch() - 1);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vorkath.setLastTickAnimation(animationId);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Abexlry <abexlry@gmail.com>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.wasdcamera;
|
||||
|
||||
import com.google.common.base.Strings;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.inject.Inject;
|
||||
import api.Client;
|
||||
import api.GameState;
|
||||
import api.VarClientStr;
|
||||
import net.runelite.client.callback.ClientThread;
|
||||
import net.runelite.client.input.KeyListener;
|
||||
import net.runelite.client.input.MouseAdapter;
|
||||
|
||||
class WASDCameraListener extends MouseAdapter implements KeyListener
|
||||
{
|
||||
@Inject
|
||||
private WASDCameraPlugin plugin;
|
||||
|
||||
@Inject
|
||||
private WASDCameraConfig config;
|
||||
|
||||
@Inject
|
||||
private Client client;
|
||||
|
||||
@Inject
|
||||
private ClientThread clientThread;
|
||||
|
||||
private final Map<Integer, Integer> modified = new HashMap<>();
|
||||
|
||||
@Override
|
||||
public void keyTyped(KeyEvent e)
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyPressed(KeyEvent e)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN || !plugin.chatboxFocused())
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (!plugin.isTyping())
|
||||
{
|
||||
if (config.up().matches(e))
|
||||
{
|
||||
modified.put(e.getKeyCode(), KeyEvent.VK_UP);
|
||||
e.setKeyCode(KeyEvent.VK_UP);
|
||||
}
|
||||
else if (config.down().matches(e))
|
||||
{
|
||||
modified.put(e.getKeyCode(), KeyEvent.VK_DOWN);
|
||||
e.setKeyCode(KeyEvent.VK_DOWN);
|
||||
}
|
||||
else if (config.left().matches(e))
|
||||
{
|
||||
modified.put(e.getKeyCode(), KeyEvent.VK_LEFT);
|
||||
e.setKeyCode(KeyEvent.VK_LEFT);
|
||||
}
|
||||
else if (config.right().matches(e))
|
||||
{
|
||||
modified.put(e.getKeyCode(), KeyEvent.VK_RIGHT);
|
||||
e.setKeyCode(KeyEvent.VK_RIGHT);
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (e.getKeyCode())
|
||||
{
|
||||
case KeyEvent.VK_ENTER:
|
||||
case KeyEvent.VK_SLASH:
|
||||
case KeyEvent.VK_COLON:
|
||||
// refocus chatbox
|
||||
plugin.setTyping(true);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
plugin.unlockChat();
|
||||
});
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (e.getKeyCode())
|
||||
{
|
||||
case KeyEvent.VK_ENTER:
|
||||
plugin.setTyping(false);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
plugin.lockChat();
|
||||
});
|
||||
break;
|
||||
case KeyEvent.VK_ESCAPE:
|
||||
plugin.setTyping(false);
|
||||
clientThread.invoke(() ->
|
||||
{
|
||||
client.setVar(VarClientStr.CHATBOX_TYPED_TEXT, "");
|
||||
plugin.lockChat();
|
||||
});
|
||||
break;
|
||||
case KeyEvent.VK_BACK_SPACE:
|
||||
if (Strings.isNullOrEmpty(client.getVar(VarClientStr.CHATBOX_TYPED_TEXT)))
|
||||
{
|
||||
plugin.setTyping(false);
|
||||
clientThread.invoke(() -> plugin.lockChat());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void keyReleased(KeyEvent e)
|
||||
{
|
||||
if (client.getGameState() != GameState.LOGGED_IN)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (plugin.chatboxFocused() && !plugin.isTyping())
|
||||
{
|
||||
modified.remove(e.getKeyCode());
|
||||
|
||||
if (config.up().matches(e))
|
||||
{
|
||||
e.setKeyCode(KeyEvent.VK_UP);
|
||||
}
|
||||
else if (config.down().matches(e))
|
||||
{
|
||||
e.setKeyCode(KeyEvent.VK_DOWN);
|
||||
}
|
||||
else if (config.left().matches(e))
|
||||
{
|
||||
e.setKeyCode(KeyEvent.VK_LEFT);
|
||||
}
|
||||
else if (config.right().matches(e))
|
||||
{
|
||||
e.setKeyCode(KeyEvent.VK_RIGHT);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
// press d + enter + release d - causes the right arrow to never be released
|
||||
Integer m = modified.get(e.getKeyCode());
|
||||
if (m != null)
|
||||
{
|
||||
modified.remove(e.getKeyCode());
|
||||
e.setKeyCode(m);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,177 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2018, John James Hamilton <https://github.com/johnhamilto>
|
||||
* 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 HOLDER OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
|
||||
* CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.worldmap;
|
||||
|
||||
import lombok.Getter;
|
||||
import api.coords.WorldPoint;
|
||||
|
||||
enum QuestStartLocation
|
||||
{
|
||||
//Free Quests
|
||||
COOKS_ASSISTANT_RFD("Cook's Assistant", new WorldPoint(3211, 3216, 0)),
|
||||
THE_CORSAIR_CURSE("The Corsair Curse", new WorldPoint(3029, 3273, 0)),
|
||||
DEMON_SLAYER("Demon Slayer", new WorldPoint(3204, 3424, 0)),
|
||||
DORICS_QUEST("Doric's Quest", new WorldPoint(2952, 3450, 0)),
|
||||
DRAGON_SLAYER("Dragon Slayer", new WorldPoint(3190, 3362, 0)),
|
||||
ERNEST_THE_CHICKEN("Ernest the Chicken", new WorldPoint(3109, 3330, 0)),
|
||||
GOBLIN_DIPLOMACY("Goblin Diplomacy", new WorldPoint(2957, 3509, 0)),
|
||||
IMP_CATCHER("Imp Catcher", new WorldPoint(3108, 3160, 0)),
|
||||
THE_KNIGHTS_SWORD("The Knight's Sword", new WorldPoint(2976, 3342, 0)),
|
||||
MISTHALIN_MYSTERY("Misthalin Mystery", new WorldPoint(3234, 3155, 0)),
|
||||
PIRATES_TREASURE("Pirate's Treasure", new WorldPoint(3051, 3252, 0)),
|
||||
PRINCE_ALI_RESCUE("Prince Ali Rescue", new WorldPoint(3301, 3163, 0)),
|
||||
THE_RESTLESS_GHOST("The Restless Ghost", new WorldPoint(3240, 3210, 0)),
|
||||
RUNE_MYSTERIES("Rune Mysteries", new WorldPoint(3210, 3220, 0)),
|
||||
SHEEP_SHEARER("Sheep Shearer", new WorldPoint(3190, 3272, 0)),
|
||||
SHIELD_OF_ARRAV_PHOENIX_GANG("Shield of Arrav (Phoenix Gang)", new WorldPoint(3208, 3495, 0)),
|
||||
SHIELD_OF_ARRAV_BLACK_ARM_GANG("Shield of Arrav (Black Arm Gang)", new WorldPoint(3208, 3392, 0)),
|
||||
VAMPIRE_SLAYER("Vampire Slayer", new WorldPoint(3096, 3266, 0)),
|
||||
WITCHS_POTION("Witch's Potion", new WorldPoint(2967, 3203, 0)),
|
||||
X_MARKS_THE_SPOT("X Marks the Spot", new WorldPoint(3227, 3242, 0)),
|
||||
|
||||
//Members' Quests
|
||||
ANIMAL_MAGNETISM("Animal Magnetism", new WorldPoint(3094, 3360, 0)),
|
||||
ANOTHER_SLICE_OF_HAM("Another Slice of H.A.M.", new WorldPoint(2799, 5428, 0)),
|
||||
THE_ASCENT_OF_ARCEUUS("The Ascent of Arceuus", new WorldPoint(1700, 3742, 0)),
|
||||
BETWEEN_A_ROCK("Between a Rock...", new WorldPoint(2823, 10168, 0)),
|
||||
BIG_CHOMPY_BIRD_HUNTING("Big Chompy Bird Hunting", new WorldPoint(2629, 2981, 0)),
|
||||
BIOHAZARD("Biohazard", new WorldPoint(2591, 3335, 0)),
|
||||
BONE_VOYAGE("Bone Voyage", new WorldPoint(3259, 3450, 0)),
|
||||
CABIN_FEVER("Cabin Fever", new WorldPoint(3674, 3496, 0)),
|
||||
CLIENT_OF_KOUREND("Client of Kourend", new WorldPoint(1823, 3690, 0)),
|
||||
CLOCK_TOWER("Clock Tower", new WorldPoint(2568, 3249, 0)),
|
||||
COLD_WAR("Cold War", new WorldPoint(2593, 3265, 0)),
|
||||
CONTACT("Contact!", new WorldPoint(3280, 2770, 0)),
|
||||
CREATURE_OF_FENKENSTRAIN("Creature of Fenkenstrain", new WorldPoint(3487, 3485, 0)),
|
||||
DARKNESS_OF_HALLOWVALE("Darkness of Hallowvale", new WorldPoint(3494, 9628, 0)),
|
||||
DEATH_PLATEAU_TROLL_STRONGHOLD("Death Plateau & Troll Stronghold", new WorldPoint(2895, 3528, 0)),
|
||||
DEATH_TO_THE_DORGESHUUN("Death to the Dorgeshuun", new WorldPoint(3316, 9613, 0)),
|
||||
THE_DEPTHS_OF_DESPAIR("The Depths of Despair", new WorldPoint(1846, 3556, 0)),
|
||||
DESERT_TREASURE("Desert Treasure", new WorldPoint(3177, 3043, 0)),
|
||||
DEVIOUS_MINDS("Devious Minds", new WorldPoint(3405, 3492, 0)),
|
||||
THE_DIG_SITE("The Dig Site", new WorldPoint(3363, 3337, 0)),
|
||||
DRAGON_SLAYER_II("Dragon Slayer II", new WorldPoint(2456, 2868, 0)),
|
||||
DREAM_MENTOR("Dream Mentor", new WorldPoint(2144, 10346, 0)),
|
||||
DRUIDIC_RITUAL("Druidic Ritual", new WorldPoint(2916, 3484, 0)),
|
||||
DWARF_CANNON("Dwarf Cannon", new WorldPoint(2566, 3461, 0)),
|
||||
EADGARS_RUSE("Eadgar's Ruse", new WorldPoint(2896, 3426, 0)),
|
||||
EAGLES_PEAK("Eagles' Peak", new WorldPoint(2605, 3264, 0)),
|
||||
ELEMENTAL_WORKSHOP("Elemental Workshop I & II", new WorldPoint(2714, 3482, 0)),
|
||||
ENAKHRAS_LAMENT("Enakhra's Lament", new WorldPoint(3190, 2926, 0)),
|
||||
ENLIGHTENED_JOURNEY("Enlightened Journey", new WorldPoint(2809, 3356, 0)),
|
||||
THE_EYES_OF_GLOUPHRIE("The Eyes of Glouphrie", new WorldPoint(2400, 3419, 0)),
|
||||
FAIRYTALE("Fairytale I & II", new WorldPoint(3077, 3258, 0)),
|
||||
FAMILY_CREST("Family Crest", new WorldPoint(3278, 3404, 0)),
|
||||
THE_FEUD("The Feud", new WorldPoint(3301, 3211, 0)),
|
||||
FIGHT_ARENA("Fight Arena", new WorldPoint(2565, 3199, 0)),
|
||||
FISHING_CONTEST_1("Fishing Contest", new WorldPoint(2875, 3483, 0)),
|
||||
FISHING_CONTEST_2("Fishing Contest", new WorldPoint(2820, 3487, 0)),
|
||||
FORGETTABLE_TALE("Forgettable Tale...", new WorldPoint(2826, 10215, 0)),
|
||||
THE_FORSAKEN_TOWER("The Forsaken Tower", new WorldPoint(1484, 3747, 0)),
|
||||
THE_FREMENNIK_ISLES("The Fremennik Isles", new WorldPoint(2645, 3711, 0)),
|
||||
THE_FREMENNIK_TRIALS("The Fremennik Trials", new WorldPoint(2657, 3669, 0)),
|
||||
GARDEN_OF_TRANQUILLITY("Garden of Tranquillity", new WorldPoint(3227, 3477, 0)),
|
||||
GERTRUDES_CAT_RATCATCHERS("Gertrude's Cat & Ratcatchers", new WorldPoint(3150, 3411, 0)),
|
||||
GHOSTS_AHOY("Ghosts Ahoy", new WorldPoint(3677, 3510, 0)),
|
||||
THE_GIANT_DWARF("The Giant Dwarf", new WorldPoint(2841, 10129, 0)),
|
||||
THE_GOLEM("The Golem", new WorldPoint(3487, 3089, 0)),
|
||||
THE_GRAND_TREE_MONKEY_MADNESS("The Grand Tree & Monkey Madness I & II", new WorldPoint(2466, 3497, 0)),
|
||||
THE_GREAT_BRAIN_ROBBERY("The Great Brain Robbery", new WorldPoint(3681, 2963, 0)),
|
||||
GRIM_TALES("Grim Tales", new WorldPoint(2890, 3454, 0)),
|
||||
THE_HAND_IN_THE_SAND("The Hand in the Sand", new WorldPoint(2552, 3101, 0)),
|
||||
HAUNTED_MINE("Haunted Mine", new WorldPoint(3443, 3258, 0)),
|
||||
HAZEEL_CULT("Hazeel Cult", new WorldPoint(2565, 3271, 0)),
|
||||
HEROES_QUEST("Heroes' Quest", new WorldPoint(2903, 3511, 0)),
|
||||
HOLY_GRAIL("Holy Grail & Merlin's Crystal", new WorldPoint(2763, 3515, 0)),
|
||||
HORROR_FROM_THE_DEEP("Horror from the Deep", new WorldPoint(2507, 3635, 0)),
|
||||
ICTHLARINS_LITTLE_HELPER("Icthlarin's Little Helper", new WorldPoint(3314, 2849, 0)),
|
||||
IN_SEARCH_OF_THE_MYREQUE("In Search of the Myreque", new WorldPoint(3502, 3477, 0)),
|
||||
JUNGLE_POTION("Jungle Potion", new WorldPoint(2809, 3086, 0)),
|
||||
KINGS_RANSOM("King's Ransom", new WorldPoint(2741, 3554, 0)),
|
||||
LEGENDS_QUEST("Legends' Quest", new WorldPoint(2725, 3367, 0)),
|
||||
LOST_CITY("Lost City", new WorldPoint(3149, 3205, 0)),
|
||||
THE_LOST_TRIBE("The Lost Tribe", new WorldPoint(3211, 3224, 0)),
|
||||
LUNAR_DIPLOMACY("Lunar Diplomacy", new WorldPoint(2619, 3689, 0)),
|
||||
MAKING_FRIENDS_WITH_MY_ARM("Making Friends with My Arm", new WorldPoint(2904, 10092, 0)),
|
||||
MAKING_HISTORY("Making History", new WorldPoint(2435, 3346, 0)),
|
||||
MONKS_FRIEND("Monk's Friend", new WorldPoint(2605, 3209, 0)),
|
||||
MOUNTAIN_DAUGHTER("Mountain Daughter", new WorldPoint(2810, 3672, 0)),
|
||||
MOURNINGS_ENDS_PART_I("Mourning's Ends Part I", new WorldPoint(2289, 3149, 0)),
|
||||
MOURNINGS_ENDS_PART_II("Mourning's Ends Part II", new WorldPoint(2352, 3172, 0)),
|
||||
MURDER_MYSTERY("Murder Mystery", new WorldPoint(2740, 3562, 0)),
|
||||
MY_ARMS_BIG_ADVENTURE("My Arm's Big Adventure", new WorldPoint(2908, 10088, 0)),
|
||||
NATURE_SPIRIT("Nature Spirit", new WorldPoint(3440, 9894, 0)),
|
||||
OBSERVATORY_QUEST("Observatory Quest", new WorldPoint(2438, 3185, 0)),
|
||||
OLAFS_QUEST("Olaf's Quest", new WorldPoint(2723, 3729, 0)),
|
||||
ONE_SMALL_FAVOUR("One Small Favour", new WorldPoint(2834, 2985, 0)),
|
||||
PLAGUE_CITY("Plague City", new WorldPoint(2567, 3334, 0)),
|
||||
PRIEST_IN_PERIL("Priest in Peril", new WorldPoint(3219, 3473, 0)),
|
||||
THE_QUEEN_OF_THIEVES("The Queen of Thieves", new WorldPoint(1795, 3782, 0)),
|
||||
RAG_AND_BONE_MAN("Rag and Bone Man I & II", new WorldPoint(3359, 3504, 0)),
|
||||
RECRUITMENT_DRIVE_BLACK_KNIGHTS_FORTRESS("Recruitment Drive & Black Knights' Fortress", new WorldPoint(2959, 3336, 0)),
|
||||
ROVING_ELVES("Roving Elves", new WorldPoint(2289, 3146, 0)),
|
||||
RUM_DEAL("Rum Deal", new WorldPoint(3679, 3535, 0)),
|
||||
SCORPION_CATCHER("Scorpion Catcher", new WorldPoint(2701, 3399, 0)),
|
||||
SEA_SLUG("Sea Slug", new WorldPoint(2715, 3302, 0)),
|
||||
SHADES_OF_MORTTON("Shades of Mort'ton", new WorldPoint(3463, 3308, 0)),
|
||||
SHADOW_OF_THE_STORM("Shadow of the Storm", new WorldPoint(3270, 3159, 0)),
|
||||
SHEEP_HERDER("Sheep Herder", new WorldPoint(2616, 3299, 0)),
|
||||
SHILO_VILLAGE("Shilo Village", new WorldPoint(2882, 2951, 0)),
|
||||
A_SOULS_BANE("A Soul's Bane", new WorldPoint(3307, 3454, 0)),
|
||||
SPIRITS_OF_THE_ELID("Spirits of the Elid", new WorldPoint(3441, 2911, 0)),
|
||||
SWAN_SONG("Swan Song", new WorldPoint(2345, 3652, 0)),
|
||||
TAI_BWO_WANNAI_TRIO("Tai Bwo Wannai Trio", new WorldPoint(2779, 3087, 0)),
|
||||
A_TAIL_OF_TWO_CATS("A Tail of Two Cats", new WorldPoint(2917, 3557, 0)),
|
||||
TALE_OF_THE_RIGHTEOUS("Tale of the Righteous", new WorldPoint(1511, 3631, 0)),
|
||||
A_TASTE_OF_HOPE("A Taste of Hope", new WorldPoint(3668, 3216, 0)),
|
||||
TEARS_OF_GUTHIX("Tears of Guthix", new WorldPoint(3251, 9517, 0)),
|
||||
TEMPLE_OF_IKOV("Temple of Ikov", new WorldPoint(2574, 3320, 0)),
|
||||
THRONE_OF_MISCELLANIA_ROYAL_TROUBLE("Throne of Miscellania & Royal Trouble", new WorldPoint(2497, 3859, 0)),
|
||||
THE_TOURIST_TRAP("The Tourist Trap", new WorldPoint(3302, 3113, 0)),
|
||||
TOWER_OF_LIFE("Tower of Life", new WorldPoint(2640, 3218, 0)),
|
||||
TREE_GNOME_VILLAGE("Tree Gnome Village", new WorldPoint(2541, 3169, 0)),
|
||||
TRIBAL_TOTEM("Tribal Totem", new WorldPoint(2790, 3182, 0)),
|
||||
TROLL_ROMANCE("Troll Romance", new WorldPoint(2890, 10097, 0)),
|
||||
UNDERGROUND_PASS_REGICIDE("Underground Pass & Regicide", new WorldPoint(2575, 3293, 0)),
|
||||
WANTED_SLUG_MENACE("Wanted! & The Slug Menace", new WorldPoint(2996, 3373, 0)),
|
||||
WATCHTOWER("Watchtower", new WorldPoint(2545, 3112, 0)),
|
||||
WATERFALL_QUEST("Waterfall Quest", new WorldPoint(2521, 3498, 0)),
|
||||
WHAT_LIES_BELOW("What Lies Below", new WorldPoint(3265, 3333, 0)),
|
||||
WITCHS_HOUSE("Witch's House", new WorldPoint(2927, 3456, 0)),
|
||||
ZOGRE_FLESH_EATERS("Zogre Flesh Eaters", new WorldPoint(2442, 3051, 0));
|
||||
|
||||
@Getter
|
||||
private final String tooltip;
|
||||
|
||||
@Getter
|
||||
private final WorldPoint location;
|
||||
|
||||
QuestStartLocation(String description, WorldPoint location)
|
||||
{
|
||||
this.tooltip = "Quest Start - " + description;
|
||||
this.location = location;
|
||||
}
|
||||
}
|
||||
@@ -1,254 +0,0 @@
|
||||
/*
|
||||
* Copyright (c) 2016-2017, Adam <Adam@sigterm.info>
|
||||
* Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
* Copyright (c) 2018 Abex
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
* this list of conditions and the following disclaimer in the documentation
|
||||
* and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
|
||||
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR
|
||||
* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
|
||||
* (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
|
||||
* LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.rs;
|
||||
|
||||
import api.Client;
|
||||
import com.google.common.io.ByteStreams;
|
||||
import io.sigpipe.jbsdiff.InvalidHeaderException;
|
||||
import io.sigpipe.jbsdiff.Patch;
|
||||
import java.applet.Applet;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.File;
|
||||
import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.net.URL;
|
||||
import java.security.cert.Certificate;
|
||||
import java.security.cert.CertificateException;
|
||||
import java.security.cert.CertificateFactory;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collection;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.jar.Attributes;
|
||||
import java.util.jar.JarEntry;
|
||||
import java.util.jar.JarInputStream;
|
||||
import java.util.jar.Manifest;
|
||||
import javax.inject.Inject;
|
||||
import javax.inject.Named;
|
||||
import javax.inject.Singleton;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.AUTO;
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.CUSTOM;
|
||||
import static net.runelite.client.rs.ClientUpdateCheckMode.NONE;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import okhttp3.Request;
|
||||
import okhttp3.Response;
|
||||
import org.apache.commons.compress.compressors.CompressorException;
|
||||
|
||||
@Slf4j
|
||||
@Singleton
|
||||
public class ClientLoader
|
||||
{
|
||||
private static final File CUSTOMFILE = new File("./injected-client/target/injected-client-1.5.25-SNAPSHOT.jar");
|
||||
private final ClientConfigLoader clientConfigLoader;
|
||||
private ClientUpdateCheckMode updateCheckMode;
|
||||
|
||||
@Inject
|
||||
private ClientLoader(
|
||||
@Named("updateCheckMode") final ClientUpdateCheckMode updateCheckMode,
|
||||
final ClientConfigLoader clientConfigLoader)
|
||||
{
|
||||
this.updateCheckMode = updateCheckMode;
|
||||
this.clientConfigLoader = clientConfigLoader;
|
||||
}
|
||||
|
||||
public Applet load()
|
||||
{
|
||||
if (updateCheckMode == NONE)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
updateCheckMode = CUSTOM;
|
||||
try
|
||||
{
|
||||
Manifest manifest = new Manifest();
|
||||
manifest.getMainAttributes().put(Attributes.Name.MANIFEST_VERSION, "1.0");
|
||||
RSConfig config = clientConfigLoader.fetch();
|
||||
|
||||
Map<String, byte[]> zipFile = new HashMap<>();
|
||||
{
|
||||
Certificate[] jagexCertificateChain = getJagexCertificateChain();
|
||||
String codebase = config.getCodeBase();
|
||||
String initialJar = config.getInitialJar();
|
||||
URL url = new URL(codebase + initialJar);
|
||||
Request request = new Request.Builder()
|
||||
.url(url)
|
||||
.build();
|
||||
|
||||
try (Response response = RuneLiteAPI.CLIENT.newCall(request).execute())
|
||||
{
|
||||
JarInputStream jis;
|
||||
|
||||
jis = new JarInputStream(response.body().byteStream());
|
||||
byte[] tmp = new byte[4096];
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
|
||||
for (; ; )
|
||||
{
|
||||
JarEntry metadata = jis.getNextJarEntry();
|
||||
if (metadata == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.reset();
|
||||
for (; ; )
|
||||
{
|
||||
int n = jis.read(tmp);
|
||||
if (n <= -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
buffer.write(tmp, 0, n);
|
||||
}
|
||||
|
||||
if (!Arrays.equals(metadata.getCertificates(), jagexCertificateChain))
|
||||
{
|
||||
if (metadata.getName().startsWith("META-INF/"))
|
||||
{
|
||||
// META-INF/JAGEXLTD.SF and META-INF/JAGEXLTD.RSA are not signed, but we don't need
|
||||
// anything in META-INF anyway.
|
||||
continue;
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new VerificationException("Unable to verify jar entry: " + metadata.getName());
|
||||
}
|
||||
}
|
||||
|
||||
zipFile.put(metadata.getName(), buffer.toByteArray());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (updateCheckMode == AUTO)
|
||||
{
|
||||
ByteArrayOutputStream patchOs = new ByteArrayOutputStream(756 * 1024);
|
||||
int patchCount = 0;
|
||||
|
||||
for (Map.Entry<String, byte[]> file : zipFile.entrySet())
|
||||
{
|
||||
byte[] bytes;
|
||||
try (InputStream is = ClientLoader.class.getResourceAsStream("/patch/" + file.getKey() + ".bs"))
|
||||
{
|
||||
if (is == null)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
bytes = ByteStreams.toByteArray(is);
|
||||
}
|
||||
|
||||
patchOs.reset();
|
||||
Patch.patch(file.getValue(), bytes, patchOs);
|
||||
file.setValue(patchOs.toByteArray());
|
||||
|
||||
++patchCount;
|
||||
}
|
||||
|
||||
log.info("Patched {} classes", patchCount);
|
||||
}
|
||||
|
||||
if (updateCheckMode == CUSTOM)
|
||||
{
|
||||
JarInputStream fis = new JarInputStream(new FileInputStream(CUSTOMFILE));
|
||||
byte[] tmp = new byte[4096];
|
||||
ByteArrayOutputStream buffer = new ByteArrayOutputStream(756 * 1024);
|
||||
for (; ; )
|
||||
{
|
||||
JarEntry metadata = fis.getNextJarEntry();
|
||||
if (metadata == null)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
buffer.reset();
|
||||
for (; ; )
|
||||
{
|
||||
int n = fis.read(tmp);
|
||||
if (n <= -1)
|
||||
{
|
||||
break;
|
||||
}
|
||||
buffer.write(tmp, 0, n);
|
||||
}
|
||||
zipFile.replace(metadata.getName(), buffer.toByteArray());
|
||||
}
|
||||
}
|
||||
|
||||
String initialClass = config.getInitialClass();
|
||||
|
||||
ClassLoader rsClassLoader = new ClassLoader(ClientLoader.class.getClassLoader())
|
||||
{
|
||||
@Override
|
||||
protected Class<?> findClass(String name) throws ClassNotFoundException
|
||||
{
|
||||
String path = name.replace('.', '/').concat(".class");
|
||||
byte[] data = zipFile.get(path);
|
||||
if (data == null)
|
||||
{
|
||||
throw new ClassNotFoundException(name);
|
||||
}
|
||||
|
||||
return defineClass(name, data, 0, data.length);
|
||||
}
|
||||
};
|
||||
|
||||
Class<?> clientClass = rsClassLoader.loadClass(initialClass);
|
||||
|
||||
Applet rs = (Applet) clientClass.newInstance();
|
||||
rs.setStub(new RSAppletStub(config));
|
||||
|
||||
if (rs instanceof Client)
|
||||
{
|
||||
log.info("client-patch {}", "420 blaze it RL pricks");
|
||||
}
|
||||
|
||||
return rs;
|
||||
}
|
||||
catch (IOException | ClassNotFoundException | InstantiationException | IllegalAccessException | SecurityException | VerificationException | CertificateException | CompressorException | InvalidHeaderException e)
|
||||
{
|
||||
if (e instanceof ClassNotFoundException)
|
||||
{
|
||||
log.error("Unable to load client - class not found. This means you"
|
||||
+ " are not running RuneLite with Maven as the client patch"
|
||||
+ " is not in your classpath.");
|
||||
}
|
||||
|
||||
log.error("Error loading RS!", e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
private static Certificate[] getJagexCertificateChain() throws CertificateException
|
||||
{
|
||||
CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509");
|
||||
Collection<? extends Certificate> certificates = certificateFactory.generateCertificates(ClientLoader.class.getResourceAsStream("jagex.crt"));
|
||||
return certificates.toArray(new Certificate[0]);
|
||||
}
|
||||
}
|
||||
@@ -1,8 +0,0 @@
|
||||
runeliteplus.title=RuneLitePlus
|
||||
runeliteplus.version=1.0
|
||||
runeliteplus.version=1.0
|
||||
runeliteplus.discord.appid=409416265891971072
|
||||
runeliteplus.discord.invite=https://discord.gg/HN5gf3m
|
||||
runeliteplus.github.link=https://github.com/runelite-extended/runelite
|
||||
runeliteplus.wiki.link=https://github.com/runelite-extended/runelite/wiki
|
||||
runeliteplus.patreon.link=https://www.patreon.com/RuneLitePlus
|
||||
Binary file not shown.
|
Before Width: | Height: | Size: 47 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 197 B |
Binary file not shown.
|
Before Width: | Height: | Size: 924 B |
Binary file not shown.
|
Before Width: | Height: | Size: 241 B |
Binary file not shown.
|
Before Width: | Height: | Size: 2.9 KiB |
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -1,166 +0,0 @@
|
||||
# Copyright (c) 2018, Tomas Slusny <slusnucky@gmail.com>
|
||||
# Copyright (c) 2018, Psikoi <https://github.com/psikoi>
|
||||
# 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.
|
||||
|
||||
RuneLite Enabled {
|
||||
kind=Dark
|
||||
colorUltraLight=#232323
|
||||
colorExtraLight=#232323
|
||||
colorLight=#232323
|
||||
colorMid=#232323
|
||||
colorDark=#232323
|
||||
colorUltraDark=#232323
|
||||
colorForeground=#C6C6C6
|
||||
}
|
||||
|
||||
RuneLite Active {
|
||||
kind=Light
|
||||
colorUltraLight=#4e4e4e
|
||||
colorExtraLight=#4e4e4e
|
||||
colorLight=#4e4e4e
|
||||
colorMid=#232323
|
||||
colorDark=#232323
|
||||
colorUltraDark=#232323
|
||||
colorForeground=#000000
|
||||
}
|
||||
|
||||
RuneLite Selected Disabled Border {
|
||||
kind=Dark
|
||||
colorUltraLight=#191919
|
||||
colorExtraLight=#191919
|
||||
colorLight=#191919
|
||||
colorMid=#191919
|
||||
colorDark=#191919
|
||||
colorUltraDark=#191919
|
||||
colorForeground=#C6C6C6
|
||||
}
|
||||
|
||||
RuneLite Border {
|
||||
kind=Dark
|
||||
colorUltraLight=#191919
|
||||
colorExtraLight=#191919
|
||||
colorLight=#191919
|
||||
colorMid=#191919
|
||||
colorDark=#191919
|
||||
colorUltraDark=#191919
|
||||
colorForeground=#C6C6C6
|
||||
}
|
||||
|
||||
RuneLite Tab Border {
|
||||
kind=Light
|
||||
colorUltraLight=#232323
|
||||
colorExtraLight=#232323
|
||||
colorLight=#232323
|
||||
colorMid=#232323
|
||||
colorDark=#232323
|
||||
colorUltraDark=#232323
|
||||
colorForeground=#232323
|
||||
}
|
||||
|
||||
RuneLite Mark Active {
|
||||
kind=Dark
|
||||
colorUltraLight=#191919
|
||||
colorExtraLight=#191919
|
||||
colorLight=#191919
|
||||
colorMid=#191919
|
||||
colorDark=#191919
|
||||
colorUltraDark=#191919
|
||||
colorForeground=#191919
|
||||
}
|
||||
|
||||
RuneLite Highlight {
|
||||
kind=Light
|
||||
colorUltraLight=#C6C6C6
|
||||
colorExtraLight=#C6C6C6
|
||||
colorLight=#C6C6C6
|
||||
colorMid=#C6C6C6
|
||||
colorDark=#C6C6C6
|
||||
colorUltraDark=#C6C6C6
|
||||
colorForeground=#191919
|
||||
}
|
||||
|
||||
RuneLite Watermark {
|
||||
kind=Light
|
||||
colorUltraLight=#313131
|
||||
colorExtraLight=#313131
|
||||
colorLight=#313131
|
||||
colorMid=#313131
|
||||
colorDark=#313131
|
||||
colorUltraDark=#313131
|
||||
colorForeground=#C6C6C6
|
||||
}
|
||||
|
||||
RuneLite Decorations Watermark {
|
||||
kind=Light
|
||||
colorUltraLight=#1e1e1e
|
||||
colorExtraLight=#1e1e1e
|
||||
colorLight=#1e1e1e
|
||||
colorMid=#1e1e1e
|
||||
colorDark=#1e1e1e
|
||||
colorUltraDark=#1e1e1e
|
||||
colorForeground=#1e1e1e
|
||||
}
|
||||
|
||||
RuneLite Separator {
|
||||
kind=Dark
|
||||
colorUltraLight=#232323
|
||||
colorExtraLight=#232323
|
||||
colorLight=#232323
|
||||
colorMid=#232323
|
||||
colorDark=#232323
|
||||
colorUltraDark=#232323
|
||||
colorForeground=#232323
|
||||
}
|
||||
|
||||
RuneLite Decorations Separator {
|
||||
kind=Dark
|
||||
colorUltraLight=#232323
|
||||
colorExtraLight=#232323
|
||||
colorLight=#232323
|
||||
colorMid=#232323
|
||||
colorDark=#232323
|
||||
colorUltraDark=#232323
|
||||
colorForeground=#232323
|
||||
}
|
||||
|
||||
RuneLite Header Watermark {
|
||||
kind=Dark
|
||||
colorUltraLight=#1e1e1e
|
||||
colorExtraLight=#1e1e1e
|
||||
colorLight=#1e1e1e
|
||||
colorMid=#1e1e1e
|
||||
colorDark=#1e1e1e
|
||||
colorUltraDark=#1e1e1e
|
||||
colorForeground=#C6C6C6
|
||||
}
|
||||
|
||||
RuneLite Header Border {
|
||||
kind=Dark
|
||||
colorUltraLight=#1e1e1e
|
||||
colorExtraLight=#1e1e1e
|
||||
colorLight=#1e1e1e
|
||||
colorMid=#1e1e1e
|
||||
colorDark=#1e1e1e
|
||||
colorUltraDark=#1e1e1e
|
||||
colorForeground=#C6C6C6
|
||||
}
|
||||
@@ -1,35 +0,0 @@
|
||||
package api.vars;
|
||||
|
||||
/**
|
||||
* An enumeration of possible account types.
|
||||
*/
|
||||
public enum AccountType
|
||||
{
|
||||
/**
|
||||
* Normal account type.
|
||||
*/
|
||||
NORMAL,
|
||||
/**
|
||||
* Ironman account type.
|
||||
*/
|
||||
IRONMAN,
|
||||
/**
|
||||
* Ultimate ironman account type.
|
||||
*/
|
||||
ULTIMATE_IRONMAN,
|
||||
/**
|
||||
* Hardcore ironman account type.
|
||||
*/
|
||||
HARDCORE_IRONMAN;
|
||||
|
||||
/**
|
||||
* Checks whether this type is an ironman.
|
||||
*
|
||||
* @return {@code true} if the type is any of the ironman types.
|
||||
*/
|
||||
public boolean isIronman()
|
||||
{
|
||||
return this.ordinal() >= IRONMAN.ordinal() && this.ordinal() <= HARDCORE_IRONMAN.ordinal();
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package rs.api;
|
||||
|
||||
import api.ClanMember;
|
||||
|
||||
public interface RSClanMate extends RSBuddy, ClanMember
|
||||
{
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package rs.api;
|
||||
|
||||
import api.Friend;
|
||||
|
||||
public interface RSFriend extends Friend, RSBuddy
|
||||
{
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package rs.api;
|
||||
|
||||
import api.Ignore;
|
||||
|
||||
public interface RSIgnored extends Ignore, RSUser
|
||||
{
|
||||
}
|
||||
@@ -1,7 +0,0 @@
|
||||
package rs.api;
|
||||
|
||||
import api.PacketBuffer;
|
||||
|
||||
public interface RSPacketBuffer extends PacketBuffer
|
||||
{
|
||||
}
|
||||
@@ -1,5 +0,0 @@
|
||||
package rs.api;
|
||||
|
||||
public interface RSSoundEffect
|
||||
{
|
||||
}
|
||||
299
bootstrap.json
Normal file
299
bootstrap.json
Normal file
@@ -0,0 +1,299 @@
|
||||
{
|
||||
"buildCommit": "2d0c2b8eb66a8088b41b29d42ec2a58ead460581",
|
||||
"artifacts": [
|
||||
{
|
||||
"hash": "b12331da8683e5f107d294adeebb83ecf9124abc1db533554d2a8d3c62832d75",
|
||||
"name": "asm-all-6.0_BETA.jar",
|
||||
"path": "https://mvn.runelite.net/org/ow2/asm/asm-all/6.0_BETA/asm-all-6.0_BETA.jar",
|
||||
"size": "265176"
|
||||
},
|
||||
{
|
||||
"hash": "37abf0103ce5318bfda004fabc004c75ed0dc6d392a8459175692ab7eac97083",
|
||||
"name": "naturalmouse-2.0.0.jar",
|
||||
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/naturalmouse-2.0.0.jar",
|
||||
"size": "3168921"
|
||||
},
|
||||
{
|
||||
"hash": "50d1e07f11827672249dee9ce8a23691fc59f663deed084bb7b52a4f778d5fbc",
|
||||
"name": "jcl-core-2.9-SNAPSHOT.jar",
|
||||
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/artifacts/jcl-core-2.9-SNAPSHOT.jar",
|
||||
"size": "3168921"
|
||||
},
|
||||
{
|
||||
"hash": "4c388a85fb538bbb8cb6e0fd93e0ba0666605123d77b976764818be6f090bbe5",
|
||||
"name": "client-1.5.28-SNAPSHOT.jar",
|
||||
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/client-1.5.28-SNAPSHOT.jar",
|
||||
"size": "5871886"
|
||||
},
|
||||
{
|
||||
"hash": "18c4a0095d5c1da6b817592e767bb23d29dd2f560ad74df75ff3961dbde25b79",
|
||||
"name": "slf4j-api-1.7.25.jar",
|
||||
"path": "https://mvn.runelite.net/org/slf4j/slf4j-api/1.7.25/slf4j-api-1.7.25.jar",
|
||||
"size": "41203"
|
||||
},
|
||||
{
|
||||
"hash": "fb53f8539e7fcb8f093a56e138112056ec1dc809ebb020b59d8a36a5ebac37e0",
|
||||
"name": "logback-classic-1.2.3.jar",
|
||||
"path": "https://mvn.runelite.net/ch/qos/logback/logback-classic/1.2.3/logback-classic-1.2.3.jar",
|
||||
"size": "290339"
|
||||
},
|
||||
{
|
||||
"hash": "5946d837fe6f960c02a53eda7a6926ecc3c758bbdd69aa453ee429f858217f22",
|
||||
"name": "logback-core-1.2.3.jar",
|
||||
"path": "https://mvn.runelite.net/ch/qos/logback/logback-core/1.2.3/logback-core-1.2.3.jar",
|
||||
"size": "471901"
|
||||
},
|
||||
{
|
||||
"hash": "9f0c8d50fa4b79b6ff1502dbec8502179d6b9497cacbe17a13074001aed537ec",
|
||||
"name": "jopt-simple-5.0.1.jar",
|
||||
"path": "https://mvn.runelite.net/net/sf/jopt-simple/jopt-simple/5.0.1/jopt-simple-5.0.1.jar",
|
||||
"size": "78826"
|
||||
},
|
||||
{
|
||||
"hash": "5be9a7d05ba0ccd74708bc8018ae412255f85843c0b92302e9b9befa6ed52564",
|
||||
"name": "guava-23.2-jre.jar",
|
||||
"path": "https://mvn.runelite.net/com/google/guava/guava/23.2-jre/guava-23.2-jre.jar",
|
||||
"size": "2649860"
|
||||
},
|
||||
{
|
||||
"hash": "905721a0eea90a81534abb7ee6ef4ea2e5e645fa1def0a5cd88402df1b46c9ed",
|
||||
"name": "jsr305-1.3.9.jar",
|
||||
"path": "https://mvn.runelite.net/com/google/code/findbugs/jsr305/1.3.9/jsr305-1.3.9.jar",
|
||||
"size": "33015"
|
||||
},
|
||||
{
|
||||
"hash": "cb4cfad870bf563a07199f3ebea5763f0dec440fcda0b318640b1feaa788656b",
|
||||
"name": "error_prone_annotations-2.0.18.jar",
|
||||
"path": "https://mvn.runelite.net/com/google/errorprone/error_prone_annotations/2.0.18/error_prone_annotations-2.0.18.jar",
|
||||
"size": "12078"
|
||||
},
|
||||
{
|
||||
"hash": "2994a7eb78f2710bd3d3bfb639b2c94e219cedac0d4d084d516e78c16dddecf6",
|
||||
"name": "j2objc-annotations-1.1.jar",
|
||||
"path": "https://mvn.runelite.net/com/google/j2objc/j2objc-annotations/1.1/j2objc-annotations-1.1.jar",
|
||||
"size": "8782"
|
||||
},
|
||||
{
|
||||
"hash": "2068320bd6bad744c3673ab048f67e30bef8f518996fa380033556600669905d",
|
||||
"name": "animal-sniffer-annotations-1.14.jar",
|
||||
"path": "https://mvn.runelite.net/org/codehaus/mojo/animal-sniffer-annotations/1.14/animal-sniffer-annotations-1.14.jar",
|
||||
"size": "3482"
|
||||
},
|
||||
{
|
||||
"hash": "9264c6931c431e928dc64adc842584d5f57d17b2f3aff29221f2b3fdea673dad",
|
||||
"name": "guice-4.1.0-no_aop.jar",
|
||||
"path": "https://mvn.runelite.net/com/google/inject/guice/4.1.0/guice-4.1.0-no_aop.jar",
|
||||
"size": "428603"
|
||||
},
|
||||
{
|
||||
"hash": "91c77044a50c481636c32d916fd89c9118a72195390452c81065080f957de7ff",
|
||||
"name": "javax.inject-1.jar",
|
||||
"path": "https://mvn.runelite.net/javax/inject/javax.inject/1/javax.inject-1.jar",
|
||||
"size": "2497"
|
||||
},
|
||||
{
|
||||
"hash": "0addec670fedcd3f113c5c8091d783280d23f75e3acb841b61a9cdb079376a08",
|
||||
"name": "aopalliance-1.0.jar",
|
||||
"path": "https://mvn.runelite.net/aopalliance/aopalliance/1.0/aopalliance-1.0.jar",
|
||||
"size": "4467"
|
||||
},
|
||||
{
|
||||
"hash": "233a0149fc365c9f6edbd683cfe266b19bdc773be98eabdaf6b3c924b48e7d81",
|
||||
"name": "gson-2.8.5.jar",
|
||||
"path": "https://mvn.runelite.net/com/google/code/gson/gson/2.8.5/gson-2.8.5.jar",
|
||||
"size": "241622"
|
||||
},
|
||||
{
|
||||
"hash": "0467d25f408428824d5c9c09ec60ee1f0bc341d9bf48971a77fd14939a826c83",
|
||||
"name": "substance-8.0.02.jar",
|
||||
"path": "https://repo.runelite.net/net/runelite/pushingpixels/substance/8.0.02/substance-8.0.02.jar",
|
||||
"size": "1589195"
|
||||
},
|
||||
{
|
||||
"hash": "3214e1c23d549d5d67c91da4da1ef33c5248470bb824f91cbe8f9e0beea59eef",
|
||||
"name": "trident-1.5.00.jar",
|
||||
"path": "https://repo.runelite.net/net/runelite/pushingpixels/trident/1.5.00/trident-1.5.00.jar",
|
||||
"size": "79726"
|
||||
},
|
||||
{
|
||||
"hash": "d4a57bbc1627da7c391308fd0fe910b83170fb66afd117236a5b111d2db1590b",
|
||||
"name": "commons-text-1.2.jar",
|
||||
"path": "https://mvn.runelite.net/org/apache/commons/commons-text/1.2/commons-text-1.2.jar",
|
||||
"size": "136544"
|
||||
},
|
||||
{
|
||||
"hash": "6e8dc31e046508d9953c96534edf0c2e0bfe6f468966b5b842b3f87e43b6a847",
|
||||
"name": "commons-lang3-3.7.jar",
|
||||
"path": "https://mvn.runelite.net/org/apache/commons/commons-lang3/3.7/commons-lang3-3.7.jar",
|
||||
"size": "499634"
|
||||
},
|
||||
{
|
||||
"hash": "e74603dc77b4183f108480279dbbf7fed3ac206069478636406c1fb45e83b31a",
|
||||
"name": "jogl-all-2.3.2.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2.jar",
|
||||
"size": "3414448"
|
||||
},
|
||||
{
|
||||
"hash": "8c53b1884cef19309d34fd10a94b010136d9d6de9a88c386f46006fb47acab5d",
|
||||
"name": "jogl-all-2.3.2-natives-windows-amd64.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-amd64.jar",
|
||||
"size": "240721"
|
||||
},
|
||||
{
|
||||
"hash": "507a0e6bd1ee4e81c3dfb287783af93775864eec742988d4162f98ce0cbac9d6",
|
||||
"name": "jogl-all-2.3.2-natives-windows-i586.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-windows-i586.jar",
|
||||
"size": "209445"
|
||||
},
|
||||
{
|
||||
"hash": "82637302ae9effdf7d6f302e1050ad6aee3b13019914ddda5b502b9faa980216",
|
||||
"name": "jogl-all-2.3.2-natives-linux-amd64.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-amd64.jar",
|
||||
"size": "224010"
|
||||
},
|
||||
{
|
||||
"hash": "f474ef2ef01be24ec811d3858b0f4bc5659076975f4a58ddd79abd787e9305c7",
|
||||
"name": "jogl-all-2.3.2-natives-linux-i586.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/jogl/jogl-all/2.3.2/jogl-all-2.3.2-natives-linux-i586.jar",
|
||||
"size": "217274"
|
||||
},
|
||||
{
|
||||
"hash": "084844543b18f7ff71b4c0437852bd22f0cb68d7e44c2c611c1bbea76f8c6fdf",
|
||||
"name": "gluegen-rt-2.3.2.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2.jar",
|
||||
"size": "345605"
|
||||
},
|
||||
{
|
||||
"hash": "3474017422eff384db466bdb56c96c61220c43133a9da6329cf1781bea16c6b6",
|
||||
"name": "gluegen-rt-2.3.2-natives-windows-amd64.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-amd64.jar",
|
||||
"size": "8159"
|
||||
},
|
||||
{
|
||||
"hash": "4eeed9fc2ebea5b9dc48a342b9478d127e989a2e1aa7129b512a98ec75cde338",
|
||||
"name": "gluegen-rt-2.3.2-natives-windows-i586.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-windows-i586.jar",
|
||||
"size": "7577"
|
||||
},
|
||||
{
|
||||
"hash": "f2dfd1800202059cf7e0294db5d57755147304e6eb220a9277526dbe6842bde2",
|
||||
"name": "gluegen-rt-2.3.2-natives-linux-amd64.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-amd64.jar",
|
||||
"size": "4149"
|
||||
},
|
||||
{
|
||||
"hash": "1365d463f98c0abec92f3ad6b35aa4b53a9599a517800cf99fdabea6712ca7ec",
|
||||
"name": "gluegen-rt-2.3.2-natives-linux-i586.jar",
|
||||
"path": "https://mvn.runelite.net/org/jogamp/gluegen/gluegen-rt/2.3.2/gluegen-rt-2.3.2-natives-linux-i586.jar",
|
||||
"size": "4130"
|
||||
},
|
||||
{
|
||||
"hash": "7b7ae00e2aa98c3b2b5ac76e793e2c9b752bf51c86c54654dbd473843a25f1aa",
|
||||
"name": "jbsdiff-1.0.jar",
|
||||
"path": "https://mvn.runelite.net/io/sigpipe/jbsdiff/1.0/jbsdiff-1.0.jar",
|
||||
"size": "24589"
|
||||
},
|
||||
{
|
||||
"hash": "55bbfe26cee9296fd5b7c0d47ce6a00ea4dd572e235b63e9bb4eaf6f802315e4",
|
||||
"name": "commons-compress-1.5.jar",
|
||||
"path": "https://mvn.runelite.net/org/apache/commons/commons-compress/1.5/commons-compress-1.5.jar",
|
||||
"size": "256241"
|
||||
},
|
||||
{
|
||||
"hash": "fbc9de96a0cc193a125b4008dbc348e9ed54e5e13fc67b8ed40e645d303cc51b",
|
||||
"name": "jna-4.5.1.jar",
|
||||
"path": "https://mvn.runelite.net/net/java/dev/jna/jna/4.5.1/jna-4.5.1.jar",
|
||||
"size": "1440662"
|
||||
},
|
||||
{
|
||||
"hash": "84c8667555ee8dd91fef44b451419f6f16f71f727d5fc475a10c2663eba83abb",
|
||||
"name": "jna-platform-4.5.1.jar",
|
||||
"path": "https://mvn.runelite.net/net/java/dev/jna/jna-platform/4.5.1/jna-platform-4.5.1.jar",
|
||||
"size": "2327547"
|
||||
},
|
||||
{
|
||||
"hash": "440c629bec3905eb21dc5965fa38464f160a4cb8f87ca76806cdecc18b2c5992",
|
||||
"name": "runelite-api-1.5.28-SNAPSHOT.jar",
|
||||
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runelite-api-1.5.28-SNAPSHOT.jar",
|
||||
"size": "1019717"
|
||||
},
|
||||
{
|
||||
"hash": "45e3bcec9e7bae4ca2facd0fbee1f3da5e0700584e8419deed784a95255552c1",
|
||||
"name": "runescape-api-1.5.28-SNAPSHOT.jar",
|
||||
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/runescape-api-1.5.28-SNAPSHOT.jar",
|
||||
"size": "56079"
|
||||
},
|
||||
{
|
||||
"hash": "811aadce9ce35ac638712da86123d4cb99570a9550614931471295cb26f91c36",
|
||||
"name": "http-api-1.5.28-SNAPSHOT.jar",
|
||||
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/http-api-1.5.28-SNAPSHOT.jar",
|
||||
"size": "101785"
|
||||
},
|
||||
{
|
||||
"hash": "f55abda036da75e1af45bd43b9dfa79b2a3d90905be9cb38687c6621597a8165",
|
||||
"name": "okhttp-3.7.0.jar",
|
||||
"path": "https://mvn.runelite.net/com/squareup/okhttp3/okhttp/3.7.0/okhttp-3.7.0.jar",
|
||||
"size": "394987"
|
||||
},
|
||||
{
|
||||
"hash": "bfe7dfe483c37137966a1690f0c7d0b448ba217902c1fed202aaffdbba3291ae",
|
||||
"name": "okio-1.12.0.jar",
|
||||
"path": "https://mvn.runelite.net/com/squareup/okio/okio/1.12.0/okio-1.12.0.jar",
|
||||
"size": "81088"
|
||||
},
|
||||
{
|
||||
"hash": "9d4924588d6280c7516db3a4b7298306db5b6f0d1cdf568ce738309b5660f008",
|
||||
"name": "commons-csv-1.4.jar",
|
||||
"path": "https://mvn.runelite.net/org/apache/commons/commons-csv/1.4/commons-csv-1.4.jar",
|
||||
"size": "39978"
|
||||
},
|
||||
{
|
||||
"hash": "7e26a8d043418f2f22d5f6a3083a9a131817009ee8cd72c004e83b50d1849a7c",
|
||||
"name": "discord-1.1.jar",
|
||||
"path": "https://repo.runelite.net/net/runelite/discord/1.1/discord-1.1.jar",
|
||||
"size": "617294"
|
||||
},
|
||||
{
|
||||
"hash": "a3cab9293960d1d61968ce1591c87859ddcaa6cb2faca554cc938961c8fb3d3a",
|
||||
"name": "injected-client-1.5.28-SNAPSHOT.jar",
|
||||
"path": "https://raw.githubusercontent.com/runelite-extended/maven-repo/master/live/injected-client-1.5.28-SNAPSHOT.jar",
|
||||
"size": "2193046"
|
||||
}
|
||||
],
|
||||
"client": {
|
||||
"artifactId": "client",
|
||||
"classifier": "",
|
||||
"extension": "jar",
|
||||
"groupId": "net.runelite",
|
||||
"properties": "",
|
||||
"version": "1.5.28"
|
||||
},
|
||||
"clientJvm9Arguments": [
|
||||
"-XX:+DisableAttachMechanism",
|
||||
"-Xmx512m",
|
||||
"-Xss2m",
|
||||
"-XX:CompileThreshold=1500",
|
||||
"-Djna.nosys=true"
|
||||
],
|
||||
"clientJvmArguments": [
|
||||
"-XX:+DisableAttachMechanism",
|
||||
"-Xmx512m",
|
||||
"-Xss2m",
|
||||
"-XX:CompileThreshold=1500",
|
||||
"-Xincgc",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+UseParNewGC",
|
||||
"-Djna.nosys=true"
|
||||
],
|
||||
"launcherArguments": [
|
||||
"-XX:+DisableAttachMechanism",
|
||||
"-Drunelite.launcher.nojvm=true",
|
||||
"-Xmx512m",
|
||||
"-Xss2m",
|
||||
"-XX:CompileThreshold=1500",
|
||||
"-Xincgc",
|
||||
"-XX:+UseConcMarkSweepGC",
|
||||
"-XX:+UseParNewGC",
|
||||
"-Djna.nosys=true"
|
||||
]
|
||||
}
|
||||
70
cache-client/pom.xml
Normal file
70
cache-client/pom.xml
Normal file
@@ -0,0 +1,70 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.5.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>cache-client</artifactId>
|
||||
<name>Cache Client</name>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>cache</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>protocol</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>cache</artifactId>
|
||||
<version>${project.version}</version>
|
||||
<type>test-jar</type>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
</project>
|
||||
48
cache-client/src/main/java/net/runelite/cache/client/ArchiveResponseHandler.java
vendored
Normal file
48
cache-client/src/main/java/net/runelite/cache/client/ArchiveResponseHandler.java
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import net.runelite.protocol.api.update.ArchiveResponsePacket;
|
||||
|
||||
public class ArchiveResponseHandler extends SimpleChannelInboundHandler<ArchiveResponsePacket>
|
||||
{
|
||||
private final CacheClient client;
|
||||
|
||||
public ArchiveResponseHandler(CacheClient client)
|
||||
{
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, ArchiveResponsePacket archiveResponse) throws Exception
|
||||
{
|
||||
client.onFileFinish(archiveResponse.getIndex(),
|
||||
archiveResponse.getArchive(),
|
||||
archiveResponse.getData());
|
||||
}
|
||||
|
||||
}
|
||||
459
cache-client/src/main/java/net/runelite/cache/client/CacheClient.java
vendored
Normal file
459
cache-client/src/main/java/net/runelite/cache/client/CacheClient.java
vendored
Normal file
@@ -0,0 +1,459 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import com.google.common.base.Stopwatch;
|
||||
import io.netty.bootstrap.Bootstrap;
|
||||
import io.netty.buffer.ByteBuf;
|
||||
import io.netty.buffer.Unpooled;
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelFuture;
|
||||
import io.netty.channel.ChannelInitializer;
|
||||
import io.netty.channel.ChannelOption;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.EventLoopGroup;
|
||||
import io.netty.channel.nio.NioEventLoopGroup;
|
||||
import io.netty.channel.socket.SocketChannel;
|
||||
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayDeque;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Queue;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
import net.runelite.cache.fs.Index;
|
||||
import net.runelite.cache.fs.Storage;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import net.runelite.cache.index.ArchiveData;
|
||||
import net.runelite.cache.index.IndexData;
|
||||
import net.runelite.protocol.update.decoders.HandshakeResponseDecoder;
|
||||
import net.runelite.protocol.update.encoders.ArchiveRequestEncoder;
|
||||
import net.runelite.protocol.update.encoders.EncryptionEncoder;
|
||||
import net.runelite.protocol.api.update.ArchiveRequestPacket;
|
||||
import net.runelite.protocol.api.login.HandshakeResponseType;
|
||||
import net.runelite.cache.util.Crc32;
|
||||
import net.runelite.protocol.api.handshake.UpdateHandshakePacket;
|
||||
import net.runelite.protocol.handshake.UpdateHandshakeEncoder;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CacheClient implements AutoCloseable
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheClient.class);
|
||||
|
||||
private static final String HOST = "oldschool1.runescape.com";
|
||||
private static final int PORT = 43594;
|
||||
|
||||
private static final int MAX_REQUESTS = 19; // too many and the server closes the conncetion
|
||||
|
||||
private final Store store; // store cache will be written to
|
||||
private final String host;
|
||||
private final int clientRevision;
|
||||
private DownloadWatcher watcher;
|
||||
|
||||
private ClientState state;
|
||||
|
||||
private final EventLoopGroup group = new NioEventLoopGroup(1);
|
||||
private Channel channel;
|
||||
|
||||
private CompletableFuture<HandshakeResponseType> handshakeFuture;
|
||||
private final Queue<PendingFileRequest> requests = new ArrayDeque<>();
|
||||
|
||||
public CacheClient(Store store, int clientRevision)
|
||||
{
|
||||
this(store, HOST, clientRevision);
|
||||
}
|
||||
|
||||
public CacheClient(Store store, String host, int clientRevision)
|
||||
{
|
||||
this.store = store;
|
||||
this.host = host;
|
||||
this.clientRevision = clientRevision;
|
||||
}
|
||||
|
||||
public CacheClient(Store store, int clientRevision, DownloadWatcher watcher)
|
||||
{
|
||||
this(store, clientRevision);
|
||||
this.watcher = watcher;
|
||||
}
|
||||
|
||||
public void connect()
|
||||
{
|
||||
Bootstrap b = new Bootstrap();
|
||||
b.group(group)
|
||||
.channel(NioSocketChannel.class)
|
||||
.option(ChannelOption.TCP_NODELAY, true)
|
||||
.handler(new ChannelInitializer<SocketChannel>()
|
||||
{
|
||||
@Override
|
||||
public void initChannel(SocketChannel ch) throws Exception
|
||||
{
|
||||
ChannelPipeline p = ch.pipeline();
|
||||
|
||||
//p.addFirst(new HttpProxyHandler(new InetSocketAddress("runelite.net", 3128)));
|
||||
p.addLast("decoder", new HandshakeResponseDecoder());
|
||||
|
||||
p.addLast(
|
||||
new CacheClientHandler(),
|
||||
new HandshakeResponseHandler(CacheClient.this),
|
||||
new ArchiveResponseHandler(CacheClient.this)
|
||||
);
|
||||
|
||||
p.addLast(
|
||||
new UpdateHandshakeEncoder(),
|
||||
new EncryptionEncoder(),
|
||||
new ArchiveRequestEncoder()
|
||||
);
|
||||
}
|
||||
});
|
||||
|
||||
// Start the client.
|
||||
ChannelFuture f = b.connect(host, PORT).syncUninterruptibly();
|
||||
channel = f.channel();
|
||||
}
|
||||
|
||||
public CompletableFuture<HandshakeResponseType> handshake()
|
||||
{
|
||||
UpdateHandshakePacket handshakePacket = new UpdateHandshakePacket();
|
||||
handshakePacket.setRevision(getClientRevision());
|
||||
|
||||
state = ClientState.HANDSHAKING;
|
||||
|
||||
assert handshakeFuture == null;
|
||||
handshakeFuture = new CompletableFuture<>();
|
||||
|
||||
channel.writeAndFlush(handshakePacket);
|
||||
|
||||
logger.info("Sent handshake with revision {}", handshakePacket.getRevision());
|
||||
|
||||
return handshakeFuture;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close()
|
||||
{
|
||||
channel.close().syncUninterruptibly();
|
||||
group.shutdownGracefully();
|
||||
}
|
||||
|
||||
public int getClientRevision()
|
||||
{
|
||||
return clientRevision;
|
||||
}
|
||||
|
||||
public ClientState getState()
|
||||
{
|
||||
return state;
|
||||
}
|
||||
|
||||
void setState(ClientState state)
|
||||
{
|
||||
this.state = state;
|
||||
}
|
||||
|
||||
CompletableFuture<HandshakeResponseType> getHandshakeFuture()
|
||||
{
|
||||
return handshakeFuture;
|
||||
}
|
||||
|
||||
public List<IndexInfo> requestIndexes() throws IOException
|
||||
{
|
||||
logger.info("Requesting indexes");
|
||||
|
||||
FileResult result = requestFile(255, 255, true).join();
|
||||
result.decompress(null);
|
||||
|
||||
ByteBuf buffer = Unpooled.wrappedBuffer(result.getContents());
|
||||
int indexCount = result.getContents().length / 8;
|
||||
List<IndexInfo> indexInfo = new ArrayList<>();
|
||||
|
||||
for (int i = 0; i < indexCount; ++i)
|
||||
{
|
||||
int crc = buffer.readInt();
|
||||
int revision = buffer.readInt();
|
||||
indexInfo.add(new IndexInfo(i, crc, revision));
|
||||
}
|
||||
|
||||
return indexInfo;
|
||||
}
|
||||
|
||||
public void download() throws IOException
|
||||
{
|
||||
Stopwatch stopwatch = Stopwatch.createStarted();
|
||||
|
||||
List<IndexInfo> indexes = requestIndexes();
|
||||
for (IndexInfo indexInfo : indexes)
|
||||
{
|
||||
int i = indexInfo.getId();
|
||||
int crc = indexInfo.getCrc();
|
||||
int revision = indexInfo.getRevision();
|
||||
|
||||
Index index = store.findIndex(i);
|
||||
|
||||
if (index == null)
|
||||
{
|
||||
logger.info("Index {} does not exist, creating", i);
|
||||
}
|
||||
else if (index.getRevision() != revision)
|
||||
{
|
||||
if (revision < index.getRevision())
|
||||
{
|
||||
logger.warn("Index {} revision is going BACKWARDS! (our revision {}, their revision {})", index.getId(), index.getRevision(), revision);
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("Index {} has the wrong revision (our revision {}, their revision {})", index.getId(), index.getRevision(), revision);
|
||||
}
|
||||
}
|
||||
else if (index.getCrc() != crc)
|
||||
{
|
||||
logger.warn("Index {} CRC has changed! (our crc {}, their crc {})",
|
||||
index.getCrc(), index.getCrc(), crc);
|
||||
}
|
||||
else
|
||||
{
|
||||
// despite the index being up to date, not everything
|
||||
// can be downloaded, eg. for tracks.
|
||||
logger.info("Index {} is up to date", index.getId());
|
||||
}
|
||||
|
||||
logger.info("Downloading index {}", i);
|
||||
|
||||
FileResult indexFileResult = requestFile(255, i, true).join();
|
||||
indexFileResult.decompress(null);
|
||||
|
||||
logger.info("Downloaded index {}", i);
|
||||
|
||||
if (indexFileResult.getCrc() != crc)
|
||||
{
|
||||
logger.warn("Corrupted download for index {}", i);
|
||||
continue;
|
||||
}
|
||||
|
||||
IndexData indexData = new IndexData();
|
||||
indexData.load(indexFileResult.getContents());
|
||||
|
||||
if (index == null)
|
||||
{
|
||||
index = store.addIndex(i);
|
||||
}
|
||||
|
||||
// update index settings
|
||||
index.setProtocol(indexData.getProtocol());
|
||||
index.setNamed(indexData.isNamed());
|
||||
index.setCrc(crc);
|
||||
index.setRevision(revision);
|
||||
|
||||
logger.info("Index {} has {} archives", i, indexData.getArchives().length);
|
||||
|
||||
for (ArchiveData ad : indexData.getArchives())
|
||||
{
|
||||
Archive existing = index.getArchive(ad.getId());
|
||||
|
||||
if (existing != null && existing.getRevision() == ad.getRevision()
|
||||
&& existing.getCrc() == ad.getCrc()
|
||||
&& existing.getNameHash() == ad.getNameHash())
|
||||
{
|
||||
logger.debug("Archive {}/{} in index {} is up to date",
|
||||
ad.getId(), indexData.getArchives().length, index.getId());
|
||||
continue;
|
||||
}
|
||||
|
||||
if (existing == null)
|
||||
{
|
||||
logger.info("Archive {}/{} in index {} is out of date, downloading",
|
||||
ad.getId(), indexData.getArchives().length, index.getId());
|
||||
}
|
||||
else if (ad.getRevision() < existing.getRevision())
|
||||
{
|
||||
logger.warn("Archive {}/{} in index {} revision is going BACKWARDS! (our revision {}, their revision {})",
|
||||
ad.getId(), indexData.getArchives().length, index.getId(),
|
||||
existing.getRevision(), ad.getRevision());
|
||||
}
|
||||
else
|
||||
{
|
||||
logger.info("Archive {}/{} in index {} is out of date, downloading. " +
|
||||
"revision: ours: {} theirs: {}, crc: ours: {} theirs {}, name: ours {} theirs {}",
|
||||
ad.getId(), indexData.getArchives().length, index.getId(),
|
||||
existing.getRevision(), ad.getRevision(),
|
||||
existing.getCrc(), ad.getCrc(),
|
||||
existing.getNameHash(), ad.getNameHash());
|
||||
}
|
||||
|
||||
final Archive archive = existing == null
|
||||
? index.addArchive(ad.getId())
|
||||
: existing;
|
||||
|
||||
archive.setRevision(ad.getRevision());
|
||||
archive.setCrc(ad.getCrc());
|
||||
archive.setNameHash(ad.getNameHash());
|
||||
|
||||
// Add files
|
||||
archive.setFileData(ad.getFiles());
|
||||
|
||||
CompletableFuture<FileResult> future = requestFile(index.getId(), ad.getId(), false);
|
||||
future.handle((fr, ex) ->
|
||||
{
|
||||
byte[] data = fr.getCompressedData();
|
||||
|
||||
Crc32 crc32 = new Crc32();
|
||||
crc32.update(data, 0, data.length);
|
||||
int hash = crc32.getHash();
|
||||
|
||||
if (hash != archive.getCrc())
|
||||
{
|
||||
logger.warn("crc mismatch on downloaded archive {}/{}: {} != {}",
|
||||
archive.getIndex().getId(), archive.getArchiveId(),
|
||||
hash, archive.getCrc());
|
||||
throw new RuntimeException("crc mismatch");
|
||||
}
|
||||
|
||||
if (watcher != null)
|
||||
{
|
||||
watcher.downloadComplete(archive, data);
|
||||
}
|
||||
else
|
||||
{
|
||||
try
|
||||
{
|
||||
Storage storage = store.getStorage();
|
||||
storage.saveArchive(archive, data);
|
||||
}
|
||||
catch (IOException ex1)
|
||||
{
|
||||
logger.warn("unable to save archive data", ex1);
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
// flush any pending requests
|
||||
channel.flush();
|
||||
|
||||
while (!requests.isEmpty())
|
||||
{
|
||||
// wait for pending requests
|
||||
synchronized (this)
|
||||
{
|
||||
try
|
||||
{
|
||||
wait();
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
logger.warn(null, ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
stopwatch.stop();
|
||||
logger.info("Download completed in {}", stopwatch);
|
||||
}
|
||||
|
||||
private synchronized CompletableFuture<FileResult> requestFile(int index, int fileId, boolean flush)
|
||||
{
|
||||
if (state != ClientState.CONNECTED)
|
||||
{
|
||||
throw new IllegalStateException("Can't request files until connected!");
|
||||
}
|
||||
|
||||
if (!flush)
|
||||
{
|
||||
while (requests.size() >= MAX_REQUESTS)
|
||||
{
|
||||
channel.flush();
|
||||
|
||||
try
|
||||
{
|
||||
wait();
|
||||
}
|
||||
catch (InterruptedException ex)
|
||||
{
|
||||
logger.warn("interrupted while waiting for requests", ex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
ArchiveRequestPacket archiveRequest = new ArchiveRequestPacket();
|
||||
archiveRequest.setPriority(false);
|
||||
archiveRequest.setIndex(index);
|
||||
archiveRequest.setArchive(fileId);
|
||||
|
||||
CompletableFuture<FileResult> future = new CompletableFuture<>();
|
||||
PendingFileRequest pf = new PendingFileRequest(index,
|
||||
fileId, future);
|
||||
|
||||
logger.trace("Sending request for {}/{}", index, fileId);
|
||||
|
||||
requests.add(pf);
|
||||
|
||||
if (!flush)
|
||||
{
|
||||
channel.write(archiveRequest);
|
||||
}
|
||||
else
|
||||
{
|
||||
channel.writeAndFlush(archiveRequest);
|
||||
}
|
||||
|
||||
return future;
|
||||
}
|
||||
|
||||
private PendingFileRequest findRequest(int index, int file)
|
||||
{
|
||||
for (PendingFileRequest pr : requests)
|
||||
{
|
||||
if (pr.getIndex() == index && pr.getArchive() == file)
|
||||
{
|
||||
return pr;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
protected synchronized void onFileFinish(int index, int file, byte[] compressedData)
|
||||
{
|
||||
PendingFileRequest pr = findRequest(index, file);
|
||||
|
||||
if (pr == null)
|
||||
{
|
||||
logger.warn("File download {}/{} with no pending request", index, file);
|
||||
return;
|
||||
}
|
||||
|
||||
requests.remove(pr);
|
||||
|
||||
notify();
|
||||
|
||||
FileResult result = new FileResult(index, file, compressedData);
|
||||
|
||||
logger.debug("File download finished for index {} file {}, length {}", index, file, compressedData.length);
|
||||
|
||||
pr.getFuture().complete(result);
|
||||
}
|
||||
}
|
||||
49
cache-client/src/main/java/net/runelite/cache/client/CacheClientHandler.java
vendored
Normal file
49
cache-client/src/main/java/net/runelite/cache/client/CacheClientHandler.java
vendored
Normal file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class CacheClientHandler extends ChannelInboundHandlerAdapter
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheClientHandler.class);
|
||||
|
||||
@Override
|
||||
public void channelInactive(ChannelHandlerContext ctx) throws Exception
|
||||
{
|
||||
logger.warn("Channel has gone inactive");
|
||||
}
|
||||
|
||||
@Override
|
||||
public void exceptionCaught(ChannelHandlerContext ctx, Throwable cause)
|
||||
{
|
||||
// Close the connection when an exception is raised.
|
||||
logger.warn(null, cause);
|
||||
ctx.close();
|
||||
}
|
||||
}
|
||||
31
cache-client/src/main/java/net/runelite/cache/client/ClientState.java
vendored
Normal file
31
cache-client/src/main/java/net/runelite/cache/client/ClientState.java
vendored
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
public enum ClientState
|
||||
{
|
||||
HANDSHAKING,
|
||||
CONNECTED
|
||||
}
|
||||
33
cache-client/src/main/java/net/runelite/cache/client/DownloadWatcher.java
vendored
Normal file
33
cache-client/src/main/java/net/runelite/cache/client/DownloadWatcher.java
vendored
Normal file
@@ -0,0 +1,33 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import net.runelite.cache.fs.Archive;
|
||||
|
||||
@FunctionalInterface
|
||||
public interface DownloadWatcher
|
||||
{
|
||||
void downloadComplete(Archive archive, byte[] data);
|
||||
}
|
||||
92
cache-client/src/main/java/net/runelite/cache/client/FileResult.java
vendored
Normal file
92
cache-client/src/main/java/net/runelite/cache/client/FileResult.java
vendored
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import java.io.IOException;
|
||||
import net.runelite.cache.fs.Container;
|
||||
|
||||
public class FileResult
|
||||
{
|
||||
private final int index;
|
||||
private final int fileId;
|
||||
private final byte[] compressedData;
|
||||
|
||||
private byte[] contents;
|
||||
private int revision;
|
||||
private int crc;
|
||||
private int compression; // compression method used by archive data
|
||||
|
||||
public FileResult(int index, int fileId, byte[] compressedData)
|
||||
{
|
||||
this.index = index;
|
||||
this.fileId = fileId;
|
||||
this.compressedData = compressedData;
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
public int getFileId()
|
||||
{
|
||||
return fileId;
|
||||
}
|
||||
|
||||
public byte[] getCompressedData()
|
||||
{
|
||||
return compressedData;
|
||||
}
|
||||
|
||||
public void decompress(int[] keys) throws IOException
|
||||
{
|
||||
Container res = Container.decompress(compressedData, keys);
|
||||
|
||||
contents = res.data;
|
||||
revision = res.revision;
|
||||
crc = res.crc;
|
||||
compression = res.compression;
|
||||
}
|
||||
|
||||
public byte[] getContents()
|
||||
{
|
||||
return contents;
|
||||
}
|
||||
|
||||
public int getRevision()
|
||||
{
|
||||
return revision;
|
||||
}
|
||||
|
||||
public int getCrc()
|
||||
{
|
||||
return crc;
|
||||
}
|
||||
|
||||
public int getCompression()
|
||||
{
|
||||
return compression;
|
||||
}
|
||||
}
|
||||
81
cache-client/src/main/java/net/runelite/cache/client/HandshakeResponseHandler.java
vendored
Normal file
81
cache-client/src/main/java/net/runelite/cache/client/HandshakeResponseHandler.java
vendored
Normal file
@@ -0,0 +1,81 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import io.netty.channel.Channel;
|
||||
import io.netty.channel.ChannelHandlerContext;
|
||||
import io.netty.channel.ChannelPipeline;
|
||||
import io.netty.channel.SimpleChannelInboundHandler;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.runelite.protocol.update.decoders.ArchiveResponseDecoder;
|
||||
import net.runelite.protocol.api.update.EncryptionPacket;
|
||||
import net.runelite.protocol.api.handshake.HandshakeResponsePacket;
|
||||
import net.runelite.protocol.api.login.HandshakeResponseType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HandshakeResponseHandler extends SimpleChannelInboundHandler<HandshakeResponsePacket>
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(HandshakeResponseHandler.class);
|
||||
|
||||
private final CacheClient client;
|
||||
|
||||
public HandshakeResponseHandler(CacheClient client)
|
||||
{
|
||||
this.client = client;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void channelRead0(ChannelHandlerContext ctx, HandshakeResponsePacket handshakeResponse) throws Exception
|
||||
{
|
||||
Channel channel = ctx.channel();
|
||||
ChannelPipeline p = ctx.pipeline();
|
||||
CompletableFuture<HandshakeResponseType> handshakeFuture = client.getHandshakeFuture();
|
||||
|
||||
assert handshakeFuture != null;
|
||||
|
||||
if (handshakeResponse.getResponse() != HandshakeResponseType.RESPONSE_OK)
|
||||
{
|
||||
logger.warn("Non-ok response from server {}", handshakeResponse.getResponse());
|
||||
handshakeFuture.complete(handshakeResponse.getResponse());
|
||||
ctx.close();
|
||||
return;
|
||||
}
|
||||
|
||||
// Send encryption packet
|
||||
EncryptionPacket encryptionPacket = new EncryptionPacket();
|
||||
encryptionPacket.setKey((byte) 0);
|
||||
channel.writeAndFlush(encryptionPacket);
|
||||
|
||||
client.setState(ClientState.CONNECTED);
|
||||
|
||||
logger.info("Client is now connected!");
|
||||
|
||||
p.replace("decoder", "decoder", new ArchiveResponseDecoder());
|
||||
|
||||
handshakeFuture.complete(handshakeResponse.getResponse());
|
||||
}
|
||||
|
||||
}
|
||||
101
cache-client/src/main/java/net/runelite/cache/client/IndexInfo.java
vendored
Normal file
101
cache-client/src/main/java/net/runelite/cache/client/IndexInfo.java
vendored
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
public class IndexInfo
|
||||
{
|
||||
private final int id;
|
||||
private final int crc;
|
||||
private final int revision;
|
||||
|
||||
public IndexInfo(int id, int crc, int revision)
|
||||
{
|
||||
this.id = id;
|
||||
this.crc = crc;
|
||||
this.revision = revision;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString()
|
||||
{
|
||||
return "IndexInfo{" + "id=" + id + ", crc=" + crc + ", revision=" + revision + '}';
|
||||
}
|
||||
|
||||
@Override
|
||||
public int hashCode()
|
||||
{
|
||||
int hash = 5;
|
||||
hash = 71 * hash + this.id;
|
||||
hash = 71 * hash + this.crc;
|
||||
hash = 71 * hash + this.revision;
|
||||
return hash;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object obj)
|
||||
{
|
||||
if (this == obj)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
if (obj == null)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (getClass() != obj.getClass())
|
||||
{
|
||||
return false;
|
||||
}
|
||||
final IndexInfo other = (IndexInfo) obj;
|
||||
if (this.id != other.id)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.crc != other.crc)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
if (this.revision != other.revision)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
|
||||
public int getCrc()
|
||||
{
|
||||
return crc;
|
||||
}
|
||||
|
||||
public int getRevision()
|
||||
{
|
||||
return revision;
|
||||
}
|
||||
}
|
||||
56
cache-client/src/main/java/net/runelite/cache/client/PendingFileRequest.java
vendored
Normal file
56
cache-client/src/main/java/net/runelite/cache/client/PendingFileRequest.java
vendored
Normal file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
|
||||
public class PendingFileRequest
|
||||
{
|
||||
private final int index;
|
||||
private final int archive;
|
||||
private final CompletableFuture<FileResult> future;
|
||||
|
||||
public PendingFileRequest(int index, int archive, CompletableFuture<FileResult> future)
|
||||
{
|
||||
this.index = index;
|
||||
this.archive = archive;
|
||||
this.future = future;
|
||||
}
|
||||
|
||||
public int getIndex()
|
||||
{
|
||||
return index;
|
||||
}
|
||||
|
||||
public int getArchive()
|
||||
{
|
||||
return archive;
|
||||
}
|
||||
|
||||
public CompletableFuture<FileResult> getFuture()
|
||||
{
|
||||
return future;
|
||||
}
|
||||
}
|
||||
74
cache-client/src/test/java/net/runelite/cache/client/CacheClientTest.java
vendored
Normal file
74
cache-client/src/test/java/net/runelite/cache/client/CacheClientTest.java
vendored
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* 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.cache.client;
|
||||
|
||||
import java.io.File;
|
||||
import java.util.concurrent.CompletableFuture;
|
||||
import net.runelite.cache.CacheProperties;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import net.runelite.protocol.api.login.HandshakeResponseType;
|
||||
import org.junit.Assert;
|
||||
import org.junit.Before;
|
||||
import org.junit.Ignore;
|
||||
import org.junit.Test;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.slf4j.impl.SimpleLogger;
|
||||
|
||||
public class CacheClientTest
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheClientTest.class);
|
||||
|
||||
@Before
|
||||
public void before()
|
||||
{
|
||||
System.setProperty(SimpleLogger.DEFAULT_LOG_LEVEL_KEY, "TRACE");
|
||||
}
|
||||
|
||||
@Test
|
||||
@Ignore
|
||||
public void test() throws Exception
|
||||
{
|
||||
try (Store store = new Store(new File("D:\\rs\\07\\temp\\cache")))
|
||||
{
|
||||
store.load();
|
||||
|
||||
CacheClient c = new CacheClient(store, CacheProperties.getRsVersion());
|
||||
c.connect();
|
||||
CompletableFuture<HandshakeResponseType> handshake = c.handshake();
|
||||
|
||||
HandshakeResponseType result = handshake.get();
|
||||
logger.info("Handshake result: {}", result);
|
||||
|
||||
Assert.assertEquals(HandshakeResponseType.RESPONSE_OK, result);
|
||||
|
||||
c.download();
|
||||
|
||||
c.close();
|
||||
|
||||
store.save();
|
||||
}
|
||||
}
|
||||
}
|
||||
105
cache-updater/pom.xml
Normal file
105
cache-updater/pom.xml
Normal file
@@ -0,0 +1,105 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
Copyright (c) 2018, 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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.5.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<name>Cache Updater</name>
|
||||
<artifactId>cache-updater</artifactId>
|
||||
|
||||
<properties>
|
||||
<spring.boot.version>1.5.6.RELEASE</spring.boot.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-starter-jdbc</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-devtools</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<optional>true</optional>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>mysql</groupId>
|
||||
<artifactId>mysql-connector-java</artifactId>
|
||||
<version>5.1.45</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>cache-client</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.sql2o</groupId>
|
||||
<artifactId>sql2o</artifactId>
|
||||
<version>1.5.4</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.minio</groupId>
|
||||
<artifactId>minio</artifactId>
|
||||
<version>3.0.6</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
<artifactId>spring-boot-maven-plugin</artifactId>
|
||||
<version>${spring.boot.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>repackage</goal>
|
||||
</goals>
|
||||
<configuration>
|
||||
<classifier>spring-boot</classifier>
|
||||
<mainClass>net.runelite.cache.updater.CacheUpdater</mainClass>
|
||||
</configuration>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
118
cache-updater/schema.sql
Normal file
118
cache-updater/schema.sql
Normal file
@@ -0,0 +1,118 @@
|
||||
-- MySQL dump 10.16 Distrib 10.2.9-MariaDB, for Linux (x86_64)
|
||||
--
|
||||
-- Host: localhost Database: cache
|
||||
-- ------------------------------------------------------
|
||||
-- Server version 10.2.9-MariaDB
|
||||
|
||||
/*!40101 SET @OLD_CHARACTER_SET_CLIENT=@@CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET @OLD_CHARACTER_SET_RESULTS=@@CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET @OLD_COLLATION_CONNECTION=@@COLLATION_CONNECTION */;
|
||||
/*!40101 SET NAMES utf8 */;
|
||||
/*!40103 SET @OLD_TIME_ZONE=@@TIME_ZONE */;
|
||||
/*!40103 SET TIME_ZONE='+00:00' */;
|
||||
/*!40014 SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0 */;
|
||||
/*!40014 SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0 */;
|
||||
/*!40101 SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='NO_AUTO_VALUE_ON_ZERO' */;
|
||||
/*!40111 SET @OLD_SQL_NOTES=@@SQL_NOTES, SQL_NOTES=0 */;
|
||||
|
||||
--
|
||||
-- Table structure for table `archive`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `archive`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `archive` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`archiveId` int(11) NOT NULL,
|
||||
`nameHash` int(11) NOT NULL,
|
||||
`crc` int(11) NOT NULL,
|
||||
`revision` int(11) NOT NULL,
|
||||
`hash` binary(32) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
KEY `archive_revision` (`archiveId`,`revision`) USING BTREE
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `cache`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `cache`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `cache` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`revision` int(11) NOT NULL,
|
||||
`date` timestamp NOT NULL DEFAULT current_timestamp() ON UPDATE current_timestamp(),
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `revision_date` (`revision`,`date`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `file`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `file`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `file` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`archive` int(11) NOT NULL,
|
||||
`fileId` int(11) NOT NULL,
|
||||
`nameHash` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `archive_file` (`archive`,`fileId`),
|
||||
CONSTRAINT `file_ibfk_1` FOREIGN KEY (`archive`) REFERENCES `archive` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `index`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `index`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `index` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`cache` int(11) NOT NULL,
|
||||
`indexId` int(11) NOT NULL,
|
||||
`crc` int(11) NOT NULL,
|
||||
`revision` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `indexId` (`cache`,`indexId`,`revision`,`crc`) USING BTREE,
|
||||
CONSTRAINT `index_ibfk_1` FOREIGN KEY (`cache`) REFERENCES `cache` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
|
||||
--
|
||||
-- Table structure for table `index_archive`
|
||||
--
|
||||
|
||||
DROP TABLE IF EXISTS `index_archive`;
|
||||
/*!40101 SET @saved_cs_client = @@character_set_client */;
|
||||
/*!40101 SET character_set_client = utf8 */;
|
||||
CREATE TABLE `index_archive` (
|
||||
`id` int(11) NOT NULL AUTO_INCREMENT,
|
||||
`index` int(11) NOT NULL,
|
||||
`archive` int(11) NOT NULL,
|
||||
PRIMARY KEY (`id`),
|
||||
UNIQUE KEY `idx_index_archive` (`index`,`archive`) USING BTREE,
|
||||
KEY `archive` (`archive`) USING BTREE,
|
||||
CONSTRAINT `index_archive_ibfk_1` FOREIGN KEY (`index`) REFERENCES `index` (`id`),
|
||||
CONSTRAINT `index_archive_ibfk_2` FOREIGN KEY (`archive`) REFERENCES `archive` (`id`)
|
||||
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
||||
/*!40101 SET character_set_client = @saved_cs_client */;
|
||||
/*!40103 SET TIME_ZONE=@OLD_TIME_ZONE */;
|
||||
|
||||
/*!40101 SET SQL_MODE=@OLD_SQL_MODE */;
|
||||
/*!40014 SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS */;
|
||||
/*!40014 SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS */;
|
||||
/*!40101 SET CHARACTER_SET_CLIENT=@OLD_CHARACTER_SET_CLIENT */;
|
||||
/*!40101 SET CHARACTER_SET_RESULTS=@OLD_CHARACTER_SET_RESULTS */;
|
||||
/*!40101 SET COLLATION_CONNECTION=@OLD_COLLATION_CONNECTION */;
|
||||
/*!40111 SET SQL_NOTES=@OLD_SQL_NOTES */;
|
||||
|
||||
-- Dump completed on 2018-02-02 21:55:48
|
||||
77
cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java
vendored
Normal file
77
cache-updater/src/main/java/net/runelite/cache/updater/CacheConfiguration.java
vendored
Normal file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2018, 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.cache.updater;
|
||||
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.errors.InvalidEndpointException;
|
||||
import io.minio.errors.InvalidPortException;
|
||||
import java.time.Instant;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import javax.sql.DataSource;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.autoconfigure.jdbc.DataSourceBuilder;
|
||||
import org.springframework.boot.context.properties.ConfigurationProperties;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
import org.springframework.context.annotation.Configuration;
|
||||
import org.sql2o.Sql2o;
|
||||
import org.sql2o.converters.Converter;
|
||||
import org.sql2o.quirks.NoQuirks;
|
||||
|
||||
@Configuration
|
||||
public class CacheConfiguration
|
||||
{
|
||||
@Value("${minio.endpoint}")
|
||||
private String minioUrl;
|
||||
|
||||
@Value("${minio.accesskey}")
|
||||
private String minioAccessKey;
|
||||
|
||||
@Value("${minio.secretkey}")
|
||||
private String minioSecretKey;
|
||||
|
||||
@Bean
|
||||
@ConfigurationProperties(prefix = "datasource.runelite-cache")
|
||||
public DataSource dataSource()
|
||||
{
|
||||
return DataSourceBuilder.create().build();
|
||||
}
|
||||
|
||||
@Bean
|
||||
@Qualifier("Runelite Cache SQL2O")
|
||||
public Sql2o sql2o(DataSource dataSource)
|
||||
{
|
||||
Map<Class, Converter> converters = new HashMap<>();
|
||||
converters.put(Instant.class, new InstantConverter());
|
||||
return new Sql2o(dataSource, new NoQuirks(converters));
|
||||
}
|
||||
|
||||
@Bean
|
||||
public MinioClient minioClient() throws InvalidEndpointException, InvalidPortException
|
||||
{
|
||||
return new MinioClient(minioUrl, minioAccessKey, minioSecretKey);
|
||||
}
|
||||
}
|
||||
177
cache-updater/src/main/java/net/runelite/cache/updater/CacheDAO.java
vendored
Normal file
177
cache-updater/src/main/java/net/runelite/cache/updater/CacheDAO.java
vendored
Normal file
@@ -0,0 +1,177 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater;
|
||||
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import net.runelite.cache.updater.beans.ArchiveEntry;
|
||||
import net.runelite.cache.updater.beans.CacheEntry;
|
||||
import net.runelite.cache.updater.beans.IndexEntry;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Query;
|
||||
import org.sql2o.ResultSetIterable;
|
||||
|
||||
class CacheDAO
|
||||
{
|
||||
// cache prepared statements for high volume queries
|
||||
private Query associateArchive;
|
||||
private Query findArchive, insertArchive;
|
||||
private Query associateFile;
|
||||
|
||||
public CacheEntry findMostRecent(Connection con)
|
||||
{
|
||||
return con.createQuery("select id, revision, date from cache order by revision desc, date desc limit 1")
|
||||
.executeAndFetchFirst(CacheEntry.class);
|
||||
}
|
||||
|
||||
public List<IndexEntry> findIndexesForCache(Connection con, CacheEntry cache)
|
||||
{
|
||||
return con.createQuery("select id, indexId, crc, revision from `index` where cache = :cache")
|
||||
.addParameter("cache", cache.getId())
|
||||
.executeAndFetch(IndexEntry.class);
|
||||
}
|
||||
|
||||
public ResultSetIterable<ArchiveEntry> findArchivesForIndex(Connection con, IndexEntry indexEntry)
|
||||
{
|
||||
return con.createQuery("select archive.id, archive.archiveId, archive.nameHash,"
|
||||
+ " archive.crc, archive.revision, archive.hash from index_archive "
|
||||
+ "join archive on index_archive.archive = archive.id "
|
||||
+ "where index_archive.index = :id")
|
||||
.addParameter("id", indexEntry.getId())
|
||||
.executeAndFetchLazy(ArchiveEntry.class);
|
||||
}
|
||||
|
||||
public CacheEntry createCache(Connection con, int revision, Instant date)
|
||||
{
|
||||
int cacheId = con.createQuery("insert into cache (revision, date) values (:revision, :date)")
|
||||
.addParameter("revision", revision)
|
||||
.addParameter("date", date)
|
||||
.executeUpdate()
|
||||
.getKey(int.class);
|
||||
|
||||
CacheEntry entry = new CacheEntry();
|
||||
entry.setId(cacheId);
|
||||
entry.setRevision(revision);
|
||||
entry.setDate(date);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public IndexEntry createIndex(Connection con, CacheEntry cache, int indexId, int crc, int revision)
|
||||
{
|
||||
int id = con.createQuery("insert into `index` (cache, indexId, crc, revision) values (:cache, :indexId, :crc, :revision)")
|
||||
.addParameter("cache", cache.getId())
|
||||
.addParameter("indexId", indexId)
|
||||
.addParameter("crc", crc)
|
||||
.addParameter("revision", revision)
|
||||
.executeUpdate()
|
||||
.getKey(int.class);
|
||||
|
||||
IndexEntry entry = new IndexEntry();
|
||||
entry.setId(id);
|
||||
entry.setIndexId(indexId);
|
||||
entry.setCrc(crc);
|
||||
entry.setRevision(revision);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public void associateArchiveToIndex(Connection con, ArchiveEntry archive, IndexEntry index)
|
||||
{
|
||||
if (associateArchive == null)
|
||||
{
|
||||
associateArchive = con.createQuery("insert into index_archive (`index`, archive) values (:index, :archive)");
|
||||
}
|
||||
associateArchive
|
||||
.addParameter("index", index.getId())
|
||||
.addParameter("archive", archive.getId())
|
||||
.executeUpdate();
|
||||
}
|
||||
|
||||
public ArchiveEntry findArchive(Connection con, IndexEntry index,
|
||||
int archiveId, int nameHash, int crc, int revision)
|
||||
{
|
||||
if (findArchive == null)
|
||||
{
|
||||
findArchive = con.createQuery("select distinct archive.id, archive.archiveId, archive.nameHash,"
|
||||
+ " archive.crc, archive.revision, archive.hash from archive "
|
||||
+ " join index_archive on index_archive.archive = archive.id"
|
||||
+ " join `index` on index.id = index_archive.index"
|
||||
+ " where archive.archiveId = :archiveId"
|
||||
+ " and archive.nameHash = :nameHash"
|
||||
+ " and archive.crc = :crc"
|
||||
+ " and archive.revision = :revision"
|
||||
+ " and index.indexId = :indexId");
|
||||
}
|
||||
|
||||
ArchiveEntry entry = findArchive
|
||||
.addParameter("archiveId", archiveId)
|
||||
.addParameter("nameHash", nameHash)
|
||||
.addParameter("crc", crc)
|
||||
.addParameter("revision", revision)
|
||||
.addParameter("indexId", index.getIndexId())
|
||||
.executeAndFetchFirst(ArchiveEntry.class);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public ArchiveEntry createArchive(Connection con, IndexEntry index,
|
||||
int archiveId, int nameHash, int crc, int revision, byte[] hash)
|
||||
{
|
||||
if (insertArchive == null)
|
||||
{
|
||||
insertArchive = con.createQuery("insert into archive (archiveId, nameHash, crc, revision, hash) values "
|
||||
+ "(:archiveId, :nameHash, :crc, :revision, :hash)");
|
||||
}
|
||||
|
||||
int id = insertArchive
|
||||
.addParameter("archiveId", archiveId)
|
||||
.addParameter("nameHash", nameHash)
|
||||
.addParameter("crc", crc)
|
||||
.addParameter("revision", revision)
|
||||
.addParameter("hash", hash)
|
||||
.executeUpdate()
|
||||
.getKey(int.class);
|
||||
|
||||
ArchiveEntry entry = new ArchiveEntry();
|
||||
entry.setId(id);
|
||||
entry.setArchiveId(archiveId);
|
||||
entry.setNameHash(nameHash);
|
||||
entry.setCrc(crc);
|
||||
entry.setRevision(revision);
|
||||
entry.setHash(hash);
|
||||
return entry;
|
||||
}
|
||||
|
||||
public void associateFileToArchive(Connection con, ArchiveEntry archive, int fileId, int nameHash)
|
||||
{
|
||||
if (associateFile == null)
|
||||
{
|
||||
associateFile = con.createQuery("insert into file (archive, fileId, nameHash) values (:archive, :fileId, :nameHash)");
|
||||
}
|
||||
associateFile
|
||||
.addParameter("archive", archive.getId())
|
||||
.addParameter("fileId", fileId)
|
||||
.addParameter("nameHash", nameHash)
|
||||
.executeUpdate();
|
||||
}
|
||||
}
|
||||
144
cache-updater/src/main/java/net/runelite/cache/updater/CacheStorage.java
vendored
Normal file
144
cache-updater/src/main/java/net/runelite/cache/updater/CacheStorage.java
vendored
Normal file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.List;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
import net.runelite.cache.fs.Index;
|
||||
import net.runelite.cache.fs.Storage;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import net.runelite.cache.index.FileData;
|
||||
import net.runelite.cache.updater.beans.ArchiveEntry;
|
||||
import net.runelite.cache.updater.beans.CacheEntry;
|
||||
import net.runelite.cache.updater.beans.IndexEntry;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.ResultSetIterable;
|
||||
|
||||
public class CacheStorage implements Storage
|
||||
{
|
||||
private CacheEntry cacheEntry;
|
||||
private final CacheDAO cacheDao;
|
||||
private final Connection con;
|
||||
|
||||
public CacheStorage(CacheEntry cacheEntry, CacheDAO cacheDao, Connection con)
|
||||
{
|
||||
this.cacheEntry = cacheEntry;
|
||||
this.cacheDao = cacheDao;
|
||||
this.con = con;
|
||||
}
|
||||
|
||||
public CacheEntry getCacheEntry()
|
||||
{
|
||||
return cacheEntry;
|
||||
}
|
||||
|
||||
public void setCacheEntry(CacheEntry cacheEntry)
|
||||
{
|
||||
this.cacheEntry = cacheEntry;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void init(Store store) throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException
|
||||
{
|
||||
}
|
||||
|
||||
@Override
|
||||
public void load(Store store) throws IOException
|
||||
{
|
||||
List<IndexEntry> indexes = cacheDao.findIndexesForCache(con, cacheEntry);
|
||||
for (IndexEntry indexEntry : indexes)
|
||||
{
|
||||
Index index = store.addIndex(indexEntry.getIndexId());
|
||||
index.setCrc(indexEntry.getCrc());
|
||||
index.setRevision(indexEntry.getRevision());
|
||||
|
||||
try (ResultSetIterable<ArchiveEntry> archives = cacheDao.findArchivesForIndex(con, indexEntry))
|
||||
{
|
||||
for (ArchiveEntry archiveEntry : archives)
|
||||
{
|
||||
if (index.getArchive(archiveEntry.getArchiveId()) != null)
|
||||
{
|
||||
throw new IOException("Duplicate archive " + archiveEntry + " on " + indexEntry);
|
||||
}
|
||||
|
||||
Archive archive = index.addArchive(archiveEntry.getArchiveId());
|
||||
archive.setNameHash(archiveEntry.getNameHash());
|
||||
archive.setCrc(archiveEntry.getCrc());
|
||||
archive.setRevision(archiveEntry.getRevision());
|
||||
archive.setHash(archiveEntry.getHash());
|
||||
|
||||
// File data is not necessary for cache updating
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void save(Store store) throws IOException
|
||||
{
|
||||
for (Index index : store.getIndexes())
|
||||
{
|
||||
IndexEntry entry = cacheDao.createIndex(con, cacheEntry, index.getId(), index.getCrc(), index.getRevision());
|
||||
|
||||
for (Archive archive : index.getArchives())
|
||||
{
|
||||
ArchiveEntry archiveEntry = cacheDao.findArchive(con, entry, archive.getArchiveId(),
|
||||
archive.getNameHash(), archive.getCrc(), archive.getRevision());
|
||||
if (archiveEntry == null)
|
||||
{
|
||||
byte[] hash = archive.getHash();
|
||||
archiveEntry = cacheDao.createArchive(con, entry, archive.getArchiveId(),
|
||||
archive.getNameHash(), archive.getCrc(), archive.getRevision(), hash);
|
||||
|
||||
for (FileData file : archive.getFileData())
|
||||
{
|
||||
cacheDao.associateFileToArchive(con, archiveEntry, file.getId(), file.getNameHash());
|
||||
}
|
||||
}
|
||||
|
||||
cacheDao.associateArchiveToIndex(con, archiveEntry, entry);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public byte[] loadArchive(Archive archive) throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void saveArchive(Archive archive, byte[] data) throws IOException
|
||||
{
|
||||
throw new UnsupportedOperationException();
|
||||
}
|
||||
|
||||
}
|
||||
173
cache-updater/src/main/java/net/runelite/cache/updater/CacheUpdater.java
vendored
Normal file
173
cache-updater/src/main/java/net/runelite/cache/updater/CacheUpdater.java
vendored
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater;
|
||||
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.errors.InvalidEndpointException;
|
||||
import io.minio.errors.InvalidPortException;
|
||||
import java.io.IOException;
|
||||
import java.time.Instant;
|
||||
import java.util.List;
|
||||
import java.util.concurrent.ExecutorService;
|
||||
import java.util.concurrent.Executors;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import net.runelite.cache.client.CacheClient;
|
||||
import net.runelite.cache.client.IndexInfo;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import net.runelite.cache.updater.beans.CacheEntry;
|
||||
import net.runelite.cache.updater.beans.IndexEntry;
|
||||
import net.runelite.http.api.RuneLiteAPI;
|
||||
import net.runelite.protocol.api.login.HandshakeResponseType;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.springframework.beans.factory.annotation.Autowired;
|
||||
import org.springframework.beans.factory.annotation.Qualifier;
|
||||
import org.springframework.beans.factory.annotation.Value;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
import org.springframework.boot.SpringApplication;
|
||||
import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.sql2o.Connection;
|
||||
import org.sql2o.Sql2o;
|
||||
|
||||
@SpringBootApplication
|
||||
public class CacheUpdater implements CommandLineRunner
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheUpdater.class);
|
||||
|
||||
private final Sql2o sql2o;
|
||||
private final MinioClient minioClient;
|
||||
|
||||
@Value("${minio.bucket}")
|
||||
private String minioBucket;
|
||||
|
||||
@Autowired
|
||||
public CacheUpdater(
|
||||
@Qualifier("Runelite Cache SQL2O") Sql2o sql2o,
|
||||
MinioClient minioClient
|
||||
)
|
||||
{
|
||||
this.sql2o = sql2o;
|
||||
this.minioClient = minioClient;
|
||||
}
|
||||
|
||||
public void update() throws IOException, InvalidEndpointException, InvalidPortException, InterruptedException
|
||||
{
|
||||
int rsVersion = RuneLiteAPI.getRsVersion();
|
||||
|
||||
try (Connection con = sql2o.beginTransaction())
|
||||
{
|
||||
CacheDAO cacheDao = new CacheDAO();
|
||||
CacheEntry cache = cacheDao.findMostRecent(con);
|
||||
boolean created = false;
|
||||
if (cache == null)
|
||||
{
|
||||
created = true;
|
||||
cache = cacheDao.createCache(con, rsVersion, Instant.now());
|
||||
}
|
||||
|
||||
CacheStorage storage = new CacheStorage(cache, cacheDao, con);
|
||||
Store store = new Store(storage);
|
||||
store.load();
|
||||
|
||||
ExecutorService executor = Executors.newSingleThreadExecutor();
|
||||
|
||||
CacheClient client = new CacheClient(store, rsVersion,
|
||||
(Archive archive, byte[] data) -> executor.submit(new CacheUploader(minioClient, minioBucket, archive, data)));
|
||||
|
||||
client.connect();
|
||||
HandshakeResponseType result = client.handshake().join();
|
||||
|
||||
if (result != HandshakeResponseType.RESPONSE_OK)
|
||||
{
|
||||
logger.warn("Out of date!");
|
||||
return;
|
||||
}
|
||||
|
||||
List<IndexInfo> indexes = client.requestIndexes();
|
||||
List<IndexEntry> entries = cacheDao.findIndexesForCache(con, cache);
|
||||
|
||||
if (!checkOutOfDate(indexes, entries))
|
||||
{
|
||||
logger.info("All up to date.");
|
||||
return;
|
||||
}
|
||||
|
||||
client.download();
|
||||
|
||||
CacheEntry newCache = created ? cache : cacheDao.createCache(con, rsVersion, Instant.now());
|
||||
|
||||
storage.setCacheEntry(newCache);
|
||||
store.save();
|
||||
|
||||
// ensure objects are added to the store before they become
|
||||
// visible in the database
|
||||
executor.shutdown();
|
||||
while (!executor.awaitTermination(1, TimeUnit.SECONDS))
|
||||
{
|
||||
logger.debug("Waiting for termination of executor...");
|
||||
}
|
||||
|
||||
// commit database
|
||||
con.commit();
|
||||
}
|
||||
}
|
||||
|
||||
private boolean checkOutOfDate(List<IndexInfo> indexes, List<IndexEntry> dbIndexes)
|
||||
{
|
||||
if (indexes.size() != dbIndexes.size())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
for (int i = 0; i < indexes.size(); ++i)
|
||||
{
|
||||
IndexInfo ii = indexes.get(i);
|
||||
IndexEntry ie = dbIndexes.get(i);
|
||||
|
||||
if (ii.getId() != ie.getIndexId()
|
||||
|| ii.getRevision() != ie.getRevision()
|
||||
|| ii.getCrc() != ie.getCrc())
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run(String... args) throws Exception
|
||||
{
|
||||
update();
|
||||
}
|
||||
|
||||
public static void main(String[] args)
|
||||
{
|
||||
SpringApplication.run(CacheUpdater.class, args).close();
|
||||
System.exit(0);
|
||||
}
|
||||
|
||||
}
|
||||
96
cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java
vendored
Normal file
96
cache-updater/src/main/java/net/runelite/cache/updater/CacheUploader.java
vendored
Normal file
@@ -0,0 +1,96 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater;
|
||||
|
||||
import com.google.common.hash.Hashing;
|
||||
import com.google.common.io.BaseEncoding;
|
||||
import io.minio.MinioClient;
|
||||
import io.minio.errors.ErrorResponseException;
|
||||
import io.minio.errors.InsufficientDataException;
|
||||
import io.minio.errors.InternalException;
|
||||
import io.minio.errors.InvalidArgumentException;
|
||||
import io.minio.errors.InvalidBucketNameException;
|
||||
import io.minio.errors.NoResponseException;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.security.InvalidKeyException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
import org.xmlpull.v1.XmlPullParserException;
|
||||
|
||||
public class CacheUploader implements Runnable
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(CacheUploader.class);
|
||||
|
||||
private final MinioClient minioClient;
|
||||
private final String minioBucket;
|
||||
private final Archive archive;
|
||||
private final byte[] data;
|
||||
|
||||
public CacheUploader(MinioClient minioClient, String minioBucket, Archive archive, byte[] data)
|
||||
{
|
||||
this.minioClient = minioClient;
|
||||
this.minioBucket = minioBucket;
|
||||
this.archive = archive;
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void run()
|
||||
{
|
||||
byte[] hash = Hashing.sha256().hashBytes(data).asBytes();
|
||||
String hashStr = BaseEncoding.base16().encode(hash);
|
||||
|
||||
archive.setHash(hash);
|
||||
|
||||
String path = new StringBuilder()
|
||||
.append(hashStr, 0, 2)
|
||||
.append('/')
|
||||
.append(hashStr.substring(2))
|
||||
.toString();
|
||||
|
||||
try
|
||||
{
|
||||
try (InputStream in = minioClient.getObject(minioBucket, path))
|
||||
{
|
||||
return; // already exists
|
||||
}
|
||||
catch (ErrorResponseException ex)
|
||||
{
|
||||
// doesn't exist
|
||||
}
|
||||
|
||||
minioClient.putObject(minioBucket, path, new ByteArrayInputStream(data), data.length, "binary/octet-stream");
|
||||
}
|
||||
catch (ErrorResponseException | InsufficientDataException | InternalException | InvalidArgumentException | InvalidBucketNameException | NoResponseException | IOException | InvalidKeyException | NoSuchAlgorithmException | XmlPullParserException ex)
|
||||
{
|
||||
logger.warn("unable to upload data to store", ex);
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
48
cache-updater/src/main/java/net/runelite/cache/updater/InstantConverter.java
vendored
Normal file
48
cache-updater/src/main/java/net/runelite/cache/updater/InstantConverter.java
vendored
Normal file
@@ -0,0 +1,48 @@
|
||||
/*
|
||||
* Copyright (c) 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:
|
||||
*
|
||||
* Redistributions of source code must retain the above copyright notice, this
|
||||
* list of conditions and the following disclaimer.
|
||||
*
|
||||
* 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 HOLDER 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.cache.updater;
|
||||
|
||||
import java.sql.Timestamp;
|
||||
import java.time.Instant;
|
||||
import org.sql2o.converters.Converter;
|
||||
import org.sql2o.converters.ConverterException;
|
||||
|
||||
public class InstantConverter implements Converter<Instant>
|
||||
{
|
||||
@Override
|
||||
public Instant convert(Object val) throws ConverterException
|
||||
{
|
||||
Timestamp ts = (Timestamp) val;
|
||||
return ts.toInstant();
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object toDatabaseParam(Instant val)
|
||||
{
|
||||
return Timestamp.from(val);
|
||||
}
|
||||
|
||||
}
|
||||
38
cache-updater/src/main/java/net/runelite/cache/updater/beans/ArchiveEntry.java
vendored
Normal file
38
cache-updater/src/main/java/net/runelite/cache/updater/beans/ArchiveEntry.java
vendored
Normal file
@@ -0,0 +1,38 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater.beans;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class ArchiveEntry
|
||||
{
|
||||
private int id;
|
||||
private int archiveId;
|
||||
private int nameHash;
|
||||
private int crc;
|
||||
private int revision;
|
||||
private byte[] hash;
|
||||
}
|
||||
36
cache-updater/src/main/java/net/runelite/cache/updater/beans/CacheEntry.java
vendored
Normal file
36
cache-updater/src/main/java/net/runelite/cache/updater/beans/CacheEntry.java
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater.beans;
|
||||
|
||||
import java.time.Instant;
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class CacheEntry
|
||||
{
|
||||
private int id;
|
||||
private int revision;
|
||||
private Instant date;
|
||||
}
|
||||
36
cache-updater/src/main/java/net/runelite/cache/updater/beans/FileEntry.java
vendored
Normal file
36
cache-updater/src/main/java/net/runelite/cache/updater/beans/FileEntry.java
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater.beans;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class FileEntry
|
||||
{
|
||||
private int id;
|
||||
private int archiveId;
|
||||
private int fileId;
|
||||
private int nameHash;
|
||||
}
|
||||
36
cache-updater/src/main/java/net/runelite/cache/updater/beans/IndexEntry.java
vendored
Normal file
36
cache-updater/src/main/java/net/runelite/cache/updater/beans/IndexEntry.java
vendored
Normal file
@@ -0,0 +1,36 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache.updater.beans;
|
||||
|
||||
import lombok.Data;
|
||||
|
||||
@Data
|
||||
public class IndexEntry
|
||||
{
|
||||
private int id;
|
||||
private int indexId;
|
||||
private int crc;
|
||||
private int revision;
|
||||
}
|
||||
16
cache-updater/src/main/resources/application.yaml
Normal file
16
cache-updater/src/main/resources/application.yaml
Normal file
@@ -0,0 +1,16 @@
|
||||
---
|
||||
# Database
|
||||
datasource:
|
||||
runelite-cache:
|
||||
driverClassName: com.mysql.jdbc.Driver
|
||||
type: com.mysql.jdbc.jdbc2.optional.MysqlDataSource
|
||||
url: jdbc:mysql://localhost/runelite-cache
|
||||
username: runelite
|
||||
password: runelite
|
||||
|
||||
# Minio client storage for cache
|
||||
minio:
|
||||
endpoint: http://localhost:9000
|
||||
accesskey: AM54M27O4WZK65N6F8IP
|
||||
secretkey: /PZCxzmsJzwCHYlogcymuprniGCaaLUOET2n6yMP
|
||||
bucket: runelite
|
||||
171
cache/pom.xml
vendored
Normal file
171
cache/pom.xml
vendored
Normal file
@@ -0,0 +1,171 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
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.
|
||||
-->
|
||||
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
|
||||
<modelVersion>4.0.0</modelVersion>
|
||||
|
||||
<parent>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>runelite-parent</artifactId>
|
||||
<version>1.5.28-SNAPSHOT</version>
|
||||
</parent>
|
||||
|
||||
<artifactId>cache</artifactId>
|
||||
<name>Cache</name>
|
||||
|
||||
<properties>
|
||||
<cache.version>165</cache.version>
|
||||
|
||||
<antlr4.version>4.6</antlr4.version>
|
||||
</properties>
|
||||
|
||||
<dependencies>
|
||||
<dependency>
|
||||
<groupId>net.runelite</groupId>
|
||||
<artifactId>http-api</artifactId>
|
||||
<version>${project.version}</version>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>com.google.guava</groupId>
|
||||
<artifactId>guava</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-api</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.apache.commons</groupId>
|
||||
<artifactId>commons-compress</artifactId>
|
||||
<version>1.10</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>com.google.code.gson</groupId>
|
||||
<artifactId>gson</artifactId>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>io.netty</groupId>
|
||||
<artifactId>netty-buffer</artifactId>
|
||||
<version>4.1.0.Final</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-runtime</artifactId>
|
||||
<version>${antlr4.version}</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>commons-cli</groupId>
|
||||
<artifactId>commons-cli</artifactId>
|
||||
<version>1.3.1</version>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.projectlombok</groupId>
|
||||
<artifactId>lombok</artifactId>
|
||||
<scope>provided</scope>
|
||||
</dependency>
|
||||
|
||||
<dependency>
|
||||
<groupId>junit</groupId>
|
||||
<artifactId>junit</artifactId>
|
||||
<version>4.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>org.slf4j</groupId>
|
||||
<artifactId>slf4j-simple</artifactId>
|
||||
<version>1.7.12</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
<dependency>
|
||||
<groupId>net.runelite.rs</groupId>
|
||||
<artifactId>cache</artifactId>
|
||||
<version>${cache.version}</version>
|
||||
<scope>test</scope>
|
||||
</dependency>
|
||||
</dependencies>
|
||||
|
||||
<build>
|
||||
<testResources>
|
||||
<testResource>
|
||||
<directory>src/test/resources</directory>
|
||||
<filtering>true</filtering>
|
||||
</testResource>
|
||||
</testResources>
|
||||
<plugins>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-surefire-plugin</artifactId>
|
||||
<configuration>
|
||||
<enableAssertions>true</enableAssertions>
|
||||
<argLine>-Xmx2048m</argLine>
|
||||
<systemProperties>
|
||||
<cache.tmpdir>${cache.tmpdir}</cache.tmpdir>
|
||||
</systemProperties>
|
||||
</configuration>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<artifactId>maven-assembly-plugin</artifactId>
|
||||
<configuration>
|
||||
<descriptorRefs>
|
||||
<descriptorRef>jar-with-dependencies</descriptorRef>
|
||||
</descriptorRefs>
|
||||
</configuration>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>make-assembly</id> <!-- this is used for inheritance merges -->
|
||||
<phase>package</phase> <!-- bind to the packaging phase -->
|
||||
<goals>
|
||||
<goal>single</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.antlr</groupId>
|
||||
<artifactId>antlr4-maven-plugin</artifactId>
|
||||
<version>${antlr4.version}</version>
|
||||
<executions>
|
||||
<execution>
|
||||
<id>process-resources</id>
|
||||
<goals>
|
||||
<goal>antlr4</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
<plugin>
|
||||
<groupId>org.apache.maven.plugins</groupId>
|
||||
<artifactId>maven-jar-plugin</artifactId>
|
||||
<executions>
|
||||
<execution>
|
||||
<goals>
|
||||
<goal>test-jar</goal>
|
||||
</goals>
|
||||
</execution>
|
||||
</executions>
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
66
cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4
vendored
Normal file
66
cache/src/main/antlr4/net/runelite/cache/script/assembler/rs2asm.g4
vendored
Normal file
@@ -0,0 +1,66 @@
|
||||
/*
|
||||
* Copyright (c) 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.
|
||||
*/
|
||||
grammar rs2asm;
|
||||
|
||||
prog: NEWLINE* (header NEWLINE+)* (line NEWLINE+)+ ;
|
||||
|
||||
header: id | int_stack_count | string_stack_count | int_var_count | string_var_count ;
|
||||
|
||||
id: '.id ' id_value ;
|
||||
int_stack_count: '.int_stack_count ' int_stack_value ;
|
||||
string_stack_count: '.string_stack_count ' string_stack_value ;
|
||||
int_var_count: '.int_var_count ' int_var_value ;
|
||||
string_var_count: '.string_var_count ' string_var_value ;
|
||||
|
||||
id_value: INT ;
|
||||
int_stack_value: INT ;
|
||||
string_stack_value: INT ;
|
||||
int_var_value: INT ;
|
||||
string_var_value: INT ;
|
||||
|
||||
line: instruction | label | switch_lookup ;
|
||||
instruction: instruction_name instruction_operand ;
|
||||
label: IDENTIFIER ':' ;
|
||||
|
||||
instruction_name: name_string | name_opcode ;
|
||||
name_string: IDENTIFIER ;
|
||||
name_opcode: INT ;
|
||||
|
||||
instruction_operand: operand_int | operand_qstring | operand_label | ;
|
||||
operand_int: INT ;
|
||||
operand_qstring: QSTRING ;
|
||||
operand_label: IDENTIFIER ;
|
||||
|
||||
switch_lookup: switch_key ':' switch_value ;
|
||||
switch_key: INT ;
|
||||
switch_value: IDENTIFIER ;
|
||||
|
||||
NEWLINE: ( '\r' | '\n' )+ ;
|
||||
INT: '-'? [0-9]+ ;
|
||||
QSTRING: '"' (~('"' | '\\' | '\r' | '\n') | '\\' ('"' | '\\'))* '"' ;
|
||||
IDENTIFIER: [a-zA-Z0-9_]+ ;
|
||||
COMMENT: ';' ~( '\r' | '\n' )* -> channel(HIDDEN) ;
|
||||
|
||||
WS: (' ' | '\t')+ -> channel(HIDDEN) ;
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 2018, https://runelitepl.us
|
||||
* Copyright (c) 2017, Adam <Adam@sigterm.info>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@@ -22,62 +22,56 @@
|
||||
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
|
||||
* SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
package net.runelite.client.plugins.barbarianassault;
|
||||
package net.runelite.cache;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.Collection;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import net.runelite.cache.definitions.AreaDefinition;
|
||||
import net.runelite.cache.definitions.loaders.AreaLoader;
|
||||
import net.runelite.cache.fs.Archive;
|
||||
import net.runelite.cache.fs.ArchiveFiles;
|
||||
import net.runelite.cache.fs.FSFile;
|
||||
import net.runelite.cache.fs.Index;
|
||||
import net.runelite.cache.fs.Storage;
|
||||
import net.runelite.cache.fs.Store;
|
||||
|
||||
public enum Calls
|
||||
{ //Attacker Calls
|
||||
RED_EGG("Red egg", "Tell-red"),
|
||||
GREEN_EGG("Green egg", "Tell-green"),
|
||||
BLUE_EGG("Blue egg", "Tell-blue"),
|
||||
//Collector Calls
|
||||
CONTROLLED("Controlled/Bullet/Wind", "Tell-controlled"),
|
||||
ACCURATE("Accurate/Field/Water", "Tell-accurate"),
|
||||
AGGRESSIVE("Aggressive/Blunt/Earth", "Tell-aggressive"),
|
||||
DEFENSIVE("Defensive/Barbed/Fire", "Tell-defensive"),
|
||||
//Healer Calls
|
||||
TOFU("Tofu", "Tell-tofu"),
|
||||
CRACKERS("Crackers", "Tell-crackers"),
|
||||
WORMS("Worms", "Tell-worms"),
|
||||
//Defender Calls
|
||||
POIS_WORMS("Pois. Worms", "Tell-worms"),
|
||||
POIS_TOFU("Pois. Tofu", "Tell-tofu"),
|
||||
POIS_MEAT("Pois. Meat", "Tell-meat");
|
||||
public class AreaManager
|
||||
{
|
||||
private final Store store;
|
||||
private final Map<Integer, AreaDefinition> areas = new HashMap<>();
|
||||
|
||||
private final String call;
|
||||
private final String option;
|
||||
|
||||
private static final Map<String, String> CALL_MENU = new HashMap<>();
|
||||
|
||||
static
|
||||
public AreaManager(Store store)
|
||||
{
|
||||
for (Calls s : values())
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public void load() throws IOException
|
||||
{
|
||||
Storage storage = store.getStorage();
|
||||
Index index = store.getIndex(IndexType.CONFIGS);
|
||||
Archive archive = index.getArchive(ConfigType.AREA.getId());
|
||||
|
||||
byte[] archiveData = storage.loadArchive(archive);
|
||||
ArchiveFiles files = archive.getFiles(archiveData);
|
||||
|
||||
for (FSFile file : files.getFiles())
|
||||
{
|
||||
CALL_MENU.put(s.getCall(), s.getOption());
|
||||
AreaLoader loader = new AreaLoader();
|
||||
AreaDefinition area = loader.load(file.getContents(), file.getFileId());
|
||||
areas.put(area.id, area);
|
||||
}
|
||||
}
|
||||
|
||||
Calls(String call, String option)
|
||||
public Collection<AreaDefinition> getAreas()
|
||||
{
|
||||
this.call = call;
|
||||
this.option = option;
|
||||
return Collections.unmodifiableCollection(areas.values());
|
||||
}
|
||||
|
||||
public String getCall()
|
||||
public AreaDefinition getArea(int areaId)
|
||||
{
|
||||
return call;
|
||||
return areas.get(areaId);
|
||||
}
|
||||
|
||||
public String getOption()
|
||||
{
|
||||
return option;
|
||||
}
|
||||
|
||||
public static String getOption(String call)
|
||||
{
|
||||
return CALL_MENU.get(call);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
161
cache/src/main/java/net/runelite/cache/Cache.java
vendored
Normal file
161
cache/src/main/java/net/runelite/cache/Cache.java
vendored
Normal file
@@ -0,0 +1,161 @@
|
||||
/*
|
||||
* Copyright (c) 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.cache;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import org.apache.commons.cli.CommandLine;
|
||||
import org.apache.commons.cli.CommandLineParser;
|
||||
import org.apache.commons.cli.DefaultParser;
|
||||
import org.apache.commons.cli.Options;
|
||||
import org.apache.commons.cli.ParseException;
|
||||
|
||||
public class Cache
|
||||
{
|
||||
public static void main(String[] args) throws IOException
|
||||
{
|
||||
Options options = new Options();
|
||||
|
||||
options.addOption("c", "cache", true, "cache base");
|
||||
|
||||
options.addOption(null, "items", true, "directory to dump items to");
|
||||
options.addOption(null, "npcs", true, "directory to dump npcs to");
|
||||
options.addOption(null, "objects", true, "directory to dump objects to");
|
||||
options.addOption(null, "sprites", true, "directory to dump sprites to");
|
||||
|
||||
CommandLineParser parser = new DefaultParser();
|
||||
CommandLine cmd;
|
||||
try
|
||||
{
|
||||
cmd = parser.parse(options, args);
|
||||
}
|
||||
catch (ParseException ex)
|
||||
{
|
||||
System.err.println("Error parsing command line options: " + ex.getMessage());
|
||||
System.exit(-1);
|
||||
return;
|
||||
}
|
||||
|
||||
String cache = cmd.getOptionValue("cache");
|
||||
|
||||
Store store = loadStore(cache);
|
||||
|
||||
if (cmd.hasOption("items"))
|
||||
{
|
||||
String itemdir = cmd.getOptionValue("items");
|
||||
|
||||
if (itemdir == null)
|
||||
{
|
||||
System.err.println("Item directory must be specified");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Dumping items to " + itemdir);
|
||||
dumpItems(store, new File(itemdir));
|
||||
}
|
||||
else if (cmd.hasOption("npcs"))
|
||||
{
|
||||
String npcdir = cmd.getOptionValue("npcs");
|
||||
|
||||
if (npcdir == null)
|
||||
{
|
||||
System.err.println("NPC directory must be specified");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Dumping npcs to " + npcdir);
|
||||
dumpNpcs(store, new File(npcdir));
|
||||
}
|
||||
else if (cmd.hasOption("objects"))
|
||||
{
|
||||
String objectdir = cmd.getOptionValue("objects");
|
||||
|
||||
if (objectdir == null)
|
||||
{
|
||||
System.err.println("Object directory must be specified");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Dumping objects to " + objectdir);
|
||||
dumpObjects(store, new File(objectdir));
|
||||
}
|
||||
else if (cmd.hasOption("sprites"))
|
||||
{
|
||||
String spritedir = cmd.getOptionValue("sprites");
|
||||
|
||||
if (spritedir == null)
|
||||
{
|
||||
System.err.println("Sprite directory must be specified");
|
||||
return;
|
||||
}
|
||||
|
||||
System.out.println("Dumping sprites to " + spritedir);
|
||||
dumpSprites(store, new File(spritedir));
|
||||
}
|
||||
else
|
||||
{
|
||||
System.err.println("Nothing to do");
|
||||
}
|
||||
}
|
||||
|
||||
private static Store loadStore(String cache) throws IOException
|
||||
{
|
||||
Store store = new Store(new File(cache));
|
||||
store.load();
|
||||
return store;
|
||||
}
|
||||
|
||||
private static void dumpItems(Store store, File itemdir) throws IOException
|
||||
{
|
||||
ItemManager dumper = new ItemManager(store);
|
||||
dumper.load();
|
||||
dumper.export(itemdir);
|
||||
dumper.java(itemdir);
|
||||
}
|
||||
|
||||
private static void dumpNpcs(Store store, File npcdir) throws IOException
|
||||
{
|
||||
NpcManager dumper = new NpcManager(store);
|
||||
dumper.load();
|
||||
dumper.dump(npcdir);
|
||||
dumper.java(npcdir);
|
||||
}
|
||||
|
||||
private static void dumpObjects(Store store, File objectdir) throws IOException
|
||||
{
|
||||
ObjectManager dumper = new ObjectManager(store);
|
||||
dumper.load();
|
||||
dumper.dump(objectdir);
|
||||
dumper.java(objectdir);
|
||||
}
|
||||
|
||||
private static void dumpSprites(Store store, File spritedir) throws IOException
|
||||
{
|
||||
SpriteManager dumper = new SpriteManager(store);
|
||||
dumper.load();
|
||||
dumper.export(spritedir);
|
||||
}
|
||||
}
|
||||
59
cache/src/main/java/net/runelite/cache/ConfigType.java
vendored
Normal file
59
cache/src/main/java/net/runelite/cache/ConfigType.java
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.cache;
|
||||
|
||||
public enum ConfigType
|
||||
{
|
||||
// types from https://github.com/im-frizzy/OpenRS/blob/master/source/net/openrs/cache/type/ConfigArchive.java
|
||||
UNDERLAY(1),
|
||||
IDENTKIT(3),
|
||||
OVERLAY(4),
|
||||
INV(5),
|
||||
OBJECT(6),
|
||||
ENUM(8),
|
||||
NPC(9),
|
||||
ITEM(10),
|
||||
SEQUENCE(12),
|
||||
SPOTANIM(13),
|
||||
VARBIT(14),
|
||||
VARCLIENT(19),
|
||||
VARCLIENTSTRING(15),
|
||||
VARPLAYER(16),
|
||||
STRUCT(34),
|
||||
AREA(35);
|
||||
|
||||
private final int id;
|
||||
|
||||
ConfigType(int id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getId()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
149
cache/src/main/java/net/runelite/cache/HeightMapDumper.java
vendored
Normal file
149
cache/src/main/java/net/runelite/cache/HeightMapDumper.java
vendored
Normal file
@@ -0,0 +1,149 @@
|
||||
/*
|
||||
* 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.cache;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.IOException;
|
||||
import net.runelite.cache.fs.Store;
|
||||
import net.runelite.cache.region.Region;
|
||||
import net.runelite.cache.region.RegionLoader;
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class HeightMapDumper
|
||||
{
|
||||
private static final Logger logger = LoggerFactory.getLogger(HeightMapDumper.class);
|
||||
|
||||
private static final int MAP_SCALE = 1;
|
||||
private static final float MAX_HEIGHT = 2048f;
|
||||
|
||||
private final Store store;
|
||||
private RegionLoader regionLoader;
|
||||
|
||||
public HeightMapDumper(Store store)
|
||||
{
|
||||
this.store = store;
|
||||
}
|
||||
|
||||
public void load() throws IOException
|
||||
{
|
||||
regionLoader = new RegionLoader(store);
|
||||
regionLoader.loadRegions();
|
||||
regionLoader.calculateBounds();
|
||||
}
|
||||
|
||||
public BufferedImage drawHeightMap(int z)
|
||||
{
|
||||
int minX = regionLoader.getLowestX().getBaseX();
|
||||
int minY = regionLoader.getLowestY().getBaseY();
|
||||
|
||||
int maxX = regionLoader.getHighestX().getBaseX() + Region.X;
|
||||
int maxY = regionLoader.getHighestY().getBaseY() + Region.Y;
|
||||
|
||||
int dimX = maxX - minX;
|
||||
int dimY = maxY - minY;
|
||||
|
||||
dimX *= MAP_SCALE;
|
||||
dimY *= MAP_SCALE;
|
||||
|
||||
logger.info("Map image dimensions: {}px x {}px, {}px per map square ({} MB)", dimX, dimY, MAP_SCALE, (dimX * dimY / 1024 / 1024));
|
||||
|
||||
BufferedImage image = new BufferedImage(dimX, dimY, BufferedImage.TYPE_INT_RGB);
|
||||
draw(image, z);
|
||||
return image;
|
||||
}
|
||||
|
||||
private void draw(BufferedImage image, int z)
|
||||
{
|
||||
int max = Integer.MIN_VALUE;
|
||||
int min = Integer.MAX_VALUE;
|
||||
|
||||
for (Region region : regionLoader.getRegions())
|
||||
{
|
||||
int baseX = region.getBaseX();
|
||||
int baseY = region.getBaseY();
|
||||
|
||||
// to pixel X
|
||||
int drawBaseX = baseX - regionLoader.getLowestX().getBaseX();
|
||||
|
||||
// to pixel Y. top most y is 0, but the top most
|
||||
// region has the greatest y, so invert
|
||||
int drawBaseY = regionLoader.getHighestY().getBaseY() - baseY;
|
||||
|
||||
for (int x = 0; x < Region.X; ++x)
|
||||
{
|
||||
int drawX = drawBaseX + x;
|
||||
|
||||
for (int y = 0; y < Region.Y; ++y)
|
||||
{
|
||||
int drawY = drawBaseY + (Region.Y - 1 - y);
|
||||
|
||||
int height = region.getTileHeight(z, x, y);
|
||||
if (height > max)
|
||||
{
|
||||
max = height;
|
||||
}
|
||||
if (height < min)
|
||||
{
|
||||
min = height;
|
||||
}
|
||||
|
||||
int rgb = toColor(height);
|
||||
|
||||
drawMapSquare(image, drawX, drawY, rgb);
|
||||
}
|
||||
}
|
||||
}
|
||||
System.out.println("max " + max);
|
||||
System.out.println("min " + min);
|
||||
}
|
||||
|
||||
private int toColor(int height)
|
||||
{
|
||||
// height seems to be between -2040 and 0, inclusive
|
||||
height = -height;
|
||||
// Convert to between 0 and 1
|
||||
float color = (float) height / MAX_HEIGHT;
|
||||
|
||||
assert color >= 0.0f && color <= 1.0f;
|
||||
|
||||
return new Color(color, color, color).getRGB();
|
||||
}
|
||||
|
||||
private void drawMapSquare(BufferedImage image, int x, int y, int rgb)
|
||||
{
|
||||
x *= MAP_SCALE;
|
||||
y *= MAP_SCALE;
|
||||
|
||||
for (int i = 0; i < MAP_SCALE; ++i)
|
||||
{
|
||||
for (int j = 0; j < MAP_SCALE; ++j)
|
||||
{
|
||||
image.setRGB(x + i, y + j, rgb);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
59
cache/src/main/java/net/runelite/cache/IndexType.java
vendored
Normal file
59
cache/src/main/java/net/runelite/cache/IndexType.java
vendored
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* 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.cache;
|
||||
|
||||
public enum IndexType
|
||||
{
|
||||
FRAMES(0),
|
||||
FRAMEMAPS(1),
|
||||
CONFIGS(2),
|
||||
INTERFACES(3),
|
||||
SOUNDEFFECTS(4),
|
||||
MAPS(5),
|
||||
TRACK1(6),
|
||||
MODELS(7),
|
||||
SPRITES(8),
|
||||
TEXTURES(9),
|
||||
BINARY(10),
|
||||
TRACK2(11),
|
||||
CLIENTSCRIPT(12),
|
||||
FONTS(13),
|
||||
VORBIS(14),
|
||||
INSTRUMENTS(15),
|
||||
WORLDMAP(16);
|
||||
|
||||
private int id;
|
||||
|
||||
IndexType(int id)
|
||||
{
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getNumber()
|
||||
{
|
||||
return id;
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user