diff --git a/.gitattributes b/.gitattributes new file mode 100644 index 0000000000..c51f397d56 --- /dev/null +++ b/.gitattributes @@ -0,0 +1,14 @@ +* text=auto + +# Always Unix-style line endings +*.sh text eol=lf + +# Always Windows-style line endings +*.bat text eol=crlf +*.cmd text eol=crlf + +# Always binary +*.jpg -text +*.ogg -text +*.png -text +*.xcf -text diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS new file mode 100644 index 0000000000..94fc9f8ff3 --- /dev/null +++ b/.github/CODEOWNERS @@ -0,0 +1,11 @@ +/src/main/java/io/github/moulberry/notenoughupdates/recipes/* @romangraef +/src/main/java/io/github/moulberry/notenoughupdates/miscgui/GuiItemRecipe.java @romangraef +/*gradle* @romangraef +/README.md @IRONM00N +/CONTRIBUTING.md @romangraef @IRONM00N +/.editorconfig @IRONM00N +/.github/CODE_OF_CONDUCT.md @IRONM00N +/.github/SECURITY.md @IRONM00N +/.github/SUPPORT.md @IRONM00N +/.idea/codeStyles/* @IRONM00N +/.idea/copyright/* @IRONM00N diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md new file mode 100644 index 0000000000..e91612f1a7 --- /dev/null +++ b/.github/CODE_OF_CONDUCT.md @@ -0,0 +1,3 @@ +# Contributor Code of Conduct + +Don't be a jerk. diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 5e58389dba..0000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,34 +0,0 @@ ---- -name: Bug report -about: Help Moulberry pinpoint problems. -title: '[Bug] Title' -labels: '' -assignees: '' - ---- - - - - -**Mod Version:** - - -**Describe the bug** - - -**To Reproduce** -1. -2. - - -**Expected behavior** - - -**Attachments** \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml new file mode 100644 index 0000000000..0063ceed9e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -0,0 +1,8 @@ +blank_issues_enabled: false +contact_links: + - name: NEU Support + url: https://discord.gg/moulberry + about: "Please ask for support in #neu-support on Moulberry's discord." + - name: Report security vulnerabilities + url: https://discord.gg/moulberry + about: "If you wish to discuss a bug *with security implications* privately, please open a ticket in Moulberry's discord using /new in #bot-commands" diff --git a/.github/SECURITY.md b/.github/SECURITY.md new file mode 100644 index 0000000000..7ddab38193 --- /dev/null +++ b/.github/SECURITY.md @@ -0,0 +1,16 @@ +# Security Policy + +## Supported Versions + +The following versions of the mod support security updates. + +| Version | Supported | +| ------- | ------------------ | +| < 2.0 | :x: | +| 2.0.x | :white_check_mark: | +| 2.1.x | :white_check_mark: | + +## Reporting a Vulnerability + +Please report vulnerabilities in our [discord server](https://discord.gg/moulberry) by creating a new +ticket in #bot-commands with the command `/new `. diff --git a/.github/SUPPORT.md b/.github/SUPPORT.md new file mode 100644 index 0000000000..24328844f6 --- /dev/null +++ b/.github/SUPPORT.md @@ -0,0 +1,7 @@ + + +# Obtain Support for NotEnoughUpdates + +If you are struggling to install the mod, having issues with it, experiencing +unexpected crashes, or have another issue: join our community [discord server](https://discord.gg/moulberry) +and ask for help in the #neu-support channel. diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index 3b6d0cbd64..639d396527 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -3,18 +3,22 @@ name: Build on: push: branches: - - '*' + - "*" paths-ignore: - - 'README.md' - - 'LICENSE' - - '.gitignore' + - "README.md" + - "COPYING" + - "COPYING.LESSER" + - ".gitignore" + - "Update Notes" pull_request: branches: - - '*' + - "*" paths-ignore: - - 'README.md' - - 'LICENSE' - - '.gitignore' + - "README.md" + - "COPYING" + - "COPYING.LESSER" + - ".gitignore" + - "Update Notes" workflow_dispatch: jobs: build: @@ -26,36 +30,36 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 - - name: Send discord notification - id: sendmsg - if: ${{ env.WEBHOOK_URL }} - run: | - ./.github/workflows/send_webhook_update.sh - env: - STATUS: WORKING - - name: Set up JDK 8 - uses: actions/setup-java@v2 - with: - java-version: 8 - distribution: zulu - cache: gradle - - name: Build with Gradle - run: chmod +x ./gradlew && ./gradlew setupCIWorkspace build --no-daemon - - uses: actions/upload-artifact@v2 - with: - path: build/libs/*-dep.jar - - name: Update discord notification - if: ${{ env.WEBHOOK_URL && success() }} - run: | - ./.github/workflows/send_webhook_update.sh - env: - STATUS: SUCCESS - MESSAGE_ID: ${{ steps.sendmsg.outputs.MESSAGE_ID }} - - name: Update discord notification - if: ${{ env.WEBHOOK_URL && failure() }} - run: | - ./.github/workflows/send_webhook_update.sh - env: - STATUS: FAILURE - MESSAGE_ID: ${{ steps.sendmsg.outputs.MESSAGE_ID }} + - uses: actions/checkout@v2 + - name: Send discord notification + id: sendmsg + if: ${{ env.WEBHOOK_URL }} + run: | + ./.github/workflows/send_webhook_update.sh + env: + STATUS: WORKING + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: 17 + distribution: temurin + cache: gradle + - name: Build with Gradle + run: chmod +x ./gradlew && ./gradlew clean test remapJar --no-daemon + - uses: actions/upload-artifact@v2 + with: + path: build/libs/*-dep.jar + - name: Update discord notification + if: ${{ env.WEBHOOK_URL && success() }} + run: | + ./.github/workflows/send_webhook_update.sh + env: + STATUS: SUCCESS + MESSAGE_ID: ${{ steps.sendmsg.outputs.MESSAGE_ID }} + - name: Update discord notification + if: ${{ env.WEBHOOK_URL && failure() }} + run: | + ./.github/workflows/send_webhook_update.sh + env: + STATUS: FAILURE + MESSAGE_ID: ${{ steps.sendmsg.outputs.MESSAGE_ID }} diff --git a/.github/workflows/infer.yml b/.github/workflows/infer.yml new file mode 100644 index 0000000000..365e748b70 --- /dev/null +++ b/.github/workflows/infer.yml @@ -0,0 +1,49 @@ +name: Infer + +on: + - pull_request + - workflow_dispatch +jobs: + inferering: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v2 + name: Checkout feature + with: + ref: ${{ github.event.pull_request.head.sha }} + - name: Set up JDK 17 + uses: actions/setup-java@v2 + with: + java-version: 17 + distribution: temurin + cache: gradle + - name: Setup Infer + uses: srz-zumix/setup-infer@v1 + - name: Run Infer on feature + run: | + echo On commit $(git log --pretty=%s -1) + mkdir -p ciwork + infer capture -- ./gradlew clean test --no-daemon + infer analyze + cp infer-out/report.json ciwork/report-feature.json + - uses: actions/checkout@v2 + name: Checkout base + with: + ref: ${{ github.event.pull_request.base.sha }} + clean: false + - name: Run Infer on base + run: | + echo On commit $(git log --pretty=%s -1) + infer capture --reactive -- ./gradlew clean test --no-daemon + infer analyze --reactive + - name: Generate report + run: | + infer reportdiff --report-current ciwork/report-feature.json --report-previous infer-out/report.json + jq -r '.[] | select(.severity == "ERROR") | ("::error file="+.file +",line=" +(.line|tostring)+"::" + .qualifier)' >$GITHUB_STEP_SUMMARY + [[ $unfixcount != 0 ]] && exit 1 || echo ok. diff --git a/.github/workflows/send_webhook_update.sh b/.github/workflows/send_webhook_update.sh index 56852159bb..f0eb00515f 100755 --- a/.github/workflows/send_webhook_update.sh +++ b/.github/workflows/send_webhook_update.sh @@ -1,4 +1,23 @@ #!/bin/bash +# +# Copyright (C) 2022 NotEnoughUpdates contributors +# +# This file is part of NotEnoughUpdates. +# +# NotEnoughUpdates is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# NotEnoughUpdates 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with NotEnoughUpdates. If not, see . +# + set -x COLOR_SUCCESS=8040199 @@ -69,7 +88,7 @@ function make_request() { curl -X $1 -H "Content-Type: multipart/form-data" -F "payload_json=$json" "$upload_arg" "$upload_name=@$to_upload" "$WEBHOOK_URL$2?wait=true" } -echo "Should replace message with id: $MESSAGE_ID" +echo "Should replace message with id: <$MESSAGE_ID>" if [ "$MESSAGE_ID" != "" ]; then discord_output=$(make_request PATCH "/messages/$MESSAGE_ID") RESULT=$? diff --git a/.gitignore b/.gitignore index a7b89d9412..e02d8fc465 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ out *.iml .idea/* !.idea/codeStyles +!.idea/copyright # gradle build @@ -23,3 +24,6 @@ gradle.properties eclipse run .vscode +infer-out/ +ciwork/ +.DS_STORE diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml index 6cedf3ffca..c2c5091347 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -1,5 +1,9 @@ + + diff --git a/.idea/copyright/NotEnoughUpdates.xml b/.idea/copyright/NotEnoughUpdates.xml new file mode 100644 index 0000000000..8dd67ac427 --- /dev/null +++ b/.idea/copyright/NotEnoughUpdates.xml @@ -0,0 +1,7 @@ + + + + \ No newline at end of file diff --git a/.idea/copyright/profiles_settings.xml b/.idea/copyright/profiles_settings.xml new file mode 100644 index 0000000000..8f73a5c01a --- /dev/null +++ b/.idea/copyright/profiles_settings.xml @@ -0,0 +1,7 @@ + + + + + + + \ No newline at end of file diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 0000000000..e7c4b37969 --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,147 @@ +# Contributing + +## Before you contribute + +- Please check your feature / bug isn't already fixed in one of our pre-releases or on [the development branch](https://github.com/NotEnoughUpdates/NotEnoughUpdates/tree/master/). +- Consider joining our [Discord](https://discord.gg/moulberry) to check in on newest developments by other people, or to get help with problems you encounter. +- Please check that your feature idea complies with the [Hypixel Rules](https://hypixel.net/rules) +- Check that your feature idea isn't already done in other mods. (E.g. Dungeon Solver) + +## Setting up a development environment + +### Software prerequisites + +- Install a Java Development Kit (You will need both version 8 and version 17) [Eclipse Temurin Download](https://adoptium.net/temurin/releases) for convenience, however any JDK will do. +- Install Git. [Windows download](https://git-scm.com/download/win) +- Install an IDE, such as [Jetbrains IntelliJ IDEA](https://www.jetbrains.com/idea/download). + +### Software configuration + +- Clone the NEU repository using `git clone https://github.com/NotEnoughUpdates/NotEnoughUpdates`. +- Import that folder as a Gradle Project in your IDE (IntelliJ should autodetect it as gradle if you select the `NotEnoughUpdates` folder in the Open dialog) +- Set your project SDK to your 1.8 JDK. This can be done in the modules settings (CTRL+ALT+SHIFT+S) in IntelliJ. +- Set your gradle JVM to your 1.17 JDK. This can be done by searching for `gradle jvm` in the CTRL+SHIFT+A dialog in IntelliJ. +- Run the `genRuns` gradle task. In IntelliJ that can be done in the gradle tab on the right side of your IDE. +- Optionally, run the `genSources` gradle task. +- Run the `Minecraft Client` to make sure that everything works. + - Note: if you are using OSX, remove the `XstartOnFirstThread` JVM option + +## Logging into Hypixel in a development environment + +Use [DevAuth](https://github.com/DJtheRedstoner/DevAuth). You do **not** need to download the jar, just follow the configuration instructions in the [DevAuth README](https://github.com/DJtheRedstoner/DevAuth#configuration-file) + +## Hot Reloading + +Hot Reloading is possible by first launching using the IntelliJ debugger with [DCEVM 1.8](https://dcevm.github.io/). Then running a regular build and confirming the reload prompt. This can cause issues (especially with commands), so restarting is sometimes still necessary. + +## Creating a new Release +
+Minimized, for your convenience + +> **Release Types** +> +> Right now we can create Full Releases, Pre Releases and Hotfixes. +> +> - A Full Release is sent to all users, regardless of update stream. +> - A Pre Release is only sent to users who have opted into receiving beta updates. +> - A Hotfix is only sent to users who have *not* opted into receiving beta updates. +> - Therefore when a bug is fixed in a hotfix update, it should *also* be fixed in a separate prerelease update. +> On the other hand, not all bugs fixed in a prerelease update need to be also dispatched in a hotfix. + +### Creating a new Full Release + +> Full Releases should be bug free, feature complete, and ideally checked by not only the community, but also by Moulberry himself, if he so desires. + +- Edit `NotEnoughUpdates.java` and change + +```java +public static final String VERSION = "2.2.0-REL"; /* Update the VERSION name */ +public static final int VERSION_ID = 20200; /* Set the VERSION_ID to match the version name like so: MAJOR * 10000 + MINOR * 100 + PATCH */ +public static final int PRE_VERSION_ID = 0; /* Reset the PRE_VERSION_ID back to 0 */ +public static final int HOTFIX_VERSION_ID = 0; /* Reset the HOTFIX_VERSION_ID back to 0 */ +``` + +- Build a jar from this, either using the CI in github actions, or using `gradle remapJar` directly. + - If building locally, make sure that all your changes are in version control so that the commit hash is set correctly (A non `dirty` jar) +- Create a github release (marked as full release). This should also simultaneously create a tag on which to base future hotfixes. +- Edit the `update.json` in the repository and change + +```json5 +{ + "version": "2.1.0-REL", /* Update to match the VERSION name in java */ + "version_id": 20100, /* Update to match the VERSION_ID in java */ + "update_msg": "§7§m§l--------------------§6§l[§c§lNEU§6§l]§7§m§l--------------------\n\n§7A new version, v§6{version}§7, is now available!\n ", /* Update the version name. Remove old patch notes; Optionally add in a short new patch note. */ + "pre_version": "0.0", /* Reset to 0.0 */ + "pre_version_id": 0, /* Reset to 0 */ + "update_link": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/", /* Change download link to the github release */ + "update_direct": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/download//NotEnoughUpdates-.jar", /* Change direct link to a direct download link */ +} +``` + +- Launch the game in an older version with this new repo locally to test the messages look first, then push to the central NEU repo (both `master` and `dangerous`) +- Create an announcement in discord [#neu-download](https://discord.com/channels/516977525906341928/693586404256645231). + +### Creating a pre release + +> Pre Releases are intended to be mostly feature complete, mostly bug free releases that either don't have enough changes to justify a new Full Release, or have outstanding PRs that are probably merged soon. + +- Edit `NotEnoughUpdates.java` and change + +```java +public static final String VERSION = "2.2.0-REL"; /* The VERSION name should still be the same as the latest previously released FULL release */ +public static final int VERSION_ID = 20200; /* Same as VERSION name */ +public static final int PRE_VERSION_ID = 1; /* Increment the PRE_VERSION_ID */ +``` + +- Build a jar from this, either using the CI in github actions, or using `gradle remapJar` directly. + - If building locally, make sure that all your changes are in version control so that the commit hash is set correctly (A non `dirty` jar) +- Create a github release (marked as pre release) +- Edit the `update.json` in the repository and change + +```json5 +{ + "version": "2.1.0-REL", /* The VERSION name should still be the same as the latest previously released FULL release */ + "version_id": 20100, /* Same as VERSION name */ + "pre_update_msg": "§7§m§l--------------------§5§l[§c§lNEU§5§l]§7§m§l--------------------\n\n§7A new pre-release, v§52.0-PRE{pre_version}§7, is now available!\n ", /* Update the version name. Remove old patch notes; Optionally add in a short new patch note. */ + "pre_version": "0.0", /* Set to a new string (preferably increase the major version every time, except for hotfixes on the prerelease stream) */ + "pre_version_id": 0, /* Set to PRE_VERSION_ID from java */ + "pre_update_link": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/", /* Change download link to the github release */ + "pre_update_direct": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/download//NotEnoughUpdates-.jar", /* Change direct link to a direct download link */ +} +``` + +- Launch the game in an older version with this new repo locally to test the messages look first, then push to the central NEU repo (both `master` and `dangerous`, as some prerelease people sadly don't know how to change repo branches) +- Create an announcement in discord [#unofficial-prereleases](https://discord.com/channels/516977525906341928/837679819487313971). + +### Creating a Hotfix + +> Hotfixes spring off of a Full Release and intend to fix bugs and security flaws. They can, but ideally shouldn't, contain features from pre releases and are intended as a drop in replacement of the current full release of NEU. These bug fixes should ideally also be released as a prerelease in tandem with the hotfix. + +- Edit `NotEnoughUpdates.java` and change + +```java +public static final String VERSION = "2.2.0-REL"; /* The VERSION name should still be the same as the latest previously released FULL release */ +public static final int VERSION_ID = 20200; /* Same as VERSION name */ +public static final int PRE_VERSION_ID = 0; /* The PRE_VERSION_ID should still be 0 (as this is based off a full release) */ +public static final int HOTFIX_VERSION_ID = 1; /* Increment the HOTFIX_VERSION_ID */ +``` + +- Build a jar from this, either using the CI in github actions, or using `gradle remapJar` directly. + - If building locally, make sure that all your changes are in version control so that the commit hash is set correctly (A non `dirty` jar) +- Create a github release (marked as full release) +- Edit the previous FULL release on github with a link to the new release. +- Edit the `update.json` in the repository and change + +```json5 +{ + "version": "2.1.0-REL", /* This version should still remain the same as the last full release */ + "version_id": 20100, /* Same as version */ + "update_msg": "§7§m§l--------------------§6§l[§c§lNEU§6§l]§7§m§l--------------------\n\n§7A new version, v§6{version}§7, is now available!\n ", /* Update the version name. Don't remove old patch notes; Optionally add in a short new patch note. Indicate that there is a hotfix present */ + "update_link": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/tag/", /* Change download link to the github release */ + "update_direct": "https://github.com/NotEnoughUpdates/NotEnoughUpdates/releases/download//NotEnoughUpdates-.jar", /* Change direct link to a direct download link */ +} +``` + +- Launch the game in an older version with this new repo locally to test the messages look first, then push to the central NEU repo (both `master` and `dangerous`) +- Create an announcement in discord [#neu-download](https://discord.com/channels/516977525906341928/693586404256645231). +
diff --git a/COPYING b/COPYING new file mode 100644 index 0000000000..e72bfddabc --- /dev/null +++ b/COPYING @@ -0,0 +1,674 @@ + GNU GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + Preamble + + The GNU General Public License is a free, copyleft license for +software and other kinds of works. + + The licenses for most software and other practical works are designed +to take away your freedom to share and change the works. By contrast, +the GNU General Public License is 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. We, the Free Software Foundation, use the +GNU General Public License for most of our software; it applies also to +any other work released this way by its authors. You can apply it to +your programs, too. + + 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. + + To protect your rights, we need to prevent others from denying you +these rights or asking you to surrender the rights. Therefore, you have +certain responsibilities if you distribute copies of the software, or if +you modify it: responsibilities to respect the freedom of others. + + For example, if you distribute copies of such a program, whether +gratis or for a fee, you must pass on to the recipients the same +freedoms that you received. You must make sure that they, too, receive +or can get the source code. And you must show them these terms so they +know their rights. + + Developers that use the GNU GPL protect your rights with two steps: +(1) assert copyright on the software, and (2) offer you this License +giving you legal permission to copy, distribute and/or modify it. + + For the developers' and authors' protection, the GPL clearly explains +that there is no warranty for this free software. For both users' and +authors' sake, the GPL requires that modified versions be marked as +changed, so that their problems will not be attributed erroneously to +authors of previous versions. + + Some devices are designed to deny users access to install or run +modified versions of the software inside them, although the manufacturer +can do so. This is fundamentally incompatible with the aim of +protecting users' freedom to change the software. The systematic +pattern of such abuse occurs in the area of products for individuals to +use, which is precisely where it is most unacceptable. Therefore, we +have designed this version of the GPL to prohibit the practice for those +products. If such problems arise substantially in other domains, we +stand ready to extend this provision to those domains in future versions +of the GPL, as needed to protect the freedom of users. + + Finally, every program is threatened constantly by software patents. +States should not allow patents to restrict development and use of +software on general-purpose computers, but in those that do, we wish to +avoid the special danger that patents applied to a free program could +make it effectively proprietary. To prevent this, the GPL assures that +patents cannot be used to render the program non-free. + + 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 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. Use with the GNU Affero General Public License. + + 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 Affero 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 special requirements of the GNU Affero General Public License, +section 13, concerning interaction through a network will apply to the +combination as such. + + 14. Revised Versions of this License. + + The Free Software Foundation may publish revised and/or new versions of +the GNU 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 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 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 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. + + + Copyright (C) + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU 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 General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . + +Also add information on how to contact you by electronic and paper mail. + + If the program does terminal interaction, make it output a short +notice like this when it starts in an interactive mode: + + Copyright (C) + This program comes with ABSOLUTELY NO WARRANTY; for details type `show w'. + This is free software, and you are welcome to redistribute it + under certain conditions; type `show c' for details. + +The hypothetical commands `show w' and `show c' should show the appropriate +parts of the General Public License. Of course, your program's commands +might be different; for a GUI interface, you would use an "about box". + + 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 GPL, see +. + + The GNU General Public License does not permit incorporating your program +into proprietary programs. If your program is a subroutine library, you +may consider it more useful to permit linking proprietary applications with +the library. If this is what you want to do, use the GNU Lesser General +Public License instead of this License. But first, please read +. \ No newline at end of file diff --git a/COPYING.LESSER b/COPYING.LESSER new file mode 100644 index 0000000000..153d416dc8 --- /dev/null +++ b/COPYING.LESSER @@ -0,0 +1,165 @@ + GNU LESSER GENERAL PUBLIC LICENSE + Version 3, 29 June 2007 + + Copyright (C) 2007 Free Software Foundation, Inc. + Everyone is permitted to copy and distribute verbatim copies + of this license document, but changing it is not allowed. + + + This version of the GNU Lesser General Public License incorporates +the terms and conditions of version 3 of the GNU General Public +License, supplemented by the additional permissions listed below. + + 0. Additional Definitions. + + As used herein, "this License" refers to version 3 of the GNU Lesser +General Public License, and the "GNU GPL" refers to version 3 of the GNU +General Public License. + + "The Library" refers to a covered work governed by this License, +other than an Application or a Combined Work as defined below. + + An "Application" is any work that makes use of an interface provided +by the Library, but which is not otherwise based on the Library. +Defining a subclass of a class defined by the Library is deemed a mode +of using an interface provided by the Library. + + A "Combined Work" is a work produced by combining or linking an +Application with the Library. The particular version of the Library +with which the Combined Work was made is also called the "Linked +Version". + + The "Minimal Corresponding Source" for a Combined Work means the +Corresponding Source for the Combined Work, excluding any source code +for portions of the Combined Work that, considered in isolation, are +based on the Application, and not on the Linked Version. + + The "Corresponding Application Code" for a Combined Work means the +object code and/or source code for the Application, including any data +and utility programs needed for reproducing the Combined Work from the +Application, but excluding the System Libraries of the Combined Work. + + 1. Exception to Section 3 of the GNU GPL. + + You may convey a covered work under sections 3 and 4 of this License +without being bound by section 3 of the GNU GPL. + + 2. Conveying Modified Versions. + + If you modify a copy of the Library, and, in your modifications, a +facility refers to a function or data to be supplied by an Application +that uses the facility (other than as an argument passed when the +facility is invoked), then you may convey a copy of the modified +version: + + a) under this License, provided that you make a good faith effort to + ensure that, in the event an Application does not supply the + function or data, the facility still operates, and performs + whatever part of its purpose remains meaningful, or + + b) under the GNU GPL, with none of the additional permissions of + this License applicable to that copy. + + 3. Object Code Incorporating Material from Library Header Files. + + The object code form of an Application may incorporate material from +a header file that is part of the Library. You may convey such object +code under terms of your choice, provided that, if the incorporated +material is not limited to numerical parameters, data structure +layouts and accessors, or small macros, inline functions and templates +(ten or fewer lines in length), you do both of the following: + + a) Give prominent notice with each copy of the object code that the + Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the object code with a copy of the GNU GPL and this license + document. + + 4. Combined Works. + + You may convey a Combined Work under terms of your choice that, +taken together, effectively do not restrict modification of the +portions of the Library contained in the Combined Work and reverse +engineering for debugging such modifications, if you also do each of +the following: + + a) Give prominent notice with each copy of the Combined Work that + the Library is used in it and that the Library and its use are + covered by this License. + + b) Accompany the Combined Work with a copy of the GNU GPL and this license + document. + + c) For a Combined Work that displays copyright notices during + execution, include the copyright notice for the Library among + these notices, as well as a reference directing the user to the + copies of the GNU GPL and this license document. + + d) Do one of the following: + + 0) Convey the Minimal Corresponding Source under the terms of this + License, and the Corresponding Application Code in a form + suitable for, and under terms that permit, the user to + recombine or relink the Application with a modified version of + the Linked Version to produce a modified Combined Work, in the + manner specified by section 6 of the GNU GPL for conveying + Corresponding Source. + + 1) Use a suitable shared library mechanism for linking with the + Library. A suitable mechanism is one that (a) uses at run time + a copy of the Library already present on the user's computer + system, and (b) will operate properly with a modified version + of the Library that is interface-compatible with the Linked + Version. + + e) Provide Installation Information, but only if you would otherwise + be required to provide such information under section 6 of the + GNU GPL, and only to the extent that such information is + necessary to install and execute a modified version of the + Combined Work produced by recombining or relinking the + Application with a modified version of the Linked Version. (If + you use option 4d0, the Installation Information must accompany + the Minimal Corresponding Source and Corresponding Application + Code. If you use option 4d1, you must provide the Installation + Information in the manner specified by section 6 of the GNU GPL + for conveying Corresponding Source.) + + 5. Combined Libraries. + + You may place library facilities that are a work based on the +Library side by side in a single library together with other library +facilities that are not Applications and are not covered by this +License, and convey such a combined library under terms of your +choice, if you do both of the following: + + a) Accompany the combined library with a copy of the same work based + on the Library, uncombined with any other library facilities, + conveyed under the terms of this License. + + b) Give prominent notice with the combined library that part of it + is a work based on the Library, and explaining where to find the + accompanying uncombined form of the same work. + + 6. Revised Versions of the GNU Lesser General Public License. + + The Free Software Foundation may publish revised and/or new versions +of the GNU Lesser 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 +Library as you received it specifies that a certain numbered version +of the GNU Lesser General Public License "or any later version" +applies to it, you have the option of following the terms and +conditions either of that published version or of any later version +published by the Free Software Foundation. If the Library as you +received it does not specify a version number of the GNU Lesser +General Public License, you may choose any version of the GNU Lesser +General Public License ever published by the Free Software Foundation. + + If the Library as you received it specifies that a proxy can decide +whether future versions of the GNU Lesser General Public License shall +apply, that proxy's public statement of acceptance of any version is +permanent authorization for you to choose that version for the +Library. \ No newline at end of file diff --git a/FAQ.md b/FAQ.md new file mode 100644 index 0000000000..346beb6387 --- /dev/null +++ b/FAQ.md @@ -0,0 +1,34 @@ +# FAQ For NEU + +## What is this feature? + +### Equipment Overlay +![Equipment Overlay](https://cdn.discordapp.com/attachments/756532125443817594/1006792213432389752/unknown.png) + +This overlay shows the current equipment of the player +#### It doesn't fit in with my texture pack !!!!! +[If you go to /neu equipment you can change the style of the overlay](https://cdn.discordapp.com/attachments/756532125443817594/1006796222415245413/unknown.png) +This also applies to the pet inventory overlay + + +## What does this mean? + +### Missing Repo Data +![Missing Repo Data](https://cdn.discordapp.com/attachments/756532125443817594/1006805696639143987/unknown.png) + +If you get this popup you need to update your repo data. +As the popup says, you can try `/neuresetrepo` but if that doesn't resolve the issue go to [#neu-support](https://discord.gg/moulberry) and ask for help + +## How do I? + +### Turn on fairy soul waypoints +You can either [run `/neusouls`](https://cdn.discordapp.com/attachments/756532125443817594/1006808649471103046/unknown.png) for the help menu or [turn on the option in the first page of `/neu`](https://cdn.discordapp.com/attachments/756532125443817594/1006808594743840778/unknown.png) + +### Help I accidentally turned off the custom storage gui +![enable storage gui](https://cdn.discordapp.com/attachments/756532125443817594/1006810880794710046/unknown.png) + +Simply go to `/neu storage` and turn on the first option + +### Move a GUI element +![Edit gui](https://cdn.discordapp.com/attachments/756532125443817594/1006811543356317797/unknown.png) +Go to the second tab of `/neu` and here you will have all the gui elements you can move diff --git a/LICENSE b/LICENSE deleted file mode 100644 index 7ff2f90df2..0000000000 --- a/LICENSE +++ /dev/null @@ -1,60 +0,0 @@ -License - -THE WORK (AS DEFINED BELOW) IS PROVIDED UNDER THE TERMS OF THIS CREATIVE COMMONS PUBLIC LICENSE ("CCPL" OR "LICENSE"). THE WORK IS PROTECTED BY COPYRIGHT AND/OR OTHER APPLICABLE LAW. ANY USE OF THE WORK OTHER THAN AS AUTHORIZED UNDER THIS LICENSE OR COPYRIGHT LAW IS PROHIBITED. - -BY EXERCISING ANY RIGHTS TO THE WORK PROVIDED HERE, YOU ACCEPT AND AGREE TO BE BOUND BY THE TERMS OF THIS LICENSE. TO THE EXTENT THIS LICENSE MAY BE CONSIDERED TO BE A CONTRACT, THE LICENSOR GRANTS YOU THE RIGHTS CONTAINED HERE IN CONSIDERATION OF YOUR ACCEPTANCE OF SUCH TERMS AND CONDITIONS. - -1. Definitions - - "Adaptation" means a work based upon the Work, or upon the Work and other pre-existing works, such as a translation, adaptation, derivative work, arrangement of music or other alterations of a literary or artistic work, or phonogram or performance and includes cinematographic adaptations or any other form in which the Work may be recast, transformed, or adapted including in any form recognizably derived from the original, except that a work that constitutes a Collection will not be considered an Adaptation for the purpose of this License. For the avoidance of doubt, where the Work is a musical work, performance or phonogram, the synchronization of the Work in timed-relation with a moving image ("synching") will be considered an Adaptation for the purpose of this License. - "Collection" means a collection of literary or artistic works, such as encyclopedias and anthologies, or performances, phonograms or broadcasts, or other works or subject matter other than works listed in Section 1(f) below, which, by reason of the selection and arrangement of their contents, constitute intellectual creations, in which the Work is included in its entirety in unmodified form along with one or more other contributions, each constituting separate and independent works in themselves, which together are assembled into a collective whole. A work that constitutes a Collection will not be considered an Adaptation (as defined above) for the purposes of this License. - "Distribute" means to make available to the public the original and copies of the Work or Adaptation, as appropriate, through sale or other transfer of ownership. - "Licensor" means the individual, individuals, entity or entities that offer(s) the Work under the terms of this License. - "Original Author" means, in the case of a literary or artistic work, the individual, individuals, entity or entities who created the Work or if no individual or entity can be identified, the publisher; and in addition (i) in the case of a performance the actors, singers, musicians, dancers, and other persons who act, sing, deliver, declaim, play in, interpret or otherwise perform literary or artistic works or expressions of folklore; (ii) in the case of a phonogram the producer being the person or legal entity who first fixes the sounds of a performance or other sounds; and, (iii) in the case of broadcasts, the organization that transmits the broadcast. - "Work" means the literary and/or artistic work offered under the terms of this License including without limitation any production in the literary, scientific and artistic domain, whatever may be the mode or form of its expression including digital form, such as a book, pamphlet and other writing; a lecture, address, sermon or other work of the same nature; a dramatic or dramatico-musical work; a choreographic work or entertainment in dumb show; a musical composition with or without words; a cinematographic work to which are assimilated works expressed by a process analogous to cinematography; a work of drawing, painting, architecture, sculpture, engraving or lithography; a photographic work to which are assimilated works expressed by a process analogous to photography; a work of applied art; an illustration, map, plan, sketch or three-dimensional work relative to geography, topography, architecture or science; a performance; a broadcast; a phonogram; a compilation of data to the extent it is protected as a copyrightable work; or a work performed by a variety or circus performer to the extent it is not otherwise considered a literary or artistic work. - "You" means an individual or entity exercising rights under this License who has not previously violated the terms of this License with respect to the Work, or who has received express permission from the Licensor to exercise rights under this License despite a previous violation. - "Publicly Perform" means to perform public recitations of the Work and to communicate to the public those public recitations, by any means or process, including by wire or wireless means or public digital performances; to make available to the public Works in such a way that members of the public may access these Works from a place and at a place individually chosen by them; to perform the Work to the public by any means or process and the communication to the public of the performances of the Work, including by public digital performance; to broadcast and rebroadcast the Work by any means including signs, sounds or images. - "Reproduce" means to make copies of the Work by any means including without limitation by sound or visual recordings and the right of fixation and reproducing fixations of the Work, including storage of a protected performance or phonogram in digital form or other electronic medium. - -2. Fair Dealing Rights. Nothing in this License is intended to reduce, limit, or restrict any uses free from copyright or rights arising from limitations or exceptions that are provided for in connection with the copyright protection under copyright law or other applicable laws. - -3. License Grant. Subject to the terms and conditions of this License, Licensor hereby grants You a worldwide, royalty-free, non-exclusive, perpetual (for the duration of the applicable copyright) license to exercise the rights in the Work as stated below: - - to Reproduce the Work, to incorporate the Work into one or more Collections, and to Reproduce the Work as incorporated in the Collections; - to create and Reproduce Adaptations provided that any such Adaptation, including any translation in any medium, takes reasonable steps to clearly label, demarcate or otherwise identify that changes were made to the original Work. For example, a translation could be marked "The original work was translated from English to Spanish," or a modification could indicate "The original work has been modified."; - to Distribute and Publicly Perform the Work including as incorporated in Collections; and, - to Distribute and Publicly Perform Adaptations. - -The above rights may be exercised in all media and formats whether now known or hereafter devised. The above rights include the right to make such modifications as are technically necessary to exercise the rights in other media and formats. Subject to Section 8(f), all rights not expressly granted by Licensor are hereby reserved, including but not limited to the rights set forth in Section 4(d). - -4. Restrictions. The license granted in Section 3 above is expressly made subject to and limited by the following restrictions: - - You may Distribute or Publicly Perform the Work only under the terms of this License. You must include a copy of, or the Uniform Resource Identifier (URI) for, this License with every copy of the Work You Distribute or Publicly Perform. You may not offer or impose any terms on the Work that restrict the terms of this License or the ability of the recipient of the Work to exercise the rights granted to that recipient under the terms of the License. You may not sublicense the Work. You must keep intact all notices that refer to this License and to the disclaimer of warranties with every copy of the Work You Distribute or Publicly Perform. When You Distribute or Publicly Perform the Work, You may not impose any effective technological measures on the Work that restrict the ability of a recipient of the Work from You to exercise the rights granted to that recipient under the terms of the License. This Section 4(a) applies to the Work as incorporated in a Collection, but this does not require the Collection apart from the Work itself to be made subject to the terms of this License. If You create a Collection, upon notice from any Licensor You must, to the extent practicable, remove from the Collection any credit as required by Section 4(c), as requested. If You create an Adaptation, upon notice from any Licensor You must, to the extent practicable, remove from the Adaptation any credit as required by Section 4(c), as requested. - You may not exercise any of the rights granted to You in Section 3 above in any manner that is primarily intended for or directed toward commercial advantage or private monetary compensation. The exchange of the Work for other copyrighted works by means of digital file-sharing or otherwise shall not be considered to be intended for or directed toward commercial advantage or private monetary compensation, provided there is no payment of any monetary compensation in connection with the exchange of copyrighted works. - If You Distribute, or Publicly Perform the Work or any Adaptations or Collections, You must, unless a request has been made pursuant to Section 4(a), keep intact all copyright notices for the Work and provide, reasonable to the medium or means You are utilizing: (i) the name of the Original Author (or pseudonym, if applicable) if supplied, and/or if the Original Author and/or Licensor designate another party or parties (e.g., a sponsor institute, publishing entity, journal) for attribution ("Attribution Parties") in Licensor's copyright notice, terms of service or by other reasonable means, the name of such party or parties; (ii) the title of the Work if supplied; (iii) to the extent reasonably practicable, the URI, if any, that Licensor specifies to be associated with the Work, unless such URI does not refer to the copyright notice or licensing information for the Work; and, (iv) consistent with Section 3(b), in the case of an Adaptation, a credit identifying the use of the Work in the Adaptation (e.g., "French translation of the Work by Original Author," or "Screenplay based on original Work by Original Author"). The credit required by this Section 4(c) may be implemented in any reasonable manner; provided, however, that in the case of a Adaptation or Collection, at a minimum such credit will appear, if a credit for all contributing authors of the Adaptation or Collection appears, then as part of these credits and in a manner at least as prominent as the credits for the other contributing authors. For the avoidance of doubt, You may only use the credit required by this Section for the purpose of attribution in the manner set out above and, by exercising Your rights under this License, You may not implicitly or explicitly assert or imply any connection with, sponsorship or endorsement by the Original Author, Licensor and/or Attribution Parties, as appropriate, of You or Your use of the Work, without the separate, express prior written permission of the Original Author, Licensor and/or Attribution Parties. - - For the avoidance of doubt: - Non-waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme cannot be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License; - Waivable Compulsory License Schemes. In those jurisdictions in which the right to collect royalties through any statutory or compulsory licensing scheme can be waived, the Licensor reserves the exclusive right to collect such royalties for any exercise by You of the rights granted under this License if Your exercise of such rights is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(b) and otherwise waives the right to collect royalties through any statutory or compulsory licensing scheme; and, - Voluntary License Schemes. The Licensor reserves the right to collect royalties, whether individually or, in the event that the Licensor is a member of a collecting society that administers voluntary licensing schemes, via that society, from any exercise by You of the rights granted under this License that is for a purpose or use which is otherwise than noncommercial as permitted under Section 4(c). - Except as otherwise agreed in writing by the Licensor or as may be otherwise permitted by applicable law, if You Reproduce, Distribute or Publicly Perform the Work either by itself or as part of any Adaptations or Collections, You must not distort, mutilate, modify or take other derogatory action in relation to the Work which would be prejudicial to the Original Author's honor or reputation. Licensor agrees that in those jurisdictions (e.g. Japan), in which any exercise of the right granted in Section 3(b) of this License (the right to make Adaptations) would be deemed to be a distortion, mutilation, modification or other derogatory action prejudicial to the Original Author's honor and reputation, the Licensor will waive or not assert, as appropriate, this Section, to the fullest extent permitted by the applicable national law, to enable You to reasonably exercise Your right under Section 3(b) of this License (right to make Adaptations) but not otherwise. - -5. Representations, Warranties and Disclaimer - -UNLESS OTHERWISE MUTUALLY AGREED TO BY THE PARTIES IN WRITING, LICENSOR OFFERS THE WORK AS-IS AND MAKES NO REPRESENTATIONS OR WARRANTIES OF ANY KIND CONCERNING THE WORK, EXPRESS, IMPLIED, STATUTORY OR OTHERWISE, INCLUDING, WITHOUT LIMITATION, WARRANTIES OF TITLE, MERCHANTIBILITY, FITNESS FOR A PARTICULAR PURPOSE, NONINFRINGEMENT, OR THE ABSENCE OF LATENT OR OTHER DEFECTS, ACCURACY, OR THE PRESENCE OF ABSENCE OF ERRORS, WHETHER OR NOT DISCOVERABLE. SOME JURISDICTIONS DO NOT ALLOW THE EXCLUSION OF IMPLIED WARRANTIES, SO SUCH EXCLUSION MAY NOT APPLY TO YOU. - -6. Limitation on Liability. EXCEPT TO THE EXTENT REQUIRED BY APPLICABLE LAW, IN NO EVENT WILL LICENSOR BE LIABLE TO YOU ON ANY LEGAL THEORY FOR ANY SPECIAL, INCIDENTAL, CONSEQUENTIAL, PUNITIVE OR EXEMPLARY DAMAGES ARISING OUT OF THIS LICENSE OR THE USE OF THE WORK, EVEN IF LICENSOR HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - -7. Termination - - This License and the rights granted hereunder will terminate automatically upon any breach by You of the terms of this License. Individuals or entities who have received Adaptations or Collections from You under this License, however, will not have their licenses terminated provided such individuals or entities remain in full compliance with those licenses. Sections 1, 2, 5, 6, 7, and 8 will survive any termination of this License. - Subject to the above terms and conditions, the license granted here is perpetual (for the duration of the applicable copyright in the Work). Notwithstanding the above, Licensor reserves the right to release the Work under different license terms or to stop distributing the Work at any time; provided, however that any such election will not serve to withdraw this License (or any other license that has been, or is required to be, granted under the terms of this License), and this License will continue in full force and effect unless terminated as stated above. - -8. Miscellaneous - - Each time You Distribute or Publicly Perform the Work or a Collection, the Licensor offers to the recipient a license to the Work on the same terms and conditions as the license granted to You under this License. - Each time You Distribute or Publicly Perform an Adaptation, Licensor offers to the recipient a license to the original Work on the same terms and conditions as the license granted to You under this License. - If any provision of this License is invalid or unenforceable under applicable law, it shall not affect the validity or enforceability of the remainder of the terms of this License, and without further action by the parties to this agreement, such provision shall be reformed to the minimum extent necessary to make such provision valid and enforceable. - No term or provision of this License shall be deemed waived and no breach consented to unless such waiver or consent shall be in writing and signed by the party to be charged with such waiver or consent. - This License constitutes the entire agreement between the parties with respect to the Work licensed here. There are no understandings, agreements or representations with respect to the Work not specified here. Licensor shall not be bound by any additional provisions that may appear in any communication from You. This License may not be modified without the mutual written agreement of the Licensor and You. - The rights granted under, and the subject matter referenced, in this License were drafted utilizing the terminology of the Berne Convention for the Protection of Literary and Artistic Works (as amended on September 28, 1979), the Rome Convention of 1961, the WIPO Copyright Treaty of 1996, the WIPO Performances and Phonograms Treaty of 1996 and the Universal Copyright Convention (as revised on July 24, 1971). These rights and subject matter take effect in the relevant jurisdiction in which the License terms are sought to be enforced according to the corresponding provisions of the implementation of those treaty provisions in the applicable national law. If the standard suite of rights granted under applicable copyright law includes additional rights not granted under this License, such additional rights are deemed to be included in the License; this License is not intended to restrict the license of any rights under applicable law. diff --git a/README.md b/README.md index 2b771bb929..4249abc866 100644 --- a/README.md +++ b/README.md @@ -1,26 +1,22 @@ - -

NotEnoughUpdates

+ +

NotEnoughUpdates

-

+

NotEnoughUpdates (NEU) is a feature rich 1.8.9 Minecraft forge mod for Hypixel Skyblock. ## Getting Started -**Installing Forge:** +#### Installing Forge 1. Run normal Minecraft 1.8.9 and once it reaches the title screen wait about 5 seconds and close it. 2. Install Minecraft **1.8.9** forge from the [forge website](http://files.minecraftforge.net/maven/net/minecraftforge/forge/index_1.8.9.html) @@ -45,9 +41,9 @@ NotEnoughUpdates (NEU) is a feature rich 1.8.9 Minecraft forge mod for Hypixel S 4. When forge is installed, open the Minecraft launcher, go under the `installations tab`, click `new installation`, select the version release `1.8.9-forge1.8.9-11.15.1.xxxx` (it will usually be all the way towards the bottom). 5. Once you are done, run this new installation that you just created. Once it reaches the title screen, wait about 5 seconds and close it. -**Installing the NotEnoughUpdates mod:** +#### Installing the NotEnoughUpdates mod -1. Download the latest mod [release](https://github.com/Moulberry/NotEnoughUpdates/releases). If it says `this file may harm your computer`, click `allow anyways` as all java files will be flagged by Chrome. +1. Download the latest mod [release](https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO/releases). If it says `this file may harm your computer`, click `allow anyways` as all java files will be flagged by Chrome. 2. Add the NEU mod: - If you have java installed, double click the file, click `install` - If not, press the windows key + R; type `%appdata%`; click on the folder called `.minecraft`; click on the folder called `mods` and drag the mods file in here. @@ -55,11 +51,9 @@ NotEnoughUpdates (NEU) is a feature rich 1.8.9 Minecraft forge mod for Hypixel S 4. Then, hop onto Skyblock and run the command `/api new`. Your api key is automatically filled out and all features should work. 5. Type `/neu`. If you see the NotEnoughUpdates menu, you have done this correctly! -*If you need further assistance feel free to join the [discord](https://discord.gg/moulberry) and ask for help in [#neu-support](discord://discord.com/channels/516977525906341928/714332750156660756)* - ## Features -- An [item list](https://github.com/Moulberry/NotEnoughUpdates-REPO) containing information and recipes about every item in skyblock. +- An [item list](https://github.com/NotEnoughUpdates/NotEnoughUpdates-REPO) containing information and recipes about every item in skyblock. - A dungeons minimap. - Dungeon loot profit checker. - Item overlays for Treecapitator, Builder's Wand, Block Zapper, and Bonemerang. @@ -77,3 +71,19 @@ NotEnoughUpdates (NEU) is a feature rich 1.8.9 Minecraft forge mod for Hypixel S - Slot Locking - Fishing Particle customization & alerts. - And [much, much, more.](https://gist.github.com/jani270/d33e249d40b0333b87ba5c5e70fca398) + +## Support + +If you need assistance installing or using the mod, feel free to join the [discord](https://discord.gg/moulberry) and ask for help in [#neu-support](discord://discord.com/channels/516977525906341928/714332750156660756) + +## Contributing + +If you would like to contribute to the project, look at our [contribution guide](CONTRIBUTING.md) for more information how to install NEU for development purposes. + +## Security + +If you have found a vulnerability, please follow our [security policy](.github/SECURITY.md). + +## License + +This project is licensed under LGPL-3.0-or-later, see [COPYING](COPYING) and [COPYING.LESSER](COPYING.LESSER) for more details. diff --git a/Update Notes/2.0-Pre30.md b/Update Notes/2.0-Pre30.md index e036627b58..99591f476c 100644 --- a/Update Notes/2.0-Pre30.md +++ b/Update Notes/2.0-Pre30.md @@ -11,18 +11,19 @@ - Added Storage to PV (with correct sizes) - Added Personal Vault to PV - Added scroll lock to storage overlay + ### **Fixed Features:** - Todo list - - Fixed fetchur display - - Fixed godpot timer + - Fixed fetchur display + - Fixed godpot timer - PV's wardrobe view not showing second page bottom row (not fully fixed could be better by dividing on every 4 and drawing per column instead of row but right now its always a full page) - Made dwarven overlay work in crystal hollows (nopo) - Added Gemstone powder to dwarven overlay (nopo) - Made smooth aote work with aotv (thanks to 8k for letting me test his aotv) (nopo) ### **Bug Fixes** - + - Arrow Key backpack option under storage gui not doing anything - Fixed pets gui going away if you open /pets (nopo) -- Fixed PV cit models dieing (nopo) \ No newline at end of file +- Fixed PV cit models dieing (nopo) diff --git a/Update Notes/2.0-Pre31-Release.md b/Update Notes/2.0-Pre31-Release.md index da4fa3f4b1..3530602398 100644 --- a/Update Notes/2.0-Pre31-Release.md +++ b/Update Notes/2.0-Pre31-Release.md @@ -1,21 +1,23 @@ # These are the change notes for PRE31-Release ### **Major Changes** -- None yet. Prob not gonna happen this is mainly for small things. +- None yet. Prob not gonna happen this is mainly for small things. ### **Minor Changes:** + - Added a check to see if the storagegui is on before yelling at you for having fastrender on. - Added toggle to disable showing the treecap cooldown in item durability. (Lulonaut)# - Added text to inform the user to "/api new" when the /pv doesn't load. - Added support for the new arrows to the PV. -- Improved metal detector location detection logic. (Keebler408) -- Improved metal detector wrong location handling. (Keebler408) -- Added Beacons waypoints for metal detector waypoint locations. (Keebler408) +- Improved metal detector location detection logic. (CraftyOldMiner) +- Improved metal detector wrong location handling. (CraftyOldMiner) +- Added Beacons waypoints for metal detector waypoint locations. (CraftyOldMiner) - Made the PV command block in the right click player menu dynamically choose its position based on a empty slot. (DeDiamondPro) - Added Tab auto completion to the AH search gui. (Lulonaut) ### **Bug Fixes** + - Fixed a nullpointer exception in dwarven textures (got some confirmation that it fixed it). - Fixed neuec not parsing correctly. - Fixed crashing when you copy text while in the neuec/neu buttons editor menu. @@ -24,24 +26,21 @@ - Fixed golden goblin not having a icon. - Fixed accessory bag overlay's reforge stat detection as hypixel broke it with their tooltip changes. - Fixed NeuEC as hypixel broke it with their tooltip changes. -- Fixed not being able to press repeat keys in chat. +- Fixed not being able to press repeat keys in chat. - Fixed gemstone gauntlet/Divan Drill not being recognised as mining tools. - Fixed morph pets not being recognized by the extended pet info tooltip tweak. -- Fixed wrong commission maxes values for goblin in dwarven mines and the crystal hollows. (Keebler408) +- Fixed wrong commission max values for goblin in dwarven mines and the crystal hollows. (CraftyOldMiner) - Fixed player right click menu command block text appearing on an inventory item. (DeDiamondPro) - - ### **Other** + - Enabled help button by default. - Added SecondPfirsisch cape. - Added Stormy_LH cape. - Change cape order in /neucosmetics because ironmoon asked for it. - ### **Notes for texturepack creators** - ### **Previous change log** -https://github.com/DoKM/NotEnoughUpdates/blob/master/Update%20Notes/2.0-Pre31.md +https://github.com/DoKM/NotEnoughUpdates/blob/master/Update%20Notes/2.0-Pre31.md diff --git a/Update Notes/2.0-Pre31.md b/Update Notes/2.0-Pre31.md index 802ad7c45c..ac85f45c16 100644 --- a/Update Notes/2.0-Pre31.md +++ b/Update Notes/2.0-Pre31.md @@ -13,8 +13,8 @@ - Added mastermode support to /pv (basically done, just needs mastermode xp) - Added support for the Golden Dragon Pet and added support for other weird pets that might get added. - ### **New Features:** + - Added Ferocity, Magic find, Mining speed and mining fortune to Accessory bag (and ferocity and magic find to /pv). - Update notifier for "Pre" version releases. (Ironm00n) - Added toggle for etherwarp helper overlay text. @@ -42,8 +42,8 @@ - Replaced the chat command when clicking on a player name with /pv (Toggleable) - Added a link to a webpage containing neu's feature /neufeatures and it shows on the first time launch. - ### **Bug Fixes** + - Fishing helper not showing "!" when the rod colours are disabled. - Decimal point values not being counted in Accessory bag overlay. - /pv not having the correct max minion tier. (Ironm00n) @@ -67,15 +67,15 @@ - Fixed dwarven mines waypoints not working if dwarven mines overlay was disabled. - Fixed being able to slot lock the 9th slot. - Fixed NEUButtons overlapping with the Accessory Bag overlay by moving the overlapping icons to the right of the overlay. (should work pretty well, too lazy to test with custom button positions but should work fine.) -- Stopped tooltip tweak rawcraftcost displaying if the cost was 0 (either due to the price being really low or api issue). +- Stopped tooltip tweak rawcraftcost displaying if the cost was 0 (either due to the price being really low or api issue). - Added a catch to the capemanger slow to catch duplicate players (https://hst.sh/enuvamecef) (idk how but hey its there now). - Fix being able to hotkey slotlocked items in a chest gui. - (Hopefully) Fix storage overlay nullpointer crash. - Fix not being able to dye undyed leather armour. - Some Storage Overlay fixes (DeDiamondPro) - ### **Other** + - Code clean up by Ironm00n. - Rename variables to be more consistent. (Ironm00n) - Devpane changes. (? - DoKM) (Ironm00n) @@ -106,6 +106,3 @@ - Added the edit button to the Storage gui texture (it was already on transparent but not on the others) please update your textures - Added neu logo to the bottom right of the Storage gui textures (so people stop asking which mod adds the gui (Atleast try to make the amount less)) - Added ironman icon to pv (notenoughupdates/pv_ironman.png) (thanks ery for the icon) - - - diff --git a/Update Notes/2.1.md b/Update Notes/2.1.md index 1a120dfb8d..359a56fe18 100644 --- a/Update Notes/2.1.md +++ b/Update Notes/2.1.md @@ -1,89 +1,189 @@ # These are the change notes for NEU 2.1 REL -### **Major Changes** -- Added mining skill overlay -- Added fishing skill overlay -- Added combat skill overlay -- Added slayer overlay -- [Added mining tab in /pv](https://cdn.discordapp.com/attachments/832652653292027904/903619242384056370/unknown.png) -- Big thanks to kwev1n for some math and jani for the texture +### **Major Changes:** + +- Added mining skill overlay - nopo +- Added fishing skill overlay - nopo +- Added combat skill overlay - nopo +- Added slayer overlay - nopo - Added blocking clicks back to the enchanting minigames (because apparently, it's not bannable?) -- [Donpireso replied to a sba dev's email about some of sba features, and it seems to imply that blocking clicks in guis aren't bannable](https://cdn.discordapp.com/attachments/823769568933576764/906101631861526559/unknown.png) -- Fixed pet overlay not updating when going into /pets -- [Added an armor overlay for the new armor slots](https://cdn.discordapp.com/attachments/832652653292027904/922399046528794634/unknown.png) -- Added a pet overlay that shows your active pet in your inventory + - [Donpireso replied to a sba dev's email about some of sba features, and it seems to imply that blocking clicks in guis aren't bannable](https://cdn.discordapp.com/attachments/823769568933576764/906101631861526559/unknown.png) + - Made it if you hold shift in the enchant solvers it overrides prevent missclicks - nopo +- Fixed pet overlay not updating when going into /pets - nopo +- Fixed pet overlay randomly going to level 100 - nopo +- [Added an armor overlay for the new armor slots](https://cdn.discordapp.com/attachments/832652653292027904/922399046528794634/unknown.png) +- Added a pet overlay that shows your active pet in your inventory - nopo - [Price graph for items on /ah and /bz](https://cdn.discordapp.com/attachments/896407218151366687/926968296929107999/unknown.png) - DeDiamondPro +- Added wishing compass solver that shows target coordinates, structure, and integrates with Skytils waypoints - CraftyOldMiner +- Improved metal detector logic to solve using a single position in most cases using known locations based on Keeper coordinates - CraftyOldMiner +- Added support for official Hypixel wiki, can be toggled in /neu misc - DeDiamondPro +- Added a calculator (/neucalc help), that also works in the auction house / bazaar - nea89 +- Added an enchant table style gui for /hex - nopo +- Added and fixed various things in the profile viewer: + - [Added hotm tab](https://media.discordapp.net/attachments/659613194066722833/991115131507441724/unknown.png) - nopo + - Big thanks to kwev1n for some math and jani for the texture + - [Added bingo tab](https://media.discordapp.net/attachments/659613194066722833/991115625772625980/unknown.png) - Lulonaut + - [Added bingo and stranded profile icons](https://cdn.discordapp.com/attachments/832652653292027904/915844465372065842/unknown.png) - nopo + - [Added trophy fishing tab](https://media.discordapp.net/attachments/659613194066722833/991114639150698567/unknown.png) - efefury + - [Added bestiary tab](https://cdn.discordapp.com/attachments/832652653292027904/991927854776459324/unknown.png) - nopo + - Added equipment - nopo + - Added blaze slayer level and kills - nopo + - Added social level - nopo + - Added various new collections and minions - nopo & CrypticPlasma & hannibal2 + - Added mastermode catacombs xp to level calculator - nopo + - Added profile viewer settings to /neu - nopo + - Added an unknown icon if neu doesn't recognize your profile type - nopo + - Added total xp to catacombs level - efefury + - Fixed minion tiers crafted by coop members not showing up in /pv - Lulonaut + - Fixed crash in /pv when the player had a pet that is not saved in the repo - Lulonaut + - Added senither and lily weight - CrypticPlasma + - Added the Quiver Info when hovering in inventory tab over Arrows display - Lulonaut + - Added the Magical Power Info when hovering in inventory tab over Accessory Bag display - Lulonaut + - Added carpentry skill to skill average - hannibal2 + - Fixed sort order of fishing rods in profile viewer page - hannibal2 + - Changing sort logic from strength plus damage to bin price for best weapons in pv inventory page - hannibal2 + - Added pronouns to /pv - nea89 + ### **Minor Changes:** -- Add built-in recipes for forge crafts - nea89 -- Add Stranded Villager Trades to the item list - nea89 -- Make cata xp in /pv be calculated on how many runs you have and shows master mode xp rates + +- Added built-in recipes for forge crafts - nea89 +- Added mob drop viewer in the recipe viewer - nea89 +- Added stranded villager trades to the item list - nea89 +- Added npc shop trades in the recipe viewer - nea89 - Added a config option to hide Dwarven Mines waypoints when already at the location - Lulonaut -- Added some info panels to some settings in /neu +- Added some info panels to some settings in /neu - nopo - Added Kat Level After Upgrade Estimator - nea89 -- Added /pv button in /neu -- Added pitch and coins/m as options in farming skill overlay +- Added pitch and coins/m as options in farming skill overlay - nopo - Make it so tab completion in ah search GUI goes down the items - Lulonaut -- Added a toggle for enchant glint in storage gui (ty ery for texture) -- Added fairy souls option to /neu misc +- Added a toggle for enchant glint in storage gui (ty ery for texture) - nopo +- Added fairy souls option to /neu misc - nopo + - Added separated settings for fairy soul tracking from showing beacons. Tracking is turned on by default. - CraftyOldMiner +- Added fairy souls beacons changing color based on their distance - CraftyOldMiner - Make it so fairy souls are tracked independently for each profile - Lulonaut -- Added a button in the storage gui to open the settings -- Added an option to change the click names for /pv to /ah -- Added a help menu to /neuec -- Made it so treecap shows foraging xp instead of farming xp on the farming overlay -- Made it so a jungle axe with cult will show the "farming" overlay -- Added /neurepomode to toggle item editing and dev mode -- Changed "NEUAH is DISABLED! Enable in /neusettings." to /neu -- Changed misc overlays tab to todo overlays -- Added a config option for npc retexturing -- Added a config option for dirt wand overlay -- Added a config option for hoe of tilling -- Added an option to use short numbers (1.5mil) for price tooltips -- Added Drills and Gauntlet to the itemlist tools category - jani -- Added an option to turn off showing next click in chronomatron -- Turns off inv search mode after 2 minutes -- Made /neustats modlist show normal /neustats if under 15 mods -- Added max enchant book to /neuec - Dokm -- [Added bingo and Stranded profile icons to /pv](https://cdn.discordapp.com/attachments/832652653292027904/915844465372065842/unknown.png) -- Added an icon if neu doesn't know about a gamemode in /pv -- Fixed pet overlay not resetting pet when making new profile +- Added a button in the storage gui to open the settings - nopo +- Added an option to change the click names for /pv to /ah - nopo +- Added a help menu to /neuec - nopo +- Made it so treecap shows foraging xp instead of farming xp on the farming overlay - nopo +- Made it so a jungle axe with cult will show the "farming" overlay - nopo +- Changed "NEUAH is DISABLED! Enable in /neusettings." to /neu - nopo +- Changed misc overlays tab to todo overlays - nopo +- Added a config option for npc retexturing - nopo +- Added a config option for dirt wand overlay - nopo +- Added a config option for hoe of tilling - nopo +- Added a config option for etherwarp block overlay - nopo +- Added an option to use short numbers (1.5mil) for price tooltips - nopo +- Added Drills, Gauntlets and Flares to the itemlist tools category - jani +- Added an option to turn off showing next click in chronomatron - nopo +- Made inv search mode automatically turn off after 2 minutes - nopo +- Made /neustats modlist show normal /neustats if under 15 mods - nopo +- Added max enchant book and max attribute shard to /neuec - Dokm +- Fixed pet overlay not resetting pet when making new profile - nopo - Added a warning in the tooltip when price info couldn't be found/is outdated - Lulonaut -- Added "Has Advanced Tab" to /neustats +- Added "Has Advanced Tab" to /neustats - nopo - Added custom runes and crab hat system - jani -- Removed unused textures -- Added total xp if player is above cata 50 in /pv - efefury +- Removed unused textures - nopo - Added daily powder to todo overlay - efefury - Added a way to include kismet feather to profit calculator - efefury - Added custom sounds for crystal hollow gemstones - nea89 - Added custom biomes for crystal hollow areas - nopo - Added a config option to hide the reforge stats for Legendary items from Hypixel on reforge stones - Lulonaut -### **Bug Fixes** -- Fix wiki pages freezing the entire game - nea89 -- Made titanium overlay and waypoints work with dwarven overlay off -- "fixed" divan rarity in NEUAH (scuffed) -- Made etherwarp block overlay config option -- Fixed ram usage in crystal hollows - Dokm -- Made skills not show int limit when at max level in skill overlays +- Added an option to alert you if you put something for too much onto ah (default 50%) - nopo +- Lowest bin alert triggers if lowest bin isnt found - nopo +- Crystal Hollows crystal states are now updated when the Heart of the Mountain menu is opened - CraftyOldMiner +- Added /neudiag command to enable/disable debug logging and dump diagnostic data - CraftyOldMiner +- Added Blaze Slayer information - whalker +- Added subcommand to /neupackdev allowing you to get NBT data from nearby mob(s) - whalker +- Added subcommand to /neupackdev allowing you to get NBT data from nearby armor stand(s) - whalker +- Added additional data to the /neupackdev NPC subcommand - whalker +- Added a subcommand to /neupackdev to get the NBT of all mobs, armor stands, and npc in the loaded world - whalker +- Added a subcommand to /neupackdev to get the NBT of the closest mob, armor stand, and npc in a radius in the loaded world - whalker +- Added optional radius argument for neupackdev subcommands. - whalker +- Added tab completion to /neupackdev subcommands. - whalker +- Added 6-10 stars to the auction search overlay - nopo +- Added 6-10 stars to /neucustomize - nopo +- Added support for attributes in neuec - nopo +- Added Heavy Pearls to todo overlay - Cobble8 +- Added Booster Cookie Warning - 2stinkysocks +- Added an option to only search for Level 100 pets in the auction house search overlay - Lulonaut +- [Added an error if you have new tab list off](https://cdn.discordapp.com/attachments/896407218151366687/913681097605398528/unknown.png) - nopo +- Added Fishing Timer over bobber - nea89 +- Added [Auction Profit Viewer Overlay](https://cdn.discordapp.com/attachments/848901833119629332/993191851400101918/176946124-28ddf336-1ec7-460b-b22a-5fe2733b46a3.png) - efefury +- Added Trophy Reward Overlay - hannibal2 +- Add Auto-Updater (linux only) - nea89 +- Added power stone feature - hannibal2 +- Added abiphone warning - hannibal2 +- Added blur limit at 100 - nopo +- Added an option to disable etherwarp overlay when TP is denied - hannibal2 +- Added bazaar search overlay - hannibal2 +- Added fraction display instead of percentage in slayer and dungeon RNG meter inventory - hannibal2 +- Added profit per score/XP to RNG meter - hannibal2 +- Added showing the amount of dungeon runs or slayer bosses needed for the rng meter to fill up - hannibal2 +- Added bazaar prices to enchants in the enchantment table - hannibal2 / nea89 +- Added an option to not open the item list when searching containers - Lulonaut +- Made config option in mod settings work - nea89 + + +### **Bug Fixes:** + +- Fixed wiki pages freezing the entire game - nea89 +- Fixed titanium overlay and waypoints working while having dwarven overlay disabled - nopo +- "fixed" divan rarity in NEUAH (scuffed) - nopo +- Fixed ram usage in crystal hollows - DokM +- Made skills not show int limit when at max level in skill overlays - nopo - Fixed space cape texture - Microcontrollers -- Make it so you can hold down keys in sign GUIs -- Added entrance to "floor one" + made blur limit at 100 -- Fixed screenshot key in /et overlay -- Fixed api key autofill with dg copy chat feature -- Made missing enchants not show on an item if its not missing any enchants -- Fixed Mining overlay crash - Dokm -- Fixed pet crash - Dokm -- Fixed fetchur for the 75th time -- [Made an error if you have new tab list off](https://cdn.discordapp.com/attachments/896407218151366687/913681097605398528/unknown.png) -- Fixed lava fishing with the fishing alert +- Make it so you can hold down keys in sign GUIs - nopo +- Fixed api key autofill with dg copy chat feature - nopo +- Made missing enchants not show on an item if its not missing any enchants - nopo +- Fixed Mining overlay crash - DokM +- Fixed pet crash - DokM +- Fixed fetchur for the 75th time - nopo +- Fixed fishing alert triggering a bit to early / not working with lava fishing - nopo & nea89 - Fixed /locraw detection, [previously allowed chat messages to trigger it](https://github.com/NotEnoughUpdates/NotEnoughUpdates/issues/35) - IRONM00N - Fixed experiment timer in todo overlay - efefury -- Fixed replace click events with /pv working in other modes +- Fixed replace click events with /pv working in other modes - nopo - Fixed /neuec presets not applying the strikethrough attribute - Lulonaut -### **Other** +- Fixed dungeon detection - nopo +- Added checks for chat messages for dungeon win overlay - nopo +- Fixed some vanilla Minecraft keybinds not working in NEU GUIs - nopo +- Fixed crash with spamming remove enchant in /neuec - nopo +- Fixed missing enchants not working with shiny items - nopo +- Fixed golden dragon not working in pet overlay - CrypticPlasma +- Fixed enchant overlay - nopo +- Fixed shortened damage - nopo +- Fixed bazaar prices sorting order in neu item list - hannibal2 +- Fixed priceless items showing first in the missing tab of the accessory bag overlay - nopo +- Fixed clicking outside of experimentation game causing it to go count that as a valid click - nopo +- Fixed storage gui when having locked backpack slots - nopo +- Fixed hyphens in /peek being the wrong color - whalker +- Fixed skill average calculation to include carpentry in /peek - whalker +- Fixed middle clicking on pets not registering pet swap - nopo +- Fixed middle clicking on an item with no id searching for it - nopo +- Fixed pets with decimal stats not showing in pv - nopo +- Changed click packets to act like vanilla - nea89/nopo +- Fixed custom trade menu - nopo +- Removed "Last Seen" from /pv as hypixel removed it from the api - jani +- Fixed profile selector in /pv if you have gui scale 5 - nopo +- Fixed Minecraft not going to be able to access the Hypixel api after 18/10/22 - nea89 + +### **Other:** + - New icons was added in storage_icons.png - Moved the help icon in /neucustomize over a little - Added dg partner cape - Changed custom_enchant_gui.png to remove top right button - Added 4 new textures for the on/off switches in /neu - Code Cleanup - IRONM00N +- Renamed Keebler408 to CraftyOldMiner +- Added JUnit unit tests for metal detector and wishing compass solver +- Custom biome names for crystal hollows: + - NeucrystalHollowsPrecursorRemnants + - NeucrystalHollowsMithrilDeposit + - NeucrystalHollowsGoblinHoldout + - NeucrystalHollowsJungle + - NeucrystalHollowsMagmaFields + - NeucrystalHollowsCrystalNucleus +- Disabled Skyclient cosmetics disabling neu map - nopo + ### **Previous change log** + https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/master/Update%20Notes/2.0-Pre31-Release.md diff --git a/build.gradle.kts b/build.gradle.kts index e824a9a0e1..deb740f57c 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -1,149 +1,180 @@ -import java.io.ByteArrayOutputStream -import net.minecraftforge.gradle.user.ReobfMappingType +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + + +import neubs.NEUBuildFlags +import neubs.applyPublishingInformation +import neubs.setVersionFromEnvironment + plugins { - java - id("net.minecraftforge.gradle.forge") version "6f5327738df" - id("com.github.johnrengelman.shadow") version "6.1.0" - id("org.spongepowered.mixin") version "d75e32e" + idea + java + id("gg.essential.loom") version "0.10.0.+" + id("dev.architectury.architectury-pack200") version "0.1.3" + id("com.github.johnrengelman.shadow") version "7.1.2" + id("io.github.juuxel.loom-quiltflower") version "1.7.3" + `maven-publish` } -group = "io.github.moulberry" -val baseVersion = "2.1" - - -var buildVersion = properties["BUILD_VERSION"] -if (buildVersion == null) { - val stdout = ByteArrayOutputStream() - val execResult = exec { - commandLine("git", "describe", "--always", "--first-parent", "--abbrev=7") - standardOutput = stdout - } - if (execResult.exitValue == 0) - buildVersion = String(stdout.toByteArray()).trim() -} -version = baseVersion + (buildVersion?.let { "+$it" } ?: "") +apply() +// Build metadata -// Toolchains: +group = "io.github.moulberry" -java { - // Forge Gradle currently prevents using the toolchain: toolchain.languageVersion.set(JavaLanguageVersion.of(8)) - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 +setVersionFromEnvironment("2.1") + +// Minecraft configuration: +loom { + launchConfigs { + "client" { + property("mixin.debug", "true") + property("asmhelper.verbose", "true") + arg("--tweakClass", "org.spongepowered.asm.launch.MixinTweaker") + arg("--mixin", "mixins.notenoughupdates.json") + } + } + runConfigs { + "server" { + isIdeConfigGenerated = false + } + } + forge { + pack200Provider.set(dev.architectury.pack200.java.Pack200Adapter()) + mixinConfig("mixins.notenoughupdates.json") + } + mixin { + defaultRefmapName.set("mixins.notenoughupdates.refmap.json") + } } -minecraft { - version = "1.8.9-11.15.1.2318-1.8.9" - runDir = "run" - mappings = "stable_22" - clientJvmArgs.addAll( - listOf( - "-Dmixin.debug=true", - "-Dasmhelper.verbose=true" - ) - ) - clientRunArgs.addAll( - listOf( - "--tweakClass org.spongepowered.asm.launch.MixinTweaker", - "--mixin mixins.notenoughupdates.json" - ) - ) + +// Dependencies: +repositories { + mavenCentral() + mavenLocal() + maven("https://repo.spongepowered.org/maven/") + maven("https://pkgs.dev.azure.com/djtheredstoner/DevAuth/_packaging/public/maven/v1") + maven("https://jitpack.io") } -mixin { - add(sourceSets.main.get(), "mixins.notenoughupdates.refmap.json") +val shadowImplementation by configurations.creating { + configurations.implementation.get().extendsFrom(this) } -// Dependencies: +val shadowApi by configurations.creating { + configurations.implementation.get().extendsFrom(this) +} -repositories { - mavenCentral() - flatDir { dirs("deps/") } - maven("https://repo.spongepowered.org/maven/") +val devEnv by configurations.creating { + configurations.runtimeClasspath.get().extendsFrom(this) + isCanBeResolved = false + isCanBeConsumed = false + isVisible = false } dependencies { - implementation("org.spongepowered:mixin:0.7.11-SNAPSHOT") - annotationProcessor("org.spongepowered:mixin:0.7.11-SNAPSHOT") - implementation("com.fasterxml.jackson.core:jackson-core:2.13.1") - implementation("info.bliki.wiki:bliki-core:3.1.0") + minecraft("com.mojang:minecraft:1.8.9") + mappings("de.oceanlabs.mcp:mcp_stable:22-1.8.9") + forge("net.minecraftforge:forge:1.8.9-11.15.1.2318-1.8.9") + + shadowImplementation("org.spongepowered:mixin:0.7.11-SNAPSHOT") { + isTransitive = false // Dependencies of mixin are already bundled by minecraft + } + annotationProcessor("org.spongepowered:mixin:0.8.4-SNAPSHOT") + shadowApi("info.bliki.wiki:bliki-core:3.1.0") + testImplementation("org.junit.jupiter:junit-jupiter:5.8.2") + testAnnotationProcessor("org.spongepowered:mixin:0.8.4-SNAPSHOT") + // modImplementation("io.github.notenoughupdates:MoulConfig:0.0.1") + + devEnv("me.djtheredstoner:DevAuth-forge-legacy:1.1.0") } + +java { + withSourcesJar() + toolchain.languageVersion.set(JavaLanguageVersion.of(8)) +} + // Tasks: tasks.withType(JavaCompile::class) { - options.encoding = "UTF-8" + options.encoding = "UTF-8" } -tasks.withType(Jar::class) { - archiveBaseName.set("NotEnoughUpdates") - manifest.attributes.run { - this["Main-Class"] = "NotSkyblockAddonsInstallerFrame" - this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker" - this["MixinConfigs"] = "mixins.notenoughupdates.json" - this["FMLCorePluginContainsFMLMod"] = "true" - this["ForceLoadAsMod"] = "true" - this["FMLAT"] = "notenoughupdates_at.cfg" - } +tasks.named("test") { + useJUnitPlatform() } -tasks.shadowJar { - archiveClassifier.set("dep") - exclude( - "module-info.class", - "LICENSE.txt" - ) - dependencies { - include(dependency("org.spongepowered:mixin:0.7.11-SNAPSHOT")) - - include(dependency("commons-io:commons-io")) - include(dependency("org.apache.commons:commons-lang3")) - include(dependency("com.fasterxml.jackson.core:jackson-databind:2.10.2")) - include(dependency("com.fasterxml.jackson.core:jackson-annotations:2.10.2")) - include(dependency("com.fasterxml.jackson.core:jackson-core:2.10.2")) - - include(dependency("info.bliki.wiki:bliki-core:3.1.0")) - include(dependency("org.slf4j:slf4j-api:1.7.18")) - include(dependency("org.luaj:luaj-jse:3.0.1")) - } - fun relocate(name: String) = relocate(name, "io.github.moulberry.notenoughupdates.deps.$name") - relocate("com.fasterxml.jackson") - relocate("org.eclipse") - relocate("org.slf4j") +tasks.withType(Jar::class) { + archiveBaseName.set("NotEnoughUpdates") + manifest.attributes.run { + this["Main-Class"] = "NotSkyblockAddonsInstallerFrame" + this["TweakClass"] = "org.spongepowered.asm.launch.MixinTweaker" + this["MixinConfigs"] = "mixins.notenoughupdates.json" + this["FMLCorePluginContainsFMLMod"] = "true" + this["ForceLoadAsMod"] = "true" + this["Manifest-Version"] = "1.0" + } } -tasks.build.get().dependsOn(tasks.shadowJar) +val remapJar by tasks.named("remapJar") { + archiveClassifier.set("dep") + from(tasks.shadowJar) + input.set(tasks.shadowJar.get().archiveFile) + doLast { + println("Jar name: ${archiveFile.get().asFile}") + } +} -reobf { - create("shadowJar") { - mappingType = ReobfMappingType.SEARGE - } +tasks.shadowJar { + archiveClassifier.set("dep-dev") + configurations = listOf(shadowImplementation, shadowApi) + exclude("**/module-info.class", "LICENSE.txt") + dependencies { + exclude { + it.moduleGroup.startsWith("org.apache.") || it.moduleName in + listOf("logback-classic", "commons-logging", "commons-codec", "logback-core") + } + } + fun relocate(name: String) = relocate(name, "io.github.moulberry.notenoughupdates.deps.$name") } +tasks.assemble.get().dependsOn(remapJar) + tasks.processResources { - from(sourceSets.main.get().resources.srcDirs) - filesMatching("mcmod.info") { - expand( - "version" to project.version, - "mcversion" to minecraft.version - ) - } - rename("(.+_at.cfg)".toPattern(), "META-INF/$1") + from(tasks["generateBuildFlags"]) + filesMatching(listOf("mcmod.info", "fabric.mod.json", "META-INF/mods.toml")) { + expand( + "version" to project.version, "mcversion" to "1.8.9" + ) + } } -val moveResources by tasks.creating { - doLast { - ant.withGroovyBuilder { - "move"( - "file" to "$buildDir/resources/main", - "todir" to "$buildDir/classes/java" - ) - } - } - dependsOn(tasks.processResources) +sourceSets.main { + output.setResourcesDir(file("$buildDir/classes/java/main")) } -tasks.classes { dependsOn(moveResources) } - +applyPublishingInformation( + "deobf" to tasks.jar, + "all" to tasks.remapJar, + "sources" to tasks["sourcesJar"], +) diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts new file mode 100644 index 0000000000..5afecadc97 --- /dev/null +++ b/buildSrc/build.gradle.kts @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +plugins { + `kotlin-dsl` +} + +repositories { + mavenCentral() +} diff --git a/buildSrc/generate-public-key.sh b/buildSrc/generate-public-key.sh new file mode 100755 index 0000000000..3f778c5396 --- /dev/null +++ b/buildSrc/generate-public-key.sh @@ -0,0 +1,31 @@ +#!/bin/bash +# +# Copyright (C) 2022 NotEnoughUpdates contributors +# +# This file is part of NotEnoughUpdates. +# +# NotEnoughUpdates is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# NotEnoughUpdates 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with NotEnoughUpdates. If not, see . +# + + +output="$(dirname $(dirname $(readlink -f "$0")))/src/main/resources/moulberry.key" + +echo processing rsa input key from $1, and outputting to $output + +tempfile="$(mktemp)" +ssh-keygen -f "$1" -e -m pkcs8 > "$tempfile" +openssl rsa -pubin -in "$tempfile" -outform der > $output + +echo saved x509 public key at $output + diff --git a/buildSrc/moulsign.sh b/buildSrc/moulsign.sh new file mode 100755 index 0000000000..dacb8ec31a --- /dev/null +++ b/buildSrc/moulsign.sh @@ -0,0 +1,26 @@ +#!/bin/bash +# +# Copyright (C) 2022 NotEnoughUpdates contributors +# +# This file is part of NotEnoughUpdates. +# +# NotEnoughUpdates is free software: you can redistribute it +# and/or modify it under the terms of the GNU Lesser General Public +# License as published by the Free Software Foundation, either +# version 3 of the License, or (at your option) any later version. +# +# NotEnoughUpdates 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 +# Lesser General Public License for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with NotEnoughUpdates. If not, see . +# + +echo use key $1, signing file $2 +openssl dgst -sign "$1" "$2" > "$2.asc" +echo signature saved to "$2.asc" + + + diff --git a/buildSrc/src/main/kotlin/neubs/buildflags.kt b/buildSrc/src/main/kotlin/neubs/buildflags.kt new file mode 100644 index 0000000000..6b7ab48970 --- /dev/null +++ b/buildSrc/src/main/kotlin/neubs/buildflags.kt @@ -0,0 +1,56 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package neubs + +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.kotlin.dsl.the +import java.nio.charset.StandardCharsets +import java.util.* + +const val NEU_BUILDFLAGS_PREFIX = "neu.buildflags." + +class NEUBuildFlags : Plugin { + override fun apply(target: Project) { + val props = + target.properties.filterKeys { it.startsWith(NEU_BUILDFLAGS_PREFIX) }.mapValues { it.value as String } + target.extensions.add("buildflags", Extension(props)) + target.tasks.create("generateBuildFlags") { + outputs.upToDateWhen { false } + val t = target.layout.buildDirectory.file("buildflags.properties") + outputs.file(t) + doLast { + val p = Properties() + p.putAll(props) + t.get().asFile.writer(StandardCharsets.UTF_8).use { + p.store(it, "Store build time configuration for NEU") + } + } + + } + } + + class Extension(val props: Map) { + fun bool(name: String) = props["$NEU_BUILDFLAGS_PREFIX$name"] == "true" + } +} + +val Project.buildFlags: NEUBuildFlags.Extension + get() = the() diff --git a/buildSrc/src/main/kotlin/neubs/publishing.kt b/buildSrc/src/main/kotlin/neubs/publishing.kt new file mode 100644 index 0000000000..4f9979a128 --- /dev/null +++ b/buildSrc/src/main/kotlin/neubs/publishing.kt @@ -0,0 +1,62 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package neubs + +import org.gradle.api.Project +import org.gradle.api.publish.PublishingExtension +import org.gradle.api.publish.maven.MavenPublication +import org.gradle.kotlin.dsl.configure +import org.gradle.kotlin.dsl.create +import org.gradle.kotlin.dsl.get + +fun Project.applyPublishingInformation( + vararg artifacts: Pair +) { + this.configure { + publications { + create("maven") { + for((name, source) in artifacts) { + artifact(source) { + classifier = name + } + } + pom { + name.set("NotEnoughUpdates") + description.set("A feature rich 1.8.9 Minecraft forge mod for Hypixel Skyblock") + licenses { + license { + name.set("GNU Lesser General Public License") + url.set("https://github.com/NotEnoughUpdates/NotEnoughUpdates/blob/master/COPYING.LESSER") + } + } + developers { + developer { + name.set("Moulberry") + } + developer { + name.set("The NotEnoughUpdates Contributors and Maintainers") + } + } + } + } + } + } + +} diff --git a/buildSrc/src/main/kotlin/neubs/versioning.kt b/buildSrc/src/main/kotlin/neubs/versioning.kt new file mode 100644 index 0000000000..254e001282 --- /dev/null +++ b/buildSrc/src/main/kotlin/neubs/versioning.kt @@ -0,0 +1,54 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package neubs + +import org.gradle.api.Project +import java.io.ByteArrayOutputStream + +fun Project.setVersionFromEnvironment(baseVersion: String) { + val buildExtra = mutableListOf() + val buildVersion = properties["BUILD_VERSION"] as? String + if (buildVersion != null) buildExtra.add(buildVersion) + if (System.getenv("CI") == "true") buildExtra.add("ci") + + val stdout = ByteArrayOutputStream() + val execResult = exec { + commandLine("git", "describe", "--always", "--first-parent", "--abbrev=7") + standardOutput = stdout + isIgnoreExitValue = true + } + if (execResult.exitValue == 0) { + buildExtra.add(String(stdout.toByteArray()).trim()) + } + + val gitDiffStdout = ByteArrayOutputStream() + val gitDiffResult = exec { + commandLine("git", "status", "--porcelain") + standardOutput = gitDiffStdout + isIgnoreExitValue = true + } + if (gitDiffStdout.toByteArray().isNotEmpty()) { + buildExtra.add("dirty") + } + + version = baseVersion + (if (buildExtra.isEmpty()) "" else buildExtra.joinToString(prefix = "+", separator = ".")) + +} + diff --git a/cape.png b/cape.png deleted file mode 100644 index a2a2d5f759..0000000000 Binary files a/cape.png and /dev/null differ diff --git a/deps/Morus-1.0.jar b/deps/Morus-1.0.jar deleted file mode 100644 index 92276d7213..0000000000 Binary files a/deps/Morus-1.0.jar and /dev/null differ diff --git a/gradle.properties b/gradle.properties index bf86fb7158..f596b2d728 100644 --- a/gradle.properties +++ b/gradle.properties @@ -1 +1,6 @@ -org.gradle.jvmargs=-Xmx2G \ No newline at end of file +org.gradle.jvmargs=-Xmx2G +loom.platform=forge +# NEU Buildflags. Please keep these flags in a commented out form while checked into version control. +# See BuildFlags.java for usages of these values. +# Build with Pronouns in PV by default +# neu.buildflags.pronouns=true diff --git a/gradle/wrapper/gradle-wrapper.jar b/gradle/wrapper/gradle-wrapper.jar index 30d399d8d2..249e5832f0 100644 Binary files a/gradle/wrapper/gradle-wrapper.jar and b/gradle/wrapper/gradle-wrapper.jar differ diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index c1ff793730..ae04661ee7 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,5 @@ -#Mon Sep 14 12:28:28 PDT 2015 distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists +distributionUrl=https\://services.gradle.org/distributions/gradle-7.5.1-bin.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists -distributionUrl=https\://services.gradle.org/distributions/gradle-6.8.3-all.zip diff --git a/gradlew b/gradlew index 91a7e269e1..a69d9cb6c2 100755 --- a/gradlew +++ b/gradlew @@ -1,79 +1,129 @@ -#!/usr/bin/env bash +#!/bin/sh + +# +# Copyright © 2015-2021 the original authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# ############################################################################## -## -## Gradle start up script for UN*X -## +# +# Gradle start up script for POSIX generated by Gradle. +# +# Important for running: +# +# (1) You need a POSIX-compliant shell to run this script. If your /bin/sh is +# noncompliant, but you have some other compliant shell such as ksh or +# bash, then to run this script, type that shell name before the whole +# command line, like: +# +# ksh Gradle +# +# Busybox and similar reduced shells will NOT work, because this script +# requires all of these POSIX shell features: +# * functions; +# * expansions «$var», «${var}», «${var:-default}», «${var+SET}», +# «${var#prefix}», «${var%suffix}», and «$( cmd )»; +# * compound commands having a testable exit status, especially «case»; +# * various built-in commands including «command», «set», and «ulimit». +# +# Important for patching: +# +# (2) This script targets any POSIX shell, so it avoids extensions provided +# by Bash, Ksh, etc; in particular arrays are avoided. +# +# The "traditional" practice of packing multiple parameters into a +# space-separated string is a well documented source of bugs and security +# problems, so this is (mostly) avoided, by progressively accumulating +# options in "$@", and eventually passing that to Java. +# +# Where the inherited environment variables (DEFAULT_JVM_OPTS, JAVA_OPTS, +# and GRADLE_OPTS) rely on word-splitting, this is performed explicitly; +# see the in-line comments for details. +# +# There are tweaks for specific operating systems such as AIX, CygWin, +# Darwin, MinGW, and NonStop. +# +# (3) This script is generated from the Groovy template +# https://github.com/gradle/gradle/blob/master/subprojects/plugins/src/main/resources/org/gradle/api/internal/plugins/unixStartScript.txt +# within the Gradle project. +# +# You can find Gradle at https://github.com/gradle/gradle/. +# ############################################################################## -# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -DEFAULT_JVM_OPTS="" +# Attempt to set APP_HOME + +# Resolve links: $0 may be a link +app_path=$0 + +# Need this for daisy-chained symlinks. +while + APP_HOME=${app_path%"${app_path##*/}"} # leaves a trailing /; empty if no leading path + [ -h "$app_path" ] +do + ls=$( ls -ld "$app_path" ) + link=${ls#*' -> '} + case $link in #( + /*) app_path=$link ;; #( + *) app_path=$APP_HOME$link ;; + esac +done + +APP_HOME=$( cd "${APP_HOME:-./}" && pwd -P ) || exit APP_NAME="Gradle" -APP_BASE_NAME=`basename "$0"` +APP_BASE_NAME=${0##*/} + +# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"' # Use the maximum available, or set MAX_FD != -1 to use that value. -MAX_FD="maximum" +MAX_FD=maximum -warn ( ) { +warn () { echo "$*" -} +} >&2 -die ( ) { +die () { echo echo "$*" echo exit 1 -} +} >&2 # OS specific support (must be 'true' or 'false'). cygwin=false msys=false darwin=false -case "`uname`" in - CYGWIN* ) - cygwin=true - ;; - Darwin* ) - darwin=true - ;; - MINGW* ) - msys=true - ;; +nonstop=false +case "$( uname )" in #( + CYGWIN* ) cygwin=true ;; #( + Darwin* ) darwin=true ;; #( + MSYS* | MINGW* ) msys=true ;; #( + NONSTOP* ) nonstop=true ;; esac -# For Cygwin, ensure paths are in UNIX format before anything is touched. -if $cygwin ; then - [ -n "$JAVA_HOME" ] && JAVA_HOME=`cygpath --unix "$JAVA_HOME"` -fi - -# Attempt to set APP_HOME -# Resolve links: $0 may be a link -PRG="$0" -# Need this for relative symlinks. -while [ -h "$PRG" ] ; do - ls=`ls -ld "$PRG"` - link=`expr "$ls" : '.*-> \(.*\)$'` - if expr "$link" : '/.*' > /dev/null; then - PRG="$link" - else - PRG=`dirname "$PRG"`"/$link" - fi -done -SAVED="`pwd`" -cd "`dirname \"$PRG\"`/" >&- -APP_HOME="`pwd -P`" -cd "$SAVED" >&- - CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar + # Determine the Java command to use to start the JVM. if [ -n "$JAVA_HOME" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then # IBM's JDK on AIX uses strange locations for the executables - JAVACMD="$JAVA_HOME/jre/sh/java" + JAVACMD=$JAVA_HOME/jre/sh/java else - JAVACMD="$JAVA_HOME/bin/java" + JAVACMD=$JAVA_HOME/bin/java fi if [ ! -x "$JAVACMD" ] ; then die "ERROR: JAVA_HOME is set to an invalid directory: $JAVA_HOME @@ -82,7 +132,7 @@ Please set the JAVA_HOME variable in your environment to match the location of your Java installation." fi else - JAVACMD="java" + JAVACMD=java which java >/dev/null 2>&1 || die "ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. Please set the JAVA_HOME variable in your environment to match the @@ -90,75 +140,101 @@ location of your Java installation." fi # Increase the maximum file descriptors if we can. -if [ "$cygwin" = "false" -a "$darwin" = "false" ] ; then - MAX_FD_LIMIT=`ulimit -H -n` - if [ $? -eq 0 ] ; then - if [ "$MAX_FD" = "maximum" -o "$MAX_FD" = "max" ] ; then - MAX_FD="$MAX_FD_LIMIT" - fi - ulimit -n $MAX_FD - if [ $? -ne 0 ] ; then - warn "Could not set maximum file descriptor limit: $MAX_FD" - fi - else - warn "Could not query maximum file descriptor limit: $MAX_FD_LIMIT" - fi +if ! "$cygwin" && ! "$darwin" && ! "$nonstop" ; then + case $MAX_FD in #( + max*) + MAX_FD=$( ulimit -H -n ) || + warn "Could not query maximum file descriptor limit" + esac + case $MAX_FD in #( + '' | soft) :;; #( + *) + ulimit -n "$MAX_FD" || + warn "Could not set maximum file descriptor limit to $MAX_FD" + esac fi -# For Darwin, add options to specify how the application appears in the dock -if $darwin; then - GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" -fi +# Collect all arguments for the java command, stacking in reverse order: +# * args from the command line +# * the main class name +# * -classpath +# * -D...appname settings +# * --module-path (only if needed) +# * DEFAULT_JVM_OPTS, JAVA_OPTS, and GRADLE_OPTS environment variables. + +# For Cygwin or MSYS, switch paths to Windows format before running java +if "$cygwin" || "$msys" ; then + APP_HOME=$( cygpath --path --mixed "$APP_HOME" ) + CLASSPATH=$( cygpath --path --mixed "$CLASSPATH" ) + + JAVACMD=$( cygpath --unix "$JAVACMD" ) -# For Cygwin, switch paths to Windows format before running java -if $cygwin ; then - APP_HOME=`cygpath --path --mixed "$APP_HOME"` - CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` - - # We build the pattern for arguments to be converted via cygpath - ROOTDIRSRAW=`find -L / -maxdepth 1 -mindepth 1 -type d 2>/dev/null` - SEP="" - for dir in $ROOTDIRSRAW ; do - ROOTDIRS="$ROOTDIRS$SEP$dir" - SEP="|" - done - OURCYGPATTERN="(^($ROOTDIRS))" - # Add a user-defined pattern to the cygpath arguments - if [ "$GRADLE_CYGPATTERN" != "" ] ; then - OURCYGPATTERN="$OURCYGPATTERN|($GRADLE_CYGPATTERN)" - fi # Now convert the arguments - kludge to limit ourselves to /bin/sh - i=0 - for arg in "$@" ; do - CHECK=`echo "$arg"|egrep -c "$OURCYGPATTERN" -` - CHECK2=`echo "$arg"|egrep -c "^-"` ### Determine if an option - - if [ $CHECK -ne 0 ] && [ $CHECK2 -eq 0 ] ; then ### Added a condition - eval `echo args$i`=`cygpath --path --ignore --mixed "$arg"` - else - eval `echo args$i`="\"$arg\"" + for arg do + if + case $arg in #( + -*) false ;; # don't mess with options #( + /?*) t=${arg#/} t=/${t%%/*} # looks like a POSIX filepath + [ -e "$t" ] ;; #( + *) false ;; + esac + then + arg=$( cygpath --path --ignore --mixed "$arg" ) fi - i=$((i+1)) + # Roll the args list around exactly as many times as the number of + # args, so each arg winds up back in the position where it started, but + # possibly modified. + # + # NB: a `for` loop captures its iteration list before it begins, so + # changing the positional parameters here affects neither the number of + # iterations, nor the values presented in `arg`. + shift # remove old arg + set -- "$@" "$arg" # push replacement arg done - case $i in - (0) set -- ;; - (1) set -- "$args0" ;; - (2) set -- "$args0" "$args1" ;; - (3) set -- "$args0" "$args1" "$args2" ;; - (4) set -- "$args0" "$args1" "$args2" "$args3" ;; - (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; - (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; - (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; - (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; - (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; - esac fi -# Split up the JVM_OPTS And GRADLE_OPTS values into an array, following the shell quoting and substitution rules -function splitJvmOpts() { - JVM_OPTS=("$@") -} -eval splitJvmOpts $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS -JVM_OPTS[${#JVM_OPTS[*]}]="-Dorg.gradle.appname=$APP_BASE_NAME" +# Collect all arguments for the java command; +# * $DEFAULT_JVM_OPTS, $JAVA_OPTS, and $GRADLE_OPTS can contain fragments of +# shell script including quotes and variable substitutions, so put them in +# double quotes to make sure that they get re-expanded; and +# * put everything else in single quotes, so that it's not re-expanded. + +set -- \ + "-Dorg.gradle.appname=$APP_BASE_NAME" \ + -classpath "$CLASSPATH" \ + org.gradle.wrapper.GradleWrapperMain \ + "$@" + +# Stop when "xargs" is not available. +if ! command -v xargs >/dev/null 2>&1 +then + die "xargs is not available" +fi -exec "$JAVACMD" "${JVM_OPTS[@]}" -classpath "$CLASSPATH" org.gradle.wrapper.GradleWrapperMain "$@" +# Use "xargs" to parse quoted args. +# +# With -n1 it outputs one arg per line, with the quotes and backslashes removed. +# +# In Bash we could simply go: +# +# readarray ARGS < <( xargs -n1 <<<"$var" ) && +# set -- "${ARGS[@]}" "$@" +# +# but POSIX shell has neither arrays nor command substitution, so instead we +# post-process each arg (as a line of input to sed) to backslash-escape any +# character that might be a shell metacharacter, then use eval to reverse +# that process (while maintaining the separation between arguments), and wrap +# the whole thing up as a single "set" statement. +# +# This will of course break if any of these variables contains a newline or +# an unmatched quote. +# + +eval "set -- $( + printf '%s\n' "$DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS" | + xargs -n1 | + sed ' s~[^-[:alnum:]+,./:=@_]~\\&~g; ' | + tr '\n' ' ' + )" '"$@"' + +exec "$JAVACMD" "$@" diff --git a/gradlew.bat b/gradlew.bat index 8a0b282aa6..f127cfd49d 100644 --- a/gradlew.bat +++ b/gradlew.bat @@ -1,4 +1,20 @@ -@if "%DEBUG%" == "" @echo off +@rem +@rem Copyright 2015 the original author or authors. +@rem +@rem Licensed under the Apache License, Version 2.0 (the "License"); +@rem you may not use this file except in compliance with the License. +@rem You may obtain a copy of the License at +@rem +@rem https://www.apache.org/licenses/LICENSE-2.0 +@rem +@rem Unless required by applicable law or agreed to in writing, software +@rem distributed under the License is distributed on an "AS IS" BASIS, +@rem WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +@rem See the License for the specific language governing permissions and +@rem limitations under the License. +@rem + +@if "%DEBUG%"=="" @echo off @rem ########################################################################## @rem @rem Gradle startup script for Windows @@ -8,20 +24,23 @@ @rem Set local scope for the variables with windows NT shell if "%OS%"=="Windows_NT" setlocal -@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. -set DEFAULT_JVM_OPTS= - set DIRNAME=%~dp0 -if "%DIRNAME%" == "" set DIRNAME=. +if "%DIRNAME%"=="" set DIRNAME=. set APP_BASE_NAME=%~n0 set APP_HOME=%DIRNAME% +@rem Resolve any "." and ".." in APP_HOME to make it shorter. +for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi + +@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. +set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m" + @rem Find java.exe if defined JAVA_HOME goto findJavaFromJavaHome set JAVA_EXE=java.exe %JAVA_EXE% -version >NUL 2>&1 -if "%ERRORLEVEL%" == "0" goto init +if %ERRORLEVEL% equ 0 goto execute echo. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. @@ -35,7 +54,7 @@ goto fail set JAVA_HOME=%JAVA_HOME:"=% set JAVA_EXE=%JAVA_HOME%/bin/java.exe -if exist "%JAVA_EXE%" goto init +if exist "%JAVA_EXE%" goto execute echo. echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% @@ -45,44 +64,26 @@ echo location of your Java installation. goto fail -:init -@rem Get command-line arguments, handling Windowz variants - -if not "%OS%" == "Windows_NT" goto win9xME_args -if "%@eval[2+2]" == "4" goto 4NT_args - -:win9xME_args -@rem Slurp the command line arguments. -set CMD_LINE_ARGS= -set _SKIP=2 - -:win9xME_args_slurp -if "x%~1" == "x" goto execute - -set CMD_LINE_ARGS=%* -goto execute - -:4NT_args -@rem Get arguments from the 4NT Shell from JP Software -set CMD_LINE_ARGS=%$ - :execute @rem Setup the command line set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar + @rem Execute Gradle -"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS% +"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* :end @rem End local scope for the variables with windows NT shell -if "%ERRORLEVEL%"=="0" goto mainEnd +if %ERRORLEVEL% equ 0 goto mainEnd :fail rem Set variable GRADLE_EXIT_CONSOLE if you need the _script_ return code instead of rem the _cmd.exe /c_ return code! -if not "" == "%GRADLE_EXIT_CONSOLE%" exit 1 -exit /b 1 +set EXIT_CODE=%ERRORLEVEL% +if %EXIT_CODE% equ 0 set EXIT_CODE=1 +if not ""=="%GRADLE_EXIT_CONSOLE%" exit %EXIT_CODE% +exit /b %EXIT_CODE% :mainEnd if "%OS%"=="Windows_NT" endlocal diff --git a/jitpack.yml b/jitpack.yml new file mode 100644 index 0000000000..6166e3d73a --- /dev/null +++ b/jitpack.yml @@ -0,0 +1,4 @@ +jdk: + - openjdk17 +env: + CI: true diff --git a/settings.gradle.kts b/settings.gradle.kts index 441383126c..eb291fb54e 100644 --- a/settings.gradle.kts +++ b/settings.gradle.kts @@ -1,17 +1,40 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + pluginManagement { - repositories { - mavenCentral() - gradlePluginPortal() - maven(url = "https://jitpack.io/") - maven(url = "https://maven.minecraftforge.net/") - maven(url = "https://repo.spongepowered.org/maven/") - } - resolutionStrategy { - eachPlugin { - when (requested.id.id) { - "net.minecraftforge.gradle.forge" -> useModule("com.github.asbyth:ForgeGradle:${requested.version}") - "org.spongepowered.mixin" -> useModule("com.github.LxGaming:MixinGradle:${requested.version}") - } - } - } + repositories { + mavenCentral() + gradlePluginPortal() + maven("https://oss.sonatype.org/content/repositories/snapshots") + maven("https://maven.architectury.dev/") + maven("https://maven.fabricmc.net") + maven(url = "https://jitpack.io/") + maven(url = "https://maven.minecraftforge.net/") + maven(url = "https://repo.spongepowered.org/maven/") + maven(url = "https://repo.sk1er.club/repository/maven-releases/") + maven(url = "https://maven.architectury.dev/") + } + resolutionStrategy { + eachPlugin { + when (requested.id.id) { + "gg.essential.loom" -> useModule("gg.essential:architectury-loom:${requested.version}") + } + } + } } diff --git a/src/main/java/NotSkyblockAddonsInstallerFrame.java b/src/main/java/NotSkyblockAddonsInstallerFrame.java index e654361704..969e6c28f0 100644 --- a/src/main/java/NotSkyblockAddonsInstallerFrame.java +++ b/src/main/java/NotSkyblockAddonsInstallerFrame.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + import javax.imageio.ImageIO; import javax.swing.*; import java.awt.*; @@ -6,7 +25,13 @@ import java.awt.event.MouseEvent; import java.awt.event.MouseListener; import java.awt.image.BufferedImage; -import java.io.*; +import java.io.BufferedReader; +import java.io.File; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.PrintWriter; +import java.io.StringWriter; import java.net.URI; import java.net.URISyntaxException; import java.nio.file.Files; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/BuildFlags.java b/src/main/java/io/github/moulberry/notenoughupdates/BuildFlags.java new file mode 100644 index 0000000000..d997d9806a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/BuildFlags.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates; + +import java.io.IOException; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; +import java.util.HashMap; +import java.util.Map; +import java.util.Properties; + +/** + * For storage of compile-time configuration flags + */ +public class BuildFlags { + + private static final Properties properties = new Properties(); + + static { + try { + properties.load(BuildFlags.class.getResourceAsStream("/buildflags.properties")); + } catch (IOException | NullPointerException e) { + System.out.println("Failed to load build properties: " + e); + } + } + + private static boolean getBuildFlag(String flag) { + return Boolean.parseBoolean(properties.getProperty("neu.buildflags." + flag)); + } + + public static Map getAllFlags() { + return Holder.ALL_FLAGS; + } + + public static final boolean ENABLE_PRONOUNS_IN_PV_BY_DEFAULT = getBuildFlag("pronouns"); + + private static class Holder { + static Map ALL_FLAGS = new HashMap<>(); + + static { + for (Field declaredField : BuildFlags.class.getDeclaredFields()) { + if (Boolean.TYPE.equals(declaredField.getType()) + && (declaredField.getModifiers() & Modifier.STATIC) != 0) { + try { + declaredField.setAccessible(true); + ALL_FLAGS.put(declaredField.getName(), (Boolean) declaredField.get(null)); + } catch (IllegalAccessException | ClassCastException | SecurityException e) { + System.err.println("Failed to access BuildFlag: " + e); + } + } + } + } + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java b/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java index 28686073a0..3911396f57 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/CustomItems.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates; import com.google.gson.JsonArray; @@ -91,11 +110,11 @@ public class CustomItems { * SHAAAAAAAAAAAAAAAAAAME */ - private static JsonObject create(String internalname, String itemid, String displayname, String... lore) { + private static JsonObject create(String internalname, String itemid, String displayName, String... lore) { JsonObject json = new JsonObject(); json.addProperty("itemid", itemid); json.addProperty("internalname", internalname); - json.addProperty("displayname", EnumChatFormatting.RED + displayname); + json.addProperty("displayname", EnumChatFormatting.RED + displayName); JsonArray jsonlore = new JsonArray(); for (String line : lore) { jsonlore.add(new JsonPrimitive(EnumChatFormatting.GRAY + line)); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java index 1804831b1a..a773abdcb9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/ItemPriceInformation.java @@ -1,18 +1,46 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates; import com.google.gson.Gson; +import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.auction.APIManager; import io.github.moulberry.notenoughupdates.core.config.KeybindHelper; import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; import net.minecraft.util.EnumChatFormatting; import org.lwjgl.input.Keyboard; -import java.io.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; +import java.text.DecimalFormat; +import java.text.DecimalFormatSymbols; import java.text.NumberFormat; import java.util.HashSet; import java.util.List; @@ -23,6 +51,7 @@ public class ItemPriceInformation { private static File file; private static HashSet auctionableItems = null; private static Gson gson; + private static final NumberFormat format = new DecimalFormat("#,##0.#", new DecimalFormatSymbols(Locale.US)); public static boolean addToTooltip(List tooltip, String internalname, ItemStack stack) { return addToTooltip(tooltip, internalname, stack, true); @@ -75,27 +104,24 @@ public static boolean addToTooltip(List tooltip, String internalname, It } JsonObject auctionInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAuctionInfo(internalname); JsonObject bazaarInfo = NotEnoughUpdates.INSTANCE.manager.auctionManager.getBazaarInfo(internalname); - float lowestBinAvg = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalname); + double lowestBinAvg = NotEnoughUpdates.INSTANCE.manager.auctionManager.getItemAvgBin(internalname); - int lowestBin = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalname); + double lowestBin = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(internalname); APIManager.CraftInfo craftCost = NotEnoughUpdates.INSTANCE.manager.auctionManager.getCraftCost(internalname); + boolean bazaarItem = bazaarInfo != null; - boolean auctionItem = lowestBin > 0 || lowestBinAvg > 0; + boolean auctionItem = !bazaarItem; boolean auctionInfoErrored = auctionInfo == null; if (auctionItem) { long currentTime = System.currentTimeMillis(); long lastUpdate = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLastLowestBinUpdateTime(); //check if info is older than 10 minutes - if (currentTime - lastUpdate > 600 * 1000) { + if (currentTime - lastUpdate > 600 * 1000 && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { tooltip.add(EnumChatFormatting.RED + "[NEU] Price info is outdated."); tooltip.add(EnumChatFormatting.RED + "It will be updated again as soon as possible."); } } - boolean bazaarItem = bazaarInfo != null; - - NumberFormat format = NumberFormat.getInstance(Locale.US); - boolean shortNumber = NotEnoughUpdates.INSTANCE.config.tooltipTweaks.shortNumberFormatPrices; if (bazaarItem) { List lines = NotEnoughUpdates.INSTANCE.config.tooltipTweaks.priceInfoBaz; @@ -120,11 +146,8 @@ public static boolean addToTooltip(List tooltip, String internalname, It tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]"); added = true; } - int bazaarBuyPrice = (int) bazaarInfo.get("avg_buy").getAsFloat() * stackMultiplier; - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Buy: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarBuyPrice > 1000 - ? Utils.shortNumberFormat(bazaarBuyPrice, 0) - : format.format(bazaarBuyPrice)) + " coins"); + double bazaarBuyPrice = bazaarInfo.get("avg_buy").getAsFloat() * stackMultiplier; + tooltip.add(formatPrice("Bazaar Buy: ", bazaarBuyPrice)); } break; case 1: @@ -135,11 +158,8 @@ public static boolean addToTooltip(List tooltip, String internalname, It tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]"); added = true; } - int bazaarSellPrice = (int) bazaarInfo.get("avg_sell").getAsFloat() * stackMultiplier; - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Sell: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarSellPrice > 1000 - ? Utils.shortNumberFormat(bazaarSellPrice, 0) - : format.format(bazaarSellPrice)) + " coins"); + double bazaarSellPrice = bazaarInfo.get("avg_sell").getAsDouble() * stackMultiplier; + tooltip.add(formatPrice("Bazaar Sell: ", bazaarSellPrice)); } break; case 2: @@ -150,12 +170,8 @@ public static boolean addToTooltip(List tooltip, String internalname, It tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]"); added = true; } - int bazaarInstantBuyPrice = (int) bazaarInfo.get("curr_buy").getAsFloat() * stackMultiplier; - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Insta-Buy: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarInstantBuyPrice > 1000 - ? Utils.shortNumberFormat(bazaarInstantBuyPrice, 0) - : format.format(bazaarInstantBuyPrice)) + - " coins"); + double bazaarInstantBuyPrice = bazaarInfo.get("curr_buy").getAsFloat() * stackMultiplier; + tooltip.add(formatPrice("Bazaar Insta-Buy: ", bazaarInstantBuyPrice)); } break; case 3: @@ -166,32 +182,22 @@ public static boolean addToTooltip(List tooltip, String internalname, It tooltip.add(EnumChatFormatting.DARK_GRAY + "[SHIFT show x" + shiftStackMultiplier + "]"); added = true; } - int bazaarInstantSellPrice = (int) bazaarInfo.get("curr_sell").getAsFloat() * stackMultiplier; - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Bazaar Insta-Sell: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + (shortNumber && bazaarInstantSellPrice > 1000 - ? Utils.shortNumberFormat( - bazaarInstantSellPrice, - 0 - ) - : format.format(bazaarInstantSellPrice)) + - " coins"); + double bazaarInstantSellPrice = bazaarInfo.get("curr_sell").getAsFloat() * stackMultiplier; + tooltip.add(formatPrice("Bazaar Insta-Sell: ", bazaarInstantSellPrice)); } break; case 4: if (craftCost != null && craftCost.fromRecipe) { - if ((int) craftCost.craftCost == 0) { + if (craftCost.craftCost == 0) { continue; } if (!added) { tooltip.add(""); added = true; } - float cost = craftCost.craftCost; + double cost = craftCost.craftCost; if (shiftPressed) cost = cost * shiftStackMultiplier; - - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Raw Craft Cost: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + - (shortNumber && cost > 1000 ? Utils.shortNumberFormat(cost, 0) : format.format((int) cost)) + " coins"); + tooltip.add(formatPrice("Raw Craft Cost: ", cost)); } break; } @@ -211,8 +217,7 @@ public static boolean addToTooltip(List tooltip, String internalname, It tooltip.add(""); added = true; } - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Lowest BIN: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + format.format(lowestBin) + " coins"); + tooltip.add(formatPrice("Lowest BIN: ", lowestBin)); } break; case 1: @@ -223,21 +228,11 @@ public static boolean addToTooltip(List tooltip, String internalname, It } if (auctionInfo.has("clean_price")) { - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "AH Price (Clean): " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + - (shortNumber && auctionInfo.get("clean_price").getAsFloat() > 1000 ? Utils.shortNumberFormat( - auctionInfo.get("clean_price").getAsFloat(), - 0 - ) : format.format((int) auctionInfo.get("clean_price").getAsFloat()) - + " coins")); + double cleanPrice = auctionInfo.get("clean_price").getAsDouble(); + tooltip.add(formatPrice("AH Price (Clean): ", cleanPrice)); } else { - int auctionPrice = - (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "AH Price: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + - (shortNumber && auctionPrice > 1000 - ? Utils.shortNumberFormat(auctionPrice, 0) - : format.format(auctionPrice)) + " coins"); + double auctionPrice = auctionInfo.get("price").getAsDouble() / auctionInfo.get("count").getAsFloat(); + tooltip.add(formatPrice("AH Price: ", auctionPrice)); } } @@ -267,18 +262,14 @@ public static boolean addToTooltip(List tooltip, String internalname, It break; case 3: if (craftCost != null && craftCost.fromRecipe) { - if ((int) craftCost.craftCost == 0) { + if (craftCost.craftCost == 0) { continue; } if (!added) { tooltip.add(""); added = true; } - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Raw Craft Cost: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + - (shortNumber && craftCost.craftCost > 1000 - ? Utils.shortNumberFormat(craftCost.craftCost, 0) - : format.format((int) craftCost.craftCost)) + " coins"); + tooltip.add(formatPrice("Raw Craft Cost: ", craftCost.craftCost)); } break; case 4: @@ -287,11 +278,7 @@ public static boolean addToTooltip(List tooltip, String internalname, It tooltip.add(""); added = true; } - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "AVG Lowest BIN: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + - (shortNumber && lowestBinAvg > 1000 - ? Utils.shortNumberFormat(lowestBinAvg, 0) - : format.format(lowestBinAvg)) + " coins"); + tooltip.add(formatPrice("AVG Lowest BIN: ", lowestBinAvg)); } break; case 5: @@ -302,41 +289,56 @@ public static boolean addToTooltip(List tooltip, String internalname, It } JsonObject itemCosts = essenceCosts.get(internalname).getAsJsonObject(); String essenceType = itemCosts.get("type").getAsString(); + boolean requiresItems = false; + JsonObject itemsObject = null; + if (itemCosts.has("items")) { + requiresItems = true; + itemsObject = itemCosts.get("items").getAsJsonObject(); + } - int dungeonItemLevel = -1; - if (stack != null && stack.hasTagCompound() && - stack.getTagCompound().hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea = stack.getTagCompound().getCompoundTag("ExtraAttributes"); + int dungeonItemLevel = Utils.getNumberOfStars(stack); - if (ea.hasKey("dungeon_item_level", 99)) { - dungeonItemLevel = ea.getInteger("dungeon_item_level"); - } - } if (dungeonItemLevel == -1) { int dungeonizeCost = 0; if (itemCosts.has("dungeonize")) { dungeonizeCost = itemCosts.get("dungeonize").getAsInt(); } - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Dungeonize Cost: " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + dungeonizeCost + " " + essenceType); - } else if (dungeonItemLevel >= 0 && dungeonItemLevel <= 4) { - String costType = (dungeonItemLevel + 1) + ""; - int upgradeCost = itemCosts.get(costType).getAsInt(); - StringBuilder star = new StringBuilder(); - for (int i = 0; i <= dungeonItemLevel; i++) { - star.append('\u272A'); + if (dungeonizeCost > 0) { + tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Dungeonize Cost: " + + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + dungeonizeCost + " " + essenceType); + } + } else if (dungeonItemLevel >= 0) { + String nextStarLevelString = (dungeonItemLevel + 1) + ""; + int nextStarLevelInt = Integer.parseInt(nextStarLevelString); + + if (itemCosts.has(nextStarLevelString)) { + int upgradeCost = itemCosts.get(nextStarLevelString).getAsInt(); + String starString = Utils.getStarsString(nextStarLevelInt); + tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Upgrade to " + + starString + EnumChatFormatting.YELLOW + EnumChatFormatting.BOLD + ": " + + EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + upgradeCost + " " + essenceType); + if (requiresItems && itemsObject.has(nextStarLevelString)) { + boolean shouldShow = Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) || + NotEnoughUpdates.INSTANCE.config.tooltipTweaks.alwaysShowRequiredItems; + + if (shouldShow) { + tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Required Items:"); + for (JsonElement item : itemsObject.get(nextStarLevelString).getAsJsonArray()) { + tooltip.add(" - " + item.getAsString()); + } + } else { + tooltip.add(EnumChatFormatting.DARK_GRAY + "[CTRL to show required items]"); + } + } } - tooltip.add(EnumChatFormatting.YELLOW.toString() + EnumChatFormatting.BOLD + "Upgrade to " + - EnumChatFormatting.GOLD + star + EnumChatFormatting.YELLOW + EnumChatFormatting.BOLD + ": " + - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD + upgradeCost + " " + essenceType); } break; } } return added; - } else if (auctionInfoErrored) { + } else if (auctionInfoErrored && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { String message = EnumChatFormatting.RED.toString() + EnumChatFormatting.BOLD + "[NEU] API is down"; if (auctionableItems != null && !auctionableItems.isEmpty()) { if (auctionableItems.contains(internalname)) { @@ -351,4 +353,13 @@ public static boolean addToTooltip(List tooltip, String internalname, It return false; } + + private static String formatPrice(String label, double price) { + boolean shortNumber = NotEnoughUpdates.INSTANCE.config.tooltipTweaks.shortNumberFormatPrices; + String number = (shortNumber && price > 1000 + ? Utils.shortNumberFormat(price, 0) + : price > 5 ? format.format((int) price) : format.format(price)); + return "§e§l" + label + "§6§l" + number + " coins"; + } + } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUApi.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUApi.java index d83035d0db..6cdeb47402 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUApi.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUApi.java @@ -1,9 +1,27 @@ -package io.github.moulberry.notenoughupdates; +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ +package io.github.moulberry.notenoughupdates; import net.minecraftforge.fml.relauncher.ReflectionHelper; public class NEUApi { - static boolean disableInventoryButtons = false; + public static boolean disableInventoryButtons = false; public static void setInventoryButtonsToDisabled() { disableInventoryButtons = true; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java deleted file mode 100644 index 84289e3456..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUEventListener.java +++ /dev/null @@ -1,2842 +0,0 @@ -package io.github.moulberry.notenoughupdates; - -import com.google.common.collect.Lists; -import com.google.gson.JsonArray; -import com.google.gson.JsonElement; -import com.google.gson.JsonObject; -import com.google.gson.JsonPrimitive; -import com.mojang.authlib.GameProfile; -import com.mojang.authlib.minecraft.MinecraftProfileTexture; -import io.github.moulberry.notenoughupdates.auction.CustomAHGui; -import io.github.moulberry.notenoughupdates.commands.profile.ViewProfileCommand; -import io.github.moulberry.notenoughupdates.core.BackgroundBlur; -import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper; -import io.github.moulberry.notenoughupdates.core.util.MiscUtils; -import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; -import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; -import io.github.moulberry.notenoughupdates.dungeons.DungeonBlocks; -import io.github.moulberry.notenoughupdates.dungeons.DungeonWin; -import io.github.moulberry.notenoughupdates.miscfeatures.*; -import io.github.moulberry.notenoughupdates.miscgui.*; -import io.github.moulberry.notenoughupdates.options.NEUConfig; -import io.github.moulberry.notenoughupdates.overlays.*; -import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; -import io.github.moulberry.notenoughupdates.util.*; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.*; -import net.minecraft.client.gui.inventory.GuiChest; -import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.gui.inventory.GuiEditSign; -import net.minecraft.client.gui.inventory.GuiInventory; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.entity.player.EntityPlayer; -import net.minecraft.event.ClickEvent; -import net.minecraft.init.Items; -import net.minecraft.inventory.ContainerChest; -import net.minecraft.inventory.IInventory; -import net.minecraft.inventory.Slot; -import net.minecraft.item.ItemStack; -import net.minecraft.nbt.NBTTagCompound; -import net.minecraft.nbt.NBTTagList; -import net.minecraft.nbt.NBTUtil; -import net.minecraft.util.*; -import net.minecraftforge.client.ClientCommandHandler; -import net.minecraftforge.client.event.*; -import net.minecraftforge.event.entity.player.ItemTooltipEvent; -import net.minecraftforge.event.world.WorldEvent; -import net.minecraftforge.fml.common.Loader; -import net.minecraftforge.fml.common.eventhandler.EventPriority; -import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; -import net.minecraftforge.fml.common.gameevent.TickEvent; -import org.apache.commons.lang3.text.WordUtils; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL11; - -import javax.swing.*; -import java.awt.*; -import java.awt.datatransfer.StringSelection; -import java.io.File; -import java.io.IOException; -import java.text.DecimalFormat; -import java.text.NumberFormat; -import java.util.List; -import java.util.*; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicBoolean; -import java.util.regex.Matcher; -import java.util.regex.Pattern; - -import static io.github.moulberry.notenoughupdates.overlays.SlayerOverlay.*; -import static io.github.moulberry.notenoughupdates.util.GuiTextures.dungeon_chest_worth; - -public class NEUEventListener { - - private final NotEnoughUpdates neu; - - private boolean hoverInv = false; - private boolean focusInv = false; - - private boolean joinedSB = false; - - public NEUEventListener(NotEnoughUpdates neu) { - this.neu = neu; - } - - private void displayUpdateMessageIfOutOfDate() { - File repo = neu.manager.repoLocation; - if (repo.exists()) { - File updateJson = new File(repo, "update.json"); - try { - JsonObject o = neu.manager.getJsonFromFile(updateJson); - - String version = o.get("version").getAsString(); - String preVersion = o.get("pre_version").getAsString(); - - boolean shouldUpdate = !NotEnoughUpdates.VERSION.equalsIgnoreCase(version); - boolean shouldPreUpdate = !NotEnoughUpdates.PRE_VERSION.equalsIgnoreCase(preVersion); - - if (o.has("version_id") && o.get("version_id").isJsonPrimitive()) { - int version_id = o.get("version_id").getAsInt(); - shouldUpdate = version_id > NotEnoughUpdates.VERSION_ID; - } - if (o.has("pre_version_id") && o.get("pre_version_id").isJsonPrimitive()) { - int pre_version_id = o.get("pre_version_id").getAsInt(); - shouldPreUpdate = pre_version_id > NotEnoughUpdates.PRE_VERSION_ID; - } - - if (shouldUpdate) { - String update_msg = o.get("update_msg").getAsString(); - - int first_len = -1; - for (String line : update_msg.split("\n")) { - FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; - int len = fr.getStringWidth(line); - if (first_len == -1) { - first_len = len; - } - int missing_len = first_len - len; - if (missing_len > 0) { - StringBuilder sb = new StringBuilder(line); - for (int i = 0; i < missing_len / 8; i++) { - sb.insert(0, " "); - } - line = sb.toString(); - } - line = line.replaceAll("\\{version}", version); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(line)); - } - - neu.displayLinks(o); - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - } else if (shouldPreUpdate && NotEnoughUpdates.VERSION_ID == o.get("version").getAsInt()) { - String pre_update_msg = o.get("pre_update_msg").getAsString(); - - int first_len = -1; - for (String line : pre_update_msg.split("\n")) { - FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; - int len = fr.getStringWidth(line); - if (first_len == -1) { - first_len = len; - } - int missing_len = first_len - len; - if (missing_len > 0) { - StringBuilder sb = new StringBuilder(line); - for (int i = 0; i < missing_len / 8; i++) { - sb.insert(0, " "); - } - line = sb.toString(); - } - line = line.replaceAll("\\{pre_version}", preVersion); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(line)); - } - - neu.displayLinks(o); - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - } - } catch (Exception ignored) { - } - } - } - - @SubscribeEvent - public void onWorldLoad(WorldEvent.Unload event) { - NotEnoughUpdates.INSTANCE.saveConfig(); - CrystalMetalDetectorSolver.reset(false); - } - - private static long notificationDisplayMillis = 0; - private static List notificationLines = null; - private static boolean showNotificationOverInv = false; - - private static final Pattern BAD_ITEM_REGEX = Pattern.compile("x[0-9]{1,2}$"); - private static final Pattern SLAYER_XP = - Pattern.compile(" (Spider|Zombie|Wolf|Enderman) Slayer LVL (\\d) - (?:Next LVL in ([\\d,]+) XP!|LVL MAXED OUT!)"); - - /** - * 1)Will send the cached message from #sendChatMessage when at least 200ms has passed since the last message. - * This is used in order to prevent the mod spamming messages. - * 2)Adds unique items to the collection log - */ - private boolean preloadedItems = false; - private long lastLongUpdate = 0; - private long lastSkyblockScoreboard = 0; - - private final ExecutorService itemPreloader = Executors.newFixedThreadPool(10); - private final List toPreload = new ArrayList<>(); - - private int inventoryLoadedTicks = 0; - private String loadedInvName = ""; - public static boolean inventoryLoaded = false; - - public static void displayNotification(List lines, boolean showForever) { - displayNotification(lines, showForever, false); - } - - public static void displayNotification(List lines, boolean showForever, boolean overInventory) { - if (showForever) { - notificationDisplayMillis = -420; - } else { - notificationDisplayMillis = System.currentTimeMillis(); - } - notificationLines = lines; - showNotificationOverInv = overInventory; - } - - @SubscribeEvent - public void onTick(TickEvent.ClientTickEvent event) { - Keyboard.enableRepeatEvents( - Minecraft.getMinecraft().currentScreen != null && (Minecraft.getMinecraft().currentScreen instanceof GuiChat - || Minecraft.getMinecraft().currentScreen instanceof GuiEditSign || - Minecraft.getMinecraft().currentScreen instanceof GuiScreenBook)); - if (event.phase != TickEvent.Phase.START) return; - if (Minecraft.getMinecraft().theWorld == null) return; - if (Minecraft.getMinecraft().thePlayer == null) return; - - if (Minecraft.getMinecraft().currentScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest cc = (ContainerChest) chest.inventorySlots; - - if (!loadedInvName.equals(cc.getLowerChestInventory().getDisplayName().getUnformattedText())) { - loadedInvName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - inventoryLoaded = false; - inventoryLoadedTicks = 3; - } - - if (!inventoryLoaded) { - if (cc.getLowerChestInventory().getStackInSlot(cc.getLowerChestInventory().getSizeInventory() - 1) != null) { - inventoryLoaded = true; - } else { - for (ItemStack stack : chest.inventorySlots.getInventory()) { - if (stack != null) { - if (--inventoryLoadedTicks <= 0) { - inventoryLoaded = true; - } - break; - } - } - } - } - } else { - inventoryLoaded = false; - inventoryLoadedTicks = 3; - } - - if ((Keyboard.isKeyDown(Keyboard.KEY_NUMPAD1) && Keyboard.isKeyDown(Keyboard.KEY_NUMPAD4) && - Keyboard.isKeyDown(Keyboard.KEY_NUMPAD9))) { - ChatComponentText component = new ChatComponentText("\u00a7cYou are permanently banned from this server!"); - component.appendText("\n"); - component.appendText("\n\u00a77Reason: \u00a7rSuspicious account activity/Other"); - component.appendText("\n\u00a77Find out more: \u00a7b\u00a7nhttps://www.hypixel.net/appeal"); - component.appendText("\n"); - component.appendText("\n\u00a77Ban ID: \u00a7r#49871982"); - component.appendText("\n\u00a77Sharing your Ban ID may affect the processing of your appeal!"); - Minecraft.getMinecraft().getNetHandler().getNetworkManager().closeChannel(component); - return; - } - - if (neu.hasSkyblockScoreboard()) { - if (!preloadedItems) { - preloadedItems = true; - List list = new ArrayList<>(neu.manager.getItemInformation().values()); - for (JsonObject json : list) { - itemPreloader.submit(() -> { - ItemStack stack = neu.manager.jsonToStack(json, true, true); - if (stack.getItem() == Items.skull) toPreload.add(stack); - }); - } - } else if (!toPreload.isEmpty()) { - Utils.drawItemStack(toPreload.get(0), -100, -100); - toPreload.remove(0); - } else { - itemPreloader.shutdown(); - } - - for (TextOverlay overlay : OverlayManager.textOverlays) { - overlay.shouldUpdateFrequent = true; - } - } - - boolean longUpdate = false; - long currentTime = System.currentTimeMillis(); - if (currentTime - lastLongUpdate > 1000) { - longUpdate = true; - lastLongUpdate = currentTime; - } - if (!NotEnoughUpdates.INSTANCE.config.dungeons.slowDungeonBlocks) { - DungeonBlocks.tick(); - } - DungeonWin.tick(); - - String containerName = null; - if (Minecraft.getMinecraft().currentScreen instanceof GuiChest) { - GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - - if (GuiCustomEnchant.getInstance().shouldOverride(containerName)) { - GuiCustomEnchant.getInstance().tick(); - } - } - - if (longUpdate) { - CrystalOverlay.tick(); - FairySouls.tick(); - XPInformation.getInstance().tick(); - ProfileApiSyncer.getInstance().tick(); - ItemCustomizeManager.tick(); - BackgroundBlur.markDirty(); - NPCRetexturing.getInstance().tick(); - StorageOverlay.getInstance().markDirty(); - - if (neu.hasSkyblockScoreboard()) { - for (TextOverlay overlay : OverlayManager.textOverlays) { - overlay.tick(); - } - } - - NotEnoughUpdates.INSTANCE.overlay.redrawItems(); - CapeManager.onTickSlow(); - - NotEnoughUpdates.profileViewer.putNameUuid( - Minecraft.getMinecraft().thePlayer.getName(), - Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", "") - ); - - if (NotEnoughUpdates.INSTANCE.config.dungeons.slowDungeonBlocks) { - DungeonBlocks.tick(); - } - - if (System.currentTimeMillis() - SBInfo.getInstance().joinedWorld > 500 && - System.currentTimeMillis() - SBInfo.getInstance().unloadedWorld > 500) { - neu.updateSkyblockScoreboard(); - } - CapeManager.getInstance().tick(); - - if (containerName != null) { - if (!containerName.trim().startsWith("Accessory Bag")) { - AccessoryBagOverlay.resetCache(); - } - } else { - AccessoryBagOverlay.resetCache(); - } - - if (neu.hasSkyblockScoreboard()) { - SBInfo.getInstance().tick(); - lastSkyblockScoreboard = currentTime; - if (!joinedSB) { - joinedSB = true; - - //SBGamemodes.loadFromFile(); - - if (NotEnoughUpdates.INSTANCE.config.notifications.showUpdateMsg) { - displayUpdateMessageIfOutOfDate(); - } - - if (NotEnoughUpdates.INSTANCE.config.notifications.doRamNotif) { - long maxMemoryMB = Runtime.getRuntime().maxMemory() / 1024L / 1024L; - if (maxMemoryMB > 4100) { - notificationDisplayMillis = System.currentTimeMillis(); - notificationLines = new ArrayList<>(); - notificationLines.add(EnumChatFormatting.GRAY + "Too much memory allocated!"); - notificationLines.add(String.format( - EnumChatFormatting.DARK_GRAY + "NEU has detected %03dMB of memory allocated to Minecraft!", - maxMemoryMB - )); - notificationLines.add(EnumChatFormatting.GRAY + "It is recommended to allocated between 2-4GB of memory"); - notificationLines.add( - EnumChatFormatting.GRAY + "More than 4GB MAY cause FPS issues, EVEN if you have 16GB+ available"); - notificationLines.add(""); - notificationLines.add( - EnumChatFormatting.GRAY + "For more information, visit #ram-info in discord.gg/moulberry"); - } - } - - if (!NotEnoughUpdates.INSTANCE.config.hidden.loadedModBefore) { - NotEnoughUpdates.INSTANCE.config.hidden.loadedModBefore = true; - if (Constants.MISC == null || !Constants.MISC.has("featureslist")) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "WARNING: " + EnumChatFormatting.RESET + - EnumChatFormatting.RED + "Could not load Feature List URL from repo.")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.RED + "Please run " + EnumChatFormatting.BOLD + "/neuresetrepo" + - EnumChatFormatting.RESET + EnumChatFormatting.RED + " and " + EnumChatFormatting.BOLD + - "restart your game" + EnumChatFormatting.RESET + EnumChatFormatting.RED + " in order to fix. " + - EnumChatFormatting.DARK_RED + EnumChatFormatting.BOLD + "If that doesn't fix it" + - EnumChatFormatting.RESET + EnumChatFormatting.RED + - ", please join discord.gg/moulberry and post in #neu-support")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "" + EnumChatFormatting.GOLD + "To view the feature list after restarting type /neufeatures")); - } else { - String url = Constants.MISC.get("featureslist").getAsString(); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.BLUE + "It seems this is your first time using NotEnoughUpdates.")); - ChatComponentText clickTextFeatures = new ChatComponentText( - EnumChatFormatting.YELLOW + - "Click this message if you would like to view a list of NotEnoughUpdate's Features."); - clickTextFeatures.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, url)); - Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextFeatures); - } - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - ChatComponentText clickTextHelp = new ChatComponentText( - EnumChatFormatting.YELLOW + - "Click this message if you would like to view a list of NotEnoughUpdate's commands."); - clickTextHelp.setChatStyle(Utils.createClickStyle(ClickEvent.Action.RUN_COMMAND, "/neuhelp")); - Minecraft.getMinecraft().thePlayer.addChatMessage(clickTextHelp); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - } - } - } - if (currentTime - lastSkyblockScoreboard < 5 * 60 * 1000) { //5 minutes - neu.manager.auctionManager.tick(); - } else { - neu.manager.auctionManager.markNeedsUpdate(); - } - } - - /*if(longUpdate && neu.hasSkyblockScoreboard()) { - if(neu.manager.getCurrentProfile() == null || neu.manager.getCurrentProfile().length() == 0) { - ProfileViewer.Profile profile = NotEnoughUpdates.profileViewer.getProfile(Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""), - callback->{}); - if(profile != null) { - String latest = profile.getLatestProfile(); - if(latest != null) { - neu.manager.setCurrentProfileBackup(profile.getLatestProfile()); - } - } - }*/ - /*if(neu.manager.getCurrentProfile() != null && neu.manager.getCurrentProfile().length() > 0) { - HashSet newItem = new HashSet<>(); - if(Minecraft.getMinecraft().currentScreen instanceof GuiContainer && - !(Minecraft.getMinecraft().currentScreen instanceof GuiCrafting)) { - boolean usableContainer = true; - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.openContainer.getInventory()) { - if(stack == null) { - continue; - } - if(stack.hasTagCompound()) { - NBTTagCompound tag = stack.getTagCompound(); - if(tag.hasKey("ExtraAttributes", 10)) { - continue; - } - } - usableContainer = false; - break; - } - if(!usableContainer) { - if(Minecraft.getMinecraft().currentScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); - - if(containerName.equals("Accessory Bag") || containerName.startsWith("Wardrobe")) { - usableContainer = true; - } - } - } - if(usableContainer) { - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { - processUniqueStack(stack, newItem); - } - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.openContainer.getInventory()) { - processUniqueStack(stack, newItem); - } - } - } else { - for(ItemStack stack : Minecraft.getMinecraft().thePlayer.inventory.mainInventory) { - processUniqueStack(stack, newItem); - } - } - newItemAddMap.keySet().retainAll(newItem); - } - }*/ - } - - /*private void processUniqueStack(ItemStack stack, HashSet newItem) { - if(stack != null && stack.hasTagCompound()) { - String internalname = neu.manager.getInternalNameForItem(stack); - if(internalname != null) { - /*ArrayList log = neu.manager.config.collectionLog.value.computeIfAbsent( - neu.manager.getCurrentProfile(), k -> new ArrayList<>()); - if(!log.contains(internalname)) { - newItem.add(internalname); - if(newItemAddMap.containsKey(internalname)) { - if(System.currentTimeMillis() - newItemAddMap.get(internalname) > 1000) { - log.add(internalname); - try { neu.manager.saveConfig(); } catch(IOException ignored) {} - } - } else { - newItemAddMap.put(internalname, System.currentTimeMillis()); - } - } - } - } - }*/ - - @SubscribeEvent(priority = EventPriority.HIGHEST) - public void onRenderEntitySpecials(RenderLivingEvent.Specials.Pre event) { - if (Minecraft.getMinecraft().currentScreen instanceof GuiProfileViewer) { - if (((GuiProfileViewer) Minecraft.getMinecraft().currentScreen).getEntityPlayer() == event.entity) { - event.setCanceled(true); - } - } - } - - @SubscribeEvent - public void onRenderGameOverlayPre(RenderGameOverlayEvent.Pre event) { - if (event.type != null && event.type.equals(RenderGameOverlayEvent.ElementType.BOSSHEALTH) && - Minecraft.getMinecraft().currentScreen instanceof GuiContainer && neu.overlay.isUsingMobsFilter()) { - event.setCanceled(true); - } - if (event.type != null && event.type.equals(RenderGameOverlayEvent.ElementType.PLAYER_LIST)) { - GlStateManager.enableDepth(); - } - } - - @SubscribeEvent - public void onRenderGameOverlayPost(RenderGameOverlayEvent.Post event) { - if (neu.hasSkyblockScoreboard() && event.type.equals(RenderGameOverlayEvent.ElementType.ALL)) { - DungeonWin.render(event.partialTicks); - GlStateManager.pushMatrix(); - GlStateManager.translate(0, 0, -200); - for (TextOverlay overlay : OverlayManager.textOverlays) { - if (OverlayManager.dontRenderOverlay != null && - OverlayManager.dontRenderOverlay.isAssignableFrom(overlay.getClass())) { - continue; - } - GlStateManager.translate(0, 0, -1); - GlStateManager.enableDepth(); - overlay.render(); - } - GlStateManager.popMatrix(); - OverlayManager.dontRenderOverlay = null; - } - if (Keyboard.isKeyDown(Keyboard.KEY_X)) { - notificationDisplayMillis = 0; - } - - if (event.type == RenderGameOverlayEvent.ElementType.ALL) { - renderNotification(); - } - - } - - private static void renderNotification() { - - long timeRemaining = 15000 - (System.currentTimeMillis() - notificationDisplayMillis); - boolean display = timeRemaining > 0 || notificationDisplayMillis == -420; - if (display && notificationLines != null && notificationLines.size() > 0) { - int width = 0; - int height = notificationLines.size() * 10 + 10; - - for (String line : notificationLines) { - int len = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line) + 8; - if (len > width) { - width = len; - } - } - - ScaledResolution sr = Utils.pushGuiScale(2); - - int midX = sr.getScaledWidth() / 2; - int topY = sr.getScaledHeight() * 3 / 4 - height / 2; - RenderUtils.drawFloatingRectDark(midX - width / 2, sr.getScaledHeight() * 3 / 4 - height / 2, width, height); - /*Gui.drawRect(midX-width/2, sr.getScaledHeight()*3/4-height/2, - midX+width/2, sr.getScaledHeight()*3/4+height/2, 0xFF3C3C3C); - Gui.drawRect(midX-width/2+2, sr.getScaledHeight()*3/4-height/2+2, - midX+width/2-2, sr.getScaledHeight()*3/4+height/2-2, 0xFFC8C8C8);*/ - - int xLen = Minecraft.getMinecraft().fontRendererObj.getStringWidth("[X] Close"); - Minecraft.getMinecraft().fontRendererObj.drawString("[X] Close", midX + width / 2f - 3 - xLen, - topY + 3, 0xFFFF5555, false - ); - - if (notificationDisplayMillis > 0) { - Minecraft.getMinecraft().fontRendererObj.drawString((timeRemaining / 1000) + "s", midX - width / 2f + 3, - topY + 3, 0xFFaaaaaa, false - ); - } - - Utils.drawStringCentered(notificationLines.get(0), Minecraft.getMinecraft().fontRendererObj, - midX, topY + 4 + 5, false, -1 - ); - for (int i = 1; i < notificationLines.size(); i++) { - String line = notificationLines.get(i); - Utils.drawStringCentered(line, Minecraft.getMinecraft().fontRendererObj, - midX, topY + 4 + 5 + 2 + i * 10, false, -1 - ); - } - - Utils.pushGuiScale(-1); - } - } - - public static long lastGuiClosed = 0; - - /** - * When opening a GuiContainer, will reset the overlay and load the config. - * When closing a GuiContainer, will save the config. - * Also includes a dev feature used for automatically acquiring crafting information from the "Crafting Table" GUI. - */ - AtomicBoolean missingRecipe = new AtomicBoolean(false); - - @SubscribeEvent - public void onGuiOpen(GuiOpenEvent event) { - NEUApi.disableInventoryButtons = false; - - if ((Minecraft.getMinecraft().currentScreen instanceof GuiScreenElementWrapper || - Minecraft.getMinecraft().currentScreen instanceof GuiItemRecipe) && - event.gui == null && !(Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) && - System.currentTimeMillis() - NotEnoughUpdates.INSTANCE.lastOpenedGui < 500) { - NotEnoughUpdates.INSTANCE.lastOpenedGui = 0; - event.setCanceled(true); - return; - } - - if (!(event.gui instanceof GuiContainer) && Minecraft.getMinecraft().currentScreen != null) { - CalendarOverlay.setEnabled(false); - } - - if (Minecraft.getMinecraft().currentScreen != null) { - lastGuiClosed = System.currentTimeMillis(); - } - - neu.manager.auctionManager.customAH.lastGuiScreenSwitch = System.currentTimeMillis(); - BetterContainers.reset(); - inventoryLoaded = false; - inventoryLoadedTicks = 3; - - if (event.gui == null && neu.manager.auctionManager.customAH.isRenderOverAuctionView() && - !(Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)) { - event.gui = new CustomAHGui(); - } - - if (!(event.gui instanceof GuiChest || event.gui instanceof GuiEditSign)) { - neu.manager.auctionManager.customAH.setRenderOverAuctionView(false); - } else if (event.gui instanceof GuiChest && (neu.manager.auctionManager.customAH.isRenderOverAuctionView() || - Minecraft.getMinecraft().currentScreen instanceof CustomAHGui)) { - GuiChest chest = (GuiChest) event.gui; - ContainerChest container = (ContainerChest) chest.inventorySlots; - String containerName = container.getLowerChestInventory().getDisplayName().getUnformattedText(); - - neu.manager.auctionManager.customAH.setRenderOverAuctionView(containerName.trim().equals("Auction View") || - containerName.trim().equals("BIN Auction View") || containerName.trim().equals("Confirm Bid") || - containerName.trim().equals("Confirm Purchase")); - } - - //OPEN - if (Minecraft.getMinecraft().currentScreen == null - && event.gui instanceof GuiContainer) { - neu.overlay.reset(); - } - if (event.gui != null && NotEnoughUpdates.INSTANCE.config.hidden.dev) { - if (event.gui instanceof GuiChest) { - GuiChest eventGui = (GuiChest) event.gui; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - IInventory lower = cc.getLowerChestInventory(); - ses.schedule(() -> { - if (Minecraft.getMinecraft().currentScreen != event.gui) { - return; - } - if (lower.getStackInSlot(23).getDisplayName().endsWith("Crafting Table")) { - try { - ItemStack res = lower.getStackInSlot(25); - String resInternalname = neu.manager.getInternalNameForItem(res); - - if (lower.getStackInSlot(48) != null) { - String backName = null; - NBTTagCompound tag = lower.getStackInSlot(48).getTagCompound(); - if (tag.hasKey("display", 10)) { - NBTTagCompound nbttagcompound = tag.getCompoundTag("display"); - if (nbttagcompound.getTagId("Lore") == 9) { - NBTTagList nbttaglist1 = nbttagcompound.getTagList("Lore", 8); - backName = nbttaglist1.getStringTagAt(0); - } - } - - if (backName != null) { - String[] split = backName.split(" "); - if (split[split.length - 1].contains("Rewards")) { - String col = backName.substring( - split[0].length() + 1, - backName.length() - split[split.length - 1].length() - 1 - ); - - JsonObject json = neu.manager.getItemInformation().get(resInternalname); - json.addProperty("crafttext", "Requires: " + col); - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - "Added: " + resInternalname)); - neu.manager.writeJsonDefaultDir(json, resInternalname + ".json"); - neu.manager.loadItem(resInternalname); - } - } - } - - /*JsonArray arr = null; - File f = new File(neu.manager.configLocation, "missing.json"); - try(InputStream instream = new FileInputStream(f)) { - BufferedReader reader = new BufferedReader(new InputStreamReader(instream, StandardCharsets.UTF_8)); - JsonObject json = neu.manager.gson.fromJson(reader, JsonObject.class); - arr = json.getAsJsonArray("missing"); - } catch(IOException e) {} - try { - JsonObject json = new JsonObject(); - JsonArray newArr = new JsonArray(); - for(JsonElement e : arr) { - if(!e.getAsString().equals(resInternalname)) { - newArr.add(e); - } - } - json.add("missing", newArr); - neu.manager.writeJson(json, f); - } catch(IOException e) {}*/ - - - - /*JsonObject recipe = new JsonObject(); - - String[] x = {"1","2","3"}; - String[] y = {"A","B","C"}; - - for(int i=0; i<=18; i+=9) { - for(int j=0; j<3; j++) { - ItemStack stack = lower.getStackInSlot(10+i+j); - String internalname = ""; - if(stack != null) { - internalname = neu.manager.getInternalNameForItem(stack); - if(!neu.manager.getItemInformation().containsKey(internalname)) { - neu.manager.writeItemToFile(stack); - } - internalname += ":"+stack.stackSize; - } - recipe.addProperty(y[i/9]+x[j], internalname); - } - } - - JsonObject json = neu.manager.getJsonForItem(res); - json.add("recipe", recipe); - json.addProperty("internalname", resInternalname); - json.addProperty("clickcommand", "viewrecipe"); - json.addProperty("modver", NotEnoughUpdates.VERSION); - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname)); - neu.manager.writeJsonDefaultDir(json, resInternalname+".json"); - neu.manager.loadItem(resInternalname);*/ - } catch (Exception e) { - e.printStackTrace(); - } - } - }, 200, TimeUnit.MILLISECONDS); - } - } - } - - /*@SubscribeEvent - public void onPlayerInteract(EntityInteractEvent event) { - if(!event.isCanceled() && NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && - Minecraft.getMinecraft().thePlayer.isSneaking() && - Minecraft.getMinecraft().ingameGUI != null) { - if(event.target instanceof EntityPlayer) { - for(NetworkPlayerInfo info : Minecraft.getMinecraft().thePlayer.sendQueue.getPlayerInfoMap()) { - String name = Minecraft.getMinecraft().ingameGUI.getTabList().getPlayerName(info); - if(name.contains("Status: "+EnumChatFormatting.RESET+EnumChatFormatting.BLUE+"Guest")) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/trade " + event.target.getName()); - event.setCanceled(true); - break; - } - } - } - } - }*/ - - private IChatComponent processChatComponent(IChatComponent chatComponent) { - IChatComponent newComponent; - if (chatComponent instanceof ChatComponentText) { - ChatComponentText text = (ChatComponentText) chatComponent; - - newComponent = new ChatComponentText(processText(text.getUnformattedTextForChat())); - newComponent.setChatStyle(text.getChatStyle().createShallowCopy()); - - for (IChatComponent sibling : text.getSiblings()) { - newComponent.appendSibling(processChatComponent(sibling)); - } - } else if (chatComponent instanceof ChatComponentTranslation) { - ChatComponentTranslation trans = (ChatComponentTranslation) chatComponent; - - Object[] args = trans.getFormatArgs(); - Object[] newArgs = new Object[args.length]; - for (int i = 0; i < trans.getFormatArgs().length; i++) { - if (args[i] instanceof IChatComponent) { - newArgs[i] = processChatComponent((IChatComponent) args[i]); - } else { - newArgs[i] = args[i]; - } - } - newComponent = new ChatComponentTranslation(trans.getKey(), newArgs); - - for (IChatComponent sibling : trans.getSiblings()) { - newComponent.appendSibling(processChatComponent(sibling)); - } - } else { - newComponent = chatComponent.createCopy(); - } - - return newComponent; - } - - private String processText(String text) { - if (SBInfo.getInstance().getLocation() == null) return text; - if (!SBInfo.getInstance().getLocation().startsWith("mining_") && - !SBInfo.getInstance().getLocation().equals("crystal_hollows")) - return text; - - if (Minecraft.getMinecraft().thePlayer == null) return text; - if (!NotEnoughUpdates.INSTANCE.config.mining.drillFuelBar) return text; - - return Utils.trimIgnoreColour(text.replaceAll(EnumChatFormatting.DARK_GREEN + "\\S+ Drill Fuel", "")); - } - - private IChatComponent replaceSocialControlsWithPV(IChatComponent chatComponent) { - - if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 > 0 && chatComponent.getChatStyle() != null && - chatComponent.getChatStyle().getChatClickEvent() != null && - chatComponent.getChatStyle().getChatClickEvent().getAction() == ClickEvent.Action.RUN_COMMAND && - NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - if (chatComponent.getChatStyle().getChatClickEvent().getValue().startsWith("/socialoptions")) { - String username = chatComponent.getChatStyle().getChatClickEvent().getValue().substring(15); - if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 == 1) { - chatComponent.setChatStyle(Utils.createClickStyle( - ClickEvent.Action.RUN_COMMAND, - "/pv " + username, - "" + EnumChatFormatting.YELLOW + "Click to open " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD + - username + EnumChatFormatting.RESET + EnumChatFormatting.YELLOW + "'s profile in " + - EnumChatFormatting.DARK_PURPLE + EnumChatFormatting.BOLD + "NEU's" + EnumChatFormatting.RESET + - EnumChatFormatting.YELLOW + " profile viewer." - )); - return chatComponent; - } else if (NotEnoughUpdates.INSTANCE.config.misc.replaceSocialOptions1 == 2) { - chatComponent.setChatStyle(Utils.createClickStyle( - ClickEvent.Action.RUN_COMMAND, - "/ah " + username, - "" + EnumChatFormatting.YELLOW + "Click to open " + EnumChatFormatting.AQUA + EnumChatFormatting.BOLD + - username + EnumChatFormatting.RESET + EnumChatFormatting.YELLOW + "'s /ah page" - )); - return chatComponent; - } - } // wanted to add this for guild but guild uses uuid :sad: - } - return chatComponent; - } - - /** - * 1) When receiving "You are playing on profile" messages, will set the current profile. - * 2) When a /viewrecipe command fails (i.e. player does not have recipe unlocked, will open the custom recipe GUI) - * 3) Replaces lobby join notifications when streamer mode is active - */ - @SubscribeEvent(priority = EventPriority.LOW, receiveCanceled = true) - public void onGuiChat(ClientChatReceivedEvent e) { - if (e.type == 2) { - CrystalMetalDetectorSolver.process(e.message); - e.message = processChatComponent(e.message); - return; - } else if (e.type == 0) { - e.message = replaceSocialControlsWithPV(e.message); - } - - DungeonWin.onChatMessage(e); - - String r = null; - String unformatted = Utils.cleanColour(e.message.getUnformattedText()); - Matcher matcher = SLAYER_XP.matcher(unformatted); - if (unformatted.startsWith("You are playing on profile: ")) { - neu.manager.setCurrentProfile(unformatted - .substring("You are playing on profile: ".length()) - .split(" ")[0].trim()); - } else if (unformatted.startsWith("Your profile was changed to: ")) {//Your profile was changed to: - neu.manager.setCurrentProfile(unformatted - .substring("Your profile was changed to: ".length()) - .split(" ")[0].trim()); - } else if (unformatted.startsWith("Your new API key is ")) { - NotEnoughUpdates.INSTANCE.config.apiKey.apiKey = unformatted.substring("Your new API key is ".length()); - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + - "[NEU] API Key automatically configured")); - NotEnoughUpdates.INSTANCE.config.apiKey.apiKey = NotEnoughUpdates.INSTANCE.config.apiKey.apiKey.substring(0, 36); - } else if (unformatted.startsWith("Player List Info is now disabled!")) { - SBInfo.getInstance().hasNewTab = false; - } else if (unformatted.startsWith("Player List Info is now enabled!")) { - SBInfo.getInstance().hasNewTab = true; - } - if (e.message.getFormattedText().equals(EnumChatFormatting.RESET.toString() + - EnumChatFormatting.RED + "You haven't unlocked this recipe!" + EnumChatFormatting.RESET)) { - r = EnumChatFormatting.RED + "You haven't unlocked this recipe!"; - } else if (e.message.getFormattedText().startsWith(EnumChatFormatting.RESET.toString() + - EnumChatFormatting.RED + "Invalid recipe ")) { - r = ""; - } else if (unformatted.equals(" NICE! SLAYER BOSS SLAIN!")) { - SlayerOverlay.isSlain = true; - } else if (unformatted.equals(" SLAYER QUEST STARTED!")) { - SlayerOverlay.isSlain = false; - if (timeSinceLastBoss == 0) { - SlayerOverlay.timeSinceLastBoss = System.currentTimeMillis(); - } else { - timeSinceLastBoss2 = timeSinceLastBoss; - timeSinceLastBoss = System.currentTimeMillis(); - } - } else if (unformatted.startsWith(" RNGesus Meter:")) { - RNGMeter = unformatted.substring(" RNGesus Meter: -------------------- ".length()); - } else if (matcher.matches()) { - //matcher.group(1); - SlayerOverlay.slayerLVL = matcher.group(2); - if (!SlayerOverlay.slayerLVL.equals("9")) { - SlayerOverlay.slayerXp = matcher.group(3); - } else { - slayerXp = "maxed"; - } - } else if (unformatted.startsWith("Sending to server") || - (unformatted.startsWith("Your Slayer Quest has been cancelled!"))) { - SlayerOverlay.slayerQuest = false; - SlayerOverlay.unloadOverlayTimer = System.currentTimeMillis(); - } - if (e.message - .getFormattedText() - .contains(EnumChatFormatting.YELLOW + "Visit the Auction House to collect your item!")) { - if (NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.latestBid != null && - System.currentTimeMillis() - NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.latestBidMillis < 5000) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/viewauction " + - NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.niceAucId( - NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.latestBid)); - } - } - if (r != null) { - if (neu.manager.failViewItem(r)) { - e.setCanceled(true); - } - missingRecipe.set(true); - } - //System.out.println(e.message); - if (unformatted.startsWith("Sending to server") && - neu.isOnSkyblock() && NotEnoughUpdates.INSTANCE.config.misc.streamerMode && - e.message instanceof ChatComponentText) { - String m = e.message.getFormattedText(); - String m2 = StreamerMode.filterChat(e.message.getFormattedText()); - if (!m.equals(m2)) { - e.message = new ChatComponentText(m2); - } - } - if (unformatted.startsWith("You found ") && SBInfo.getInstance().getLocation() != null && - SBInfo.getInstance().getLocation().equals("crystal_hollows")) { - CrystalMetalDetectorSolver.reset(true); - } - if (unformatted.startsWith("[NPC] Keeper of ") | unformatted.startsWith("[NPC] Professor Robot: ") || - unformatted.startsWith(" ") || unformatted.startsWith("✦") || - unformatted.equals(" You've earned a Crystal Loot Bundle!")) - OverlayManager.crystalHollowOverlay.message(unformatted); - } - - public static boolean drawingGuiScreen = false; - - /** - * Sets hoverInv and focusInv variables, representing whether the NEUOverlay should render behind the inventory when - * (hoverInv == true) and whether mouse/kbd inputs shouldn't be sent to NEUOverlay (focusInv == true). - *

- * If hoverInv is true, will render the overlay immediately (resulting in the inventory being drawn over the GUI) - * If hoverInv is false, the overlay will render in #onGuiScreenDraw (resulting in the GUI being drawn over the inv) - *

- * All of this only matters if players are using gui scale auto which may result in the inventory being drawn - * over the various panes. - */ - @SubscribeEvent - public void onGuiBackgroundDraw(GuiScreenEvent.BackgroundDrawnEvent event) { - if (showNotificationOverInv) { - - renderNotification(); - - } - if ((shouldRenderOverlay(event.gui) || event.gui instanceof CustomAHGui) && neu.isOnSkyblock()) { - ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); - int width = scaledresolution.getScaledWidth(); - - boolean hoverPane = event.getMouseX() < width * neu.overlay.getInfoPaneOffsetFactor() || - event.getMouseX() > width * neu.overlay.getItemPaneOffsetFactor(); - - if (event.gui instanceof GuiContainer) { - try { - int xSize = ((GuiContainer) event.gui).xSize; - int ySize = ((GuiContainer) event.gui).ySize; - int guiLeft = ((GuiContainer) event.gui).guiLeft; - int guiTop = ((GuiContainer) event.gui).guiTop; - - hoverInv = event.getMouseX() > guiLeft && event.getMouseX() < guiLeft + xSize && - event.getMouseY() > guiTop && event.getMouseY() < guiTop + ySize; - - if (hoverPane) { - if (!hoverInv) focusInv = false; - } else { - focusInv = true; - } - } catch (NullPointerException npe) { - focusInv = !hoverPane; - } - } - if (event.gui instanceof GuiItemRecipe) { - GuiItemRecipe guiItemRecipe = ((GuiItemRecipe) event.gui); - hoverInv = event.getMouseX() > guiItemRecipe.guiLeft && - event.getMouseX() < guiItemRecipe.guiLeft + guiItemRecipe.xSize && - event.getMouseY() > guiItemRecipe.guiTop && event.getMouseY() < guiItemRecipe.guiTop + guiItemRecipe.ySize; - - if (hoverPane) { - if (!hoverInv) focusInv = false; - } else { - focusInv = true; - } - } - if (focusInv) { - try { - neu.overlay.render(hoverInv); - } catch (ConcurrentModificationException e) { - e.printStackTrace(); - } - GL11.glTranslatef(0, 0, 10); - } - if (hoverInv) { - renderDungeonChestOverlay(event.gui); - if (NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay) { - AccessoryBagOverlay.renderOverlay(); - } - } - } - - drawingGuiScreen = true; - } - - private boolean doInventoryButtons = false; - - @SubscribeEvent - public void onGuiScreenDrawPre(GuiScreenEvent.DrawScreenEvent.Pre event) { - doInventoryButtons = false; - - if (AuctionSearchOverlay.shouldReplace()) { - AuctionSearchOverlay.render(); - event.setCanceled(true); - return; - } - if (RancherBootOverlay.shouldReplace()) { - RancherBootOverlay.render(); - event.setCanceled(true); - return; - } - - String containerName = null; - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - GuiChest eventGui = (GuiChest) guiScreen; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - } - - if (GuiCustomEnchant.getInstance().shouldOverride(containerName)) { - GuiCustomEnchant.getInstance().render(event.renderPartialTicks); - event.setCanceled(true); - return; - } - - boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); - boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); - boolean customAhActive = - event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); - - if (storageOverlayActive) { - StorageOverlay.getInstance().render(); - event.setCanceled(true); - return; - } - - if (tradeWindowActive || customAhActive) { - event.setCanceled(true); - - ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); - int width = scaledResolution.getScaledWidth(); - int height = scaledResolution.getScaledHeight(); - - //Dark background - Utils.drawGradientRect(0, 0, width, height, -1072689136, -804253680); - - if (event.mouseX < width * neu.overlay.getWidthMult() / 3 || - event.mouseX > width - width * neu.overlay.getWidthMult() / 3) { - if (customAhActive) { - neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); - } else if (tradeWindowActive) { - TradeWindow.render(event.mouseX, event.mouseY); - } - neu.overlay.render(false); - } else { - neu.overlay.render(false); - if (customAhActive) { - neu.manager.auctionManager.customAH.drawScreen(event.mouseX, event.mouseY); - } else if (tradeWindowActive) { - TradeWindow.render(event.mouseX, event.mouseY); - } - } - } - - if (CalendarOverlay.isEnabled() || event.isCanceled()) return; - if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) - && event.gui instanceof GuiContainer) { - doInventoryButtons = true; - - int zOffset = 50; - - GlStateManager.translate(0, 0, zOffset); - - int xSize = ((GuiContainer) event.gui).xSize; - int ySize = ((GuiContainer) event.gui).ySize; - int guiLeft = ((GuiContainer) event.gui).guiLeft; - int guiTop = ((GuiContainer) event.gui).guiTop; - - if (!NEUApi.disableInventoryButtons) { - for (NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { - if (!button.isActive()) continue; - if (button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue; - - int x = guiLeft + button.x; - int y = guiTop + button.y; - if (button.anchorRight) { - x += xSize; - } - if (button.anchorBottom) { - y += ySize; - } - if (AccessoryBagOverlay.isInAccessoryBag()) { - if (x > guiLeft + xSize && x < guiLeft + xSize + 80 + 28 + 5 && y > guiTop - 18 && y < guiTop + 150) { - x += 80 + 28; - } - } - if (NEUOverlay.isRenderingArmorHud()) { - if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { - x -= 25; - } - } - if (NEUOverlay.isRenderingPetHud()) { - if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { - x -= 25; - } - } - - GlStateManager.color(1, 1, 1, 1f); - - GlStateManager.enableDepth(); - GlStateManager.enableAlpha(); - Minecraft.getMinecraft().getTextureManager().bindTexture(EDITOR); - Utils.drawTexturedRect(x, y, 18, 18, - button.backgroundIndex * 18 / 256f, (button.backgroundIndex * 18 + 18) / 256f, - 18 / 256f, 36 / 256f, GL11.GL_NEAREST - ); - - if (button.icon != null && !button.icon.trim().isEmpty()) { - GuiInvButtonEditor.renderIcon(button.icon, x + 1, y + 1); - } - } - } - GlStateManager.translate(0, 0, -zOffset); - } - } - - private static boolean shouldRenderOverlay(Gui gui) { - boolean validGui = gui instanceof GuiContainer || gui instanceof GuiItemRecipe; - if (gui instanceof GuiChest) { - GuiChest eventGui = (GuiChest) gui; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - String containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - if (containerName.trim().equals("Fast Travel")) { - validGui = false; - } - } - return validGui; - } - - private static final ResourceLocation EDITOR = new ResourceLocation("notenoughupdates:invbuttons/editor.png"); - private NEUConfig.InventoryButton buttonHovered = null; - private long buttonHoveredMillis = 0; - public static boolean disableCraftingText = false; - - /** - * Will draw the NEUOverlay over the inventory if focusInv == false. (z-translation of 300 is so that NEUOverlay - * will draw over Items in the inventory (which render at a z value of about 250)) - */ - @SubscribeEvent - public void onGuiScreenDrawPost(GuiScreenEvent.DrawScreenEvent.Post event) { - drawingGuiScreen = false; - disableCraftingText = false; - - String containerName = null; - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - GuiChest eventGui = (GuiChest) guiScreen; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - - if (GuiCustomEnchant.getInstance().shouldOverride(containerName)) - return; - } - - boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); - boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); - boolean customAhActive = - event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); - - if (!(tradeWindowActive || storageOverlayActive || customAhActive)) { - if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { - GlStateManager.pushMatrix(); - if (!focusInv) { - GL11.glTranslatef(0, 0, 300); - neu.overlay.render(hoverInv && focusInv); - GL11.glTranslatef(0, 0, -300); - } - GlStateManager.popMatrix(); - } - } - - if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock() && !hoverInv) { - renderDungeonChestOverlay(event.gui); - if (NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay) { - AccessoryBagOverlay.renderOverlay(); - } - } - - boolean hoveringButton = false; - if (!doInventoryButtons) return; - if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) && - event.gui instanceof GuiContainer) { - int xSize = ((GuiContainer) event.gui).xSize; - int ySize = ((GuiContainer) event.gui).ySize; - int guiLeft = ((GuiContainer) event.gui).guiLeft; - int guiTop = ((GuiContainer) event.gui).guiTop; - - if (!NEUApi.disableInventoryButtons) { - for (NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { - if (!button.isActive()) continue; - if (button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue; - - int x = guiLeft + button.x; - int y = guiTop + button.y; - if (button.anchorRight) { - x += xSize; - } - if (button.anchorBottom) { - y += ySize; - } - if (AccessoryBagOverlay.isInAccessoryBag()) { - if (x > guiLeft + xSize && x < guiLeft + xSize + 80 + 28 + 5 && y > guiTop - 18 && y < guiTop + 150) { - x += 80 + 28; - } - } - if (NEUOverlay.isRenderingArmorHud()) { - if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { - x -= 25; - } - } - if (NEUOverlay.isRenderingPetHud()) { - if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { - x -= 25; - } - } - - if (x - guiLeft >= 85 && x - guiLeft <= 115 && y - guiTop >= 4 && y - guiTop <= 25) { - disableCraftingText = true; - } - - if (event.mouseX >= x && event.mouseX <= x + 18 && - event.mouseY >= y && event.mouseY <= y + 18) { - hoveringButton = true; - long currentTime = System.currentTimeMillis(); - - if (buttonHovered != button) { - buttonHoveredMillis = currentTime; - buttonHovered = button; - } - - if (currentTime - buttonHoveredMillis > 600) { - String command = button.command.trim(); - if (!command.startsWith("/")) { - command = "/" + command; - } - - Utils.drawHoveringText(Lists.newArrayList("\u00a77" + command), event.mouseX, event.mouseY, - event.gui.width, event.gui.height, -1, Minecraft.getMinecraft().fontRendererObj - ); - } - } - } - } - } - if (!hoveringButton) buttonHovered = null; - - if (AuctionBINWarning.getInstance().shouldShow()) { - AuctionBINWarning.getInstance().render(); - } - } - - private void renderDungeonChestOverlay(GuiScreen gui) { - if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 3) return; - - if (gui instanceof GuiChest && NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc != 2) { - try { - int xSize = ((GuiContainer) gui).xSize; - int ySize = ((GuiContainer) gui).ySize; - int guiLeft = ((GuiContainer) gui).guiLeft; - int guiTop = ((GuiContainer) gui).guiTop; - - GuiChest eventGui = (GuiChest) gui; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - IInventory lower = cc.getLowerChestInventory(); - - ItemStack rewardChest = lower.getStackInSlot(31); - if (rewardChest != null && - rewardChest.getDisplayName().endsWith(EnumChatFormatting.GREEN + "Open Reward Chest")) { - int chestCost = 0; - try { - String line6 = Utils.cleanColour(neu.manager.getLoreFromNBT(rewardChest.getTagCompound())[6]); - StringBuilder cost = new StringBuilder(); - for (int i = 0; i < line6.length(); i++) { - char c = line6.charAt(i); - if ("0123456789".indexOf(c) >= 0) { - cost.append(c); - } - } - if (cost.length() > 0) { - chestCost = Integer.parseInt(cost.toString()); - } - } catch (Exception ignored) { - } - - String missingItem = null; - int totalValue = 0; - HashMap itemValues = new HashMap<>(); - for (int i = 0; i < 5; i++) { - ItemStack item = lower.getStackInSlot(11 + i); - String internal = neu.manager.getInternalNameForItem(item); - if (internal != null) { - internal = internal.replace("\u00CD", "I").replace("\u0130", "I"); - float bazaarPrice = -1; - JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal); - if (bazaarInfo != null && bazaarInfo.has("curr_sell")) { - bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat(); - } - if (bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000; - - float worth = -1; - if (bazaarPrice > 0) { - worth = bazaarPrice; - } else { - switch (NotEnoughUpdates.INSTANCE.config.dungeons.profitType) { - case 1: - worth = neu.manager.auctionManager.getItemAvgBin(internal); - break; - case 2: - JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal); - if (auctionInfo != null) { - if (auctionInfo.has("clean_price")) { - worth = (int) auctionInfo.get("clean_price").getAsFloat(); - } else { - worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); - } - } - break; - default: - worth = neu.manager.auctionManager.getLowestBin(internal); - } - if (worth <= 0) { - worth = neu.manager.auctionManager.getLowestBin(internal); - if (worth <= 0) { - worth = neu.manager.auctionManager.getItemAvgBin(internal); - if (worth <= 0) { - JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal); - if (auctionInfo != null) { - if (auctionInfo.has("clean_price")) { - worth = (int) auctionInfo.get("clean_price").getAsFloat(); - } else { - worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); - } - } - } - } - } - } - - if (worth > 0 && totalValue >= 0) { - totalValue += worth; - String display = item.getDisplayName(); - - if (display.contains("Enchanted Book")) { - NBTTagCompound tag = item.getTagCompound(); - if (tag != null && tag.hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - NBTTagCompound enchants = ea.getCompoundTag("enchantments"); - - int highestLevel = -1; - for (String enchname : enchants.getKeySet()) { - int level = enchants.getInteger(enchname); - if (level > highestLevel) { - display = EnumChatFormatting.BLUE + WordUtils.capitalizeFully( - enchname.replace("_", " ") - .replace("Ultimate", "") - .trim()) + " " + level; - } - } - } - } - - itemValues.put(display, worth); - } else { - if (totalValue != -1) { - missingItem = internal; - } - totalValue = -1; - } - } - } - - NumberFormat format = NumberFormat.getInstance(Locale.US); - String valueStringBIN1; - String valueStringBIN2; - if (totalValue >= 0) { - valueStringBIN1 = EnumChatFormatting.YELLOW + "Value (BIN): "; - valueStringBIN2 = EnumChatFormatting.GOLD + format.format(totalValue) + " coins"; - } else { - valueStringBIN1 = EnumChatFormatting.YELLOW + "Can't find BIN: "; - valueStringBIN2 = missingItem; - } - - int profitLossBIN = totalValue - chestCost; - - boolean kismetUsed = false; - // checking for kismet - Slot slot = (eventGui.inventorySlots.getSlot(50)); - if (slot.getHasStack()) { - String[] lore = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(slot.getStack().getTagCompound()); - for (String line : lore) { - if (line.contains("You already rerolled a chest!")) { - kismetUsed = true; - break; - } - } - } - int kismetPrice = neu.manager.auctionManager.getLowestBin("KISMET_FEATHER"); - String kismetStr = EnumChatFormatting.RED + format.format(kismetPrice) + " coins"; - if (neu.config.dungeons.useKismetOnDungeonProfit) - profitLossBIN = kismetUsed ? profitLossBIN - kismetPrice : profitLossBIN; - - String profitPrefix = EnumChatFormatting.DARK_GREEN.toString(); - String lossPrefix = EnumChatFormatting.RED.toString(); - String prefix = profitLossBIN >= 0 ? profitPrefix : lossPrefix; - - String plStringBIN; - if (profitLossBIN >= 0) { - plStringBIN = prefix + "+" + format.format(profitLossBIN) + " coins"; - } else { - plStringBIN = prefix + "-" + format.format(-profitLossBIN) + " coins"; - } - - if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 1 && !valueStringBIN2.equals(missingItem)) { - int w = Minecraft.getMinecraft().fontRendererObj.getStringWidth(plStringBIN); - GlStateManager.disableLighting(); - GlStateManager.translate(0, 0, 200); - Minecraft.getMinecraft().fontRendererObj.drawString(plStringBIN, guiLeft + xSize - 5 - w, guiTop + 5, - 0xffffffff, true - ); - GlStateManager.translate(0, 0, -200); - return; - } - - Minecraft.getMinecraft().getTextureManager().bindTexture(dungeon_chest_worth); - GL11.glColor4f(1, 1, 1, 1); - GlStateManager.disableLighting(); - Utils.drawTexturedRect(guiLeft + xSize + 4, guiTop, 180, 101, 0, 180 / 256f, 0, 101 / 256f, GL11.GL_NEAREST); - - Utils.renderAlignedString(valueStringBIN1, valueStringBIN2, - guiLeft + xSize + 4 + 10, guiTop + 14, 160 - ); - if (neu.config.dungeons.useKismetOnDungeonProfit && kismetUsed) { - Utils.renderAlignedString(EnumChatFormatting.YELLOW + "Kismet Feather: ", kismetStr, - guiLeft + xSize + 4 + 10, guiTop + 24, 160 - ); - } - if (totalValue >= 0) { - Utils.renderAlignedString( - EnumChatFormatting.YELLOW + "Profit/Loss: ", - plStringBIN, - guiLeft + xSize + 4 + 10, - guiTop + (neu.config.dungeons.useKismetOnDungeonProfit ? (kismetUsed ? 34 : 24) : 24), - 160 - ); - } - - int index = 0; - for (Map.Entry entry : itemValues.entrySet()) { - Utils.renderAlignedString( - entry.getKey(), - prefix + - format.format(entry.getValue().intValue()), - guiLeft + xSize + 4 + 10, - guiTop + (neu.config.dungeons.useKismetOnDungeonProfit ? (kismetUsed ? 39 : 29) : 29) + (++index) * 10, - 160 - ); - } - } - } catch (Exception e) { - e.printStackTrace(); - } - } - } - - public void drawStringShadow(String str, float x, float y, int len) { - for (int xOff = -2; xOff <= 2; xOff++) { - for (int yOff = -2; yOff <= 2; yOff++) { - if (Math.abs(xOff) != Math.abs(yOff)) { - Utils.drawStringCenteredScaledMaxWidth(Utils.cleanColourNotModifiers(str), - Minecraft.getMinecraft().fontRendererObj, - x + xOff / 2f, y + yOff / 2f, false, len, - new Color(20, 20, 20, 100 / Math.max(Math.abs(xOff), Math.abs(yOff))).getRGB() - ); - } - } - } - - Utils.drawStringCenteredScaledMaxWidth(str, - Minecraft.getMinecraft().fontRendererObj, - x, y, false, len, - new Color(64, 64, 64, 255).getRGB() - ); - } - - /** - * Sends a mouse event to NEUOverlay if the inventory isn't hovered AND focused. - * Will also cancel the event if if NEUOverlay#mouseInput returns true. - */ - @SubscribeEvent(priority = EventPriority.LOW) - public void onGuiScreenMouse(GuiScreenEvent.MouseInputEvent.Pre event) { - if (Mouse.getEventButtonState() && StorageManager.getInstance().onAnyClick()) { - event.setCanceled(true); - return; - } - - final ScaledResolution scaledresolution = new ScaledResolution(Minecraft.getMinecraft()); - final int scaledWidth = scaledresolution.getScaledWidth(); - final int scaledHeight = scaledresolution.getScaledHeight(); - int mouseX = Mouse.getX() * scaledWidth / Minecraft.getMinecraft().displayWidth; - int mouseY = scaledHeight - Mouse.getY() * scaledHeight / Minecraft.getMinecraft().displayHeight - 1; - - if (AuctionBINWarning.getInstance().shouldShow()) { - AuctionBINWarning.getInstance().mouseInput(mouseX, mouseY); - event.setCanceled(true); - return; - } - - if (!event.isCanceled()) { - Utils.scrollTooltip(Mouse.getEventDWheel()); - } - if (AuctionSearchOverlay.shouldReplace()) { - AuctionSearchOverlay.mouseEvent(); - event.setCanceled(true); - return; - } - if (RancherBootOverlay.shouldReplace()) { - RancherBootOverlay.mouseEvent(); - event.setCanceled(true); - return; - } - - String containerName = null; - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - GuiChest eventGui = (GuiChest) guiScreen; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - containerName = cc.getLowerChestInventory().getDisplayName().getUnformattedText(); - if (containerName.contains(" Profile") && BetterContainers.profileViewerStackIndex != -1 && - eventGui.isMouseOverSlot(cc.inventorySlots.get(BetterContainers.profileViewerStackIndex), mouseX, mouseY) && - Mouse.getEventButton() >= 0) { - event.setCanceled(true); - if (Mouse.getEventButtonState() && eventGui.inventorySlots.inventorySlots.get(22).getStack() != null && - eventGui.inventorySlots.inventorySlots.get(22).getStack().getTagCompound() != null) { - NBTTagCompound tag = eventGui.inventorySlots.inventorySlots.get(22).getStack().getTagCompound(); - if (tag.hasKey("SkullOwner") && tag.getCompoundTag("SkullOwner").hasKey("Name")) { - String username = tag.getCompoundTag("SkullOwner").getString("Name"); - Utils.playPressSound(); - ViewProfileCommand.RUNNABLE.accept(new String[]{username}); - } - } - } - } - - if (GuiCustomEnchant.getInstance().shouldOverride(containerName) && - GuiCustomEnchant.getInstance().mouseInput(mouseX, mouseY)) { - event.setCanceled(true); - return; - } - - boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); - boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); - boolean customAhActive = - event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); - - if (storageOverlayActive) { - if (StorageOverlay.getInstance().mouseInput(mouseX, mouseY)) { - event.setCanceled(true); - } - return; - } - - if (tradeWindowActive || customAhActive) { - event.setCanceled(true); - if (customAhActive) { - neu.manager.auctionManager.customAH.handleMouseInput(); - } else if (tradeWindowActive) { - TradeWindow.handleMouseInput(); - } - neu.overlay.mouseInput(); - return; - } - - if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { - if (!NotEnoughUpdates.INSTANCE.config.accessoryBag.enableOverlay || !AccessoryBagOverlay.mouseClick()) { - if (!(hoverInv && focusInv)) { - if (neu.overlay.mouseInput()) { - event.setCanceled(true); - } - } else { - neu.overlay.mouseInputInv(); - } - } - } - if (event.isCanceled()) return; - if (!doInventoryButtons) return; - if (NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && shouldRenderOverlay(event.gui) && - Mouse.getEventButton() >= 0 - && event.gui instanceof GuiContainer) { - int xSize = ((GuiContainer) event.gui).xSize; - int ySize = ((GuiContainer) event.gui).ySize; - int guiLeft = ((GuiContainer) event.gui).guiLeft; - int guiTop = ((GuiContainer) event.gui).guiTop; - if (!NEUApi.disableInventoryButtons) { - for (NEUConfig.InventoryButton button : NotEnoughUpdates.INSTANCE.config.hidden.inventoryButtons) { - if (!button.isActive()) continue; - if (button.playerInvOnly && !(event.gui instanceof GuiInventory)) continue; - - int x = guiLeft + button.x; - int y = guiTop + button.y; - if (button.anchorRight) { - x += xSize; - } - if (button.anchorBottom) { - y += ySize; - } - if (AccessoryBagOverlay.isInAccessoryBag()) { - if (x > guiLeft + xSize && x < guiLeft + xSize + 80 + 28 + 5 && y > guiTop - 18 && y < guiTop + 150) { - x += 80 + 28; - } - } - if (NEUOverlay.isRenderingArmorHud()) { - if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop && y < guiTop + 84) { - x -= 25; - } - } - if (NEUOverlay.isRenderingPetHud()) { - if (x < guiLeft + xSize - 150 && x > guiLeft + xSize - 200 && y > guiTop + 60 && y < guiTop + 120) { - x -= 25; - } - } - - if (mouseX >= x && mouseX <= x + 18 && mouseY >= y && mouseY <= y + 18) { - if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { - int clickType = NotEnoughUpdates.INSTANCE.config.inventoryButtons.clickType; - if ((clickType == 0 && Mouse.getEventButtonState()) || (clickType == 1 && !Mouse.getEventButtonState())) { - String command = button.command.trim(); - if (!command.startsWith("/")) { - command = "/" + command; - } - if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, command) == 0) { - NotEnoughUpdates.INSTANCE.sendChatMessage(command); - } - } - } else { - event.setCanceled(true); - } - return; - } - } - } - } - } - - ScheduledExecutorService ses = Executors.newScheduledThreadPool(1); - - JsonObject essenceJson = new JsonObject(); - - /** - * Sends a kbd event to NEUOverlay, cancelling if NEUOverlay#keyboardInput returns true. - * Also includes a dev function used for creating custom named json files with recipes. - */ - @SubscribeEvent - public void onGuiScreenKeyboard(GuiScreenEvent.KeyboardInputEvent.Pre event) { - if (AuctionBINWarning.getInstance().shouldShow()) { - AuctionBINWarning.getInstance().keyboardInput(); - event.setCanceled(true); - return; - } - - if (AuctionSearchOverlay.shouldReplace()) { - AuctionSearchOverlay.keyEvent(); - event.setCanceled(true); - return; - } - if (RancherBootOverlay.shouldReplace()) { - RancherBootOverlay.keyEvent(); - event.setCanceled(true); - return; - } - - String containerName = null; - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - - if (guiScreen instanceof GuiChest) { - containerName = ((ContainerChest) ((GuiChest) guiScreen).inventorySlots) - .getLowerChestInventory() - .getDisplayName() - .getUnformattedText(); - } - - if (GuiCustomEnchant.getInstance().shouldOverride(containerName) && - GuiCustomEnchant.getInstance().keyboardInput()) { - event.setCanceled(true); - return; - } - - boolean tradeWindowActive = TradeWindow.tradeWindowActive(containerName); - boolean storageOverlayActive = StorageManager.getInstance().shouldRenderStorageOverlay(containerName); - boolean customAhActive = - event.gui instanceof CustomAHGui || neu.manager.auctionManager.customAH.isRenderOverAuctionView(); - - if (storageOverlayActive) { - if (StorageOverlay.getInstance().keyboardInput()) { - event.setCanceled(true); - return; - } - } - - if (tradeWindowActive || customAhActive) { - if (customAhActive) { - if (neu.manager.auctionManager.customAH.keyboardInput()) { - event.setCanceled(true); - Minecraft.getMinecraft().dispatchKeypresses(); - } else if (neu.overlay.keyboardInput(focusInv)) { - event.setCanceled(true); - } - } else if (tradeWindowActive) { - TradeWindow.keyboardInput(); - if (Keyboard.getEventKey() != Keyboard.KEY_ESCAPE) { - event.setCanceled(true); - Minecraft.getMinecraft().dispatchKeypresses(); - neu.overlay.keyboardInput(focusInv); - } - } - return; - } - - if (shouldRenderOverlay(event.gui) && neu.isOnSkyblock()) { - if (neu.overlay.keyboardInput(focusInv)) { - event.setCanceled(true); - } - } - if (NotEnoughUpdates.INSTANCE.config.hidden.dev && NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing && - Minecraft.getMinecraft().theWorld != null && - Keyboard.getEventKey() == Keyboard.KEY_N && Keyboard.getEventKeyState()) { - GuiScreen gui = Minecraft.getMinecraft().currentScreen; - if (gui instanceof GuiChest) { - GuiChest eventGui = (GuiChest) event.gui; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - IInventory lower = cc.getLowerChestInventory(); - - if (!lower.getDisplayName().getUnformattedText().endsWith("Essence")) return; - - for (int i = 0; i < lower.getSizeInventory(); i++) { - ItemStack stack = lower.getStackInSlot(i); - - String internalname = neu.manager.getInternalNameForItem(stack); - if (internalname != null) { - String[] lore = neu.manager.getLoreFromNBT(stack.getTagCompound()); - - for (String line : lore) { - if (line.contains(":") && (line.startsWith("\u00A77Upgrade to") || - line.startsWith("\u00A77Convert to Dungeon Item"))) { - String[] split = line.split(":"); - String after = Utils.cleanColour(split[1]); - StringBuilder costS = new StringBuilder(); - for (char c : after.toCharArray()) { - if (c >= '0' && c <= '9') { - costS.append(c); - } - } - int cost = Integer.parseInt(costS.toString()); - String[] afterSplit = after.split(" "); - String type = afterSplit[afterSplit.length - 2]; - - if (!essenceJson.has(internalname)) { - essenceJson.add(internalname, new JsonObject()); - } - JsonObject obj = essenceJson.get(internalname).getAsJsonObject(); - obj.addProperty("type", type); - - if (line.startsWith("\u00A77Convert to Dungeon Item")) { - obj.addProperty("dungeonize", cost); - } else if (line.startsWith("\u00A77Upgrade to")) { - int stars = 0; - for (char c : line.toCharArray()) { - if (c == '\u272A') stars++; - } - if (stars > 0) { - obj.addProperty(stars + "", cost); - } - } - } - } - } - } - System.out.println(essenceJson); - } - } - if (NotEnoughUpdates.INSTANCE.config.hidden.dev && NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing && - Minecraft.getMinecraft().theWorld != null && - Keyboard.getEventKey() == Keyboard.KEY_O && Keyboard.getEventKeyState()) { - GuiScreen gui = Minecraft.getMinecraft().currentScreen; - if (gui instanceof GuiChest) { - GuiChest eventGui = (GuiChest) event.gui; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - IInventory lower = cc.getLowerChestInventory(); - - if (lower.getStackInSlot(23) != null && - lower.getStackInSlot(23).getDisplayName().endsWith("Crafting Table")) { - ItemStack res = lower.getStackInSlot(25); - String resInternalname = neu.manager.getInternalNameForItem(res); - JTextField tf = new JTextField(); - tf.setText(resInternalname); - tf.addAncestorListener(new RequestFocusListener()); - JOptionPane.showOptionDialog(null, - tf, - "Enter Name:", - JOptionPane.NO_OPTION, - JOptionPane.PLAIN_MESSAGE, - null, new String[]{"Enter"}, "Enter" - ); - resInternalname = tf.getText(); - if (resInternalname.trim().length() == 0) { - return; - } - - JsonObject recipe = new JsonObject(); - - String[] x = {"1", "2", "3"}; - String[] y = {"A", "B", "C"}; - - for (int i = 0; i <= 18; i += 9) { - for (int j = 0; j < 3; j++) { - ItemStack stack = lower.getStackInSlot(10 + i + j); - String internalname = ""; - if (stack != null) { - internalname = neu.manager.getInternalNameForItem(stack); - if (!neu.manager.getItemInformation().containsKey(internalname)) { - neu.manager.writeItemToFile(stack); - } - internalname += ":" + stack.stackSize; - } - recipe.addProperty(y[i / 9] + x[j], internalname); - } - } - - JsonObject json = neu.manager.getJsonForItem(res); - json.add("recipe", recipe); - json.addProperty("internalname", resInternalname); - json.addProperty("clickcommand", "viewrecipe"); - json.addProperty("modver", NotEnoughUpdates.VERSION); - try { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Added: " + resInternalname)); - neu.manager.writeJsonDefaultDir(json, resInternalname + ".json"); - neu.manager.loadItem(resInternalname); - } catch (IOException ignored) { - } - } - } - } - } - - private final HashSet percentStats = new HashSet<>(); - - { - percentStats.add("bonus_attack_speed"); - percentStats.add("crit_damage"); - percentStats.add("crit_chance"); - percentStats.add("sea_creature_chance"); - percentStats.add("ability_damage"); - } - - private String currentRarity = "COMMON"; - private boolean showReforgeStoneStats = true; - private boolean pressedArrowLast = false; - private boolean pressedShiftLast = false; - - private boolean copied = false; - - //just to try and optimize it a bit - private int sbaloaded = -1; - - private boolean isSbaloaded() { - if (sbaloaded == -1) { - if (Loader.isModLoaded("skyblockaddons")) { - sbaloaded = 1; - } else { - sbaloaded = 0; - } - } - return sbaloaded == 1; - } - - @SubscribeEvent(priority = EventPriority.LOW) - public void onItemTooltipLow(ItemTooltipEvent event) { - if (!NotEnoughUpdates.INSTANCE.isOnSkyblock()) return; - - String internalname = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack); - if (internalname == null) { - onItemToolTipInternalNameNull(event); - return; - } - - boolean hasEnchantments = - event.itemStack.getTagCompound().getCompoundTag("ExtraAttributes").hasKey("enchantments", 10); - Set enchantIds = new HashSet<>(); - if (hasEnchantments) - enchantIds = - event.itemStack.getTagCompound().getCompoundTag("ExtraAttributes").getCompoundTag("enchantments").getKeySet(); - - JsonObject enchantsConst = Constants.ENCHANTS; - JsonArray allItemEnchs = null; - Set ignoreFromPool = new HashSet<>(); - if (enchantsConst != null && hasEnchantments && NotEnoughUpdates.INSTANCE.config.tooltipTweaks.missingEnchantList) { - try { - JsonArray enchantPools = enchantsConst.get("enchant_pools").getAsJsonArray(); - for (JsonElement element : enchantPools) { - Set currentPool = new HashSet<>(); - for (JsonElement poolElement : element.getAsJsonArray()) { - String poolS = poolElement.getAsString(); - currentPool.add(poolS); - } - for (JsonElement poolElement : element.getAsJsonArray()) { - String poolS = poolElement.getAsString(); - if (enchantIds.contains(poolS)) { - ignoreFromPool.addAll(currentPool); - break; - } - } - } - - JsonObject enchantsObj = enchantsConst.get("enchants").getAsJsonObject(); - NBTTagCompound tag = event.itemStack.getTagCompound(); - if (tag != null) { - NBTTagCompound display = tag.getCompoundTag("display"); - if (display.hasKey("Lore", 9)) { - NBTTagList list = display.getTagList("Lore", 8); - out: - for (int i = list.tagCount(); i >= 0; i--) { - String line = list.getStringTagAt(i); - for (int j = 0; j < Utils.rarityArrC.length; j++) { - for (Map.Entry entry : enchantsObj.entrySet()) { - if (line.contains(Utils.rarityArrC[j] + " " + entry.getKey()) || - line.contains(Utils.rarityArrC[j] + " DUNGEON " + entry.getKey())) { - allItemEnchs = entry.getValue().getAsJsonArray(); - break out; - } - } - } - } - } - } - } catch (Exception ignored) { - } - } - - boolean gotToEnchants = false; - boolean passedEnchants = false; - - boolean dungeonProfit = false; - int index = 0; - List newTooltip = new ArrayList<>(); - - for (String line : event.toolTip) { - if (line.endsWith(EnumChatFormatting.DARK_GRAY + "Reforge Stone") && - NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showReforgeStats) { - JsonObject reforgeStones = Constants.REFORGESTONES; - - if (reforgeStones != null && reforgeStones.has(internalname)) { - boolean shift = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); - if (!pressedShiftLast && shift) { - showReforgeStoneStats = !showReforgeStoneStats; - } - pressedShiftLast = shift; - - newTooltip.add(line); - newTooltip.add(""); - if (!showReforgeStoneStats) { - newTooltip.add(EnumChatFormatting.DARK_GRAY + "[Press SHIFT to show extra info]"); - } else { - newTooltip.add(EnumChatFormatting.DARK_GRAY + "[Press SHIFT to hide extra info]"); - } - - JsonObject reforgeInfo = reforgeStones.get(internalname).getAsJsonObject(); - JsonArray requiredRaritiesArray = reforgeInfo.get("requiredRarities").getAsJsonArray(); - - if (showReforgeStoneStats && requiredRaritiesArray.size() > 0) { - String reforgeName = Utils.getElementAsString(reforgeInfo.get("reforgeName"), ""); - - String[] requiredRarities = new String[requiredRaritiesArray.size()]; - for (int i = 0; i < requiredRaritiesArray.size(); i++) { - requiredRarities[i] = requiredRaritiesArray.get(i).getAsString(); - } - - int rarityIndex = requiredRarities.length - 1; - String rarity = requiredRarities[rarityIndex]; - for (int i = 0; i < requiredRarities.length; i++) { - String rar = requiredRarities[i]; - if (rar.equalsIgnoreCase(currentRarity)) { - rarity = rar; - rarityIndex = i; - break; - } - } - - boolean left = Keyboard.isKeyDown(Keyboard.KEY_LEFT); - boolean right = Keyboard.isKeyDown(Keyboard.KEY_RIGHT); - if (!pressedArrowLast && (left || right)) { - if (left) { - rarityIndex--; - } else if (right) { - rarityIndex++; - } - if (rarityIndex < 0) rarityIndex = 0; - if (rarityIndex >= requiredRarities.length) rarityIndex = requiredRarities.length - 1; - currentRarity = requiredRarities[rarityIndex]; - rarity = currentRarity; - } - pressedArrowLast = left || right; - - JsonElement statsE = reforgeInfo.get("reforgeStats"); - - String rarityFormatted = Utils.rarityArrMap.getOrDefault(rarity, rarity); - - JsonElement reforgeAbilityE = reforgeInfo.get("reforgeAbility"); - String reforgeAbility = null; - if (reforgeAbilityE != null) { - if (reforgeAbilityE.isJsonPrimitive() && reforgeAbilityE.getAsJsonPrimitive().isString()) { - reforgeAbility = Utils.getElementAsString(reforgeInfo.get("reforgeAbility"), ""); - - } else if (reforgeAbilityE.isJsonObject()) { - if (reforgeAbilityE.getAsJsonObject().has(rarity)) { - reforgeAbility = reforgeAbilityE.getAsJsonObject().get(rarity).getAsString(); - } - } - } - - if (reforgeAbility != null && !reforgeAbility.isEmpty()) { - String text = EnumChatFormatting.BLUE + (reforgeName.isEmpty() ? "Bonus: " : reforgeName + " Bonus: ") + - EnumChatFormatting.GRAY + reforgeAbility; - boolean first = true; - for (String s : Minecraft.getMinecraft().fontRendererObj.listFormattedStringToWidth(text, 150)) { - newTooltip.add((first ? "" : " ") + s); - first = false; - } - newTooltip.add(""); - } - - newTooltip.add(EnumChatFormatting.BLUE + "Stats for " + rarityFormatted + - "\u00a79: [\u00a7l\u00a7m< \u00a79Switch\u00a7l\u27a1\u00a79]"); - - if (statsE != null && statsE.isJsonObject()) { - JsonObject stats = statsE.getAsJsonObject(); - - JsonElement statsRarE = stats.get(rarity); - if (statsRarE != null && statsRarE.isJsonObject()) { - - JsonObject statsRar = statsRarE.getAsJsonObject(); - - TreeSet> sorted = new TreeSet<>(Map.Entry.comparingByKey()); - sorted.addAll(statsRar.entrySet()); - - for (Map.Entry entry : sorted) { - if (entry.getValue().isJsonPrimitive() && ((JsonPrimitive) entry.getValue()).isNumber()) { - float statNumF = entry.getValue().getAsFloat(); - String statNumS; - if (statNumF % 1 == 0) { - statNumS = String.valueOf(Math.round(statNumF)); - } else { - statNumS = Utils.floatToString(statNumF, 1); - } - String reforgeNamePretty = WordUtils.capitalizeFully(entry.getKey().replace("_", " ")); - String text = - EnumChatFormatting.GRAY + reforgeNamePretty + ": " + EnumChatFormatting.GREEN + "+" + statNumS; - if (percentStats.contains(entry.getKey())) { - text += "%"; - } - newTooltip.add(" " + text); - } - } - } - } - - JsonElement reforgeCostsE = reforgeInfo.get("reforgeCosts"); - int reforgeCost = -1; - if (reforgeCostsE != null) { - if (reforgeCostsE.isJsonPrimitive() && reforgeCostsE.getAsJsonPrimitive().isNumber()) { - reforgeCost = (int) Utils.getElementAsFloat(reforgeInfo.get("reforgeAbility"), -1); - - } else if (reforgeCostsE.isJsonObject()) { - if (reforgeCostsE.getAsJsonObject().has(rarity)) { - reforgeCost = (int) Utils.getElementAsFloat(reforgeCostsE.getAsJsonObject().get(rarity), -1); - } - } - } - - if (reforgeCost >= 0) { - String text = EnumChatFormatting.BLUE + "Apply Cost: " + EnumChatFormatting.GOLD + - NumberFormat.getNumberInstance().format(reforgeCost) + " coins"; - newTooltip.add(""); - newTooltip.add(text); - } - - } - - continue; - } - - } else if (line.contains("\u00A7cR\u00A76a\u00A7ei\u00A7an\u00A7bb\u00A79o\u00A7dw\u00A79 Rune")) { - line = line.replace( - "\u00A7cR\u00A76a\u00A7ei\u00A7an\u00A7bb\u00A79o\u00A7dw\u00A79 Rune", - Utils.chromaString("Rainbow Rune", index, false) + EnumChatFormatting.BLUE - ); - } else if (hasEnchantments) { - if (Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && - NotEnoughUpdates.INSTANCE.config.tooltipTweaks.missingEnchantList) { - boolean lineHasEnch = false; - for (String s : enchantIds) { - String enchantName = WordUtils.capitalizeFully(s.replace("_", " ")); - if (line.contains(enchantName)) { - lineHasEnch = true; - break; - } - } - if (lineHasEnch) { - gotToEnchants = true; - } else { - if (gotToEnchants && !passedEnchants && Utils.cleanColour(line).trim().length() == 0) { - if (enchantsConst != null && allItemEnchs != null) { - List missing = new ArrayList<>(); - for (JsonElement enchIdElement : allItemEnchs) { - String enchId = enchIdElement.getAsString(); - if (!enchId.startsWith("ultimate_") && !ignoreFromPool.contains(enchId) && - !enchantIds.contains(enchId)) { - missing.add(enchId); - } - } - if (!missing.isEmpty()) { - newTooltip.add(""); - StringBuilder currentLine = - new StringBuilder(EnumChatFormatting.RED + "Missing: " + EnumChatFormatting.GRAY); - for (int i = 0; i < missing.size(); i++) { - String enchName = WordUtils.capitalizeFully(missing.get(i).replace("_", " ")); - if (currentLine.length() != 0 && - (Utils.cleanColour(currentLine.toString()).length() + enchName.length()) > 40) { - newTooltip.add(currentLine.toString()); - currentLine = new StringBuilder(); - } - if (currentLine.length() != 0 && i != 0) { - currentLine.append(", ").append(enchName); - } else { - currentLine.append(EnumChatFormatting.GRAY).append(enchName); - } - } - if (currentLine.length() != 0) { - newTooltip.add(currentLine.toString()); - } - } - } - passedEnchants = true; - } - } - } - for (String op : NotEnoughUpdates.INSTANCE.config.hidden.enchantColours) { - List colourOps = GuiEnchantColour.splitter.splitToList(op); - String enchantName = GuiEnchantColour.getColourOpIndex(colourOps, 0); - String comparator = GuiEnchantColour.getColourOpIndex(colourOps, 1); - String comparison = GuiEnchantColour.getColourOpIndex(colourOps, 2); - String colourCode = GuiEnchantColour.getColourOpIndex(colourOps, 3); - String modifier = GuiEnchantColour.getColourOpIndex(colourOps, 4); - - int modifierI = GuiEnchantColour.getIntModifier(modifier); - - if (enchantName.length() == 0) continue; - if (comparator.length() == 0) continue; - if (comparison.length() == 0) continue; - if (colourCode.length() == 0) continue; - - int comparatorI = ">=<".indexOf(comparator.charAt(0)); - - int levelToFind = -1; - try { - levelToFind = Integer.parseInt(comparison); - } catch (Exception e) { - continue; - } - - if (comparatorI < 0) continue; - String regexText = "0123456789abcdefz"; - if (isSbaloaded()) { - regexText = regexText + "Z"; - } - - if (regexText.indexOf(colourCode.charAt(0)) < 0) continue; - - //item_lore = item_lore.replaceAll("\\u00A79("+lvl4Max+" IV)", EnumChatFormatting.DARK_PURPLE+"$1"); - //9([a-zA-Z ]+?) ([0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X))(,|$) - Pattern pattern; - try { - pattern = Pattern.compile("(\\u00A79|\\u00A7(9|l)\\u00A7d\\u00A7l)(?" + enchantName + ") " + - "(?[0-9]+|(I|II|III|IV|V|VI|VII|VIII|IX|X|XI|XII|XIII|XIV|XV|XVI|XVII|XVIII|XIX|XX))((\\u00A79)?,|( \\u00A78(?:,?[0-9]+)*)?$)"); - } catch (Exception e) { - continue; - } //malformed regex - Matcher matcher = pattern.matcher(line); - int matchCount = 0; - while (matcher.find() && matchCount < 5) { - if (Utils.cleanColour(matcher.group("enchantName")).startsWith(" ")) continue; - - matchCount++; - int level = -1; - String levelStr = matcher.group("level"); - if (levelStr == null) continue; - try { - level = Integer.parseInt(levelStr); - } catch (Exception e) { - switch (levelStr) { - case "I": - level = 1; - break; - case "II": - level = 2; - break; - case "III": - level = 3; - break; - case "IV": - level = 4; - break; - case "V": - level = 5; - break; - case "VI": - level = 6; - break; - case "VII": - level = 7; - break; - case "VIII": - level = 8; - break; - case "IX": - level = 9; - break; - case "X": - level = 10; - break; - case "XI": - level = 11; - break; - case "XII": - level = 12; - break; - case "XIII": - level = 13; - break; - case "XIV": - level = 14; - break; - case "XV": - level = 15; - break; - case "XVI": - level = 16; - break; - case "XVII": - level = 17; - break; - case "XVIII": - level = 18; - break; - case "XIX": - level = 19; - break; - case "XX": - level = 20; - break; - } - } - boolean matches = false; - if (level > 0) { - switch (comparator) { - case ">": - matches = level > levelToFind; - break; - case "=": - matches = level == levelToFind; - break; - case "<": - matches = level < levelToFind; - break; - } - } - if (matches) { - String enchantText = matcher.group("enchantName"); - StringBuilder extraModifiersBuilder = new StringBuilder(); - - if ((modifierI & GuiEnchantColour.BOLD_MODIFIER) != 0) { - extraModifiersBuilder.append(EnumChatFormatting.BOLD); - } - if ((modifierI & GuiEnchantColour.ITALIC_MODIFIER) != 0) { - extraModifiersBuilder.append(EnumChatFormatting.ITALIC); - } - if ((modifierI & GuiEnchantColour.UNDERLINE_MODIFIER) != 0) { - extraModifiersBuilder.append(EnumChatFormatting.UNDERLINE); - } - if ((modifierI & GuiEnchantColour.OBFUSCATED_MODIFIER) != 0) { - extraModifiersBuilder.append(EnumChatFormatting.OBFUSCATED); - } - if ((modifierI & GuiEnchantColour.STRIKETHROUGH_MODIFIER) != 0) { - extraModifiersBuilder.append(EnumChatFormatting.STRIKETHROUGH); - } - - String extraMods = extraModifiersBuilder.toString(); - - if (!colourCode.equals("z")) { - line = line.replace( - "\u00A79" + enchantText, - "\u00A7" + colourCode + extraMods + enchantText - ); - line = line.replace( - "\u00A79\u00A7d\u00A7l" + enchantText, - "\u00A7" + colourCode + extraMods + enchantText - ); - line = line.replace( - "\u00A7l\u00A7d\u00A7l" + enchantText, - "\u00A7" + colourCode + extraMods + enchantText - ); - } else { - int offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll( - "\\u00A79" + enchantText + ".*", "")); - line = - line.replace("\u00A79" + enchantText, Utils.chromaString(enchantText, offset / 12f + index, false)); - - offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll( - "\\u00A79\\u00A7d\\u00A7l" + enchantText + ".*", "")); - line = line.replace("\u00A79\u00A7d\u00A7l" + enchantText, Utils.chromaString(enchantText, - offset / 12f + index, true - )); - offset = Minecraft.getMinecraft().fontRendererObj.getStringWidth(line.replaceAll( - "\\u00A7l\\u00A7d\\u00A7l" + enchantText + ".*", "")); - line = line.replace("\u00A7l\u00A7d\u00A7l" + enchantText, Utils.chromaString(enchantText, - offset / 12f + index, true - )); - } - } - } - } - } - - newTooltip.add(line); - - if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showPriceInfoAucItem) { - if (line.contains(EnumChatFormatting.GRAY + "Buy it now: ") || - line.contains(EnumChatFormatting.GRAY + "Bidder: ") || - line.contains(EnumChatFormatting.GRAY + "Starting bid: ")) { - - if (!Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) && !Keyboard.isKeyDown(Keyboard.KEY_RSHIFT)) { - newTooltip.add(""); - newTooltip.add(EnumChatFormatting.GRAY + "[SHIFT for Price Info]"); - } else { - ItemPriceInformation.addToTooltip(newTooltip, internalname, event.itemStack); - } - } - } - - if (NotEnoughUpdates.INSTANCE.config.dungeons.profitDisplayLoc == 2 && - Minecraft.getMinecraft().currentScreen instanceof GuiChest) { - if (line.contains(EnumChatFormatting.GREEN + "Open Reward Chest")) { - dungeonProfit = true; - } else if (index == 7 && dungeonProfit) { - GuiChest eventGui = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest cc = (ContainerChest) eventGui.inventorySlots; - IInventory lower = cc.getLowerChestInventory(); - - int chestCost = 0; - try { - String line6 = Utils.cleanColour(line); - StringBuilder cost = new StringBuilder(); - for (int i = 0; i < line6.length(); i++) { - char c = line6.charAt(i); - if ("0123456789".indexOf(c) >= 0) { - cost.append(c); - } - } - if (cost.length() > 0) { - chestCost = Integer.parseInt(cost.toString()); - } - } catch (Exception ignored) { - } - - String missingItem = null; - int totalValue = 0; - HashMap itemValues = new HashMap<>(); - for (int i = 0; i < 5; i++) { - ItemStack item = lower.getStackInSlot(11 + i); - String internal = neu.manager.getInternalNameForItem(item); - if (internal != null) { - internal = internal.replace("\u00CD", "I").replace("\u0130", "I"); - float bazaarPrice = -1; - JsonObject bazaarInfo = neu.manager.auctionManager.getBazaarInfo(internal); - if (bazaarInfo != null && bazaarInfo.has("curr_sell")) { - bazaarPrice = bazaarInfo.get("curr_sell").getAsFloat(); - } - if (bazaarPrice < 5000000 && internal.equals("RECOMBOBULATOR_3000")) bazaarPrice = 5000000; - - float worth = -1; - if (bazaarPrice > 0) { - worth = bazaarPrice; - } else { - switch (NotEnoughUpdates.INSTANCE.config.dungeons.profitType) { - case 1: - worth = neu.manager.auctionManager.getItemAvgBin(internal); - break; - case 2: - JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal); - if (auctionInfo != null) { - if (auctionInfo.has("clean_price")) { - worth = (int) auctionInfo.get("clean_price").getAsFloat(); - } else { - worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); - } - } - break; - default: - worth = neu.manager.auctionManager.getLowestBin(internal); - } - if (worth <= 0) { - worth = neu.manager.auctionManager.getLowestBin(internal); - if (worth <= 0) { - worth = neu.manager.auctionManager.getItemAvgBin(internal); - if (worth <= 0) { - JsonObject auctionInfo = neu.manager.auctionManager.getItemAuctionInfo(internal); - if (auctionInfo != null) { - if (auctionInfo.has("clean_price")) { - worth = (int) auctionInfo.get("clean_price").getAsFloat(); - } else { - worth = (int) (auctionInfo.get("price").getAsFloat() / auctionInfo.get("count").getAsFloat()); - } - } - } - } - } - } - - if (worth > 0 && totalValue >= 0) { - totalValue += worth; - - String display = item.getDisplayName(); - - if (display.contains("Enchanted Book")) { - NBTTagCompound tag = item.getTagCompound(); - if (tag != null && tag.hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - NBTTagCompound enchants = ea.getCompoundTag("enchantments"); - - int highestLevel = -1; - for (String enchname : enchants.getKeySet()) { - int level = enchants.getInteger(enchname); - if (level > highestLevel) { - display = EnumChatFormatting.BLUE + WordUtils.capitalizeFully( - enchname.replace("_", " ") - .replace("Ultimate", "") - .trim()) + " " + level; - } - } - } - } - - itemValues.put(display, worth); - } else { - if (totalValue != -1) { - missingItem = internal; - } - totalValue = -1; - } - } - } - - NumberFormat format = NumberFormat.getInstance(Locale.US); - String valueStringBIN1; - String valueStringBIN2; - if (totalValue >= 0) { - valueStringBIN1 = EnumChatFormatting.YELLOW + "Value (BIN): "; - valueStringBIN2 = EnumChatFormatting.GOLD + format.format(totalValue) + " coins"; - } else { - valueStringBIN1 = EnumChatFormatting.YELLOW + "Can't find BIN: "; - valueStringBIN2 = missingItem; - } - - int profitLossBIN = totalValue - chestCost; - String profitPrefix = EnumChatFormatting.DARK_GREEN.toString(); - String lossPrefix = EnumChatFormatting.RED.toString(); - String prefix = profitLossBIN >= 0 ? profitPrefix : lossPrefix; - - String plStringBIN; - if (profitLossBIN >= 0) { - plStringBIN = prefix + "+" + format.format(profitLossBIN) + " coins"; - } else { - plStringBIN = prefix + "-" + format.format(-profitLossBIN) + " coins"; - } - - String neu = EnumChatFormatting.YELLOW + "[NEU] "; - - newTooltip.add(neu + valueStringBIN1 + " " + valueStringBIN2); - if (totalValue >= 0) { - newTooltip.add(neu + EnumChatFormatting.YELLOW + "Profit/Loss: " + plStringBIN); - } - - for (Map.Entry entry : itemValues.entrySet()) { - newTooltip.add(neu + entry.getKey() + prefix + "+" + - format.format(entry.getValue().intValue())); - } - } - } - - index++; - } - - for (int i = newTooltip.size() - 1; i >= 0; i--) { - String line = Utils.cleanColour(newTooltip.get(i)); - for (int i1 = 0; i1 < Utils.rarityArr.length; i1++) { - if (line.equals(Utils.rarityArr[i1])) { - if (i - 2 < 0) { - break; - } - newTooltip.addAll(i - 1, petToolTipXPExtend(event)); - break; - } - } - } - - pressedShiftLast = Keyboard.isKeyDown(Keyboard.KEY_LSHIFT) || Keyboard.isKeyDown(Keyboard.KEY_RSHIFT); - pressedArrowLast = Keyboard.isKeyDown(Keyboard.KEY_LEFT) || Keyboard.isKeyDown(Keyboard.KEY_RIGHT); - - event.toolTip.clear(); - event.toolTip.addAll(newTooltip); - - HashMap> loreBuckets = new HashMap<>(); - - List hypixelOrder = new ArrayList<>(); - - hypixelOrder.add("attributes"); - hypixelOrder.add("enchants"); - hypixelOrder.add("ability"); - hypixelOrder.add("reforge_bonus"); - hypixelOrder.add("rarity"); - - if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.showPriceInfoInvItem) { - ItemPriceInformation.addToTooltip(event.toolTip, internalname, event.itemStack); - } - - if (event.itemStack.getTagCompound() != null && event.itemStack.getTagCompound().getBoolean("NEUHIDEPETTOOLTIP") && - NotEnoughUpdates.INSTANCE.config.petOverlay.hidePetTooltip) { - event.toolTip.clear(); - } - } - - private final Pattern xpLevelPattern = Pattern.compile("(.*) (\\xA7e(.*)\\xA76/\\xA7e(.*))"); - - private void onItemToolTipInternalNameNull(ItemTooltipEvent event) { - petToolTipXPExtendPetMenu(event); - } - - private List petToolTipXPExtend(ItemTooltipEvent event) { - List tooltipText = new ArrayList<>(); - if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) { - if (event.itemStack.getTagCompound().hasKey("DisablePetExp")) { - if (event.itemStack.getTagCompound().getBoolean("DisablePetExp")) { - return tooltipText; - } - } - //7 is just a random number i chose, prob no pets with less lines than 7 - if (event.toolTip.size() > 7) { - if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { - - GuiProfileViewer.PetLevel petlevel = null; - - //this is the item itself - NBTTagCompound tag = event.itemStack.getTagCompound(); - if (tag.hasKey("ExtraAttributes")) { - if (tag.getCompoundTag("ExtraAttributes").hasKey("petInfo")) { - JsonObject petInfo = NotEnoughUpdates.INSTANCE.manager.gson.fromJson( - tag.getCompoundTag("ExtraAttributes").getString("petInfo"), JsonObject.class); - if (petInfo.has("exp") && petInfo.get("exp").isJsonPrimitive()) { - JsonPrimitive exp = petInfo.getAsJsonPrimitive("exp"); - String petName = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack); - //Utils.getRarityFromInt(Utils.checkItemTypePet(event.toolTip))).getAsInt(); - petlevel = GuiProfileViewer.getPetLevel( - petName, - Utils.getRarityFromInt(Utils.checkItemTypePet(event.toolTip)), - exp.getAsLong() - ); - } - } - } - - if (petlevel != null) { - tooltipText.add(""); - if (petlevel.totalXp > petlevel.maxXP) { - tooltipText.add(EnumChatFormatting.AQUA + "" + EnumChatFormatting.BOLD + "MAX LEVEL"); - } else { - tooltipText.add( - EnumChatFormatting.GRAY + "Progress to Level " + (int) Math.floor(petlevel.level + 1) + ": " + - EnumChatFormatting.YELLOW + Utils.round(petlevel.levelPercentage * 100, 1) + "%"); - int levelpercentage = Math.round(petlevel.levelPercentage * 20); - tooltipText.add( - EnumChatFormatting.DARK_GREEN + String.join("", Collections.nCopies(levelpercentage, "-")) + - EnumChatFormatting.WHITE + String.join("", Collections.nCopies(20 - levelpercentage, "-"))); - tooltipText.add( - EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petlevel.levelXp) + - EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + - myFormatter.format(petlevel.currentLevelRequirement) + " EXP"); - } - } - } - } - } - return tooltipText; - } - - private static final String petToolTipRegex = - "((Farming)|(Combat)|(Fishing)|(Mining)|(Foraging)|(Enchanting)|(Alchemy)) ((Mount)|(Pet)|(Morph)).*"; - - private void petToolTipXPExtendPetMenu(ItemTooltipEvent event) { - if (NotEnoughUpdates.INSTANCE.config.tooltipTweaks.petExtendExp) { - //7 is just a random number i chose, prob no pets with less lines than 7 - if (event.toolTip.size() > 7) { - if (Utils.cleanColour(event.toolTip.get(1)).matches(petToolTipRegex)) { - GuiProfileViewer.PetLevel petlevel = null; - - int xpLine = -1; - for (int i = event.toolTip.size() - 1; i >= 0; i--) { - Matcher matcher = xpLevelPattern.matcher(event.toolTip.get(i)); - if (matcher.matches()) { - xpLine = i; - event.toolTip.set(xpLine, matcher.group(1)); - break; - } else if (event.toolTip.get(i).matches("MAX LEVEL")) { - return; - } - } - - PetInfoOverlay.Pet pet = PetInfoOverlay.getPetFromStack( - event.itemStack.getDisplayName(), - NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(event.itemStack.getTagCompound()) - ); - if (pet == null) { - return; - } - petlevel = pet.petLevel; - - if (petlevel == null || xpLine == -1) { - return; - } - - event.toolTip.add( - xpLine + 1, - EnumChatFormatting.GRAY + "EXP: " + EnumChatFormatting.YELLOW + myFormatter.format(petlevel.levelXp) + - EnumChatFormatting.GOLD + "/" + EnumChatFormatting.YELLOW + - myFormatter.format(petlevel.currentLevelRequirement) - ); - - } - } - } - } - - DecimalFormat myFormatter = new DecimalFormat("###,###.###"); - - /** - * This method does the following: - * Move the pet inventory display tooltip to the left to avoid conflicts - * Remove reforge stats for Legendary items from Hypixel if enabled - * Show NBT data when holding LCONTROL - */ - @SubscribeEvent - public void onItemTooltip(ItemTooltipEvent event) { - if (!neu.isOnSkyblock()) return; - if (event.toolTip == null) return; - //Render the pet inventory display tooltip to the left to avoid things from other mods rendering over the tooltip - if (event.itemStack.getTagCompound() != null && event.itemStack.getTagCompound().getBoolean("NEUPETINVDISPLAY")) { - GlStateManager.translate(-200, 0, 0); - } - - if (event.toolTip.size() > 2 && NotEnoughUpdates.INSTANCE.config.tooltipTweaks.hideDefaultReforgeStats) { - String secondLine = StringUtils.stripControlCodes(event.toolTip.get(1)); - if (secondLine.equals("Reforge Stone")) { - Integer startIndex = null; - Integer cutoffIndex = null; - //loop from the back of the List to find the wanted index sooner - for (int i = event.toolTip.size() - 1; i >= 0; i--) { - //rarity or mining level requirement - String line = StringUtils.stripControlCodes(event.toolTip.get(i)); - if (line.contains("REFORGE STONE") || line.contains("Requires Mining Skill Level")) { - cutoffIndex = i; - } - - //The line where the Hypixel stats start - if (line.contains("(Legendary):")) { - startIndex = i; - break; - } - } - if (startIndex != null && cutoffIndex != null && startIndex < cutoffIndex) { - event.toolTip.subList(startIndex, cutoffIndex).clear(); - } - } - } - - if (Keyboard.isKeyDown(Keyboard.KEY_LCONTROL) && NotEnoughUpdates.INSTANCE.config.hidden.dev && - event.toolTip.size() > 0 && - event.toolTip.get(event.toolTip.size() - 1).startsWith(EnumChatFormatting.DARK_GRAY + "NBT: ")) { - event.toolTip.remove(event.toolTip.size() - 1); - - StringBuilder sb = new StringBuilder(); - String nbt = event.itemStack.getTagCompound().toString(); - int indent = 0; - for (char c : nbt.toCharArray()) { - boolean newline = false; - if (c == '{' || c == '[') { - indent++; - newline = true; - } else if (c == '}' || c == ']') { - indent--; - sb.append("\n"); - for (int i = 0; i < indent; i++) sb.append(" "); - } else if (c == ',') { - newline = true; - } else if (c == '\"') { - sb.append(EnumChatFormatting.RESET.toString() + EnumChatFormatting.GRAY); - } - - sb.append(c); - if (newline) { - sb.append("\n"); - for (int i = 0; i < indent; i++) sb.append(" "); - } - } - event.toolTip.add(sb.toString()); - if (Keyboard.isKeyDown(Keyboard.KEY_H)) { - if (!copied) { - copied = true; - StringSelection selection = new StringSelection(sb.toString()); - Toolkit.getDefaultToolkit().getSystemClipboard().setContents(selection, selection); - } - } else { - copied = false; - } - } else if (NotEnoughUpdates.INSTANCE.packDevEnabled) { - event.toolTip.add(""); - event.toolTip.add(EnumChatFormatting.AQUA + "NEU Pack Dev Info:"); - event.toolTip.add("Press " + EnumChatFormatting.GOLD + "[KEY]" + EnumChatFormatting.GRAY + " to copy line"); - - String internal = NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem(event.itemStack); - - boolean k = Keyboard.isKeyDown(Keyboard.KEY_K); - boolean m = Keyboard.isKeyDown(Keyboard.KEY_M); - boolean n = Keyboard.isKeyDown(Keyboard.KEY_N); - - event.toolTip.add( - EnumChatFormatting.AQUA + "Internal Name: " + EnumChatFormatting.GRAY + internal + EnumChatFormatting.GOLD + - " [K]"); - if (!copied && k) { - MiscUtils.copyToClipboard(internal); - } - - if (event.itemStack.getTagCompound() != null) { - NBTTagCompound tag = event.itemStack.getTagCompound(); - - if (tag.hasKey("SkullOwner", 10)) { - GameProfile gameprofile = NBTUtil.readGameProfileFromNBT(tag.getCompoundTag("SkullOwner")); - - if (gameprofile != null) { - event.toolTip.add(EnumChatFormatting.AQUA + "Skull UUID: " + EnumChatFormatting.GRAY + gameprofile.getId() + - EnumChatFormatting.GOLD + " [M]"); - if (!copied && m) { - MiscUtils.copyToClipboard(gameprofile.getId().toString()); - } - - Map map = - Minecraft.getMinecraft().getSkinManager().loadSkinFromCache(gameprofile); - - if (map.containsKey(MinecraftProfileTexture.Type.SKIN)) { - MinecraftProfileTexture profTex = map.get(MinecraftProfileTexture.Type.SKIN); - event.toolTip.add( - EnumChatFormatting.AQUA + "Skull Texture Link: " + EnumChatFormatting.GRAY + profTex.getUrl() + - EnumChatFormatting.GOLD + " [N]"); - - if (!copied && n) { - MiscUtils.copyToClipboard(profTex.getUrl()); - } - } - } - } - } - - copied = k || m || n; - } - } - - @SubscribeEvent - public void onRenderLast(RenderWorldLastEvent event) { - CrystalMetalDetectorSolver.render(event.partialTicks); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java index df31834f99..598ecc2e09 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUManager.java @@ -1,14 +1,46 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates; -import com.google.gson.*; +import com.google.gson.Gson; +import com.google.gson.GsonBuilder; +import com.google.gson.JsonArray; +import com.google.gson.JsonElement; +import com.google.gson.JsonObject; +import com.google.gson.JsonPrimitive; import io.github.moulberry.notenoughupdates.auction.APIManager; +import io.github.moulberry.notenoughupdates.events.RepositoryReloadEvent; import io.github.moulberry.notenoughupdates.miscgui.GuiItemRecipe; import io.github.moulberry.notenoughupdates.miscgui.KatSitterOverlay; +import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag; import io.github.moulberry.notenoughupdates.recipes.CraftingOverlay; import io.github.moulberry.notenoughupdates.recipes.CraftingRecipe; import io.github.moulberry.notenoughupdates.recipes.Ingredient; import io.github.moulberry.notenoughupdates.recipes.NeuRecipe; -import io.github.moulberry.notenoughupdates.util.*; +import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.HotmInformation; +import io.github.moulberry.notenoughupdates.util.ApiUtil; +import io.github.moulberry.notenoughupdates.util.ItemResolutionQuery; +import io.github.moulberry.notenoughupdates.util.ItemUtils; +import io.github.moulberry.notenoughupdates.util.SBInfo; +import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.settings.KeyBinding; import net.minecraft.init.Blocks; @@ -16,23 +48,48 @@ import net.minecraft.inventory.ContainerChest; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; -import net.minecraft.nbt.*; +import net.minecraft.nbt.CompressedStreamTools; +import net.minecraft.nbt.JsonToNBT; +import net.minecraft.nbt.NBTException; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.nbt.NBTTagList; +import net.minecraft.nbt.NBTTagString; import net.minecraft.util.ResourceLocation; -import net.minecraftforge.fml.common.ProgressManager; import org.apache.commons.io.FileUtils; import org.lwjgl.input.Keyboard; -import org.lwjgl.opengl.Display; -import javax.swing.JDialog; -import javax.swing.JOptionPane; -import java.io.*; +import javax.net.ssl.HttpsURLConnection; +import java.io.BufferedInputStream; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.ByteArrayInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; +import java.io.Reader; import java.net.URL; import java.net.URLConnection; import java.nio.charset.StandardCharsets; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.Base64; +import java.util.Collections; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Locale; +import java.util.Map; +import java.util.NavigableMap; +import java.util.Optional; +import java.util.Set; +import java.util.TreeMap; +import java.util.TreeSet; import java.util.concurrent.CompletableFuture; -import java.util.concurrent.ExecutorService; -import java.util.concurrent.Executors; import java.util.stream.Collectors; import java.util.zip.ZipEntry; import java.util.zip.ZipInputStream; @@ -43,6 +100,7 @@ public class NEUManager { public final APIManager auctionManager; private final TreeMap itemMap = new TreeMap<>(); + private boolean hasBeenLoadedBefore = false; private final TreeMap>> titleWordMap = new TreeMap<>(); private final TreeMap>> loreWordMap = new TreeMap<>(); @@ -66,18 +124,10 @@ public class NEUManager { public String viewItemAttemptID = null; public long viewItemAttemptTime = 0; - private final String currentProfile = ""; - private final String currentProfileBackup = ""; - public final HypixelApi hypixelApi = new HypixelApi(); + public final ApiUtil apiUtils = new ApiUtil(); private final Map itemstackCache = new HashMap<>(); - private final ExecutorService repoLoaderES = Executors.newSingleThreadExecutor(); - - private static String GIT_COMMITS_URL; - - // TODO: private final Map - private final Set recipes = new HashSet<>(); private final HashMap> recipesMap = new HashMap<>(); private final HashMap> usagesMap = new HashMap<>(); @@ -101,8 +151,6 @@ public NEUManager(NotEnoughUpdates neu, File configLocation) { this.craftingOverlay = new CraftingOverlay(this); this.katSitterOverlay = new KatSitterOverlay(); - GIT_COMMITS_URL = neu.config.hidden.repoCommitsURL; - gson = new GsonBuilder().setPrettyPrinting().create(); this.repoLocation = new File(configLocation, "repo"); @@ -159,186 +207,74 @@ public void resetRepo() { } } - /** - * Called when the game is first loaded. Compares the local repository to the github repository and handles the - * downloading of new/updated files. This then calls the "loadItem" method for every item in the local repository. - */ - public void loadItemInformation() { - /*File repoFile = new File(configLocation, "repo2"); - repoFile.mkdirs(); - - try(Git git = Git.init().setDirectory(repoFile).call()) { - StoredConfig config = git.getRepository().getConfig(); - config.setString("branch", "master", "merge", "refs/heads/master"); - config.setString("branch", "master", "remote", "origin"); - config.setString("remote", "origin", "fetch", "+refs/heads/*:refs/remotes/origin/*"); - config.setString("remote", "origin", "url", "https://github.com/Moulberry/NotEnoughUpdates-REPO.git"); - config.save(); - - git.remoteAdd().setName("origin").setUri(new URIish("https://github.com/Moulberry/NotEnoughUpdates-REPO.git")).call(); - PullResult result = git.pull().setRemote("origin").setTimeout(30000).call(); - System.out.println("successful pull: " + result.isSuccessful()); - } catch(Exception e) { - e.printStackTrace(); - }*/ - - /*if(repoFile.mkdirs()) { - try { - Git.cloneRepository() - .setURI("https://github.com/Moulberry/NotEnoughUpdates-REPO.git") - .setDirectory(repoFile) - .call(); - } catch(Exception e) { - e.printStackTrace(); - } - } else { - - }*/ - - repoLoaderES.submit(() -> { - JDialog dialog = null; + public CompletableFuture fetchRepository() { + return CompletableFuture.supplyAsync(() -> { try { - if (NotEnoughUpdates.INSTANCE.config.hidden.autoupdate) { - JOptionPane pane = new JOptionPane("Getting items to download from remote repository."); - dialog = pane.createDialog("NotEnoughUpdates Remote Sync"); - dialog.setModal(false); - if (NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true); - - if (Display.isActive()) dialog.toFront(); - - JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json")); - - latestRepoCommit = null; - try (Reader inReader = new InputStreamReader(new URL(GIT_COMMITS_URL).openStream())) { - JsonObject commits = gson.fromJson(inReader, JsonObject.class); - latestRepoCommit = commits.get("sha").getAsString(); - } catch (Exception e) { - e.printStackTrace(); - } - if (latestRepoCommit == null || latestRepoCommit.isEmpty()) return; + JsonObject currentCommitJSON = getJsonFromFile(new File(configLocation, "currentCommit.json")); + + latestRepoCommit = null; + try (Reader inReader = new InputStreamReader(new URL(neu.config.apiData.getCommitApiUrl()).openStream())) { + JsonObject commits = gson.fromJson(inReader, JsonObject.class); + latestRepoCommit = commits.get("sha").getAsString(); + } catch (Exception e) { + e.printStackTrace(); + } + if (latestRepoCommit == null || latestRepoCommit.isEmpty()) return false; - if (new File(configLocation, "repo").exists() && new File(configLocation, "repo/items").exists()) { - if (currentCommitJSON != null && currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) { - dialog.setVisible(false); - return; - } + if (new File(configLocation, "repo").exists() && new File(configLocation, "repo/items").exists()) { + if (currentCommitJSON != null && currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) { + return false; } + } + Utils.recursiveDelete(repoLocation); + repoLocation.mkdirs(); - if (Display.isActive()) dialog.toFront(); - - Utils.recursiveDelete(repoLocation); - repoLocation.mkdirs(); + File itemsZip = new File(repoLocation, "neu-items-master.zip"); + try { + itemsZip.createNewFile(); + } catch (IOException e) { + return false; + } - String dlUrl = neu.config.hidden.repoURL; + URL url = new URL(neu.config.apiData.getDownloadUrl(latestRepoCommit)); + URLConnection urlConnection = url.openConnection(); + urlConnection.setConnectTimeout(15000); + urlConnection.setReadTimeout(30000); + + try (InputStream is = urlConnection.getInputStream()) { + FileUtils.copyInputStreamToFile(is, itemsZip); + } catch (IOException e) { + e.printStackTrace(); + System.err.println("Failed to download NEU Repo! Please report this issue to the mod creator"); + return false; + } - pane.setMessage("Downloading NEU Master Archive. (DL# >20)"); - dialog.pack(); - if (NotEnoughUpdates.INSTANCE.config.hidden.dev) dialog.setVisible(true); - if (Display.isActive()) dialog.toFront(); + unzipIgnoreFirstFolder(itemsZip.getAbsolutePath(), repoLocation.getAbsolutePath()); - File itemsZip = new File(repoLocation, "neu-items-master.zip"); + if (currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) { + JsonObject newCurrentCommitJSON = new JsonObject(); + newCurrentCommitJSON.addProperty("sha", latestRepoCommit); try { - itemsZip.createNewFile(); - } catch (IOException e) { - return; - } - - URL url = new URL(dlUrl); - URLConnection urlConnection = url.openConnection(); - urlConnection.setConnectTimeout(15000); - urlConnection.setReadTimeout(30000); - - try (InputStream is = urlConnection.getInputStream()) { - FileUtils.copyInputStreamToFile(is, itemsZip); - } catch (IOException e) { - dialog.dispose(); - e.printStackTrace(); - System.err.println("Failed to download NEU Repo! Please report this issue to the mod creator"); - return; - } - /*try ( - BufferedInputStream inStream = new BufferedInputStream(urlConnection.getInputStream()); - FileOutputStream fileOutputStream = new FileOutputStream(itemsZip) - ) { - byte dataBuffer[] = new byte[1024]; - int bytesRead; - while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) { - fileOutputStream.write(dataBuffer, 0, bytesRead); - } - } catch (IOException e) { - dialog.dispose(); - return; - }*/ - - pane.setMessage("Unzipping NEU Master Archive."); - dialog.pack(); - //dialog.setVisible(true); - if (Display.isActive()) dialog.toFront(); - - unzipIgnoreFirstFolder(itemsZip.getAbsolutePath(), repoLocation.getAbsolutePath()); - - if (currentCommitJSON == null || !currentCommitJSON.get("sha").getAsString().equals(latestRepoCommit)) { - JsonObject newCurrentCommitJSON = new JsonObject(); - newCurrentCommitJSON.addProperty("sha", latestRepoCommit); - try { - writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json")); - } catch (IOException ignored) { - } + writeJson(newCurrentCommitJSON, new File(configLocation, "currentCommit.json")); + } catch (IOException ignored) { } } } catch (Exception e) { e.printStackTrace(); - } finally { - if (dialog != null) dialog.dispose(); - } - - File items = new File(repoLocation, "items"); - if (items.exists()) { - File[] itemFiles = new File(repoLocation, "items").listFiles(); - if (itemFiles != null) { - ProgressManager.ProgressBar bar = ProgressManager.push("Loading recipes", itemFiles.length); - for (File f : itemFiles) { - String internalname = f.getName().substring(0, f.getName().length() - 5); - bar.step(internalname); - synchronized (itemMap) { - if (!itemMap.containsKey(internalname)) { - loadItem(internalname); - } - } - } - ProgressManager.pop(bar); - } - } - - try { - Constants.reload(); - } catch (Exception e) { - e.printStackTrace(); } + return true; }); + } - File items = new File(repoLocation, "items"); - if (items.exists()) { - File[] itemFiles = new File(repoLocation, "items").listFiles(); - if (itemFiles != null) { - ProgressManager.ProgressBar bar = ProgressManager.push("Loading items", itemFiles.length); - for (File f : itemFiles) { - String internalname = f.getName().substring(0, f.getName().length() - 5); - bar.step(internalname); - synchronized (itemMap) { - if (!itemMap.containsKey(internalname)) { - loadItem(internalname); - } - } - } - ProgressManager.pop(bar); - } - } - - try { - Constants.reload(); - } catch (Exception e) { - e.printStackTrace(); + /** + * Called when the game is first loaded. Compares the local repository to the github repository and handles the + * downloading of new/updated files. This then calls the "loadItem" method for every item in the local repository. + */ + public void loadItemInformation() { + if (NotEnoughUpdates.INSTANCE.config.apiData.autoupdate) { + fetchRepository().thenRun(this::reloadRepository); + } else { + reloadRepository(); } } @@ -435,6 +371,10 @@ public void registerNeuRecipe(NeuRecipe recipe) { for (Ingredient input : recipe.getIngredients()) { usagesMap.computeIfAbsent(input.getInternalItemId(), ignored -> new HashSet<>()).add(recipe); } + for (Ingredient catalystItem : recipe.getCatalystItems()) { + recipesMap.computeIfAbsent(catalystItem.getInternalItemId(), ignored -> new HashSet<>()).add(recipe); + usagesMap.computeIfAbsent(catalystItem.getInternalItemId(), ignored -> new HashSet<>()).add(recipe); + } } public Set getRecipesFor(String internalName) { @@ -453,29 +393,94 @@ public List getAvailableUsagesFor(String internalname) { return getUsagesFor(internalname).stream().filter(NeuRecipe::isAvailable).collect(Collectors.toList()); } + private static class DebugMatch { + int index; + String match; + + DebugMatch(int index, String match) { + this.index = index; + this.match = match; + } + } + + + private String searchDebug(String[] searchArray, ArrayList debugMatches) { + //splitToSearch, debugMatches and query + final String ANSI_RED = "\u001B[31m"; + final String ANSI_RESET = "\u001B[0m"; + final String ANSI_YELLOW = "\u001B[33m"; + + //create debug message + StringBuilder debugBuilder = new StringBuilder(); + for (int i = 0; i < searchArray.length; i++) { + final int fi = i; + Object[] matches = debugMatches.stream().filter((d) -> d.index == fi).toArray(); + + if (matches.length > 0) { + debugBuilder.append(ANSI_YELLOW + "[").append(((DebugMatch) matches[0]).match).append("]"); + debugBuilder.append(ANSI_RED + "[").append(searchArray[i]).append("]").append(ANSI_RESET).append(" "); + } else { + debugBuilder.append(searchArray[i]).append(" "); + } + } + + //yellow = query match and red = string match + return debugBuilder.toString(); + } + /** * Searches a string for a query. This method is used to mimic the behaviour of the more complex map-based search * function. This method is used for the chest-item-search feature. */ public boolean searchString(String toSearch, String query) { - int lastMatch = -1; + final String ANSI_RESET = "\u001B[0m"; + final String ANSI_YELLOW = "\u001B[33m"; + + int lastStringMatch = -1; + ArrayList debugMatches = new ArrayList<>(); toSearch = clean(toSearch).toLowerCase(); query = clean(query).toLowerCase(); - String[] splitToSeach = toSearch.split(" "); - out: - for (String s : query.split(" ")) { - for (int i = 0; i < splitToSeach.length; i++) { - if (!(lastMatch == -1 || lastMatch == i - 1)) continue; - if (splitToSeach[i].startsWith(s)) { - lastMatch = i; - continue out; + String[] splitToSearch = toSearch.split(" "); + String[] queryArray = query.split(" "); + + { + String currentSearch = queryArray[0]; + int queryIndex = 0; + boolean matchedLastQueryItem = false; + + for (int k = 0; k < splitToSearch.length; k++) { + if (queryIndex - 1 != -1 && (queryArray.length - queryIndex) > (splitToSearch.length - k)) continue; + if (splitToSearch[k].startsWith(currentSearch)) { + if (((lastStringMatch != -1 ? lastStringMatch : k-1) == k-1)) { + debugMatches.add(new DebugMatch(k, currentSearch)); + lastStringMatch = k; + if (queryIndex+1 != queryArray.length) { + queryIndex++; + currentSearch = queryArray[queryIndex]; + } else { + matchedLastQueryItem = true; + } + } + } else if (queryIndex != 0) { + queryIndex = 0; + currentSearch = queryArray[queryIndex]; + lastStringMatch = -1; } } - return false; - } - return true; + if (matchedLastQueryItem) { + if (NEUDebugFlag.SEARCH.isSet()) { + NotEnoughUpdates.LOGGER.info("Found match for \"" + ANSI_YELLOW + query + ANSI_RESET + "\":\n\t" + searchDebug(splitToSearch, debugMatches)); + } + } else { + if (NEUDebugFlag.SEARCH.isSet() && lastStringMatch != -1) { + NotEnoughUpdates.LOGGER.info("Found partial match for \"" + ANSI_YELLOW + query + ANSI_RESET + "\":\n\t" + searchDebug(splitToSearch, debugMatches)); + } + } + + return matchedLastQueryItem; + } } /** @@ -723,82 +728,35 @@ public String getUUIDFromNBT(NBTTagCompound tag) { return uuid; } - public String getInternalnameFromNBT(NBTTagCompound tag) { - String internalname = null; - if (tag != null && tag.hasKey("ExtraAttributes", 10)) { - NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); - - if (ea.hasKey("id", 8)) { - internalname = ea.getString("id").replaceAll(":", "-"); - } else { - return null; - } - - if ("PET".equals(internalname)) { - String petInfo = ea.getString("petInfo"); - if (petInfo.length() > 0) { - JsonObject petInfoObject = gson.fromJson(petInfo, JsonObject.class); - internalname = petInfoObject.get("type").getAsString(); - String tier = petInfoObject.get("tier").getAsString(); - switch (tier) { - case "COMMON": - internalname += ";0"; - break; - case "UNCOMMON": - internalname += ";1"; - break; - case "RARE": - internalname += ";2"; - break; - case "EPIC": - internalname += ";3"; - break; - case "LEGENDARY": - internalname += ";4"; - break; - case "MYTHIC": - internalname += ";5"; - break; - } - } - } - if ("ENCHANTED_BOOK".equals(internalname) && ea.hasKey("enchantments", 10)) { - NBTTagCompound enchants = ea.getCompoundTag("enchantments"); - - for (String enchname : enchants.getKeySet()) { - internalname = enchname.toUpperCase() + ";" + enchants.getInteger(enchname); - break; - } - } - if ("RUNE".equals(internalname) && ea.hasKey("runes", 10)) { - NBTTagCompound rune = ea.getCompoundTag("runes"); - - for (String runename : rune.getKeySet()) { - internalname = runename.toUpperCase() + "_RUNE" + ";" + rune.getInteger(runename); - break; - } - } - if ("PARTY_HAT_CRAB".equals(internalname) && (ea.getString("party_hat_color") != null)) { - String crabhat = ea.getString("party_hat_color"); - internalname = "PARTY_HAT_CRAB" + "_" + crabhat.toUpperCase(); + public String getSkullValueFromNBT(NBTTagCompound tag) { + if (tag != null && tag.hasKey("SkullOwner", 10)) { + NBTTagCompound ea = tag.getCompoundTag("SkullOwner"); + NBTTagCompound ea3 = tag.getCompoundTag("display"); + + if (ea.hasKey("Properties", 10)) { + NBTTagCompound ea2 = ea; + ea = ea.getCompoundTag("Properties"); + ea = ea.getTagList("textures", 10).getCompoundTagAt(0); + String name = ea3.getString("Name").replaceAll(" M{0,4}(CM|CD|D?C{0,3})(XC|XL|L?X{0,3})(IX|IV|V?I{0,3})$", ""); + return "put(\"ID\", Utils.createSkull(EnumChatFormatting.AQUA + \"" + name + "\" ,\"" + ea2.getString("Id") + + "\", \"" + ea.getString("Value") + "\"));"; } } + return null; + } - return internalname; + /** + * Replaced with {@link #createItemResolutionQuery()} + */ + @Deprecated + public String getInternalnameFromNBT(NBTTagCompound tag) { + return createItemResolutionQuery() + .withItemNBT(tag) + .resolveInternalName(); } public String[] getLoreFromNBT(NBTTagCompound tag) { - String[] lore = new String[0]; - NBTTagCompound display = tag.getCompoundTag("display"); - - if (display.hasKey("Lore", 9)) { - NBTTagList list = display.getTagList("Lore", 8); - lore = new String[list.tagCount()]; - for (int k = 0; k < list.tagCount(); k++) { - lore[k] = list.getStringTagAt(k); - } - } - return lore; + return ItemUtils.getLore(tag).toArray(new String[0]); } public JsonObject getJsonFromNBT(NBTTagCompound tag) { @@ -826,14 +784,14 @@ public JsonObject getJsonFromNBTEntry(NBTTagCompound tag) { if (itemMc != null) { itemid = itemMc.getRegistryName(); } - String displayname = display.getString("Name"); + String displayName = display.getString("Name"); String[] info = new String[0]; String clickcommand = ""; JsonObject item = new JsonObject(); item.addProperty("internalname", internalname); item.addProperty("itemid", itemid); - item.addProperty("displayname", displayname); + item.addProperty("displayname", displayName); if (tag != null && tag.hasKey("ExtraAttributes", 10)) { NBTTagCompound ea = tag.getCompoundTag("ExtraAttributes"); @@ -894,12 +852,12 @@ public void showRecipe(JsonObject item) { String clickcommand = item.get("clickcommand").getAsString(); switch (clickcommand.intern()) { case "viewrecipe": - displayGuiItemRecipe(internalName, null); + displayGuiItemRecipe(internalName); break; - case "viewoption": + case "viewpotion": neu.sendChatMessage("/viewpotion " + internalName.split(";")[0].toLowerCase(Locale.ROOT)); } - displayGuiItemRecipe(internalName, ""); + displayGuiItemRecipe(internalName); } public void showRecipe(String internalName) { @@ -952,10 +910,24 @@ public JsonObject getJsonForItem(ItemStack stack) { return json; } - public String getInternalNameForItem(ItemStack stack) { + public String getSkullValueForItem(ItemStack stack) { if (stack == null) return null; NBTTagCompound tag = stack.getTagCompound(); - return getInternalnameFromNBT(tag); + return getSkullValueFromNBT(tag); + } + + public ItemResolutionQuery createItemResolutionQuery() { + return new ItemResolutionQuery(this); + } + + /** + * Replaced with {@link #createItemResolutionQuery()} + */ + @Deprecated + public String getInternalNameForItem(ItemStack stack) { + return createItemResolutionQuery() + .withItemStack(stack) + .resolveInternalName(); } public String getUUIDForItem(ItemStack stack) { @@ -988,17 +960,15 @@ public boolean displayGuiItemUsages(String internalName) { if (!usagesMap.containsKey(internalName)) return false; List usages = getAvailableUsagesFor(internalName); if (usages.isEmpty()) return false; - Minecraft.getMinecraft().displayGuiScreen( - new GuiItemRecipe("Item Usages", usages, this)); + NotEnoughUpdates.INSTANCE.openGui = (new GuiItemRecipe(usages, this)); return true; } - public boolean displayGuiItemRecipe(String internalName, String text) { + public boolean displayGuiItemRecipe(String internalName) { if (!recipesMap.containsKey(internalName)) return false; List recipes = getAvailableRecipesFor(internalName); if (recipes.isEmpty()) return false; - Minecraft.getMinecraft().displayGuiScreen( - new GuiItemRecipe(text != null ? text : "Item Recipe", recipes, this)); + NotEnoughUpdates.INSTANCE.openGui = (new GuiItemRecipe(recipes, this)); return true; } @@ -1009,7 +979,7 @@ public boolean displayGuiItemRecipe(String internalName, String text) { public boolean failViewItem(String text) { if (viewItemAttemptID != null && !viewItemAttemptID.isEmpty()) { if (System.currentTimeMillis() - viewItemAttemptTime < 500) { - return displayGuiItemRecipe(viewItemAttemptID, text); + return displayGuiItemRecipe(viewItemAttemptID); } } return false; @@ -1032,11 +1002,12 @@ public CompletableFuture getWebFile(String url) { } catch (IOException e) { return null; } - try ( - BufferedInputStream inStream = new BufferedInputStream(new URL( - url + "?action=raw&templates=expand").openStream()); - FileOutputStream fileOutputStream = new FileOutputStream(f) - ) { + try { + HttpsURLConnection con = (HttpsURLConnection) new URL(url + "?action=raw&templates=expand").openConnection(); + con.setRequestMethod("GET"); + con.setRequestProperty("User-Agent", "NotEnoughUpdates"); + BufferedInputStream inStream = new BufferedInputStream(con.getInputStream()); + FileOutputStream fileOutputStream = new FileOutputStream(f); byte[] dataBuffer = new byte[1024]; int bytesRead; while ((bytesRead = inStream.read(dataBuffer, 0, 1024)) != -1) { @@ -1149,7 +1120,7 @@ public static void unzip(InputStream src, File dest) { * json files representing skyblock item data. */ public JsonObject createItemJson( - String internalname, String itemid, String displayname, String[] lore, + String internalname, String itemid, String displayName, String[] lore, String crafttext, String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag ) { @@ -1157,7 +1128,7 @@ public JsonObject createItemJson( new JsonObject(), internalname, itemid, - displayname, + displayName, lore, crafttext, infoType, @@ -1169,7 +1140,7 @@ public JsonObject createItemJson( } public JsonObject createItemJson( - JsonObject base, String internalname, String itemid, String displayname, String[] lore, + JsonObject base, String internalname, String itemid, String displayName, String[] lore, String crafttext, String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag ) { @@ -1180,7 +1151,7 @@ public JsonObject createItemJson( JsonObject json = gson.fromJson(gson.toJson(base, JsonObject.class), JsonObject.class); json.addProperty("internalname", internalname); json.addProperty("itemid", itemid); - json.addProperty("displayname", displayname); + json.addProperty("displayname", displayName); json.addProperty("crafttext", crafttext); json.addProperty("clickcommand", clickcommand); json.addProperty("damage", damage); @@ -1206,14 +1177,14 @@ public JsonObject createItemJson( } public boolean writeItemJson( - String internalname, String itemid, String displayname, String[] lore, String crafttext, + String internalname, String itemid, String displayName, String[] lore, String crafttext, String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag ) { return writeItemJson( new JsonObject(), internalname, itemid, - displayname, + displayName, lore, crafttext, infoType, @@ -1225,14 +1196,14 @@ public boolean writeItemJson( } public boolean writeItemJson( - JsonObject base, String internalname, String itemid, String displayname, String[] lore, + JsonObject base, String internalname, String itemid, String displayName, String[] lore, String crafttext, String infoType, String[] info, String clickcommand, int damage, NBTTagCompound nbttag ) { JsonObject json = createItemJson( base, internalname, itemid, - displayname, + displayName, lore, crafttext, infoType, @@ -1294,7 +1265,7 @@ public String removeUnusedDecimal(double num) { } } - public HashMap getLoreReplacements(String petname, String tier, int level) { + public HashMap getPetLoreReplacements(String petname, String tier, int level) { JsonObject petnums = null; if (petname != null && tier != null) { petnums = Constants.PETNUMS; @@ -1407,7 +1378,7 @@ public HashMap getLoreReplacements(String petname, String tier, float statMax = entry.getValue().getAsFloat(); float statMin = min.get("statNums").getAsJsonObject().get(entry.getKey()).getAsFloat(); float val = statMin * minMix + statMax * maxMix; - String statStr = (statMin > 0 ? "+" : "") + (int) Math.floor(val); + String statStr = (statMin > 0 ? "+" : "") + removeUnusedDecimal(Math.floor(val * 10) / 10); replacements.put(entry.getKey(), statStr); } } @@ -1419,7 +1390,7 @@ public HashMap getLoreReplacements(String petname, String tier, return replacements; } - public HashMap getLoreReplacements(NBTTagCompound tag, int level) { + public HashMap getPetLoreReplacements(NBTTagCompound tag, int level) { String petname = null; String tier = null; if (tag != null && tag.hasKey("ExtraAttributes")) { @@ -1453,7 +1424,7 @@ public HashMap getLoreReplacements(NBTTagCompound tag, int level } } } - return getLoreReplacements(petname, tier, level); + return getPetLoreReplacements(petname, tier, level); } public NBTTagList processLore(JsonArray lore, HashMap replacements) { @@ -1484,6 +1455,7 @@ public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useRepla } public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useReplacements, boolean copyStack) { + if (useReplacements) useCache = false; if (json == null) return new ItemStack(Items.painting, 1, 10); String internalname = json.get("internalname").getAsString(); @@ -1523,13 +1495,13 @@ public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useRepla HashMap replacements = new HashMap<>(); if (useReplacements) { - replacements = getLoreReplacements(stack.getTagCompound(), -1); + replacements = getPetLoreReplacements(stack.getTagCompound(), -1); - String displayname = json.get("displayname").getAsString(); + String displayName = json.get("displayname").getAsString(); for (Map.Entry entry : replacements.entrySet()) { - displayname = displayname.replace("{" + entry.getKey() + "}", entry.getValue()); + displayName = displayName.replace("{" + entry.getKey() + "}", entry.getValue()); } - stack.setStackDisplayName(displayname); + stack.setStackDisplayName(displayName); } if (json.has("lore")) { @@ -1552,20 +1524,73 @@ public ItemStack jsonToStack(JsonObject json, boolean useCache, boolean useRepla } } - public void reloadRepository() { - File items = new File(repoLocation, "items"); - if (items.exists()) { - recipes.clear(); - recipesMap.clear(); - usagesMap.clear(); + public CompletableFuture> userFacingRepositoryReload() { + String lastCommit = NotEnoughUpdates.INSTANCE.manager.latestRepoCommit; + NotEnoughUpdates.INSTANCE.manager.resetRepo(); + return NotEnoughUpdates.INSTANCE.manager + .fetchRepository() + .thenCompose(ignored -> NotEnoughUpdates.INSTANCE.manager.reloadRepository()) + .thenApply(ignored -> { + String newCommitHash = NotEnoughUpdates.INSTANCE.manager.latestRepoCommit; + String newCommitShortHash = (newCommitHash == null ? "MISSING" : newCommitHash.substring(0, 7)); + return Arrays.asList( + "§aRepository reloaded.", + (lastCommit == null + ? "§eYou downloaded the repository version §b" + newCommitShortHash + "§e." + : "§eYou updated your repository from §b" + lastCommit.substring(0, 7) + "§e to §b" + + newCommitShortHash + "§e." + ) + ); + }) + .exceptionally(ex -> { + ex.printStackTrace(); + return Arrays.asList( + "§cRepository not fully reloaded.", + "§cThere was an error reloading your repository.", + "§cThis might be caused by an outdated version of neu", + "§c(or by not using the dangerous repository if you are using a prerelease of neu).", + "§aYour repository will still work, but is in a suboptimal state.", + "§eJoin §bdiscord.gg/moulberry §efor help." + ); + }); + } - File[] itemFiles = new File(repoLocation, "items").listFiles(); - if (itemFiles != null) { - for (File f : itemFiles) { - String internalname = f.getName().substring(0, f.getName().length() - 5); - loadItem(internalname); + public CompletableFuture reloadRepository() { + CompletableFuture comp = new CompletableFuture<>(); + Minecraft.getMinecraft().addScheduledTask(() -> { + try { + File items = new File(repoLocation, "items"); + if (items.exists()) { + recipes.clear(); + recipesMap.clear(); + usagesMap.clear(); + + File[] itemFiles = new File(repoLocation, "items").listFiles(); + if (itemFiles != null) { + for (File f : itemFiles) { + String internalname = f.getName().substring(0, f.getName().length() - 5); + loadItem(internalname); + } + } } + + new RepositoryReloadEvent(repoLocation, !hasBeenLoadedBefore).post(); + hasBeenLoadedBefore = true; + comp.complete(null); + } catch (Exception e) { + comp.completeExceptionally(e); } - } + }); + return comp; + } + + public ItemStack createItem(String internalName) { + return createItemResolutionQuery() + .withKnownInternalName(internalName) + .resolveToItemStack(); + } + + public boolean isValidInternalName(String internalName) { + return itemMap.containsKey(internalName); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java index d1bfed14d1..14078069a0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEUOverlay.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates; import com.google.common.collect.Lists; @@ -16,23 +35,27 @@ import io.github.moulberry.notenoughupdates.mbgui.MBGuiElement; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupAligned; import io.github.moulberry.notenoughupdates.mbgui.MBGuiGroupFloating; -import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; +import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; +import io.github.moulberry.notenoughupdates.miscgui.NeuSearchCalculator; import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; import io.github.moulberry.notenoughupdates.util.Constants; +import io.github.moulberry.notenoughupdates.util.GuiTextures; import io.github.moulberry.notenoughupdates.util.LerpingFloat; +import io.github.moulberry.notenoughupdates.util.NotificationHandler; import io.github.moulberry.notenoughupdates.util.SpecialColour; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.Gui; -import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.gui.GuiTextField; -import net.minecraft.client.gui.inventory.GuiChest; import net.minecraft.client.gui.inventory.GuiContainer; -import net.minecraft.client.gui.inventory.GuiInventory; -import net.minecraft.client.renderer.*; +import net.minecraft.client.renderer.GlStateManager; +import net.minecraft.client.renderer.OpenGlHelper; +import net.minecraft.client.renderer.RenderHelper; +import net.minecraft.client.renderer.Tessellator; +import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.block.model.BakedQuad; import net.minecraft.client.renderer.entity.RenderManager; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; @@ -43,8 +66,6 @@ import net.minecraft.entity.EntityList; import net.minecraft.entity.EntityLivingBase; import net.minecraft.init.Items; -import net.minecraft.inventory.ContainerChest; -import net.minecraft.inventory.IInventory; import net.minecraft.inventory.Slot; import net.minecraft.item.Item; import net.minecraft.item.ItemStack; @@ -62,82 +83,61 @@ import org.lwjgl.opengl.GL14; import org.lwjgl.util.vector.Vector2f; -import java.awt.Color; +import java.awt.*; import java.lang.reflect.InvocationTargetException; -import java.util.*; +import java.util.ArrayList; +import java.util.Comparator; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; +import java.util.List; +import java.util.Map; +import java.util.Set; +import java.util.TreeSet; +import java.util.UUID; import java.util.concurrent.CompletableFuture; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicReference; -import static io.github.moulberry.notenoughupdates.util.GuiTextures.*; - public class NEUOverlay extends Gui { - private static final ResourceLocation SUPERGEHEIMNISVERMOGEN = - new ResourceLocation("notenoughupdates:supersecretassets/bald.png"); + private static final ResourceLocation SUPERGEHEIMNISVERMOGEN = new ResourceLocation( + "notenoughupdates:supersecretassets/bald.png"); + + private static final ResourceLocation ATMOULBERRYWHYISMYLUNARCLIENTBUGGING = new ResourceLocation( + "notenoughupdates:supersecretassets/lunar.png"); private static final ResourceLocation SEARCH_BAR = new ResourceLocation("notenoughupdates:search_bar.png"); private static final ResourceLocation SEARCH_BAR_GOLD = new ResourceLocation("notenoughupdates:search_bar_gold.png"); - private static final ResourceLocation ARMOR_DISPLAY = - new ResourceLocation("notenoughupdates:armordisplay/armordisplay.png"); - private static final ResourceLocation ARMOR_DISPLAY_GREY = - new ResourceLocation("notenoughupdates:armordisplay/armordisplay_grey.png"); - private static final ResourceLocation ARMOR_DISPLAY_DARK = - new ResourceLocation("notenoughupdates:armordisplay/armordisplay_phq_dark.png"); - private static final ResourceLocation ARMOR_DISPLAY_FSR = - new ResourceLocation("notenoughupdates:armordisplay/armordisplay_fsr.png"); - private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT = - new ResourceLocation("notenoughupdates:armordisplay/armordisplay_transparent.png"); - private static final ResourceLocation ARMOR_DISPLAY_TRANSPARENT_PET = - new ResourceLocation("notenoughupdates:armordisplay/armordisplay_transparent_pet.png"); - - private static final ResourceLocation QUESTION_MARK = new ResourceLocation("notenoughupdates:pv_unknown.png"); - - private static final ResourceLocation PET_DISPLAY = - new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo.png"); - private static final ResourceLocation PET_DISPLAY_GREY = - new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_dark.png"); - private static final ResourceLocation PET_DISPLAY_DARK = - new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_phqdark.png"); - private static final ResourceLocation PET_DISPLAY_FSR = - new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_fsr.png"); - private static final ResourceLocation PET_DISPLAY_TRANSPARENT = - new ResourceLocation("notenoughupdates:petdisplay/petdisplaysolo_transparent.png"); - - private static final ResourceLocation PET_ARMOR_DISPLAY = - new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_GREY = - new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_dark.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_DARK = - new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_phqdark.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_FSR = - new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_fsr.png"); - private static final ResourceLocation PET_ARMOR_DISPLAY_TRANSPARENT = - new ResourceLocation("notenoughupdates:petdisplay/petdisplayarmor_transparent.png"); - - private static boolean renderingArmorHud; - private static boolean renderingPetHud; - public static boolean shouldUseCachedPet; - public static long cachedPetTimer; - private final NEUManager manager; - private final String mobRegex = ".*?((_MONSTER)|(_ANIMAL)|(_MINIBOSS)|(_BOSS)|(_SC))$"; + private final String mobRegex = ".*?((_MONSTER)|(_NPC)|(_ANIMAL)|(_MINIBOSS)|(_BOSS)|(_SC))$"; private final String petRegex = ".*?;[0-5]$"; private final ResourceLocation[] sortIcons = new ResourceLocation[]{ - sort_all, sort_mob, sort_pet, sort_tool, sort_armor, sort_accessory + GuiTextures.sort_all, + GuiTextures.sort_mob, + GuiTextures.sort_pet, + GuiTextures.sort_tool, + GuiTextures.sort_armor, + GuiTextures.sort_accessory }; private final ResourceLocation[] sortIconsActive = new ResourceLocation[]{ - sort_all_active, sort_mob_active, sort_pet_active, sort_tool_active, sort_armor_active, sort_accessory_active + GuiTextures.sort_all_active, + GuiTextures.sort_mob_active, + GuiTextures.sort_pet_active, + GuiTextures.sort_tool_active, + GuiTextures.sort_armor_active, + GuiTextures.sort_accessory_active }; private final ResourceLocation[] orderIcons = new ResourceLocation[]{ - order_alphabetical, order_rarity, order_value + GuiTextures.order_alphabetical, GuiTextures.order_rarity, GuiTextures.order_value }; private final ResourceLocation[] orderIconsActive = new ResourceLocation[]{ - order_alphabetical_active, order_rarity_active, order_value_active + GuiTextures.order_alphabetical_active, GuiTextures.order_rarity_active, GuiTextures.order_value_active }; //Various constants used for GUI structure @@ -166,6 +166,7 @@ public class NEUOverlay extends Gui { private List selectedItemGroup = null; private boolean itemPaneOpen = false; + private long itemPaneShouldOpen = -1; private int page = 0; @@ -186,8 +187,8 @@ public class NEUOverlay extends Gui { private boolean redrawItems = false; - private boolean searchBarHasFocus = false; - private final GuiTextField textField = new GuiTextField(0, null, 0, 0, 0, 0); + public static boolean searchBarHasFocus = false; + private static final GuiTextField textField = new GuiTextField(0, null, 0, 0, 0, 0); private static final int COMPARE_MODE_ALPHABETICAL = 0; private static final int COMPARE_MODE_RARITY = 1; @@ -241,15 +242,17 @@ public void mouseClick(float x, float y, int mouseX, int mouseY) { } if (Mouse.getEventButtonState()) { setSearchBarFocus(true); + if (Mouse.getEventButton() == 1) { //Right mouse button down textField.setText(""); updateSearch(); } else { if (System.currentTimeMillis() - millisLastLeftClick < 300) { searchMode = !searchMode; + itemPaneShouldOpen = -1; lastSearchMode = System.currentTimeMillis(); if (searchMode && NotEnoughUpdates.INSTANCE.config.hidden.firstTimeSearchFocus) { - NEUEventListener.displayNotification(Lists.newArrayList( + NotificationHandler.displayNotification(Lists.newArrayList( "\u00a7eSearch Highlight", "\u00a77In this mode NEU will gray out non matching items in", "\u00a77your inventory or chests.", @@ -328,7 +331,7 @@ public void render(float x, float y) { } //Search bar text - fr.drawString(textField.getText(), (int) x + 5, + fr.drawString(NeuSearchCalculator.format(textField.getText()), (int) x + 5, (int) y - 4 + getHeight() / 2, Color.WHITE.getRGB() ); @@ -366,8 +369,7 @@ public void render(float x, float y) { } @Override - public void recalculate() { - } + public void recalculate() {} }; } @@ -384,8 +386,7 @@ public int getHeight() { } @Override - public void recalculate() { - } + public void recalculate() {} @Override public void mouseClick(float x, float y, int mouseX, int mouseY) { @@ -398,8 +399,7 @@ public void mouseClick(float x, float y, int mouseX, int mouseY) { } @Override - public void mouseClickOutside() { - } + public void mouseClickOutside() {} @Override public void render(float x, float y) { @@ -409,13 +409,13 @@ public void render(float x, float y) { if (!NotEnoughUpdates.INSTANCE.config.toolbar.enableSettingsButton) { return; } - Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.quickcommand_background); GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect(x, y, searchYSize + paddingUnscaled * 2, searchYSize + paddingUnscaled * 2, GL11.GL_NEAREST ); - Minecraft.getMinecraft().getTextureManager().bindTexture(settings); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.settings); GlStateManager.color(1f, 1f, 1f, 1f); Utils.drawTexturedRect((int) x + paddingUnscaled, (int) y + paddingUnscaled, searchYSize, searchYSize @@ -439,8 +439,7 @@ public int getHeight() { } @Override - public void recalculate() { - } + public void recalculate() {} @Override public void mouseClick(float x, float y, int mouseX, int mouseY) { @@ -457,8 +456,7 @@ public void mouseClick(float x, float y, int mouseX, int mouseY) { } @Override - public void mouseClickOutside() { - } + public void mouseClickOutside() {} @Override public void render(float x, float y) { @@ -469,13 +467,13 @@ public void render(float x, float y) { return; } - Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.quickcommand_background); GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect(x, y, searchYSize + paddingUnscaled * 2, searchYSize + paddingUnscaled * 2, GL11.GL_NEAREST ); - Minecraft.getMinecraft().getTextureManager().bindTexture(help); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.help); GlStateManager.color(1f, 1f, 1f, 1f); Utils.drawTexturedRect((int) x + paddingUnscaled, (int) y + paddingUnscaled, getSearchBarYSize(), getSearchBarYSize() @@ -499,16 +497,15 @@ public int getHeight() { } @Override - public void recalculate() { - } + public void recalculate() {} @Override public void mouseClick(float x, float y, int mouseX, int mouseY) { if (!NotEnoughUpdates.INSTANCE.config.toolbar.quickCommands) return; + if (EnchantingSolvers.disableButtons()) return; if ((NotEnoughUpdates.INSTANCE.config.toolbar.quickCommandsClickType != 0 && Mouse.getEventButtonState()) || - (NotEnoughUpdates.INSTANCE.config.toolbar.quickCommandsClickType == 0 && - !Mouse.getEventButtonState() && + (NotEnoughUpdates.INSTANCE.config.toolbar.quickCommandsClickType == 0 && !Mouse.getEventButtonState() && Mouse.getEventButton() != -1)) { if (quickCommandStr.contains(":")) { String command = quickCommandStr.split(":")[0].trim(); @@ -523,12 +520,12 @@ public void mouseClick(float x, float y, int mouseX, int mouseY) { } @Override - public void mouseClickOutside() { - } + public void mouseClickOutside() {} @Override public void render(float x, float y) { if (!NotEnoughUpdates.INSTANCE.config.toolbar.quickCommands) return; + if (EnchantingSolvers.disableButtons()) return; int paddingUnscaled = getPaddingUnscaled(); int bigItemSize = getSearchBarYSize(); @@ -574,7 +571,7 @@ public void render(float x, float y) { tag.setString("qc_id", quickCommandStrSplit[0].toLowerCase().trim()); render.setTagCompound(tag); - Minecraft.getMinecraft().getTextureManager().bindTexture(quickcommand_background); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.quickcommand_background); GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect(x, y, bigItemSize + paddingUnscaled * 2, bigItemSize + paddingUnscaled * 2, GL11.GL_NEAREST @@ -582,8 +579,7 @@ public void render(float x, float y) { int mouseX = Mouse.getX() * Utils.peekGuiScale().getScaledWidth() / Minecraft.getMinecraft().displayWidth; int mouseY = Utils.peekGuiScale().getScaledHeight() - - Mouse.getY() * Utils.peekGuiScale().getScaledHeight() / Minecraft.getMinecraft().displayHeight - - 1; + Mouse.getY() * Utils.peekGuiScale().getScaledHeight() / Minecraft.getMinecraft().displayHeight - 1; if (mouseX > x && mouseX < x + bigItemSize) { if (mouseY > y && mouseY < y + bigItemSize) { @@ -619,8 +615,11 @@ public int getPadding() { } private MBGuiGroupAligned createSearchBarGroup() { - List children = - Lists.newArrayList(createSettingsButton(this), createSearchBar(), createHelpButton(this)); + List children = Lists.newArrayList( + createSettingsButton(this), + createSearchBar(), + createHelpButton(this) + ); return new MBGuiGroupAligned(children, false) { public int getPadding() { return getPaddingUnscaled() * 4; @@ -714,19 +713,33 @@ public void reset() { public void showInfo(JsonObject item) { if (item.has("info") && item.has("infoType")) { JsonArray lore = item.get("info").getAsJsonArray(); - StringBuilder loreBuilder = new StringBuilder(); - for (int i = 0; i < lore.size(); i++) { - loreBuilder.append(lore.get(i).getAsString()); - if (i != lore.size() - 1) - loreBuilder.append("\n"); + String infoType = item.get("infoType").getAsString(); + String infoText = ""; + if (infoType.equals("WIKI_URL")) { + for (JsonElement url : lore) { + infoText = url.getAsString(); + if ( + url.getAsString().startsWith("https://wiki.hypixel.net/") && NotEnoughUpdates.INSTANCE.config.misc.wiki == 0 + || url.getAsString().startsWith("https://hypixel-skyblock.fandom.com/") && + NotEnoughUpdates.INSTANCE.config.misc.wiki == 1) break; + } + } else { + StringBuilder loreBuilder = new StringBuilder(); + for (int i = 0; i < lore.size(); i++) { + loreBuilder.append(lore.get(i).getAsString()); + if (i != lore.size() - 1) + loreBuilder.append("\n"); + } + infoText = loreBuilder.toString(); } - String infoText = loreBuilder.toString(); String internalname = item.get("internalname").getAsString(); String name = item.get("displayname").getAsString(); - String infoType = item.get("infoType").getAsString(); - displayInformationPane(new TextInfoPane(this, manager, "Loading", "Loading your requested information about " + - name + - ".")); + displayInformationPane(new TextInfoPane( + this, + manager, + EnumChatFormatting.GRAY + "Loading", + EnumChatFormatting.GRAY + "Loading your requested information about " + name + EnumChatFormatting.GRAY + "." + )); infoPaneLoadingJob = InfoPane.create(this, manager, infoType, name, internalname, infoText) .thenAccept(this::displayInformationPane); } @@ -740,7 +753,9 @@ public void mouseInputInv() { if (slot != null) { ItemStack hover = slot.getStack(); if (hover != null) { - textField.setText("id:" + manager.getInternalNameForItem(hover)); + if (manager.getInternalNameForItem(hover) != null) { + textField.setText("id:" + manager.getInternalNameForItem(hover)); + } itemPaneOpen = true; updateSearch(); } @@ -752,7 +767,7 @@ public void mouseInputInv() { /** * Handles the mouse input, cancelling the forge event if a NEU gui element is clicked. */ - public boolean mouseInput() { + public synchronized boolean mouseInput() { if (disabled) { return false; } @@ -785,6 +800,10 @@ public boolean mouseInput() { if (selectedItemGroup != null) { int selectedX = Math.min(selectedItemGroupX, width - getBoxPadding() - 18 * selectedItemGroup.size()); if (mouseY > selectedItemGroupY + 17 && mouseY < selectedItemGroupY + 35) { + if (!Mouse.getEventButtonState()) { + Utils.pushGuiScale(-1); + return true; //End early if the mouse isn't pressed, but still cancel event. + } for (int i = 0; i < selectedItemGroup.size(); i++) { if (mouseX >= selectedX - 1 + 18 * i && mouseX <= selectedX + 17 + 18 * i) { JsonObject item = selectedItemGroup.get(i); @@ -941,7 +960,7 @@ public int getPaddingUnscaled() { return paddingUnscaled; } - public GuiTextField getTextField() { + public static GuiTextField getTextField() { return textField; } @@ -1006,7 +1025,6 @@ public void setSearchBarFocus(boolean focus) { */ public boolean keyboardInput(boolean hoverInv) { if (Minecraft.getMinecraft().currentScreen == null) return false; - Keyboard.enableRepeatEvents(true); int keyPressed = Keyboard.getEventKey() == 0 ? Keyboard.getEventCharacter() + 256 : Keyboard.getEventKey(); @@ -1062,7 +1080,7 @@ public boolean keyboardInput(boolean hoverInv) { internalname.set(manager.getInternalNameForItem(hover)); itemstack.set(hover); } - } else if (!hoverInv) { + } else { Utils.pushGuiScale(NotEnoughUpdates.INSTANCE.config.itemlist.paneGuiScale); int width = Utils.peekGuiScale().getScaledWidth(); @@ -1097,9 +1115,10 @@ public void consume(int x, int y, int id) { } if (internalname.get() != null) { if (itemstack.get() != null) { - if (NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing && Keyboard.getEventCharacter() == 'k') { - Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager, - internalname.get(), manager.getJsonForItem(itemstack.get()) + if (NotEnoughUpdates.INSTANCE.config.apiData.repositoryEditing && Keyboard.getEventCharacter() == 'k') { + Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor( + internalname.get(), + manager.getJsonForItem(itemstack.get()) )); return true; } @@ -1120,11 +1139,9 @@ public void consume(int x, int y, int id) { Minecraft.getMinecraft().thePlayer.inventory.addItemStackToInventory( manager.jsonToStack(item)); } - } else if (NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing && + } else if (NotEnoughUpdates.INSTANCE.config.apiData.repositoryEditing && Keyboard.getEventCharacter() == 'k') { - Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(manager, - internalname.get(), item - )); + Minecraft.getMinecraft().displayGuiScreen(new NEUItemEditor(internalname.get(), item)); return true; } else if (keyPressed == manager.keybindItemSelect.getKeyCode() && NotEnoughUpdates.INSTANCE.config.toolbar.searchBar) { @@ -1153,40 +1170,6 @@ public void toggleFavourite(String internalname) { updateSearch(); } - String[] rarityArr = new String[]{ - EnumChatFormatting.WHITE + EnumChatFormatting.BOLD.toString() + "COMMON", - EnumChatFormatting.GREEN + EnumChatFormatting.BOLD.toString() + "UNCOMMON", - EnumChatFormatting.BLUE + EnumChatFormatting.BOLD.toString() + "RARE", - EnumChatFormatting.DARK_PURPLE + EnumChatFormatting.BOLD.toString() + "EPIC", - EnumChatFormatting.GOLD + EnumChatFormatting.BOLD.toString() + "LEGENDARY", - EnumChatFormatting.LIGHT_PURPLE + EnumChatFormatting.BOLD.toString() + "MYTHIC", - EnumChatFormatting.RED + EnumChatFormatting.BOLD.toString() + "SPECIAL", - }; - - /** - * Finds the rarity from the lore of an item. - * -1 = UNKNOWN - * 0 = COMMON - * 1 = UNCOMMON - * 2 = RARE - * 3 = EPIC - * 4 = LEGENDARY - * 5 = MYTHIC - * 6 = SPECIAL - */ - public int getRarity(JsonArray lore) { - for (int i = lore.size() - 1; i >= 0; i--) { - String line = lore.get(i).getAsString(); - - for (int j = 0; j < rarityArr.length; j++) { - if (line.startsWith(rarityArr[j])) { - return j; - } - } - } - return -1; - } - /** * Convenience functions that get various compare/sort modes from the config. */ @@ -1214,19 +1197,21 @@ private Comparator getItemComparator() { return (o1, o2) -> { //1 (mult) if o1 should appear after o2 //-1 (-mult) if o2 should appear after o1 - if (getFavourites().contains(o1.get("internalname").getAsString()) && - !getFavourites().contains(o2.get("internalname").getAsString())) { + if (getFavourites().contains(o1.get("internalname").getAsString()) && !getFavourites().contains(o2 + .get("internalname") + .getAsString())) { return -1; } - if (!getFavourites().contains(o1.get("internalname").getAsString()) && - getFavourites().contains(o2.get("internalname").getAsString())) { + if (!getFavourites().contains(o1.get("internalname").getAsString()) && getFavourites().contains(o2 + .get("internalname") + .getAsString())) { return 1; } int mult = getCompareAscending().get(getCompareMode()) ? 1 : -1; if (getCompareMode() == COMPARE_MODE_RARITY) { - int rarity1 = getRarity(o1.get("lore").getAsJsonArray()); - int rarity2 = getRarity(o2.get("lore").getAsJsonArray()); + int rarity1 = Utils.getRarityFromLore(o1.get("lore").getAsJsonArray()); + int rarity2 = Utils.getRarityFromLore(o2.get("lore").getAsJsonArray()); if (rarity1 < rarity2) return mult; if (rarity1 > rarity2) return -mult; @@ -1234,8 +1219,8 @@ private Comparator getItemComparator() { String internal1 = o1.get("internalname").getAsString(); String internal2 = o2.get("internalname").getAsString(); - float cost1 = manager.auctionManager.getLowestBin(internal1); - float cost2 = manager.auctionManager.getLowestBin(internal2); + double cost1 = manager.auctionManager.getBazaarOrBin(internal1); + double cost2 = manager.auctionManager.getBazaarOrBin(internal2); if (cost1 < cost2) return mult; if (cost1 > cost2) return -mult; @@ -1280,7 +1265,7 @@ public int checkItemType(JsonArray lore, String... typeMatches) { for (int i = lore.size() - 1; i >= 0; i--) { String line = lore.get(i).getAsString(); - for (String rarity : rarityArr) { + for (String rarity : Utils.rarityArrC) { for (int j = 0; j < typeMatches.length; j++) { if (line.trim().equals(rarity + " " + typeMatches[j])) { return j; @@ -1295,14 +1280,13 @@ public int checkItemType(JsonArray lore, String... typeMatches) { * Checks whether an item matches the current sort mode. */ public boolean checkMatchesSort(String internalname, JsonObject item) { - if (!NotEnoughUpdates.INSTANCE.config.itemlist.showVanillaItems && - item.has("vanilla") && + if (!NotEnoughUpdates.INSTANCE.config.itemlist.showVanillaItems && item.has("vanilla") && item.get("vanilla").getAsBoolean()) { return false; } if (getSortMode() == SORT_MODE_ALL) { - return !internalname.matches(mobRegex); + return NotEnoughUpdates.INSTANCE.config.itemlist.alwaysShowMonsters || !internalname.matches(mobRegex); } else if (getSortMode() == SORT_MODE_MOB) { return internalname.matches(mobRegex); } else if (getSortMode() == SORT_MODE_PET) { @@ -1321,13 +1305,13 @@ public boolean checkMatchesSort(String internalname, JsonObject item) { "DUNGEON SWORD", "DUNGEON BOW", "DRILL", - "GAUNTLET" + "GAUNTLET", + "LONGSWORD", + "DEPLOYABLE" ) >= 0; } else if (getSortMode() == SORT_MODE_ARMOR) { return checkItemType( - item - .get("lore") - .getAsJsonArray(), + item.get("lore").getAsJsonArray(), "HELMET", "CHESTPLATE", "LEGGINGS", @@ -1335,9 +1319,13 @@ public boolean checkMatchesSort(String internalname, JsonObject item) { "DUNGEON HELMET", "DUNGEON CHESTPLATE", "DUNGEON LEGGINGS", - "DUNGEON BOOTS" - ) >= - 0; + "DUNGEON BOOTS", + "BELT", + "GLOVES", + "CLOAK", + "NECKLACE", + "BRACELET" + ) >= 0; } else if (getSortMode() == SORT_MODE_ACCESSORY) { return checkItemType(item.get("lore").getAsJsonArray(), "ACCESSORY", "HATCCESSORY", "DUNGEON ACCESSORY") >= 0; } @@ -1449,7 +1437,7 @@ public void updateSearch() { * Returns an index-able array containing the elements in searchedItems. * Whenever searchedItems is updated in updateSearch(), the array is recreated here. */ - public List getSearchedItems() { + public synchronized List getSearchedItems() { if (searchedItems == null) { updateSearch(); return new ArrayList<>(); @@ -1472,7 +1460,7 @@ public JsonObject getSearchedItemPage(int index) { if (index < getSlotsXSize() * getSlotsYSize()) { int actualIndex = index + getSlotsXSize() * getSlotsYSize() * page; List searchedItems = getSearchedItems(); - if (actualIndex < searchedItems.size()) { + if (0 <= actualIndex && actualIndex < searchedItems.size()) { return searchedItems.get(actualIndex); } else { return null; @@ -1620,12 +1608,12 @@ public void renderNavElement(int leftSide, int rightSide, int maxPages, int page drawRect(leftSide - 1, top, leftSide - 1 + buttonXSize, top + ySize, fg.getRGB()); GlStateManager.color(1f, 1f, 1f, 1f); - Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.rightarrow); Utils.drawTexturedRect(leftSide - 1 + leftPressed, top + leftPressed, buttonXSize, ySize, 1, 0, 0, 1 ); - Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow_overlay); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.rightarrow_overlay); Utils.drawTexturedRect(leftSide - 1, top, buttonXSize, ySize, 1 - leftPressed, leftPressed, 1 - leftPressed, leftPressed @@ -1639,12 +1627,12 @@ public void renderNavElement(int leftSide, int rightSide, int maxPages, int page drawRect(rightSide + 1 - buttonXSize, top, rightSide + 1, top + ySize, fg.getRGB()); GlStateManager.color(1f, 1f, 1f, 1f); - Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.rightarrow); Utils.drawTexturedRect(rightSide + 1 - buttonXSize + rightPressed, top + rightPressed, buttonXSize, ySize ); - Minecraft.getMinecraft().getTextureManager().bindTexture(rightarrow_overlay); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.rightarrow_overlay); Utils.drawTexturedRect(rightSide + 1 - buttonXSize, top, buttonXSize, ySize, 1 - rightPressed, rightPressed, 1 - rightPressed, rightPressed @@ -1802,129 +1790,13 @@ public void updateGuiGroupSize() { int guiScaleLast = 0; private boolean showVanillaLast = false; - - private boolean wardrobeOpen = false; - - private boolean isInNamedGui(String guiName) { - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - IInventory lower = container.getLowerChestInventory(); - String containerName = lower.getDisplayName().getUnformattedText(); - wardrobeOpen = containerName.contains(guiName); - } - if (guiScreen instanceof GuiInventory) { - wardrobeOpen = false; - } - return wardrobeOpen; - } - - private int wardrobePage = -1; - - private int getWardrobePage() { - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - if (isInNamedGui("Wardrobe")) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - ContainerChest container = (ContainerChest) chest.inventorySlots; - IInventory lower = container.getLowerChestInventory(); - String containerName = lower.getDisplayName().getUnformattedText(); - try { - wardrobePage = Integer.parseInt(containerName.substring(10, 11)); - } catch (NumberFormatException e) { - System.out.println(containerName.charAt(10)); - System.out.println("Did hypixel change the wardrobe string?"); - wardrobePage = -1; - } - } else wardrobePage = -1; - } - return wardrobePage; - } - - private ItemStack getChestSlotsAsItemStack(int slot) { - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - if (guiScreen instanceof GuiChest) { - GuiChest chest = (GuiChest) Minecraft.getMinecraft().currentScreen; - return chest.inventorySlots.getSlot(slot).getStack(); - } else { - return null; - } - } - - private int selectedArmor = 9; - - private int getEquippedArmor() { - if (!isInNamedGui("Wardrobe")) return selectedArmor; - - ItemStack nullTest1 = getChestSlotsAsItemStack(8); - ItemStack nullTest2 = getChestSlotsAsItemStack(17); - ItemStack nullTest3 = getChestSlotsAsItemStack(26); - ItemStack nullTest4 = getChestSlotsAsItemStack(35); - ItemStack nullTest5 = getChestSlotsAsItemStack(44); - if (nullTest1 != null || nullTest2 != null || nullTest3 != null || nullTest4 != null || nullTest5 != null) { - selectedArmor = 9; - } - for (int ii = 1; ii < 5; ii++) { - if (ii != 1 && selectedArmor != 9) continue; - if (getWardrobePage() != ii) continue; - for (int i = 8; i < 54; i += 9) { - ItemStack stack1 = getChestSlotsAsItemStack(i); - if (stack1 == null) continue; - String[] lore1 = NotEnoughUpdates.INSTANCE.manager.getLoreFromNBT(stack1.getTagCompound()); - for (String line : lore1) { - if (line.contains("to unequip this armor")) { - selectedArmor = i; - break; - } - } - } - } - return selectedArmor; - } - - private ItemStack getWardrobeSlot(int armourSlot) { - if (isInNamedGui("Wardrobe")) { - if (getChestSlotsAsItemStack(getEquippedArmor() - armourSlot) != null && getEquippedArmor() != 9) { - return getChestSlotsAsItemStack(getEquippedArmor() - armourSlot); - } else return null; - } else return null; - } - - public boolean isWardrobeSystemOnMainServer() { - JsonElement alphaWardrobeElement = Utils.getElement(Constants.DISABLE, "wardrobeFeature"); - if (alphaWardrobeElement == null || !alphaWardrobeElement.isJsonObject()) { - return true; - } - JsonObject isWardrobe = alphaWardrobeElement.getAsJsonObject(); - if (isWardrobe.has("enableNewWardrob")) { - return isWardrobe.get("enableNewWardrob").getAsBoolean(); - } else { - return true; - } - } - - public ItemStack slot1 = null; - public ItemStack slot2 = null; - public ItemStack slot3 = null; - public ItemStack slot4 = null; - public ItemStack petSlot = null; - - public static boolean isRenderingArmorHud() { - return renderingArmorHud; - } - - public static boolean isRenderingPetHud() { - return renderingPetHud; - } - /** * Renders the search bar, quick commands, item selection (right), item info (left) and armor hud gui elements. */ public void render(boolean hoverInv) { - if (disabled) return; - renderingArmorHud = false; - renderingPetHud = false; + if (disabled) { + return; + } GlStateManager.enableDepth(); FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; @@ -1948,236 +1820,13 @@ public void render(boolean hoverInv) { Utils.drawTexturedRect((width - 64) / 2f, (height - 64) / 2f - 114, 64, 64, GL11.GL_LINEAR); GlStateManager.bindTexture(0); } - GuiScreen guiScreen = Minecraft.getMinecraft().currentScreen; - - if (NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud && - NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect - && - NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() && - isWardrobeSystemOnMainServer()) { - if (getWardrobeSlot(1) != null) { - slot1 = getWardrobeSlot(4); - slot2 = getWardrobeSlot(3); - slot3 = getWardrobeSlot(2); - slot4 = getWardrobeSlot(1); - } - if (guiScreen instanceof GuiInventory) { - renderingArmorHud = true; - selectedArmor = 9; - - List tooltipToDisplay = null; - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 0) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY); - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_GREY); - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 2) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_DARK); - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 3) { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3 && - NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay && - petSlot != null) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT_PET); - } else { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_TRANSPARENT); - } - } - if (NotEnoughUpdates.INSTANCE.config.customArmour.colourStyle == 4) { - Minecraft.getMinecraft().getTextureManager().bindTexture(ARMOR_DISPLAY_FSR); - } - - GlStateManager.color(1, 1, 1, 1); - GL11.glTranslatef(0, 0, 401); - float yNumber = (float) (height - 167) / 2f; - Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 86, GL11.GL_NEAREST); - GlStateManager.bindTexture(0); - Utils.drawItemStack(slot1, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105)); - Utils.drawItemStack(slot2, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 18); - Utils.drawItemStack(slot3, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 36); - Utils.drawItemStack(slot4, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 54); - if (slot1 == null) { - Minecraft.getMinecraft().getTextureManager().bindTexture(QUESTION_MARK); - GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(((width - 208) / 2f), ((height + 60) / 2f - 105), 16, 16, GL11.GL_NEAREST); - GlStateManager.bindTexture(0); - - tooltipToDisplay = Lists.newArrayList( - EnumChatFormatting.RED + "Warning", - EnumChatFormatting.GREEN + "You need to open /wardrobe", - EnumChatFormatting.GREEN + "To cache your armour" - ); - if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { - if (mouseY >= ((height + 60) / 2f - 105) && - mouseY <= ((height + 60) / 2f - 105) + 70 && - NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand) { - if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { - if (Mouse.getEventButtonState()) { - if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/wardrobe") == - 0) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/wardrobe"); - } - } - } - } - if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) { - Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); - GL11.glTranslatef(0, 0, -401); - } - } - - } - if (slot1 != null && slot2 != null && slot3 != null && slot4 != null) { - if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { - if (mouseY >= ((height + 60) / 2f - 105) && - mouseY <= ((height + 60) / 2f - 105) + 70 && - NotEnoughUpdates.INSTANCE.config.customArmour.sendWardrobeCommand) { - if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { - if (Mouse.getEventButtonState()) { - if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/wardrobe") == - 0) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/wardrobe"); - } - } - } - } - //top slot - if (mouseY >= ((height + 60) / 2f - 105) && mouseY <= ((height + 60) / 2f - 105) + 16) { - tooltipToDisplay = slot1.getTooltip(Minecraft.getMinecraft().thePlayer, false); - Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); - tooltipToDisplay = null; - GL11.glTranslatef(0, 0, -401); - } - if (mouseY >= ((height + 60) / 2f - 105) + 18 && mouseY <= ((height + 60) / 2f - 105) + 34) { - tooltipToDisplay = slot2.getTooltip(Minecraft.getMinecraft().thePlayer, false); - Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); - tooltipToDisplay = null; - GL11.glTranslatef(0, 0, -401); - } - if (mouseY >= ((height + 60) / 2f - 105) + 36 && mouseY <= ((height + 60) / 2f - 105) + 52) { - tooltipToDisplay = slot3.getTooltip(Minecraft.getMinecraft().thePlayer, false); - Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); - tooltipToDisplay = null; - GL11.glTranslatef(0, 0, -401); - } - if (mouseY >= ((height + 60) / 2f - 105) + 54 && mouseY <= ((height + 60) / 2f - 105) + 70) { - tooltipToDisplay = slot4.getTooltip(Minecraft.getMinecraft().thePlayer, false); - Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); - tooltipToDisplay = null; - GL11.glTranslatef(0, 0, -401); - } - } - GL11.glTranslatef(0, 0, -401); - } - } - } - if (PetInfoOverlay.getCurrentPet() != null) { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.petInvDisplay - && - (NotEnoughUpdates.INSTANCE.manager - .jsonToStack(NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .get(PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)) - .hasDisplayName() - || - NotEnoughUpdates.INSTANCE.manager - .jsonToStack(NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .get(PetInfoOverlay.getCurrentPet().petType + ";" + (PetInfoOverlay.getCurrentPet().rarity.petId - 1))) - .hasDisplayName()) - && - NotEnoughUpdates.INSTANCE.config.misc.hidePotionEffect && - NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { - if (!NotEnoughUpdates.INSTANCE.manager - .jsonToStack( - NotEnoughUpdates.INSTANCE.manager - .getItemInformation() - .get(PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)) - .hasDisplayName()) { - petSlot = NotEnoughUpdates.INSTANCE.manager.jsonToStack( - NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( - PetInfoOverlay.getCurrentPet().petType + ";" + (PetInfoOverlay.getCurrentPet().rarity.petId - 1))); - } else { - petSlot = NotEnoughUpdates.INSTANCE.manager.jsonToStack( - NotEnoughUpdates.INSTANCE.manager.getItemInformation().get( - PetInfoOverlay.getCurrentPet().petType + ";" + PetInfoOverlay.getCurrentPet().rarity.petId)); - } - petSlot.getTagCompound().setBoolean("NEUPETINVDISPLAY", true); - petSlot - .getTagCompound() - .setBoolean("NEUHIDEPETTOOLTIP", NotEnoughUpdates.INSTANCE.config.petOverlay.hidePetTooltip); - ItemStack petInfo = petSlot; - - if (guiScreen instanceof GuiInventory) { - GL11.glTranslatef(0, 0, 401); - if (!NotEnoughUpdates.INSTANCE.config.customArmour.enableArmourHud || !isWardrobeSystemOnMainServer()) { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_GREY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_DARK); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_TRANSPARENT); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_DISPLAY_FSR); - } - } else { - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 0) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 1) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_GREY); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 2) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_DARK); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 3) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_TRANSPARENT); - } - if (NotEnoughUpdates.INSTANCE.config.petOverlay.colourStyle == 4) { - Minecraft.getMinecraft().getTextureManager().bindTexture(PET_ARMOR_DISPLAY_FSR); - } - } - - GlStateManager.color(1, 1, 1, 1); - float yNumber = (float) (height - 23) / 2f; - Utils.drawTexturedRect((float) ((width - 224.1) / 2f), yNumber, 31, 32, GL11.GL_NEAREST); - GlStateManager.bindTexture(0); - - Utils.drawItemStack(petInfo, (int) ((width - 208) / 2f), (int) ((height + 60) / 2f - 105) + 72); - renderingPetHud = true; - - List tooltipToDisplay = null; - if (petInfo != null) { - if (mouseX >= ((width - 208) / 2f) && mouseX < ((width - 208) / 2f) + 16) { - if (mouseY >= ((height + 60) / 2f - 105) + 72 && - mouseY <= ((height + 60) / 2f - 105) + 88 && - NotEnoughUpdates.INSTANCE.config.petOverlay.sendPetsCommand) { - if (Minecraft.getMinecraft().thePlayer.inventory.getItemStack() == null) { - if (Mouse.getEventButtonState()) { - if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, "/pets") == - 0) { - NotEnoughUpdates.INSTANCE.sendChatMessage("/pets"); - } - } - } - tooltipToDisplay = petInfo.getTooltip(Minecraft.getMinecraft().thePlayer, false); - Utils.drawHoveringText(tooltipToDisplay, mouseX, mouseY, width, height, -1, fr); - tooltipToDisplay = null; - GL11.glTranslatef(0, 0, -80); - } - } - - } - } - } + if (textField.getText().toLowerCase().contains("lunar")) { + Minecraft.getMinecraft().getTextureManager().bindTexture(ATMOULBERRYWHYISMYLUNARCLIENTBUGGING); + GlStateManager.color(1, 1, 1, 1); + GlStateManager.translate(0, 0, 100); + Utils.drawTexturedRect((width + 410) / 2f, (height + 450) / 2f - 114, 113, 64, GL11.GL_LINEAR); + GlStateManager.bindTexture(0); } SunTzu.setEnabled(textField.getText().toLowerCase().startsWith("potato")); @@ -2208,6 +1857,13 @@ public void render(boolean hoverInv) { (int) (fgFavourite2.getBlue() * 0.8f), fgFavourite2.getAlpha() ); + if (!NotEnoughUpdates.INSTANCE.config.itemlist.openWhenSearching && searchMode) { + itemPaneOpen = false; + } + if (itemPaneShouldOpen != -1 && System.currentTimeMillis() > itemPaneShouldOpen) { + itemPaneOpen = true; + itemPaneShouldOpen = -1; + } if (itemPaneOpen) { if (itemPaneTabOffset.getValue() == 0) { if (itemPaneOffsetFactor.getTarget() != 2 / 3f) { @@ -2252,7 +1908,7 @@ public void render(boolean hoverInv) { //Tab if (NotEnoughUpdates.INSTANCE.config.itemlist.tabOpen) { - Minecraft.getMinecraft().getTextureManager().bindTexture(itemPaneTabArrow); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.itemPaneTabArrow); GlStateManager.color(1f, 1f, 1f, 0.3f); Utils.drawTexturedRect(width - itemPaneTabOffset.getValue() * 64 / 20f, height / 2f - 32, 64, 64); GlStateManager.bindTexture(0); @@ -2308,17 +1964,14 @@ public void render(boolean hoverInv) { int orderIconX = leftSide + getBoxPadding() + getItemBoxXPadding() + i * scaledItemPaddedSize; drawRect(orderIconX, iconTop, scaledITEM_SIZE + orderIconX, iconTop + scaledITEM_SIZE, fg.getRGB()); - Minecraft - .getMinecraft() - .getTextureManager() - .bindTexture(getCompareMode() == i ? orderIconsActive[i] : orderIcons[i]); + Minecraft.getMinecraft().getTextureManager().bindTexture( + getCompareMode() == i ? orderIconsActive[i] : orderIcons[i]); GlStateManager.color(1f, 1f, 1f, 1f); Utils.drawTexturedRect(orderIconX, iconTop, scaledITEM_SIZE, scaledITEM_SIZE, 0, 1, 0, 1, GL11.GL_NEAREST); - Minecraft - .getMinecraft() - .getTextureManager() - .bindTexture(getCompareAscending().get(i) ? ascending_overlay : descending_overlay); + Minecraft.getMinecraft().getTextureManager().bindTexture(getCompareAscending().get(i) + ? GuiTextures.ascending_overlay + : GuiTextures.descending_overlay); GlStateManager.color(1f, 1f, 1f, 1f); Utils.drawTexturedRect(orderIconX, iconTop, scaledITEM_SIZE, scaledITEM_SIZE, 0, 1, 0, 1, GL11.GL_NEAREST); GlStateManager.bindTexture(0); @@ -2341,10 +1994,8 @@ public void render(boolean hoverInv) { for (int i = 0; i < sortIcons.length; i++) { int sortIconX = rightSide - scaledITEM_SIZE - i * scaledItemPaddedSize; drawRect(sortIconX, iconTop, scaledITEM_SIZE + sortIconX, iconTop + scaledITEM_SIZE, fg.getRGB()); - Minecraft - .getMinecraft() - .getTextureManager() - .bindTexture(getSortMode() == i ? sortIconsActive[i] : sortIcons[i]); + Minecraft.getMinecraft().getTextureManager().bindTexture( + getSortMode() == i ? sortIconsActive[i] : sortIcons[i]); GlStateManager.color(1f, 1f, 1f, 1f); Utils.drawTexturedRect(sortIconX, iconTop, scaledITEM_SIZE, scaledITEM_SIZE, 0, 1, 0, 1, GL11.GL_NEAREST); GlStateManager.bindTexture(0); @@ -2504,7 +2155,7 @@ public void consume(int x, int y, int id) { activeInfoPane.render(width, height, bg, fg, Utils.peekGuiScale(), mouseX, mouseY); GlStateManager.color(1f, 1f, 1f, 1f); - Minecraft.getMinecraft().getTextureManager().bindTexture(close); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.close); Utils.drawTexturedRect(rightSide - getBoxPadding() - 8, getBoxPadding() - 8, 16, 16); GL11.glBindTexture(GL11.GL_TEXTURE_2D, 0); } @@ -2550,7 +2201,6 @@ public void consume(int x, int y, int id) { GlStateManager.enableAlpha(); GlStateManager.alphaFunc(516, 0.1F); GlStateManager.disableLighting(); - Utils.pushGuiScale(-1); if (System.currentTimeMillis() - lastSearchMode > 120000 && @@ -2560,6 +2210,7 @@ public void consume(int x, int y, int id) { } } + /** * Used in SettingsInfoPane to redraw the items when a setting changes. */ @@ -2585,8 +2236,7 @@ private void checkFramebufferSizes(int width, int height) { int sw = width * Utils.peekGuiScale().getScaleFactor(); int sh = height * Utils.peekGuiScale().getScaleFactor(); for (int i = 0; i < itemFramebuffers.length; i++) { - if (itemFramebuffers[i] == null || - itemFramebuffers[i].framebufferWidth != sw || + if (itemFramebuffers[i] == null || itemFramebuffers[i].framebufferWidth != sw || itemFramebuffers[i].framebufferHeight != sh) { if (itemFramebuffers[i] == null) { itemFramebuffers[i] = new Framebuffer(sw, sh, true); @@ -2772,7 +2422,7 @@ public void consume(int x, int y, int id) { return; } - Minecraft.getMinecraft().getTextureManager().bindTexture(item_mask); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.item_mask); if (getFavourites().contains(json.get("internalname").getAsString())) { if (NotEnoughUpdates.INSTANCE.config.itemlist.itemStyle == 0) { GlStateManager.color(fgFavourite2.getRed() / 255f, fgFavourite2.getGreen() / 255f, @@ -2854,7 +2504,7 @@ public void consume(int x, int y, int id) { GlStateManager.translate(0, 0, 50); if (searchedItemsSubgroup.containsKey(json.get("internalname").getAsString())) { - Minecraft.getMinecraft().getTextureManager().bindTexture(item_haschild); + Minecraft.getMinecraft().getTextureManager().bindTexture(GuiTextures.item_haschild); GlStateManager.color(1, 1, 1, 1); Utils.drawTexturedRect(x - 1, y - 1, ITEM_SIZE + 2, ITEM_SIZE + 2, GL11.GL_NEAREST); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NEURepoResourcePack.java b/src/main/java/io/github/moulberry/notenoughupdates/NEURepoResourcePack.java new file mode 100644 index 0000000000..bc279188d0 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/NEURepoResourcePack.java @@ -0,0 +1,99 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates; + +import com.google.gson.JsonObject; +import net.minecraft.client.resources.IResourcePack; +import net.minecraft.client.resources.data.IMetadataSection; +import net.minecraft.client.resources.data.IMetadataSerializer; +import net.minecraft.util.ResourceLocation; + +import java.awt.image.BufferedImage; +import java.io.BufferedInputStream; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; +import java.util.HashSet; +import java.util.Set; + +public class NEURepoResourcePack implements IResourcePack { + + File repoLocation; + Set resourceDomains = new HashSet<>(); + + public NEURepoResourcePack(File repoLocation, String domain) { + this.repoLocation = repoLocation; + resourceDomains.add(domain); + } + + public boolean loadRepoLocation() { + if (repoLocation != null) return true; + NotEnoughUpdates instance = NotEnoughUpdates.INSTANCE; + if (instance == null) return false; + NEUManager manager = instance.manager; + if (manager == null) return false; + repoLocation = manager.repoLocation; + return repoLocation != null; + } + + public File getFileForResource(ResourceLocation loc) { + if (repoLocation == null) { + if (!loadRepoLocation()) + return null; + } + if (!"neurepo".equals(loc.getResourceDomain())) { + return null; + } + return new File(repoLocation, loc.getResourcePath()); + } + + @Override + public InputStream getInputStream(ResourceLocation resourceLocation) throws IOException { + return new BufferedInputStream(new FileInputStream(getFileForResource(resourceLocation))); + } + + @Override + public boolean resourceExists(ResourceLocation resourceLocation) { + File file = getFileForResource(resourceLocation); + return file != null && file.exists(); + } + + @Override + public Set getResourceDomains() { + return resourceDomains; + } + + @Override + public T getPackMetadata(IMetadataSerializer iMetadataSerializer, String s) + throws IOException { + return iMetadataSerializer.parseMetadataSection(s, new JsonObject()); + } + + @Override + public BufferedImage getPackImage() throws IOException { + return null; + } + + @Override + public String getPackName() { + return "NEU Repo Resources"; + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java index b6ac71a42c..39826dedf1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/NotEnoughUpdates.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates; import com.google.common.collect.Sets; @@ -7,22 +26,60 @@ import io.github.moulberry.notenoughupdates.commands.Commands; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; import io.github.moulberry.notenoughupdates.cosmetics.CapeManager; +import io.github.moulberry.notenoughupdates.cosmetics.ShaderManager; import io.github.moulberry.notenoughupdates.dungeons.DungeonMap; -import io.github.moulberry.notenoughupdates.miscfeatures.*; +import io.github.moulberry.notenoughupdates.listener.ChatListener; +import io.github.moulberry.notenoughupdates.listener.ItemTooltipEssenceShopListener; +import io.github.moulberry.notenoughupdates.listener.ItemTooltipListener; +import io.github.moulberry.notenoughupdates.listener.ItemTooltipRngListener; +import io.github.moulberry.notenoughupdates.listener.NEUEventListener; +import io.github.moulberry.notenoughupdates.listener.OldAnimationChecker; +import io.github.moulberry.notenoughupdates.listener.RenderListener; +import io.github.moulberry.notenoughupdates.miscfeatures.AbiphoneWarning; +import io.github.moulberry.notenoughupdates.miscfeatures.AntiCoopAdd; +import io.github.moulberry.notenoughupdates.miscfeatures.AuctionBINWarning; +import io.github.moulberry.notenoughupdates.miscfeatures.AuctionProfit; +import io.github.moulberry.notenoughupdates.miscfeatures.BetterContainers; +import io.github.moulberry.notenoughupdates.miscfeatures.CrystalOverlay; +import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver; +import io.github.moulberry.notenoughupdates.miscfeatures.CustomItemEffects; +import io.github.moulberry.notenoughupdates.miscfeatures.CustomSkulls; +import io.github.moulberry.notenoughupdates.miscfeatures.DwarvenMinesWaypoints; +import io.github.moulberry.notenoughupdates.miscfeatures.EnchantingSolvers; +import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls; +import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCooldowns; +import io.github.moulberry.notenoughupdates.miscfeatures.ItemCustomizeManager; +import io.github.moulberry.notenoughupdates.miscfeatures.MiningStuff; +import io.github.moulberry.notenoughupdates.miscfeatures.NPCRetexturing; +import io.github.moulberry.notenoughupdates.miscfeatures.Navigation; +import io.github.moulberry.notenoughupdates.miscfeatures.NullzeeSphere; +import io.github.moulberry.notenoughupdates.miscfeatures.PetInfoOverlay; +import io.github.moulberry.notenoughupdates.miscfeatures.PowerStoneStatsDisplay; +import io.github.moulberry.notenoughupdates.miscfeatures.SlotLocking; +import io.github.moulberry.notenoughupdates.miscfeatures.StorageManager; +import io.github.moulberry.notenoughupdates.miscfeatures.SunTzu; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBlockSounds; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.DwarvenMinesTextures; +import io.github.moulberry.notenoughupdates.miscfeatures.updater.AutoUpdater; import io.github.moulberry.notenoughupdates.miscgui.CalendarOverlay; import io.github.moulberry.notenoughupdates.miscgui.InventoryStorageSelector; +import io.github.moulberry.notenoughupdates.miscgui.SignCalculator; +import io.github.moulberry.notenoughupdates.miscgui.TrophyRewardOverlay; +import io.github.moulberry.notenoughupdates.mixins.AccessorMinecraft; import io.github.moulberry.notenoughupdates.options.NEUConfig; +import io.github.moulberry.notenoughupdates.overlays.EquipmentOverlay; import io.github.moulberry.notenoughupdates.overlays.FuelBar; import io.github.moulberry.notenoughupdates.overlays.OverlayManager; import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.recipes.RecipeGenerator; +import io.github.moulberry.notenoughupdates.util.Constants; import io.github.moulberry.notenoughupdates.util.SBInfo; import io.github.moulberry.notenoughupdates.util.Utils; import io.github.moulberry.notenoughupdates.util.XPInformation; import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.FontRenderer; import net.minecraft.client.gui.GuiScreen; import net.minecraft.client.resources.IReloadableResourceManager; import net.minecraft.client.settings.KeyBinding; @@ -31,82 +88,46 @@ import net.minecraft.scoreboard.Scoreboard; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; -import net.minecraft.world.biome.*; +import net.minecraft.world.biome.BiomeGenBase; +import net.minecraft.world.biome.BiomeGenHell; +import net.minecraft.world.biome.BiomeGenJungle; +import net.minecraft.world.biome.BiomeGenMesa; +import net.minecraft.world.biome.BiomeGenSnow; +import net.minecraftforge.client.ClientCommandHandler; import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.client.FMLClientHandler; import net.minecraftforge.fml.client.registry.ClientRegistry; import net.minecraftforge.fml.common.Mod; import net.minecraftforge.fml.common.Mod.EventHandler; import net.minecraftforge.fml.common.event.FMLPreInitializationEvent; import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; import net.minecraftforge.fml.common.gameevent.TickEvent; +import org.apache.logging.log4j.LogManager; +import org.apache.logging.log4j.Logger; import java.awt.*; -import java.io.*; +import java.io.BufferedReader; +import java.io.BufferedWriter; +import java.io.File; +import java.io.FileInputStream; +import java.io.FileOutputStream; +import java.io.InputStreamReader; +import java.io.OutputStreamWriter; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Set; -@Mod(modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true) +@Mod( + modid = NotEnoughUpdates.MODID, version = NotEnoughUpdates.VERSION, clientSideOnly = true, useMetadata = true, + guiFactory = "io.github.moulberry.notenoughupdates.core.config.MoulConfigGuiForgeInterop") public class NotEnoughUpdates { public static final String MODID = "notenoughupdates"; public static final String VERSION = "2.1.0-REL"; - public static final String PRE_VERSION = "0.0"; - public static final int VERSION_ID = 20100; + public static final int VERSION_ID = 20101; //2.1.1 only so update notif works public static final int PRE_VERSION_ID = 0; + public static final int HOTFIX_VERSION_ID = 0; - public static NotEnoughUpdates INSTANCE = null; - - public NEUManager manager; - public NEUOverlay overlay; - public NEUConfig config; - - private File configFile; - - public File getConfigFile() { - return this.configFile; - } - - public void newConfigFile() { - this.configFile = new File(NotEnoughUpdates.INSTANCE.getNeuDir(), "configNew.json"); - } - - private static final long CHAT_MSG_COOLDOWN = 200; - private long lastChatMessage = 0; - private long secondLastChatMessage = 0; - private String currChatMessage = null; - - //Stolen from Biscut and used for detecting whether in skyblock - private static final Set SKYBLOCK_IN_ALL_LANGUAGES = - Sets.newHashSet("SKYBLOCK", "\u7A7A\u5C9B\u751F\u5B58", "\u7A7A\u5CF6\u751F\u5B58"); - - public GuiScreen openGui = null; - public long lastOpenedGui = 0; - - public Commands commands; - - public static HashMap petRarityToColourMap = new HashMap() {{ - put("UNKNOWN", EnumChatFormatting.RED.toString()); - put("COMMON", EnumChatFormatting.WHITE.toString()); - put("UNCOMMON", EnumChatFormatting.GREEN.toString()); - put("RARE", EnumChatFormatting.BLUE.toString()); - put("EPIC", EnumChatFormatting.DARK_PURPLE.toString()); - put("LEGENDARY", EnumChatFormatting.GOLD.toString()); - put("MYTHIC", EnumChatFormatting.LIGHT_PURPLE.toString()); - }}; - - public static ProfileViewer profileViewer; - - public boolean packDevEnabled = false; - - private final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create(); - private File neuDir; - - public File getNeuDir() { - return this.neuDir; - } - - public Color[][] colourMap = null; - + public static final Logger LOGGER = LogManager.getLogger("NotEnoughUpdates"); /** * Registers the biomes for the crystal hollows here so optifine knows they exists */ @@ -140,6 +161,57 @@ public File getNeuDir() { .setBiomeName("NeuCrystalHollowsCrystalNucleus") .setFillerBlockMetadata(5470985) .setTemperatureRainfall(0.95F, 0.9F); + private static final long CHAT_MSG_COOLDOWN = 200; + //Stolen from Biscut and used for detecting whether in skyblock + private static final Set SKYBLOCK_IN_ALL_LANGUAGES = + Sets.newHashSet("SKYBLOCK", "\u7A7A\u5C9B\u751F\u5B58", "\u7A7A\u5CF6\u751F\u5B58"); + public static NotEnoughUpdates INSTANCE = null; + public static HashMap petRarityToColourMap = new HashMap() {{ + put("UNKNOWN", EnumChatFormatting.RED.toString()); + put("COMMON", EnumChatFormatting.WHITE.toString()); + put("UNCOMMON", EnumChatFormatting.GREEN.toString()); + put("RARE", EnumChatFormatting.BLUE.toString()); + put("EPIC", EnumChatFormatting.DARK_PURPLE.toString()); + put("LEGENDARY", EnumChatFormatting.GOLD.toString()); + put("MYTHIC", EnumChatFormatting.LIGHT_PURPLE.toString()); + }}; + public static ProfileViewer profileViewer; + private final Gson gson = new GsonBuilder().setPrettyPrinting().excludeFieldsWithoutExposeAnnotation().create(); + public NEUManager manager; + public NEUOverlay overlay; + public NEUConfig config; + public Navigation navigation = new Navigation(this); + public GuiScreen openGui = null; + public long lastOpenedGui = 0; + public Commands commands; + public boolean packDevEnabled = false; + public Color[][] colourMap = null; + public AutoUpdater autoUpdater = new AutoUpdater(this); + private File configFile; + private long lastChatMessage = 0; + private long secondLastChatMessage = 0; + private String currChatMessage = null; + private File neuDir; + private boolean hasSkyblockScoreboard; + + public File getConfigFile() { + return this.configFile; + } + + public void newConfigFile() { + this.configFile = new File(NotEnoughUpdates.INSTANCE.getNeuDir(), "configNew.json"); + } + + public File getNeuDir() { + return this.neuDir; + } + + public NotEnoughUpdates() { + // Budget Construction Event + ((AccessorMinecraft) FMLClientHandler.instance().getClient()) + .onGetDefaultResourcePacks() + .add(new NEURepoResourcePack(null, "neurepo")); + } /** * Instantiates NEUIo, NEUManager and NEUOverlay instances. Registers keybinds and adds a shutdown hook to clear tmp folder. @@ -161,19 +233,42 @@ public void preinit(FMLPreInitializationEvent event) { )) ) { config = gson.fromJson(reader, NEUConfig.class); - } catch (Exception ignored) { + } catch (Exception exc) { + new RuntimeException("Invalid config file. This will reset the config to default", exc).printStackTrace(); } } ItemCustomizeManager.loadCustomization(new File(neuDir, "itemCustomization.json")); StorageManager.getInstance().loadConfig(new File(neuDir, "storageItems.json")); - FairySouls.load(new File(neuDir, "collected_fairy_souls.json"), gson); + FairySouls.getInstance().loadFoundSoulsForAllProfiles(new File(neuDir, "collected_fairy_souls.json"), gson); PetInfoOverlay.loadConfig(new File(neuDir, "petCache.json")); SlotLocking.getInstance().loadConfig(new File(neuDir, "slotLocking.json")); ItemPriceInformation.init(new File(neuDir, "auctionable_items.json"), gson); if (config == null) { config = new NEUConfig(); + saveConfig(); + } else { + if (config.apiKey != null && config.apiKey.apiKey != null) { + config.apiData.apiKey = config.apiKey.apiKey; + config.apiKey = null; + } + + //add the trophy fishing tab to the config + if (config.profileViewer.pageLayout.size() == 8) { + config.profileViewer.pageLayout.add(8); + } + if (config.profileViewer.pageLayout.size() == 9) { + config.profileViewer.pageLayout.add(9); + } + + // Remove after 2.1 ig + if ("dangerous".equals(config.apiData.repoBranch) || "rune".equals(config.apiData.repoBranch)) { + config.apiData.repoBranch = "master"; + } else if ("jani270".equals(config.apiData.repoUser)) { + config.apiData.repoUser = "NotEnoughUpdates"; + } + saveConfig(); } @@ -186,15 +281,16 @@ public void preinit(FMLPreInitializationEvent event) { MinecraftForge.EVENT_BUS.register(new CalendarOverlay()); MinecraftForge.EVENT_BUS.register(SBInfo.getInstance()); MinecraftForge.EVENT_BUS.register(CustomItemEffects.INSTANCE); + MinecraftForge.EVENT_BUS.register(new Constants()); MinecraftForge.EVENT_BUS.register(new DungeonMap()); MinecraftForge.EVENT_BUS.register(new SunTzu()); MinecraftForge.EVENT_BUS.register(new MiningStuff()); - MinecraftForge.EVENT_BUS.register(new FairySouls()); + MinecraftForge.EVENT_BUS.register(FairySouls.getInstance()); MinecraftForge.EVENT_BUS.register(new CrystalOverlay()); MinecraftForge.EVENT_BUS.register(new ItemCooldowns()); MinecraftForge.EVENT_BUS.register(new DwarvenMinesWaypoints()); MinecraftForge.EVENT_BUS.register(new FuelBar()); - //MinecraftForge.EVENT_BUS.register(new FancyPortals()); + MinecraftForge.EVENT_BUS.register(new AuctionProfit()); MinecraftForge.EVENT_BUS.register(XPInformation.getInstance()); MinecraftForge.EVENT_BUS.register(OverlayManager.petInfoOverlay); MinecraftForge.EVENT_BUS.register(OverlayManager.timersOverlay); @@ -202,13 +298,30 @@ public void preinit(FMLPreInitializationEvent event) { MinecraftForge.EVENT_BUS.register(InventoryStorageSelector.getInstance()); MinecraftForge.EVENT_BUS.register(SlotLocking.getInstance()); MinecraftForge.EVENT_BUS.register(FishingHelper.getInstance()); + MinecraftForge.EVENT_BUS.register(CrystalWishingCompassSolver.getInstance()); MinecraftForge.EVENT_BUS.register(new DwarvenMinesTextures()); + MinecraftForge.EVENT_BUS.register(EquipmentOverlay.INSTANCE); MinecraftForge.EVENT_BUS.register(CustomBiomes.INSTANCE); + MinecraftForge.EVENT_BUS.register(new ChatListener(this)); + MinecraftForge.EVENT_BUS.register(new ItemTooltipListener(this)); + MinecraftForge.EVENT_BUS.register(new ItemTooltipRngListener(this)); + MinecraftForge.EVENT_BUS.register(new ItemTooltipEssenceShopListener(this)); + MinecraftForge.EVENT_BUS.register(new RenderListener(this)); + MinecraftForge.EVENT_BUS.register(new OldAnimationChecker()); + MinecraftForge.EVENT_BUS.register(new SignCalculator()); + MinecraftForge.EVENT_BUS.register(TrophyRewardOverlay.getInstance()); + MinecraftForge.EVENT_BUS.register(PowerStoneStatsDisplay.getInstance()); + MinecraftForge.EVENT_BUS.register(new AntiCoopAdd()); + MinecraftForge.EVENT_BUS.register(AbiphoneWarning.getInstance()); + MinecraftForge.EVENT_BUS.register(new BetterContainers()); + MinecraftForge.EVENT_BUS.register(AuctionBINWarning.getInstance()); + MinecraftForge.EVENT_BUS.register(navigation); if (Minecraft.getMinecraft().getResourceManager() instanceof IReloadableResourceManager) { IReloadableResourceManager manager = (IReloadableResourceManager) Minecraft.getMinecraft().getResourceManager(); manager.registerReloadListener(CustomSkulls.getInstance()); manager.registerReloadListener(NPCRetexturing.getInstance()); + manager.registerReloadListener(ShaderManager.getInstance()); manager.registerReloadListener(new ItemCustomizeManager.ReloadListener()); manager.registerReloadListener(new CustomBlockSounds.ReloaderListener()); } @@ -234,7 +347,6 @@ public void preinit(FMLPreInitializationEvent event) { } tmp.delete(); } - //saveConfig(); })); } @@ -262,7 +374,7 @@ public void saveConfig() { } catch (Exception ignored) { } try { - FairySouls.save(new File(neuDir, "collected_fairy_souls.json"), gson); + FairySouls.getInstance().saveFoundSoulsForAllProfiles(new File(neuDir, "collected_fairy_souls.json"), gson); } catch (Exception ignored) { } try { @@ -290,11 +402,16 @@ public void sendChatMessage(String message) { } } - public void displayLinks(JsonObject update) { + public void trySendCommand(String message) { + if (ClientCommandHandler.instance.executeCommand(Minecraft.getMinecraft().thePlayer, message) == 0) { + sendChatMessage(message); + } + } + + public void displayLinks(JsonObject update, int totalWidth) { String discord_link = update.get("discord_link").getAsString(); String youtube_link = update.get("youtube_link").getAsString(); String twitch_link = update.get("twitch_link").getAsString(); - String update_link = update.get("update_link").getAsString(); String github_link = update.get("github_link").getAsString(); String other_text = update.get("other_text").getAsString(); String other_link = update.get("other_link").getAsString(); @@ -307,8 +424,7 @@ public void displayLinks(JsonObject update) { } ChatComponentText links = new ChatComponentText(""); ChatComponentText separator = new ChatComponentText( - EnumChatFormatting.GRAY + EnumChatFormatting.BOLD.toString() + EnumChatFormatting.STRIKETHROUGH + - (other == null ? "--" : "-")); + EnumChatFormatting.GRAY + EnumChatFormatting.BOLD.toString() + EnumChatFormatting.STRIKETHROUGH + "-"); ChatComponentText discord = new ChatComponentText( EnumChatFormatting.GRAY + "[" + EnumChatFormatting.BLUE + "Discord" + EnumChatFormatting.GRAY + "]"); discord.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, discord_link)); @@ -318,9 +434,6 @@ public void displayLinks(JsonObject update) { ChatComponentText twitch = new ChatComponentText( EnumChatFormatting.GRAY + "[" + EnumChatFormatting.DARK_PURPLE + "Twitch" + EnumChatFormatting.GRAY + "]"); twitch.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, twitch_link)); - ChatComponentText release = new ChatComponentText( - EnumChatFormatting.GRAY + "[" + EnumChatFormatting.GREEN + "Release" + EnumChatFormatting.GRAY + "]"); - release.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, update_link)); ChatComponentText github = new ChatComponentText( EnumChatFormatting.GRAY + "[" + EnumChatFormatting.DARK_PURPLE + "GitHub" + EnumChatFormatting.GRAY + "]"); github.setChatStyle(Utils.createClickStyle(ClickEvent.Action.OPEN_URL, github_link)); @@ -332,16 +445,28 @@ public void displayLinks(JsonObject update) { links.appendSibling(separator); links.appendSibling(twitch); links.appendSibling(separator); - links.appendSibling(release); - links.appendSibling(separator); links.appendSibling(github); links.appendSibling(separator); if (other != null) { links.appendSibling(other); links.appendSibling(separator); } - - Minecraft.getMinecraft().thePlayer.addChatMessage(links); + FontRenderer fr = Minecraft.getMinecraft().fontRendererObj; + int missingWidth = Math.max(0, totalWidth - fr.getStringWidth(links.getFormattedText())); + int missingCharsOnEitherSide = missingWidth / fr.getStringWidth(EnumChatFormatting.BOLD + "-") / 2; + StringBuilder sb = new StringBuilder(missingCharsOnEitherSide + 6); + sb.append(EnumChatFormatting.GRAY); + sb.append(EnumChatFormatting.BOLD); + sb.append(EnumChatFormatting.STRIKETHROUGH); + for (int i = 0; i < missingCharsOnEitherSide; i++) { + sb.append("-"); + } + String padding = sb.toString(); + ChatComponentText cp = new ChatComponentText(""); + cp.appendText(padding); + cp.appendSibling(links); + cp.appendText(padding); + Minecraft.getMinecraft().thePlayer.addChatMessage(cp); } @SubscribeEvent @@ -374,8 +499,6 @@ public boolean isOnSkyblock() { return hasSkyblockScoreboard(); } - private boolean hasSkyblockScoreboard; - public boolean hasSkyblockScoreboard() { return hasSkyblockScoreboard; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java index c47e0844ac..1b6896dbb3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/APIManager.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.auction; import com.google.gson.JsonArray; @@ -27,10 +46,21 @@ import java.io.ByteArrayInputStream; import java.io.IOException; -import java.util.*; +import java.util.Base64; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.HashSet; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.NoSuchElementException; +import java.util.Set; +import java.util.TreeMap; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.function.Consumer; +import java.util.regex.Matcher; +import java.util.regex.Pattern; public class APIManager { private final NEUManager manager; @@ -41,6 +71,9 @@ public class APIManager { private final HashSet playerBids = new HashSet<>(); private final HashSet playerBidsNotified = new HashSet<>(); private final HashSet playerBidsFinishedNotified = new HashSet<>(); + private final int LOWEST_BIN_UPDATE_INTERVAL = 2 * 60 * 1000; // 2 minutes + private final int AUCTION_AVG_UPDATE_INTERVAL = 5 * 60 * 1000; // 5 minutes + private final int BAZAAR_UPDATE_INTERVAL = 5 * 60 * 1000; // 5 minutes private JsonObject lowestBins = null; private JsonObject auctionPricesAvgLowestBinJson = null; @@ -92,7 +125,7 @@ public HashSet getAuctionsForInternalname(String internalname) { public class Auction { public String auctioneerUuid; public long end; - public int starting_bid; + public long starting_bid; public int highest_bid_amount; public int bid_count; public boolean bin; @@ -106,7 +139,7 @@ public class Auction { public int enchLevel = 0; //0 = clean, 1 = ench, 2 = ench/hpb public Auction( - String auctioneerUuid, long end, int starting_bid, int highest_bid_amount, int bid_count, + String auctioneerUuid, long end, long starting_bid, int highest_bid_amount, int bid_count, boolean bin, String category, String rarity, int dungeonTier, String item_tag_str ) { this.auctioneerUuid = auctioneerUuid; @@ -135,6 +168,7 @@ public ItemStack getStack() { return stack; } else { JsonObject item = manager.getJsonFromNBT(item_tag); + if (item == null) return null; ItemStack stack = manager.jsonToStack(item, false); JsonObject itemDefault = manager.getItemInformation().get(item.get("internalname").getAsString()); @@ -180,8 +214,8 @@ public void tick() { customAH.tick(); long currentTime = System.currentTimeMillis(); if (NotEnoughUpdates.INSTANCE.config.neuAuctionHouse.enableNeuAuctionHouse && - NotEnoughUpdates.INSTANCE.config.apiKey.apiKey != null && - !NotEnoughUpdates.INSTANCE.config.apiKey.apiKey.isEmpty()) { + NotEnoughUpdates.INSTANCE.config.apiData.apiKey != null && + !NotEnoughUpdates.INSTANCE.config.apiData.apiKey.isEmpty()) { if (currentTime - lastAuctionUpdate > 60 * 1000) { lastAuctionUpdate = currentTime; updatePageTick(); @@ -203,15 +237,16 @@ public void tick() { } } } - if (currentTime - lastAuctionAvgUpdate > 5 * 60 * 1000) { //5 minutes - lastAuctionAvgUpdate = currentTime - 4 * 60 * 1000; //Try again in 1 minute if updateAvgPrices doesn't succeed + if (currentTime - lastAuctionAvgUpdate > AUCTION_AVG_UPDATE_INTERVAL) { + lastAuctionAvgUpdate = currentTime - AUCTION_AVG_UPDATE_INTERVAL + 60 * 1000; // Try again in 1 minute on failure updateAvgPrices(); } - if (currentTime - lastBazaarUpdate > 5 * 60 * 1000) { //5 minutes - lastBazaarUpdate = currentTime; + if (currentTime - lastBazaarUpdate > BAZAAR_UPDATE_INTERVAL) { + lastBazaarUpdate = currentTime - BAZAAR_UPDATE_INTERVAL + 60 * 1000; // Try again in 1 minute on failure updateBazaar(); } - if (currentTime - lastLowestBinUpdate > 2 * 60 * 1000) { + if (currentTime - lastLowestBinUpdate > LOWEST_BIN_UPDATE_INTERVAL) { + lastLowestBinUpdate = currentTime - LOWEST_BIN_UPDATE_INTERVAL + 30 * 1000; // Try again in 30 seconds on failure updateLowestBin(); } } @@ -241,34 +276,37 @@ public Set getLowestBinKeySet() { return keys; } - public int getLowestBin(String internalname) { - if (lowestBins != null && lowestBins.has(internalname)) { - JsonElement e = lowestBins.get(internalname); + public long getLowestBin(String internalName) { + if (lowestBins != null && lowestBins.has(internalName)) { + JsonElement e = lowestBins.get(internalName); if (e.isJsonPrimitive() && e.getAsJsonPrimitive().isNumber()) { - return e.getAsInt(); + return e.getAsBigDecimal().longValue(); } } return -1; } public void updateLowestBin() { - manager.hypixelApi.getMyApiGZIPAsync("lowestbin.json.gz", (jsonObject) -> { - if (lowestBins == null) { - lowestBins = new JsonObject(); - } - if (!jsonObject.entrySet().isEmpty()) { - lastLowestBinUpdate = System.currentTimeMillis(); - } - for (Map.Entry entry : jsonObject.entrySet()) { - lowestBins.add(entry.getKey(), entry.getValue()); - } - if (!didFirstUpdate) { - ItemPriceInformation.updateAuctionableItemsList(); - didFirstUpdate = true; - } - GuiPriceGraph.addToCache(lowestBins, false); - }, () -> { - }); + manager.apiUtils + .newMoulberryRequest("lowestbin.json.gz") + .gunzip() + .requestJson() + .thenAccept(jsonObject -> { + if (lowestBins == null) { + lowestBins = new JsonObject(); + } + if (!jsonObject.entrySet().isEmpty()) { + lastLowestBinUpdate = System.currentTimeMillis(); + } + for (Map.Entry entry : jsonObject.entrySet()) { + lowestBins.add(entry.getKey(), entry.getValue()); + } + if (!didFirstUpdate) { + ItemPriceInformation.updateAuctionableItemsList(); + didFirstUpdate = true; + } + GuiPriceGraph.addToCache(lowestBins, false); + }); } private void ahNotification() { @@ -377,6 +415,7 @@ private void updatePageTickShort() { int page = pagesToDownload.pop(); getPageFromAPI(page); } catch (NoSuchElementException ignored) { + return; } //Weird race condition? } } @@ -424,20 +463,23 @@ private void updatePageTick() { } }; - manager.hypixelApi.getMyApiGZIPAsync("auctionLast.json.gz", process, () -> - System.out.println("Error downloading auction from Moulberry's jank API. :(")); + manager.apiUtils.newMoulberryRequest("auctionLast.json.gz") + .gunzip().requestJson().thenAccept(process); - manager.hypixelApi.getMyApiGZIPAsync("auction.json.gz", jsonObject -> { - if (jsonObject.get("success").getAsBoolean()) { - long apiUpdate = (long) jsonObject.get("time").getAsFloat(); - if (lastApiUpdate == apiUpdate) { - lastAuctionUpdate -= 30 * 1000; - } - lastApiUpdate = apiUpdate; + manager.apiUtils + .newMoulberryRequest("auction.json.gz") + .gunzip().requestJson() + .thenAccept(jsonObject -> { + if (jsonObject.get("success").getAsBoolean()) { + long apiUpdate = (long) jsonObject.get("time").getAsFloat(); + if (lastApiUpdate == apiUpdate) { + lastAuctionUpdate -= 30 * 1000; + } + lastApiUpdate = apiUpdate; - process.accept(jsonObject); - } - }, () -> System.out.println("Error downloading auction from Moulberry's jank API. :(")); + process.accept(jsonObject); + } + }); } @@ -508,7 +550,7 @@ private void processAuction(JsonObject auction) { String auctionUuid = auction.get("uuid").getAsString(); String auctioneerUuid = auction.get("auctioneer").getAsString(); long end = auction.get("end").getAsLong(); - int starting_bid = auction.get("starting_bid").getAsInt(); + long starting_bid = auction.get("starting_bid").getAsLong(); int highest_bid_amount = auction.get("highest_bid_amount").getAsInt(); int bid_count = auction.get("bids").getAsJsonArray().size(); boolean bin = false; @@ -637,8 +679,10 @@ private void getPageFromAPI(int page) { //System.out.println("Trying to update page: " + page); HashMap args = new HashMap<>(); args.put("page", "" + page); - manager.hypixelApi.getHypixelApiAsync(null, "skyblock/auctions", - args, jsonObject -> { + manager.apiUtils + .newAnonymousHypixelApiRequest("skyblock/auctions") + .requestJson() + .thenAccept(jsonObject -> { if (jsonObject == null) return; if (jsonObject.get("success").getAsBoolean()) { @@ -665,16 +709,30 @@ private void getPageFromAPI(int page) { } else { pagesToDownload.addLast(page); } - }, () -> pagesToDownload.addLast(page) - ); + }) + .handle((ignored, ex) -> { + if (ex != null) { + pagesToDownload.addLast(page); + } + return null; + }); + } + + private static final Pattern BAZAAR_ENCHANTMENT_PATTERN = Pattern.compile("ENCHANTMENT_(\\D*)_(\\d+)"); + + public String transformHypixelBazaarToNEUItemId(String hypixelId) { + Matcher matcher = BAZAAR_ENCHANTMENT_PATTERN.matcher(hypixelId); + if (matcher.matches()) { + return matcher.group(1) + ";" + matcher.group(2); + } + return hypixelId.replace(":", "-"); } public void updateBazaar() { - manager.hypixelApi.getHypixelApiAsync( - NotEnoughUpdates.INSTANCE.config.apiKey.apiKey, - "skyblock/bazaar", - new HashMap<>(), - (jsonObject) -> { + manager.apiUtils + .newHypixelApiRequest("skyblock/bazaar") + .requestJson() + .thenAccept(jsonObject -> { if (!jsonObject.get("success").getAsBoolean()) return; craftCost.clear(); @@ -705,24 +763,27 @@ public void updateBazaar() { } } - bazaarJson.add(entry.getKey().replace(":", "-"), productInfo); + bazaarJson.add(transformHypixelBazaarToNEUItemId(entry.getKey()), productInfo); } } GuiPriceGraph.addToCache(bazaarJson, true); - } - ); + }); } public void updateAvgPrices() { - manager.hypixelApi.getMyApiGZIPAsync("auction_averages/3day.json.gz", (jsonObject) -> { - craftCost.clear(); - auctionPricesJson = jsonObject; - lastAuctionAvgUpdate = System.currentTimeMillis(); - }, () -> { - }); - manager.hypixelApi.getMyApiGZIPAsync("auction_averages_lbin/1day.json.gz", (jsonObject) -> - auctionPricesAvgLowestBinJson = jsonObject, () -> { - }); + manager.apiUtils + .newMoulberryRequest("auction_averages/3day.json.gz") + .gunzip().requestJson().thenAccept((jsonObject) -> { + craftCost.clear(); + auctionPricesJson = jsonObject; + lastAuctionAvgUpdate = System.currentTimeMillis(); + }); + manager.apiUtils + .newMoulberryRequest("auction_averages_lbin/1day.json.gz") + .gunzip().requestJson() + .thenAccept((jsonObject) -> { + auctionPricesAvgLowestBinJson = jsonObject; + }); } public Set getItemAuctionInfoKeySet() { @@ -743,13 +804,13 @@ public JsonObject getItemAuctionInfo(String internalname) { return e.getAsJsonObject(); } - public float getItemAvgBin(String internalname) { + public double getItemAvgBin(String internalName) { if (auctionPricesAvgLowestBinJson == null) return -1; - JsonElement e = auctionPricesAvgLowestBinJson.get(internalname); + JsonElement e = auctionPricesAvgLowestBinJson.get(internalName); if (e == null) { return -1; } - return Math.round(e.getAsFloat()); + return Math.round(e.getAsDouble()); } public Set getBazaarKeySet() { @@ -761,9 +822,18 @@ public Set getBazaarKeySet() { return keys; } - public JsonObject getBazaarInfo(String internalname) { + public double getBazaarOrBin(String internalName) { + JsonObject bazaarInfo = manager.auctionManager.getBazaarInfo(internalName); + if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) { + return bazaarInfo.get("curr_buy").getAsFloat(); + } else { + return manager.auctionManager.getLowestBin(internalName); + } + } + + public JsonObject getBazaarInfo(String internalName) { if (bazaarJson == null) return null; - JsonElement e = bazaarJson.get(internalname); + JsonElement e = bazaarJson.get(internalName); if (e == null) { return null; } @@ -791,7 +861,7 @@ public boolean isVanillaItem(String internalname) { public static class CraftInfo { public boolean fromRecipe = false; public boolean vanillaItem = false; - public float craftCost = -1; + public double craftCost = -1; } public CraftInfo getCraftCost(String internalname) { @@ -807,10 +877,10 @@ private CraftInfo getCraftCost(String internalname, Set visited) { visited.add(internalname); boolean vanillaItem = isVanillaItem(internalname); - float craftCost = Float.POSITIVE_INFINITY; + double craftCost = Double.POSITIVE_INFINITY; JsonObject auctionInfo = getItemAuctionInfo(internalname); - float lowestBin = getLowestBin(internalname); + double lowestBin = getLowestBin(internalname); JsonObject bazaarInfo = getBazaarInfo(internalname); if (bazaarInfo != null && bazaarInfo.get("curr_buy") != null) { @@ -857,7 +927,7 @@ private CraftInfo getCraftCost(String internalname, Set visited) { } } visited.remove(internalname); - if (Float.isInfinite(craftCost)) { + if (Double.isInfinite(craftCost)) { return null; } CraftInfo craftInfo = new CraftInfo(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java index 123da60a93..7b4542d033 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAH.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.auction; import com.google.gson.JsonObject; @@ -35,14 +54,23 @@ import java.awt.*; import java.awt.datatransfer.StringSelection; import java.text.NumberFormat; +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.HashMap; +import java.util.HashSet; import java.util.List; -import java.util.*; +import java.util.Locale; +import java.util.Map; +import java.util.Set; import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; import java.util.regex.Matcher; import java.util.regex.Pattern; -import static io.github.moulberry.notenoughupdates.util.GuiTextures.*; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.auction_accept; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.auction_price; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.auction_view; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.auction_view_buttons; public class CustomAH extends Gui { private enum PriceFilter { @@ -66,7 +94,7 @@ private enum PriceFilter { private boolean shouldUpdateSearch = false; private boolean shouldSortItems = false; - private int startingBid = 0; + private long startingBid = 0; private String currentAucId = null; private int clickedMainCategory = -1; @@ -105,6 +133,8 @@ private enum PriceFilter { public int guiLeft = -1; public int guiTop = -1; + private String lastSearch = ""; + private final Category CATEGORY_SWORD = new Category("sword", "Swords", "diamond_sword"); private final Category CATEGORY_ARMOR = new Category("armor", "Armor", "diamond_chestplate"); private final Category CATEGORY_BOWS = new Category("bow", "Bows", "bow"); @@ -247,7 +277,11 @@ public void clearSearch() { } public void setSearch(String search) { - searchField.setText(search); + if (search == null) { + searchField.setText(lastSearch); + } else { + searchField.setText(search); + } updateSearch(); } @@ -612,7 +646,7 @@ public void drawScreen(int mouseX, int mouseY) { } } if (priceNumbers.length() > 0) { - startingBid = Integer.parseInt(priceNumbers.toString()); + startingBid = Long.parseLong(priceNumbers.toString()); } } } @@ -651,7 +685,7 @@ public void drawScreen(int mouseX, int mouseY) { boolean hasAuctionPrice = auctionInfo != null; boolean hasBazaarPrice = bazaarInfo != null; - int lowestBin = manager.auctionManager.getLowestBin(internalname); + long lowestBin = manager.auctionManager.getLowestBin(internalname); NumberFormat format = NumberFormat.getInstance(Locale.US); @@ -1347,7 +1381,7 @@ private boolean doesAucMatch(APIManager.Auction auc) { } } if (getBinPriceFilterAmount() > -1) { - int lowestBin = + long lowestBin = NotEnoughUpdates.INSTANCE.manager.auctionManager.getLowestBin(NotEnoughUpdates.INSTANCE.manager.getInternalNameForItem( auc.getStack())); if (lowestBin > 0) { @@ -1459,8 +1493,15 @@ public void updateSearch() { auctionIdsNew.add(entry.getKey()); } } + if (NotEnoughUpdates.INSTANCE.config.neuAuctionHouse.saveLastSearch) { + lastSearch = ""; + } } else { String query = searchField.getText(); + + if (NotEnoughUpdates.INSTANCE.config.neuAuctionHouse.saveLastSearch) { + lastSearch = query; + } Set dontMatch = new HashSet<>(); HashSet allMatch = new HashSet<>(); @@ -1550,18 +1591,18 @@ public void sortItems() throws ConcurrentModificationException { if (auc2 == null) return -1; if (sortMode == SORT_MODE_HIGH) { - int price1 = Math.max(auc1.highest_bid_amount, auc1.starting_bid); - int price2 = Math.max(auc2.highest_bid_amount, auc2.starting_bid); - int diff = price2 - price1; + long price1 = Math.max(auc1.highest_bid_amount, auc1.starting_bid); + long price2 = Math.max(auc2.highest_bid_amount, auc2.starting_bid); + long diff = price2 - price1; if (diff != 0) { - return diff; + return Long.compare(price2, price1); } } else if (sortMode == SORT_MODE_LOW) { - int price1 = Math.max(auc1.highest_bid_amount, auc1.starting_bid); - int price2 = Math.max(auc2.highest_bid_amount, auc2.starting_bid); - int diff = price1 - price2; + long price1 = Math.max(auc1.highest_bid_amount, auc1.starting_bid); + long price2 = Math.max(auc2.highest_bid_amount, auc2.starting_bid); + long diff = price1 - price2; if (diff != 0) { - return diff; + return Long.compare(price1, price2); } } else { long end1 = auc1.end; @@ -1589,7 +1630,6 @@ public boolean keyboardInput() { return false; } - Keyboard.enableRepeatEvents(true); if (isEditingPrice() && Keyboard.getEventKey() == Keyboard.KEY_RETURN) { Minecraft.getMinecraft().displayGuiScreen(null); } else if (Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { @@ -1652,16 +1692,16 @@ private void increasePriceByFactor(float factor) { priceField.setText((int) (priceI * factor) + end); } - private int getPriceFilterAmount() { + private long getPriceFilterAmount() { return getNumberFromTextBox(priceFilterField); } - private int getNumberFromTextBox(GuiTextField textField) { + private long getNumberFromTextBox(GuiTextField textField) { if (textField.getText().equals("")) { return -2; } try { - int parsed = Integer.parseInt(textField.getText()); + long parsed = Long.parseLong(textField.getText()); if (parsed < 0) { return -1; } @@ -1671,7 +1711,7 @@ private int getNumberFromTextBox(GuiTextField textField) { } } - private int getBinPriceFilterAmount() { + private long getBinPriceFilterAmount() { return getNumberFromTextBox(binPriceFilterField); } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAHGui.java b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAHGui.java index 9311040d7c..ca85ca1cb4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAHGui.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/auction/CustomAHGui.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.auction; import net.minecraft.client.gui.GuiScreen; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/collectionlog/CollectionConstant.java b/src/main/java/io/github/moulberry/notenoughupdates/collectionlog/CollectionConstant.java deleted file mode 100644 index e789e88294..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/collectionlog/CollectionConstant.java +++ /dev/null @@ -1,15 +0,0 @@ -package io.github.moulberry.notenoughupdates.collectionlog; - -import java.util.HashMap; -import java.util.List; -import java.util.regex.Pattern; - -public class CollectionConstant { - public static class DropEntry { - public String type; - public Pattern regex; - public HashMap items; - } - - public List dropdata; -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/collectionlog/GuiCollectionLog.java b/src/main/java/io/github/moulberry/notenoughupdates/collectionlog/GuiCollectionLog.java deleted file mode 100644 index dac104c602..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/collectionlog/GuiCollectionLog.java +++ /dev/null @@ -1,111 +0,0 @@ -package io.github.moulberry.notenoughupdates.collectionlog; - -import io.github.moulberry.notenoughupdates.core.BackgroundBlur; -import io.github.moulberry.notenoughupdates.core.GlScissorStack; -import io.github.moulberry.notenoughupdates.util.Utils; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.ResourceLocation; -import org.lwjgl.opengl.GL11; - -public class GuiCollectionLog extends GuiScreen { - private static final ResourceLocation COLLECTION_LOG_TEX = new ResourceLocation("notenoughupdates:collectionlog.png"); - - @Override - public void drawScreen(int mouseX, int mouseY, float partialTicks) { - ScaledResolution scaledResolution = new ScaledResolution(Minecraft.getMinecraft()); - int width = scaledResolution.getScaledWidth(); - int height = scaledResolution.getScaledHeight(); - - int colwidth = 307; - int colheight = 187; - - int left = width / 2 - colwidth / 2; - int top = height / 2 - colheight / 2; - - BackgroundBlur.renderBlurredBackground(10, width, height, left, top, colwidth, colheight); - super.drawDefaultBackground(); - - Utils.drawStringCentered("\u00a7lCollection Log", fontRendererObj, width / 2, top - 27, true, 0xfff5aa00); - - String[] cats = {"Bosses", "Dragons", "Slayer", "Dungeons"}; - - GlStateManager.enableDepth(); - - GlStateManager.translate(0, 0, 2); - for (int i = 0; i < 4; i++) { - if (i == 0) { - int offset = i == 0 ? 1 : 2; - - Minecraft.getMinecraft().getTextureManager().bindTexture(COLLECTION_LOG_TEX); - GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(left + i * 71, top - 21, 71, 25, - (71 * offset) / 512f, (71 + 71 * offset) / 512f, 211 / 512f, (211 + 25) / 512f, GL11.GL_NEAREST - ); - - Utils.drawStringCentered(cats[i], fontRendererObj, left + i * 71 + 71 / 2, top - 8, true, 0xfff5aa00); - } - } - - GlStateManager.translate(0, 0, -1); - Minecraft.getMinecraft().getTextureManager().bindTexture(COLLECTION_LOG_TEX); - GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(left, top, colwidth, colheight, - 0, colwidth / 512f, 0, colheight / 512f, GL11.GL_NEAREST - ); - - GlScissorStack.push(0, top + 3, width, top + colheight - 6, scaledResolution); - int catIndex = 0; - for (int h = top + 3; h < top + colheight - 6; h += 24) { - catIndex += 2; - - Minecraft.getMinecraft().getTextureManager().bindTexture(COLLECTION_LOG_TEX); - GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(left, h, 100, 24, - 0, 100 / 512f, 187 / 512f, 211 / 512f, GL11.GL_NEAREST - ); - - fontRendererObj.drawString("Thing " + catIndex, left + 5, h + 2, 0xfff5aa00, true); - fontRendererObj.drawString("Thing " + (catIndex + 1), left + 5, h + 14, 0xfff5aa00, true); - } - GlScissorStack.pop(scaledResolution); - - fontRendererObj.drawString("\u00a7lSuperior Dragon", left + 119, top + 8, 0xfff5aa00, true); - fontRendererObj.drawString( - "Obtained: " + EnumChatFormatting.YELLOW + "3/5", - left + 122, - top + 23, - 0xfff5aa00, - true - ); - - String killCountText = "Kills: " + EnumChatFormatting.WHITE + "3"; - //int killCountLen = fontRendererObj.getStringWidth(killCountText); - fontRendererObj.drawString(killCountText, left + 122, top + 68, 0xfff5aa00, true); - - Minecraft.getMinecraft().getTextureManager().bindTexture(COLLECTION_LOG_TEX); - GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(left + colwidth - 196, top, 196, colheight, - (512 - 196) / 512f, 1, 0 / 512f, colheight / 512f, GL11.GL_NEAREST - ); - - GlStateManager.translate(0, 0, -1); - - for (int i = 0; i < 4; i++) { - if (i != 0) { - Minecraft.getMinecraft().getTextureManager().bindTexture(COLLECTION_LOG_TEX); - GlStateManager.color(1, 1, 1, 1); - Utils.drawTexturedRect(left + i * 71, top - 21, 71, 25, - 0, 71 / 512f, 211 / 512f, (211 + 25) / 512f, GL11.GL_NEAREST - ); - - Utils.drawStringCentered(cats[i], fontRendererObj, left + i * 71 + 71 / 2, top - 8, true, 0xfff5aa00); - } - } - - super.drawScreen(mouseX, mouseY, partialTicks); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/ClientCommandBase.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/ClientCommandBase.java index 8ba87ecdfe..e0ae7a1a76 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/ClientCommandBase.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/ClientCommandBase.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands; import net.minecraft.command.CommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java index de017cb57c..62981a300d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/Commands.java @@ -1,22 +1,54 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands; -import io.github.moulberry.notenoughupdates.commands.dev.*; +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.dev.DevTestCommand; +import io.github.moulberry.notenoughupdates.commands.dev.DiagCommand; +import io.github.moulberry.notenoughupdates.commands.dev.DungeonWinTestCommand; +import io.github.moulberry.notenoughupdates.commands.dev.EnableStorageCommand; +import io.github.moulberry.notenoughupdates.commands.dev.NullzeeSphereCommand; +import io.github.moulberry.notenoughupdates.commands.dev.PackDevCommand; +import io.github.moulberry.notenoughupdates.commands.dev.ReloadRepoCommand; +import io.github.moulberry.notenoughupdates.commands.dev.ResetRepoCommand; +import io.github.moulberry.notenoughupdates.commands.dev.StatsCommand; import io.github.moulberry.notenoughupdates.commands.dungeon.DhCommand; import io.github.moulberry.notenoughupdates.commands.dungeon.DnCommand; import io.github.moulberry.notenoughupdates.commands.dungeon.JoinDungeonCommand; import io.github.moulberry.notenoughupdates.commands.dungeon.MapCommand; -import io.github.moulberry.notenoughupdates.commands.help.*; +import io.github.moulberry.notenoughupdates.commands.help.FeaturesCommand; +import io.github.moulberry.notenoughupdates.commands.help.HelpCommand; +import io.github.moulberry.notenoughupdates.commands.help.LinksCommand; +import io.github.moulberry.notenoughupdates.commands.help.SettingsCommand; +import io.github.moulberry.notenoughupdates.commands.help.StorageViewerWhyCommand; import io.github.moulberry.notenoughupdates.commands.misc.AhCommand; +import io.github.moulberry.notenoughupdates.commands.misc.CalculatorCommand; import io.github.moulberry.notenoughupdates.commands.misc.CalendarCommand; import io.github.moulberry.notenoughupdates.commands.misc.CosmeticsCommand; import io.github.moulberry.notenoughupdates.commands.misc.CustomizeCommand; +import io.github.moulberry.notenoughupdates.commands.misc.PronounsCommand; +import io.github.moulberry.notenoughupdates.commands.misc.UpdateCommand; import io.github.moulberry.notenoughupdates.commands.profile.CataCommand; import io.github.moulberry.notenoughupdates.commands.profile.PeekCommand; import io.github.moulberry.notenoughupdates.commands.profile.PvCommand; import io.github.moulberry.notenoughupdates.commands.profile.ViewProfileCommand; -import io.github.moulberry.notenoughupdates.commands.repo.ReloadRepoCommand; -import io.github.moulberry.notenoughupdates.commands.repo.RepoModeCommand; -import io.github.moulberry.notenoughupdates.commands.repo.ResetRepoCommand; import io.github.moulberry.notenoughupdates.miscfeatures.FairySouls; import io.github.moulberry.notenoughupdates.miscgui.GuiEnchantColour; import io.github.moulberry.notenoughupdates.miscgui.GuiInvButtonEditor; @@ -40,11 +72,10 @@ public Commands() { ClientCommandHandler.instance.registerCommand(new StatsCommand()); ClientCommandHandler.instance.registerCommand(new DevTestCommand()); ClientCommandHandler.instance.registerCommand(new NullzeeSphereCommand()); - - // Repo Commands - ClientCommandHandler.instance.registerCommand(new ResetRepoCommand()); - ClientCommandHandler.instance.registerCommand(new RepoModeCommand()); + ClientCommandHandler.instance.registerCommand(new DiagCommand()); ClientCommandHandler.instance.registerCommand(new ReloadRepoCommand()); + ClientCommandHandler.instance.registerCommand(new ResetRepoCommand()); + ClientCommandHandler.instance.registerCommand(new EnableStorageCommand()); // Profile Commands ClientCommandHandler.instance.registerCommand(new PeekCommand()); @@ -66,7 +97,10 @@ public Commands() { ClientCommandHandler.instance.registerCommand(new ScreenCommand("neuoverlay", NEUOverlayPlacements::new)); //ClientCommandHandler.instance.registerCommand(new ScreenCommand("neututorial", NeuTutorial::new)); ClientCommandHandler.instance.registerCommand(new AhCommand()); + ClientCommandHandler.instance.registerCommand(new CalculatorCommand()); ClientCommandHandler.instance.registerCommand(new CalendarCommand()); + ClientCommandHandler.instance.registerCommand(new UpdateCommand(NotEnoughUpdates.INSTANCE)); + ClientCommandHandler.instance.registerCommand(new PronounsCommand()); // Fairy Soul Commands ClientCommandHandler.instance.registerCommand(new FairySouls.FairySoulsCommand()); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/EntityViewerCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/EntityViewerCommand.java new file mode 100644 index 0000000000..e3738661ba --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/EntityViewerCommand.java @@ -0,0 +1,100 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands; + +import com.google.common.collect.Lists; +import io.github.moulberry.notenoughupdates.miscfeatures.entityviewer.EntityViewer; +import net.minecraft.client.Minecraft; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.event.ClickEvent; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.ChatStyle; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.ResourceLocation; +import net.minecraftforge.common.MinecraftForge; +import net.minecraftforge.fml.common.eventhandler.SubscribeEvent; +import net.minecraftforge.fml.common.gameevent.TickEvent; + +import java.util.Arrays; +import java.util.List; +import java.util.Queue; +import java.util.concurrent.ConcurrentLinkedDeque; + +public class EntityViewerCommand extends ClientCommandBase { + public EntityViewerCommand() { + super("neushowentity"); + MinecraftForge.EVENT_BUS.register(this); + } + + @Override + public List getCommandAliases() { + return Lists.newArrayList("neuentityviewer"); + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return EnumChatFormatting.RED + "Use /neushowentity list"; + } + + public void showUsage(ICommandSender sender) { + sender.addChatMessage(new ChatComponentText(getCommandUsage(sender))); + } + + private final Queue queuedGUIS = new ConcurrentLinkedDeque<>(); + + @SubscribeEvent + public void onTick(TickEvent event) { + if (Minecraft.getMinecraft().currentScreen == null) { + EntityViewer poll = queuedGUIS.poll(); + if (poll == null) return; + Minecraft.getMinecraft().displayGuiScreen(poll); + } + } + + @Override + public void processCommand(ICommandSender sender, String[] strings) throws CommandException { + if (strings.length == 0) { + showUsage(sender); + return; + } + if (strings[0].equals("list")) { + for (String label : EntityViewer.validEntities.keySet()) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.BLUE + " " + label) + .setChatStyle(new ChatStyle().setChatClickEvent( + new ClickEvent(ClickEvent.Action.SUGGEST_COMMAND, "/neuentityviewer " + label)))); + } + return; + } + EntityLivingBase entityLivingBase; + if (strings[0].startsWith("@")) { + ResourceLocation resourceLocation = new ResourceLocation(strings[0].substring(1)); + entityLivingBase = EntityViewer.constructEntity(resourceLocation); + } else { + entityLivingBase = EntityViewer.constructEntity(strings[0], Arrays.copyOfRange(strings, 1, strings.length)); + } + if (entityLivingBase == null) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Could not create that entity")); + return; + } + queuedGUIS.add(new EntityViewer(strings[0], entityLivingBase)); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/ScreenCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/ScreenCommand.java index 29dd9d55a7..1b90e5dfa1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/ScreenCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/ScreenCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java index 66da4f9f32..972557c8e2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DevTestCommand.java @@ -1,34 +1,66 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dev; +import io.github.moulberry.notenoughupdates.BuildFlags; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.core.config.GuiPositionEditor; -import io.github.moulberry.notenoughupdates.miscfeatures.FancyPortals; import io.github.moulberry.notenoughupdates.miscfeatures.FishingHelper; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.CustomBiomes; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.LocationChangeEvent; import io.github.moulberry.notenoughupdates.miscfeatures.customblockzones.SpecialBlockZone; import io.github.moulberry.notenoughupdates.miscgui.GuiPriceGraph; +import io.github.moulberry.notenoughupdates.util.PronounDB; import io.github.moulberry.notenoughupdates.util.SBInfo; import net.minecraft.client.Minecraft; -import net.minecraft.client.entity.EntityPlayerSP; +import net.minecraft.client.gui.GuiScreen; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; -import net.minecraft.util.*; +import net.minecraft.util.BlockPos; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.EnumParticleTypes; import net.minecraftforge.common.MinecraftForge; -import java.io.File; import java.util.Arrays; import java.util.List; -import java.util.concurrent.Executors; -import java.util.concurrent.ScheduledExecutorService; -import java.util.concurrent.TimeUnit; -import java.util.concurrent.atomic.AtomicInteger; +import java.util.stream.Collectors; public class DevTestCommand extends ClientCommandBase { private static final List DEV_TESTERS = - Arrays.asList("moulberry", "lucycoconut", "ironm00n", "ariyio", "throwpo", "lrg89", "dediamondpro"); + Arrays.asList( + "moulberry", + "lucycoconut", + "ironm00n", + "ariyio", + "throwpo", + "lrg89", + "dediamondpro", + "lulonaut", + "craftyoldminer", + "eisengolem", + "whalker", + "ascynx" + ); private static final String[] DEV_FAIL_STRINGS = { "No.", @@ -48,9 +80,7 @@ public class DevTestCommand extends ClientCommandBase { "", "Ok, this is actually the last message, use the command again and you'll crash I promise" }; - private int devFailIndex = 0; - private final ScheduledExecutorService devES = Executors.newSingleThreadScheduledExecutor(); public DevTestCommand() { super("neudevtest"); @@ -84,10 +114,6 @@ public void printStackTrace() { DEV_FAIL_STRINGS[devFailIndex++])); return; } - /*if(args.length == 1) { - DupePOC.doDupe(args[0]); - return; - }*/ if (args.length >= 1 && args[0].equalsIgnoreCase("profileinfo")) { String currentProfile = SBInfo.getInstance().currentProfile; SBInfo.Gamemode gamemode = SBInfo.getInstance().getGamemodeForProfile(currentProfile); @@ -97,6 +123,14 @@ public void printStackTrace() { " with the mode " + gamemode)); } + if (args.length >= 1 && args[0].equalsIgnoreCase("buildflags")) { + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + "BuildFlags: \n" + + BuildFlags.getAllFlags().entrySet().stream() + .map(it -> " + " + it.getKey() + " - " + it.getValue()) + .collect(Collectors.joining("\n")))); + return; + } if (args.length >= 1 && args[0].equalsIgnoreCase("pricetest")) { if (args.length == 1) { NotEnoughUpdates.INSTANCE.manager.auctionManager.updateBazaar(); @@ -142,66 +176,24 @@ public void printStackTrace() { "I would never search")); return; } + if (args.length == 1 && args[0].equalsIgnoreCase("bluehair")) { + PronounDB.test(); + return; + } + if (args.length == 2 && args[0].equalsIgnoreCase("openGui")) { + try { + NotEnoughUpdates.INSTANCE.openGui = (GuiScreen) Class.forName(args[1]).newInstance(); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( + "Opening gui: " + NotEnoughUpdates.INSTANCE.openGui)); + } catch (InstantiationException | IllegalAccessException | ClassNotFoundException | ClassCastException e) { + e.printStackTrace(); + Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("Failed to open this gui.")); + } + } if (args.length == 1 && args[0].equalsIgnoreCase("center")) { double x = Math.floor(Minecraft.getMinecraft().thePlayer.posX) + 0.5f; double z = Math.floor(Minecraft.getMinecraft().thePlayer.posZ) + 0.5f; Minecraft.getMinecraft().thePlayer.setPosition(x, Minecraft.getMinecraft().thePlayer.posY, z); - return; } - if (args.length == 1 && args[0].equalsIgnoreCase("pansc")) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + - "Taking panorama screenshot")); - - AtomicInteger perspective = new AtomicInteger(0); - FancyPortals.perspectiveId = 0; - - EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; - p.prevRotationYaw = p.rotationYaw = 0; - p.prevRotationPitch = p.rotationPitch = 90; - devES.schedule(new Runnable() { - @Override - public void run() { - Minecraft.getMinecraft().addScheduledTask(() -> { - ScreenShotHelper.saveScreenshot(new File("C:/Users/James/Desktop/"), "pansc-" + perspective.get() + ".png", - Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight, - Minecraft.getMinecraft().getFramebuffer() - ); - }); - if (perspective.incrementAndGet() >= 6) { - FancyPortals.perspectiveId = -1; - return; - } - devES.schedule(() -> { - FancyPortals.perspectiveId = perspective.get(); - if (FancyPortals.perspectiveId == 5) { - p.prevRotationYaw = p.rotationYaw = 0; - p.prevRotationPitch = p.rotationPitch = -90; - } else if (FancyPortals.perspectiveId >= 1 && FancyPortals.perspectiveId <= 4) { - float yaw = 90 * FancyPortals.perspectiveId - 180; - if (yaw > 180) yaw -= 360; - p.prevRotationYaw = p.rotationYaw = yaw; - p.prevRotationPitch = p.rotationPitch = 0; - } - devES.schedule(this, 3000L, TimeUnit.MILLISECONDS); - }, 100L, TimeUnit.MILLISECONDS); - } - }, 3000L, TimeUnit.MILLISECONDS); - - return; - } - - /* if(args.length == 1 && args[0].equalsIgnoreCase("update")) { - NEUEventListener.displayUpdateMessageIfOutOfDate(); - } */ - - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.GREEN + - "Executing dubious code")); - /*Minecraft.getMinecraft().thePlayer.rotationYaw = 0; - Minecraft.getMinecraft().thePlayer.rotationPitch = 0; - Minecraft.getMinecraft().thePlayer.setPosition( - Math.floor(Minecraft.getMinecraft().thePlayer.posX) + Float.parseFloat(args[0]), - Minecraft.getMinecraft().thePlayer.posY, - Minecraft.getMinecraft().thePlayer.posZ);*/ - //Hot reload me yay! } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java new file mode 100644 index 0000000000..fb546efb51 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DiagCommand.java @@ -0,0 +1,134 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands.dev; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import io.github.moulberry.notenoughupdates.miscfeatures.CrystalMetalDetectorSolver; +import io.github.moulberry.notenoughupdates.miscfeatures.CrystalWishingCompassSolver; +import io.github.moulberry.notenoughupdates.options.customtypes.NEUDebugFlag; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +public class DiagCommand extends ClientCommandBase { + public DiagCommand() { + super("neudiag"); + } + + private static final String USAGE_TEXT = EnumChatFormatting.WHITE + + "Usage: /neudiag \n\n" + + "/neudiag metal Metal Detector Solver diagnostics\n" + + " Show current solution diags\n" + + " center= Disable / enable using center\n" + + "/neudiag wishing Wishing Compass Solver diagnostics\n" + + "/neudiag debug\n" + + " Show all enabled flags\n" + + " Show all flags\n"+ + " Enable/disable flag\n"; + + private void showUsage(ICommandSender sender) { + sender.addChatMessage(new ChatComponentText(USAGE_TEXT)); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + if (args.length == 0) { + showUsage(sender); + return; + } + + String command = args[0].toLowerCase(); + switch (command) { + case "metal": + if (args.length == 1) { + CrystalMetalDetectorSolver.logDiagnosticData(true); + return; + } + + String subCommand = args[1].toLowerCase(); + if (subCommand.equals("center=off")) { + CrystalMetalDetectorSolver.setDebugDoNotUseCenter(true); + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + + "Center coordinates-based solutions disabled")); + } else if (subCommand.equals("center=on")) { + CrystalMetalDetectorSolver.setDebugDoNotUseCenter(false); + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + + "Center coordinates-based solutions enabled")); + } else { + showUsage(sender); + return; + } + + break; + case "wishing": + CrystalWishingCompassSolver.getInstance().logDiagnosticData(true); + break; + case "debug": + if (args.length > 1) { + boolean enablingFlag = true; + String action = args[1]; + switch (action) { + case "list": + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.YELLOW + "Here are all flags:\n" + NEUDebugFlag.getFlagList())); + return; + case "disable": + enablingFlag = false; + // falls through + case "enable": + if (args.length != 3) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + + "You must specify a flag:\n" + + NEUDebugFlag.getFlagList())); + return; + } + + String flagName = args[2].toUpperCase(); + try { + NEUDebugFlag debugFlag = NEUDebugFlag.valueOf(flagName); + if (enablingFlag) { + NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.add(debugFlag); + } else { + NotEnoughUpdates.INSTANCE.config.hidden.debugFlags.remove(debugFlag); + } + } catch (IllegalArgumentException e) { + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + + flagName + " is invalid. Valid flags are:\n" + + NEUDebugFlag.getFlagList())); + return; + } + break; + default: + showUsage(sender); + return; + } + } + + sender.addChatMessage(new ChatComponentText(EnumChatFormatting.YELLOW + "Effective debug flags: \n" + + NEUDebugFlag.getEnabledFlags())); + break; + default: + showUsage(sender); + return; + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DungeonWinTestCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DungeonWinTestCommand.java index 223e154a2c..be25e697c4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DungeonWinTestCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/DungeonWinTestCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dev; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/EnableStorageCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/EnableStorageCommand.java new file mode 100644 index 0000000000..3415b030b3 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/EnableStorageCommand.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands.dev; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; + +public class EnableStorageCommand extends ClientCommandBase { + + public EnableStorageCommand() { + super("neuenablestorage"); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + NotEnoughUpdates.INSTANCE.config.storageGUI.enableStorageGUI3 = true; + NotEnoughUpdates.INSTANCE.saveConfig(); + } + +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/NullzeeSphereCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/NullzeeSphereCommand.java index 64d645451a..3a9ce90f90 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/NullzeeSphereCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/NullzeeSphereCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dev; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java index e809ed7234..e1504472ec 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/PackDevCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dev; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -5,55 +24,281 @@ import io.github.moulberry.notenoughupdates.core.util.MiscUtils; import net.minecraft.client.Minecraft; import net.minecraft.client.entity.AbstractClientPlayer; -import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; +import net.minecraft.entity.Entity; +import net.minecraft.entity.EntityLiving; +import net.minecraft.entity.EntityLivingBase; +import net.minecraft.entity.item.EntityArmorStand; import net.minecraft.entity.player.EntityPlayer; +import net.minecraft.item.ItemStack; +import net.minecraft.nbt.NBTBase; +import net.minecraft.nbt.NBTTagCompound; +import net.minecraft.util.BlockPos; import net.minecraft.util.ChatComponentText; import net.minecraft.util.EnumChatFormatting; +import java.util.HashMap; +import java.util.List; +import java.util.function.Supplier; + public class PackDevCommand extends ClientCommandBase { + static Minecraft mc = Minecraft.getMinecraft(); public PackDevCommand() { super("neupackdev"); } + private static final HashMap> commands = new HashMap>() {{ + put( + "getnpc", + new Command<>( + "NPC", + () -> mc.theWorld.playerEntities, + true, + AbstractClientPlayer.class + ) + ); + put( + "getnpcs", + new Command<>( + "NPC", + () -> mc.theWorld.playerEntities, + false, + AbstractClientPlayer.class + ) + ); + put( + "getmob", + new Command<>( + "mob", + () -> mc.theWorld.loadedEntityList, + true, + EntityLiving.class + ) + ); + put( + "getmobs", + new Command<>( + "mob", + () -> mc.theWorld.loadedEntityList, + false, + EntityLiving.class + ) + ); + put( + "getarmorstand", + new Command<>( + "armor stand", + () -> mc.theWorld.loadedEntityList, + true, + EntityArmorStand.class + ) + ); + put( + "getarmorstands", + new Command<>( + "armor stand", + () -> mc.theWorld.loadedEntityList, + false, + EntityArmorStand.class + ) + ); + }}; + + @Override + public List addTabCompletionOptions(ICommandSender sender, String[] args, BlockPos pos) { + return args.length == 1 ? getListOfStringsMatchingLastWord(args, commands.keySet()) : null; + } + + public static void togglePackDeveloperMode(ICommandSender sender) { + NotEnoughUpdates.INSTANCE.packDevEnabled = !NotEnoughUpdates.INSTANCE.packDevEnabled; + if (NotEnoughUpdates.INSTANCE.packDevEnabled) { + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.GREEN + "Enabled pack developer mode.")); + } else { + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.RED + "Disabled pack developer mode.")); + } + } + @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (args.length == 1 && args[0].equalsIgnoreCase("getnpc")) { - double distSq = 25; - EntityPlayer closestNPC = null; - EntityPlayerSP p = Minecraft.getMinecraft().thePlayer; - for (EntityPlayer player : Minecraft.getMinecraft().theWorld.playerEntities) { - if (player instanceof AbstractClientPlayer && p != player && player.getUniqueID().version() != 4) { - double dSq = player.getDistanceSq(p.posX, p.posY, p.posZ); - if (dSq < distSq) { - distSq = dSq; - closestNPC = player; + if (args.length == 0) { + togglePackDeveloperMode(sender); + return; + } + + double dist = 5.0; + if (args.length >= 2) { + try { + dist = Double.parseDouble(args[1]); + } catch (NumberFormatException e) { + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.RED + "Invalid distance! Must be a number, defaulting to a radius of 5.")); + } + } + + StringBuilder output; + String subCommand = args[0].toLowerCase(); + if (commands.containsKey(subCommand)) { + Command command = commands.get(subCommand); + output = command.getData(dist); + } else if (subCommand.equals("getall")) { + output = getAll(dist); + } else if (subCommand.equals("getallclose")) { + output = getAllClose(dist); + } else { + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.RED + "Invalid sub-command.")); + return; + } + + if (output.length() != 0) { + MiscUtils.copyToClipboard(output.toString()); + } + } + + private static StringBuilder getAllClose(Double dist) { + StringBuilder sb = new StringBuilder(); + sb.append(commands.get("getmob").getData(dist)); + sb.append(commands.get("getarmorstand").getData(dist)); + sb.append(commands.get("getnpc").getData(dist)); + return sb; + } + + private static StringBuilder getAll(Double dist) { + StringBuilder sb = new StringBuilder(); + sb.append(commands.get("getmobs").getData(dist)); + sb.append(commands.get("getarmorstands").getData(dist)); + sb.append(commands.get("getnpcs").getData(dist)); + return sb; + } + + public static StringBuilder livingBaseDataBuilder(T entity, Class clazz) { + StringBuilder entityData = new StringBuilder(); + if (EntityPlayer.class.isAssignableFrom(entity.getClass())) { + EntityPlayer entityPlayer = (EntityPlayer) entity; + + // NPC Information + String skinResourcePath = ((AbstractClientPlayer) entityPlayer).getLocationSkin().getResourcePath(); + entityData + .append("Player Id: ") + .append(entityPlayer.getUniqueID() != null ? entityPlayer.getUniqueID().toString() : "null") + .append(entityPlayer.getCustomNameTag() != null ? entityPlayer.getCustomNameTag() : "null") + .append("\nEntity Texture Id: ") + .append(skinResourcePath != null ? skinResourcePath.replace("skins/", "") : "null"); + } + + if (!clazz.isAssignableFrom(entity.getClass())) { + return entityData; + } + + //Entity Information + entityData + .append("Entity Id: ") + .append(entity.getEntityId()) + .append("\nMob: ") + .append(entity.getName() != null ? entity.getName() : "null") + .append("\nCustom Name: ") + .append(entity.getCustomNameTag() != null ? entity.getCustomNameTag() : "null"); + + //Held Item + if (entity.getHeldItem() != null) { + entityData + .append("\nItem: ") + .append(entity.getHeldItem()) + .append("\nItem Display Name: ") + .append(entity.getHeldItem().getDisplayName() != null + ? entity.getHeldItem().getDisplayName() + : "null") + .append("\nItem Tag Compound: "); + NBTTagCompound heldItemTagCompound = entity.getHeldItem().getTagCompound(); + if (heldItemTagCompound != null) { + String heldItemString = heldItemTagCompound.toString(); + NBTBase extraAttrTag = heldItemTagCompound.getTag("ExtraAttributes"); + entityData + .append(heldItemString != null ? heldItemString : "null") + .append("\nItem Tag Compound Extra Attributes: ") + .append(extraAttrTag != null ? extraAttrTag : "null"); + } else { + entityData.append("null"); + } + + } else { + entityData.append("\nItem: null"); + } + + entityData.append(armorDataBuilder(entity)).append("\n\n"); + + return entityData; + } + + private static final String[] armorPieceTypes = {"Boots", "Leggings", "Chestplate", "Helmet"}; + + public static StringBuilder armorDataBuilder(T entity) { + StringBuilder armorData = new StringBuilder(); + for (int i = 0; i < 4; i++) { + ItemStack currentArmor = entity.getCurrentArmor(0); + armorData.append(String.format("\n%s: ", armorPieceTypes[i])); + if (currentArmor == null) { + armorData.append("null"); + } else { + armorData.append(currentArmor.getTagCompound() != null ? currentArmor.getTagCompound().toString() : "null"); + } + } + return armorData; + } + + static class Command { + String typeFriendlyName; + Supplier> entitySupplier; + Class clazz; + boolean single; + + Command( + String typeFriendlyName, + Supplier> entitySupplier, + boolean single, + Class clazz + ) { + this.typeFriendlyName = typeFriendlyName; + this.entitySupplier = entitySupplier; + this.single = single; + this.clazz = clazz; + } + + @SuppressWarnings("unchecked") + public StringBuilder getData(double dist) { + StringBuilder result = new StringBuilder(); + double distSq = dist * dist; + T closest = null; + for (Entity entity : entitySupplier.get()) { + if (!clazz.isAssignableFrom(entity.getClass()) || entity == mc.thePlayer) { + continue; + } + T entityT = (T) entity; + double entityDistanceSq = entity.getDistanceSq(mc.thePlayer.posX, mc.thePlayer.posY, mc.thePlayer.posZ); + if (entityDistanceSq < distSq) { + if (single) { + distSq = entityDistanceSq; + closest = entityT; + } else { + result.append(livingBaseDataBuilder(entityT, clazz)); } } } - if (closestNPC == null) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "No NPCs found within 5 blocks :(")); + if ((single && closest == null) || (!single && result.length() == 0)) { + mc.thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.RED + "No " + typeFriendlyName + "s found within " + dist + " blocks.")); } else { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.GREEN + "Copied entity texture id to clipboard")); - MiscUtils.copyToClipboard(((AbstractClientPlayer) closestNPC) - .getLocationSkin() - .getResourcePath() - .replace("skins/", "")); + mc.thePlayer.addChatMessage(new ChatComponentText( + EnumChatFormatting.GREEN + "Copied " + typeFriendlyName + " data to clipboard")); + return single ? livingBaseDataBuilder(closest, clazz) : result; } - return; - } - NotEnoughUpdates.INSTANCE.packDevEnabled = !NotEnoughUpdates.INSTANCE.packDevEnabled; - if (NotEnoughUpdates.INSTANCE.packDevEnabled) { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.GREEN + "Enabled pack developer mode.")); - } else { - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.RED + "Disabled pack developer mode.")); + + return result; } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ReloadRepoCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ReloadRepoCommand.java new file mode 100644 index 0000000000..0bf57594b0 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ReloadRepoCommand.java @@ -0,0 +1,39 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands.dev; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; + +public class ReloadRepoCommand extends ClientCommandBase { + + public ReloadRepoCommand() { + super("neureloadrepo"); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + NotEnoughUpdates.INSTANCE.manager.reloadRepository(); + sender.addChatMessage(new ChatComponentText("§e[NEU] Reloaded repository.")); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ResetRepoCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ResetRepoCommand.java new file mode 100644 index 0000000000..3f693898c2 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/ResetRepoCommand.java @@ -0,0 +1,42 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands.dev; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; + +public class ResetRepoCommand extends ClientCommandBase { + + public ResetRepoCommand() { + super("neuresetrepo"); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + NotEnoughUpdates.INSTANCE.manager + .userFacingRepositoryReload() + .thenAccept(strings -> + strings.forEach(line -> + sender.addChatMessage(new ChatComponentText("§e[NEU] " + line)))); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java index 38eafe3946..756afc8873 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dev/StatsCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dev; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -146,7 +165,7 @@ private static String createStats() { builder.append("Loaded Mods", String.valueOf(activeModCount)); builder.append("Forge", ForgeVersion.getVersion()); builder.category("Neu Settings"); - builder.append("API Key", NotEnoughUpdates.INSTANCE.config.apiKey.apiKey.isEmpty() ? "FALSE" : "TRUE"); + builder.append("API Key", NotEnoughUpdates.INSTANCE.config.apiData.apiKey.isEmpty() ? "FALSE" : "TRUE"); builder.append("On Skyblock", NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard() ? "TRUE" : "FALSE"); builder.append( "Mod Version", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DhCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DhCommand.java index 89299a36ed..222862f995 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DhCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DhCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dungeon; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java index 8fbbceba08..a5a7bcca5a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/DnCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dungeon; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java index 874e81dbad..d69f86f312 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/JoinDungeonCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dungeon; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java index ae06a34615..f5381adb75 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/dungeon/MapCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.dungeon; import com.google.gson.JsonElement; @@ -31,6 +50,7 @@ public MapCommand() { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { + if (NotEnoughUpdates.INSTANCE.colourMap == null) { try ( BufferedReader reader = new BufferedReader(new InputStreamReader(Minecraft diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java index 593f257554..5f709c4fc0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/FeaturesCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.help; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java index 9669be60e4..7655f5615b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/HelpCommand.java @@ -1,15 +1,32 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.help; import com.google.common.collect.Lists; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import net.minecraft.client.Minecraft; -import net.minecraft.command.CommandException; import net.minecraft.command.ICommandSender; import net.minecraft.util.ChatComponentText; import java.util.ArrayList; -import java.util.List; public class HelpCommand extends ClientCommandBase { @@ -33,8 +50,8 @@ public void processCommand(ICommandSender sender, String[] args) { "\u00a76/neulinks \u00a7r\u00a77- Shows links to neu/moulberry.", "\u00a76/neuoverlay \u00a7r\u00a77- Opens GUI Editor for quickcommands and searchbar.", "\u00a76/neuah \u00a7r\u00a77- Opens neu's custom ah GUI.", - "\u00a76/neumap \u00a7r\u00a77- Opens the dungeon map GUI.", "\u00a76/neucalendar \u00a7r\u00a77- Opens neu's custom calendar GUI.", + "\u00a76/neucalc \u00a7r\u00a77- Run calculations.", "", "\u00a76\u00a7lOld commands:", "\u00a76/peek \u00a7b?{user} \u00a72\u2D35 \u00a7r\u00a77- Shows quickly stats for a user.", @@ -46,7 +63,7 @@ public void processCommand(ICommandSender sender, String[] args) { "\u00a76/neureloadrepo \u00a7r\u00a77- Debug command with repo.", "", "\u00a76\u00a7lDev commands:", - "\u00a76/neupackdev \u00a7r\u00a77- pack creator command - getnpc" + "\u00a76/neupackdev \u00a7r\u00a77- pack creator command - getnpc, getmob(s), getarmorstand(s), getall. Optional radius argument for all." ); for (String neuHelpMessage : neuHelpMessages) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(neuHelpMessage)); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java index c81f44a8f5..9938403c9c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/LinksCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.help; import com.google.gson.JsonObject; @@ -25,7 +44,7 @@ public void processCommand(ICommandSender sender, String[] args) throws CommandE JsonObject update = NotEnoughUpdates.INSTANCE.manager.getJsonFromFile(updateJson); Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); - NotEnoughUpdates.INSTANCE.displayLinks(update); + NotEnoughUpdates.INSTANCE.displayLinks(update,0 ); Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("")); } catch (Exception ignored) { } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java index 08350be9d5..9964b73924 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/SettingsCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.help; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/StorageViewerWhyCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/StorageViewerWhyCommand.java index 4f85c26efb..820c6f2a8c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/help/StorageViewerWhyCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/help/StorageViewerWhyCommand.java @@ -1,8 +1,27 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.help; import com.google.common.collect.Lists; -import io.github.moulberry.notenoughupdates.NEUEventListener; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import io.github.moulberry.notenoughupdates.util.NotificationHandler; import net.minecraft.command.ICommandSender; public class StorageViewerWhyCommand extends ClientCommandBase { @@ -13,7 +32,7 @@ public StorageViewerWhyCommand() { @Override public void processCommand(ICommandSender sender, String[] args) { - NEUEventListener.displayNotification(Lists.newArrayList( + NotificationHandler.displayNotification(Lists.newArrayList( "\u00a7eStorage Viewer", "\u00a77Currently, the storage viewer requires you to click twice", "\u00a77in order to switch between pages. This is because Hypixel", diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java index 0b2c155ec4..bd8abf1dc0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/AhCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.misc; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -21,8 +40,8 @@ public void processCommand(ICommandSender sender, String[] args) throws CommandE if (!NotEnoughUpdates.INSTANCE.hasSkyblockScoreboard()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "You must be on Skyblock to use this feature.")); - } else if (NotEnoughUpdates.INSTANCE.config.apiKey.apiKey == null || - NotEnoughUpdates.INSTANCE.config.apiKey.apiKey.trim().isEmpty()) { + } else if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null || + NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Can't open NeuAH, apikey is not set. Run /api new and put the result in settings.")); } else { @@ -31,8 +50,13 @@ public void processCommand(ICommandSender sender, String[] args) throws CommandE NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.clearSearch(); NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.updateSearch(); - if (args.length > 0) + if (args.length > 0) { NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.setSearch(StringUtils.join(args, " ")); + } else { + if (NotEnoughUpdates.INSTANCE.config.neuAuctionHouse.saveLastSearch) { + NotEnoughUpdates.INSTANCE.manager.auctionManager.customAH.setSearch(null); + } + } } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/ButtonsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/ButtonsCommand.java index 63d5c327c2..5511346272 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/ButtonsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/ButtonsCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.misc; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java new file mode 100644 index 0000000000..2ba93585d3 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalculatorCommand.java @@ -0,0 +1,75 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands.misc; + +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import io.github.moulberry.notenoughupdates.util.Calculator; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; +import net.minecraft.util.EnumChatFormatting; + +import java.text.DecimalFormat; +import java.math.BigDecimal; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public class CalculatorCommand extends ClientCommandBase { + public CalculatorCommand() { + super("neucalc"); + } + + @Override + public List getCommandAliases() { + return Arrays.asList("neucalculator"); + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + if ((args.length == 1 && Objects.equals(args[0], "help")) || args.length == 0) { + sender.addChatMessage(new ChatComponentText( + "\n§e[NEU] §5It's a calculator.\n" + + "§eFor Example §b/neucalc 3m*7k§e.\n" + + "§eYou can also use suffixes (k, m, b, t, s)§e.\n" + + "§eThe \"s\" suffix acts as 64.\n" + + "§eTurn on Sign Calculator in /neu misc to also support this in sign popups and the neu search bar.\n")); + return; + } + String source = String.join(" ", args); + try { + BigDecimal calculate = Calculator.calculate(source); + DecimalFormat formatter = new DecimalFormat("#,##0.##"); + String format = formatter.format(calculate); + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.YELLOW + "[NEU] " + EnumChatFormatting.WHITE + source + " " + EnumChatFormatting.YELLOW + + "= " + EnumChatFormatting.GREEN + format + )); + } catch (Calculator.CalculatorException e) { + sender.addChatMessage(new ChatComponentText( + EnumChatFormatting.YELLOW + "[NEU] " + EnumChatFormatting.RED + "Error during calculation: " + + e.getMessage() + "\n" + + EnumChatFormatting.WHITE + source.substring(0, e.getOffset()) + EnumChatFormatting.DARK_RED + + source.substring(e.getOffset(), e.getLength() + e.getOffset()) + EnumChatFormatting.GRAY + + source.substring(e.getLength() + e.getOffset()) + )); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalendarCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalendarCommand.java index d3c472bd84..58c134749b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalendarCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CalendarCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.misc; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CollectionLogCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CollectionLogCommand.java deleted file mode 100644 index 1bde763139..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CollectionLogCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.moulberry.notenoughupdates.commands.misc; - -import io.github.moulberry.notenoughupdates.collectionlog.GuiCollectionLog; -import io.github.moulberry.notenoughupdates.commands.ScreenCommand; - -import java.util.Arrays; -import java.util.Collections; -import java.util.List; - -public class CollectionLogCommand extends ScreenCommand { - - public CollectionLogCommand() { - super("neucl", GuiCollectionLog::new); - } - - @Override - public List getCommandAliases() { - return Collections.singletonList("collectionlog"); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java index 9ccb7cf0e4..f74b581385 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CosmeticsCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.misc; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -18,7 +37,7 @@ public CosmeticsCommand() { @Override public void processCommand(ICommandSender sender, String[] args) throws CommandException { - if (!OpenGlHelper.isFramebufferEnabled()) { + if (!OpenGlHelper.isFramebufferEnabled() && NotEnoughUpdates.INSTANCE.config.notifications.doFastRenderNotif) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "NEU cosmetics do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java index 6bce4f5a5f..cca6535e1f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/CustomizeCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.misc; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -9,7 +28,6 @@ import net.minecraft.item.ItemStack; import net.minecraft.util.ChatComponentText; -import java.util.Arrays; import java.util.Collections; import java.util.List; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/GamemodesCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/GamemodesCommand.java deleted file mode 100644 index d33e560a57..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/GamemodesCommand.java +++ /dev/null @@ -1,20 +0,0 @@ -package io.github.moulberry.notenoughupdates.commands.misc; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import io.github.moulberry.notenoughupdates.gamemodes.GuiGamemodes; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; - -public class GamemodesCommand extends ClientCommandBase { - - public GamemodesCommand() { - super("neugamemodes"); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - boolean upgradeOverride = args.length == 1 && args[0].equals("upgradeOverride"); - NotEnoughUpdates.INSTANCE.openGui = new GuiGamemodes(upgradeOverride); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java new file mode 100644 index 0000000000..5a4f14000d --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/PronounsCommand.java @@ -0,0 +1,94 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands.misc; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import io.github.moulberry.notenoughupdates.util.MinecraftExecutor; +import io.github.moulberry.notenoughupdates.util.PronounDB; +import io.github.moulberry.notenoughupdates.util.Utils; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiNewChat; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; + +import java.util.Optional; +import java.util.Random; +import java.util.UUID; +import java.util.concurrent.CompletableFuture; + +public class PronounsCommand extends ClientCommandBase { + public PronounsCommand() { + super("neupronouns"); + } + + @Override + public String getCommandUsage(ICommandSender sender) { + return "/neupronouns [platform]"; + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + switch (args.length) { + case 1: + fetchPronouns("minecraft", args[0]); + break; + case 2: + fetchPronouns(args[1], args[0]); + break; + default: + sender.addChatMessage(new ChatComponentText("§4" + getCommandUsage(sender))); + } + } + + private void fetchPronouns(String platform, String user) { + GuiNewChat nc = Minecraft.getMinecraft().ingameGUI.getChatGUI(); + int id = new Random().nextInt(); + nc.printChatMessageWithOptionalDeletion(new ChatComponentText("§e[NEU] Fetching Pronouns..."), id); + + CompletableFuture> pronouns; + if ("minecraft".equals(platform)) { + CompletableFuture c = new CompletableFuture<>(); + NotEnoughUpdates.profileViewer.getPlayerUUID(user, uuidString -> { + if (uuidString == null) { + c.completeExceptionally(new NullPointerException()); + } else { + c.complete(Utils.parseDashlessUUID(uuidString)); + } + }); + pronouns = c.thenCompose(PronounDB::getPronounsFor); + } else { + pronouns = PronounDB.getPronounsFor(platform, user); + } + pronouns.handleAsync((pronounChoice, throwable) -> { + if (throwable != null || !pronounChoice.isPresent()) { + nc.printChatMessageWithOptionalDeletion(new ChatComponentText("§e[NEU] §4Failed to fetch pronouns."), id); + return null; + } + PronounDB.PronounChoice betterPronounChoice = pronounChoice.get(); + nc.printChatMessageWithOptionalDeletion(new ChatComponentText( + "§e[NEU] Pronouns for §b" + user + " §eon §b" + platform + "§e:"), id); + betterPronounChoice.render().forEach(it -> nc.printChatMessage(new ChatComponentText("§e[NEU] §a" + it))); + return null; + }, MinecraftExecutor.INSTANCE); + + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/UpdateCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/UpdateCommand.java new file mode 100644 index 0000000000..cac933692a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/misc/UpdateCommand.java @@ -0,0 +1,78 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.commands.misc; + +import io.github.moulberry.notenoughupdates.NotEnoughUpdates; +import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; +import net.minecraft.command.CommandException; +import net.minecraft.command.ICommandSender; +import net.minecraft.util.ChatComponentText; + +import java.net.MalformedURLException; +import java.net.URL; +import java.util.Arrays; +import java.util.List; +import java.util.Objects; + +public class UpdateCommand extends ClientCommandBase { + NotEnoughUpdates neu; + + public UpdateCommand(NotEnoughUpdates neu) { + super("neuupdate"); + this.neu = neu; + } + + @Override + public List getCommandAliases() { + return Arrays.asList("neuupdates", "enoughupdates"); + } + + public void displayHelp(ICommandSender sender) { + sender.addChatMessage(new ChatComponentText( + "" + + "§e[NEU] §b/neuupdate help - View help.\n" + + "§e[NEU] §b/neuupdate check - Check for updates.\n" + + "" + )); + + } + + @Override + public void processCommand(ICommandSender sender, String[] args) throws CommandException { + if ((args.length == 1 && Objects.equals(args[0], "help")) || args.length == 0) { + displayHelp(sender); + return; + } + switch (args[0].toLowerCase().intern()) { + case "check": + neu.autoUpdater.displayUpdateMessageIfOutOfDate(); + break; + case "scheduledownload": + neu.autoUpdater.scheduleDownload(); + break; + case "updatemodes": + sender.addChatMessage(new ChatComponentText("§e[NEU] §bTo ensure we do not accidentally corrupt your mod folder, we can only offer support for autoupdates on system with certain capabilities for file deletions (specifically unix systems). You can still manually update your files")); + break; + default: + displayHelp(sender); + + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java index 09253e503a..afc47418fe 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/CataCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.profile; import io.github.moulberry.notenoughupdates.profileviewer.GuiProfileViewer; @@ -11,7 +30,7 @@ public CataCommand() { @Override public void processCommand(ICommandSender sender, String[] args) { - GuiProfileViewer.currentPage = GuiProfileViewer.ProfileViewerPage.DUNG; + GuiProfileViewer.currentPage = GuiProfileViewer.ProfileViewerPage.DUNGEON; super.processCommand(sender, args); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java index d69139aaf2..75e779fc5f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PeekCommand.java @@ -1,10 +1,29 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.profile; -import com.google.gson.JsonElement; import com.google.gson.JsonObject; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; import io.github.moulberry.notenoughupdates.profileviewer.PlayerStats; +import io.github.moulberry.notenoughupdates.profileviewer.ProfileViewer; import io.github.moulberry.notenoughupdates.util.Utils; import net.minecraft.client.Minecraft; import net.minecraft.command.CommandException; @@ -16,16 +35,19 @@ import org.apache.commons.lang3.text.WordUtils; import java.util.ArrayList; +import java.util.Arrays; import java.util.List; import java.util.Map; import java.util.Random; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; +import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; public class PeekCommand extends ClientCommandBase { private ScheduledExecutorService peekCommandExecutorService = null; + private ScheduledFuture peekScheduledFuture = null; public PeekCommand() { super("peek"); @@ -50,23 +72,23 @@ public void processCommand(ICommandSender sender, String[] args) throws CommandE } else { profile.resetCache(); - if (peekCommandExecutorService == null || peekCommandExecutorService.isShutdown()) { + if (peekCommandExecutorService == null) { peekCommandExecutorService = Executors.newSingleThreadScheduledExecutor(); - } else { + } + + if (peekScheduledFuture != null && !peekScheduledFuture.isDone()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( EnumChatFormatting.RED + "[PEEK] New peek command run, cancelling old one.")); - peekCommandExecutorService.shutdownNow(); - peekCommandExecutorService = Executors.newSingleThreadScheduledExecutor(); + peekScheduledFuture.cancel(true); } Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessageWithOptionalDeletion(new ChatComponentText( EnumChatFormatting.YELLOW + "[PEEK] Getting the player's Skyblock profile(s)..."), id); long startTime = System.currentTimeMillis(); - peekCommandExecutorService.schedule(new Runnable() { + peekScheduledFuture = peekCommandExecutorService.schedule(new Runnable() { public void run() { if (System.currentTimeMillis() - startTime > 10 * 1000) { - Minecraft.getMinecraft().ingameGUI .getChatGUI() .printChatMessageWithOptionalDeletion(new ChatComponentText( @@ -83,7 +105,8 @@ public void run() { boolean isMe = name.equalsIgnoreCase("moulberry"); PlayerStats.Stats stats = profile.getStats(null); - JsonObject skill = profile.getSkillInfo(null); + if (stats == null) return; + Map skyblockInfo = profile.getSkyblockInfo(null); Minecraft.getMinecraft().ingameGUI .getChatGUI() @@ -92,27 +115,25 @@ public void run() { Utils.getElementAsString(profile.getHypixelProfile().get("displayname"), name) + "'s Info " + EnumChatFormatting.STRIKETHROUGH + "-=-"), id); - if (skill == null) { + if (skyblockInfo == null) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( - EnumChatFormatting.YELLOW + "Skills api disabled!")); + EnumChatFormatting.YELLOW + "Skills API disabled!")); } else { float totalSkillLVL = 0; float totalSkillCount = 0; - for (Map.Entry entry : skill.entrySet()) { - if (entry.getKey().startsWith("level_skill")) { - if (entry.getKey().contains("runecrafting")) continue; - if (entry.getKey().contains("carpentry")) continue; - totalSkillLVL += entry.getValue().getAsFloat(); - totalSkillCount++; - } + List skills = Arrays.asList("taming", "mining", "foraging", "enchanting", "farming", "combat", "fishing", "alchemy", "carpentry"); + for (String skillName : skills) { + totalSkillLVL += skyblockInfo.get(skillName).level; + totalSkillCount++; } - float combat = Utils.getElementAsFloat(skill.get("level_skill_combat"), 0); - float zombie = Utils.getElementAsFloat(skill.get("level_slayer_zombie"), 0); - float spider = Utils.getElementAsFloat(skill.get("level_slayer_spider"), 0); - float wolf = Utils.getElementAsFloat(skill.get("level_slayer_wolf"), 0); - float enderman = Utils.getElementAsFloat(skill.get("level_slayer_enderman"), 0); + float combat = skyblockInfo.get("combat").level; + float zombie = skyblockInfo.get("zombie").level; + float spider = skyblockInfo.get("spider").level; + float wolf = skyblockInfo.get("wolf").level; + float enderman = skyblockInfo.get("enderman").level; + float blaze = skyblockInfo.get("blaze").level; float avgSkillLVL = totalSkillLVL / totalSkillCount; @@ -123,6 +144,7 @@ public void run() { spider = 1; wolf = 2; enderman = 0; + blaze = 0; } EnumChatFormatting combatPrefix = combat > 20 @@ -141,6 +163,11 @@ public void run() { ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) : EnumChatFormatting.RED; + EnumChatFormatting blazePrefix = blaze > 3 + ? (blaze > 6 + ? EnumChatFormatting.GREEN + : EnumChatFormatting.YELLOW) + : EnumChatFormatting.RED; EnumChatFormatting avgPrefix = avgSkillLVL > 20 ? (avgSkillLVL > 35 ? EnumChatFormatting.GREEN @@ -151,9 +178,10 @@ public void run() { overallScore += spider * spider / 81f; overallScore += wolf * wolf / 81f; overallScore += enderman * enderman / 81f; + overallScore += blaze * blaze / 81f; overallScore += avgSkillLVL / 20f; - int cata = (int) Utils.getElementAsFloat(skill.get("level_skill_catacombs"), 0); + int cata = (int) skyblockInfo.get("catacombs").level; EnumChatFormatting cataPrefix = cata > 15 ? (cata > 25 ? EnumChatFormatting.GREEN : EnumChatFormatting.YELLOW) : EnumChatFormatting.RED; @@ -167,8 +195,9 @@ public void run() { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( g + "Slayer: " + zombiePrefix + (int) Math.floor(zombie) + g + "-" + spiderPrefix + (int) Math.floor(spider) + g + "-" + - wolfPrefix + (int) Math.floor(wolf) + "-" + - endermanPrefix + (int) Math.floor(enderman))); + wolfPrefix + (int) Math.floor(wolf) + g+ "-" + + endermanPrefix + (int) Math.floor(enderman) + g + "-" + + blazePrefix + (int) Math.floor(blaze))); } if (stats == null) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText( @@ -266,7 +295,7 @@ public void run() { peekCommandExecutorService.shutdownNow(); } else { - peekCommandExecutorService.schedule(this, 200, TimeUnit.MILLISECONDS); + peekScheduledFuture = peekCommandExecutorService.schedule(this, 200, TimeUnit.MILLISECONDS); } } }, 200, TimeUnit.MILLISECONDS); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PvCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PvCommand.java index 07394ffd30..2d5c05f4a9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PvCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/PvCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.profile; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java index 371db3944d..e4ca497c9e 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/commands/profile/ViewProfileCommand.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.commands.profile; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -23,8 +42,8 @@ public class ViewProfileCommand extends ClientCommandBase { "Some parts of the profile viewer do not work with OF Fast Render. Go to ESC > Options > Video Settings > Performance > Fast Render to disable it.")); } - if (NotEnoughUpdates.INSTANCE.config.apiKey.apiKey == null || - NotEnoughUpdates.INSTANCE.config.apiKey.apiKey.trim().isEmpty()) { + if (NotEnoughUpdates.INSTANCE.config.apiData.apiKey == null || + NotEnoughUpdates.INSTANCE.config.apiData.apiKey.trim().isEmpty()) { Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText(EnumChatFormatting.RED + "Can't view profile, apikey is not set. Run /api new and put the result in settings.")); } else if (args.length == 0) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/ReloadRepoCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/ReloadRepoCommand.java deleted file mode 100644 index e363b59f62..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/ReloadRepoCommand.java +++ /dev/null @@ -1,39 +0,0 @@ -package io.github.moulberry.notenoughupdates.commands.repo; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import io.github.moulberry.notenoughupdates.options.NEUConfig; -import io.github.moulberry.notenoughupdates.util.Constants; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; - -import java.io.BufferedReader; -import java.io.FileInputStream; -import java.io.InputStreamReader; -import java.nio.charset.StandardCharsets; - -public class ReloadRepoCommand extends ClientCommandBase { - - public ReloadRepoCommand() { - super("neureloadrepo"); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - NotEnoughUpdates.INSTANCE.manager.reloadRepository(); - Constants.reload(); - - NotEnoughUpdates.INSTANCE.newConfigFile(); - if (NotEnoughUpdates.INSTANCE.getConfigFile().exists()) { - try ( - BufferedReader reader = new BufferedReader(new InputStreamReader( - new FileInputStream(NotEnoughUpdates.INSTANCE.getConfigFile()), - StandardCharsets.UTF_8 - )) - ) { - NotEnoughUpdates.INSTANCE.config = NotEnoughUpdates.INSTANCE.manager.gson.fromJson(reader, NEUConfig.class); - } catch (Exception ignored) { - } - } - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/RepoModeCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/RepoModeCommand.java deleted file mode 100644 index bb6e1675e1..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/RepoModeCommand.java +++ /dev/null @@ -1,23 +0,0 @@ -package io.github.moulberry.notenoughupdates.commands.repo; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import net.minecraft.client.Minecraft; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; -import net.minecraft.util.ChatComponentText; - -public class RepoModeCommand extends ClientCommandBase { - - public RepoModeCommand() { - super("neurepomode"); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - NotEnoughUpdates.INSTANCE.config.hidden.dev = !NotEnoughUpdates.INSTANCE.config.hidden.dev; - NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing = - !NotEnoughUpdates.INSTANCE.config.hidden.enableItemEditing; - Minecraft.getMinecraft().thePlayer.addChatMessage(new ChatComponentText("\u00a75Toggled NEU repo dev mode.")); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/ResetRepoCommand.java b/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/ResetRepoCommand.java deleted file mode 100644 index b9a0d7cd4d..0000000000 --- a/src/main/java/io/github/moulberry/notenoughupdates/commands/repo/ResetRepoCommand.java +++ /dev/null @@ -1,18 +0,0 @@ -package io.github.moulberry.notenoughupdates.commands.repo; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.commands.ClientCommandBase; -import net.minecraft.command.CommandException; -import net.minecraft.command.ICommandSender; - -public class ResetRepoCommand extends ClientCommandBase { - - public ResetRepoCommand() { - super("neuresetrepo"); - } - - @Override - public void processCommand(ICommandSender sender, String[] args) throws CommandException { - NotEnoughUpdates.INSTANCE.manager.resetRepo(); - } -} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java b/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java index c85841b3f0..fc2be97b0f 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/BackgroundBlur.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/ChromaColour.java b/src/main/java/io/github/moulberry/notenoughupdates/core/ChromaColour.java index 8f4dd87dee..05a9a65ea6 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/ChromaColour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/ChromaColour.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import java.awt.*; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GlScissorStack.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GlScissorStack.java index 7cc8893fff..40b9fe7ac6 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GlScissorStack.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GlScissorStack.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import net.minecraft.client.Minecraft; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElement.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElement.java index c1c76675e0..2a684164cb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElement.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElement.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import net.minecraft.client.gui.Gui; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java index d5cbb3ad66..b05862104d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementBoolean.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import io.github.moulberry.notenoughupdates.core.util.lerp.LerpUtils; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java index 48996c8d41..1f655aafe2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementColour.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java index 51a4654c3c..45dc58ccd6 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiElementTextField.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import io.github.moulberry.notenoughupdates.core.util.StringUtils; @@ -36,6 +55,7 @@ public class GuiElementTextField { private int y; private String prependText = ""; + private String masterStarUnicode = ""; private int customTextColour = 0xffffffff; private final GuiTextField textField = new GuiTextField(0, Minecraft.getMinecraft().fontRendererObj, @@ -395,6 +415,55 @@ public void keyTyped(char typedChar, int keyCode) { textField.setCursorPosition(pos + 1); } } + } else { + for (int i = 0; i < 10; i++) { + if (typedChar == Integer.toString(i + 1).charAt(0)) { + int pos = textField.getCursorPosition() - 2; + if (pos >= 0 && pos < textField.getText().length()) { + if (textField.getText().charAt(pos) == '*') { + switch (i) { + case 0: + masterStarUnicode = "\u278A"; + break; + case 1: + masterStarUnicode = "\u278B"; + break; + case 2: + masterStarUnicode = "\u278C"; + break; + case 3: + masterStarUnicode = "\u278D"; + break; + case 4: + masterStarUnicode = "\u278E"; + break; + case 5: + masterStarUnicode = "\u278F"; + break; + case 6: + masterStarUnicode = "\u2790"; + break; + case 7: + masterStarUnicode = "\u2791"; + break; + case 8: + masterStarUnicode = "\u2792"; + break; + case 9: + masterStarUnicode = "\u2793"; + break; + } + String before = textField.getText().substring(0, pos); + String after = ""; + if (pos + 2 < textField.getText().length()) { + after = textField.getText().substring(pos + 2); + } + textField.setText(before + masterStarUnicode + after); + textField.setCursorPosition(pos + 1); + } + } + } + } } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiScreenElementWrapper.java b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiScreenElementWrapper.java index c7c4517bd1..95ed8a5f5a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/GuiScreenElementWrapper.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/GuiScreenElementWrapper.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core; import net.minecraft.client.gui.GuiScreen; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java index 2a696a44ed..6bafb1fd1b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Config.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config; public class Config { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/GuiPositionEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/GuiPositionEditor.java index 9d0133cb45..eac1e5cda0 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/GuiPositionEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/GuiPositionEditor.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config; import net.minecraft.client.Minecraft; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/KeybindHelper.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/KeybindHelper.java index 30226a22e5..d63f871cb1 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/KeybindHelper.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/KeybindHelper.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config; import org.lwjgl.input.Keyboard; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/MoulConfigGuiForgeInterop.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/MoulConfigGuiForgeInterop.java new file mode 100644 index 0000000000..40887e548a --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/MoulConfigGuiForgeInterop.java @@ -0,0 +1,69 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.core.config; + +import io.github.moulberry.notenoughupdates.core.GuiScreenElementWrapper; +import io.github.moulberry.notenoughupdates.options.NEUConfigEditor; +import net.minecraft.client.Minecraft; +import net.minecraft.client.gui.GuiScreen; +import net.minecraftforge.fml.client.IModGuiFactory; +import org.lwjgl.input.Keyboard; + +import java.io.IOException; +import java.util.Set; + +public class MoulConfigGuiForgeInterop implements IModGuiFactory { + @Override + public void initialize(Minecraft minecraft) {} + + @Override + public Class mainConfigGuiClass() { + return WrappedMoulConfig.class; + } + + @Override + public Set runtimeGuiCategories() { + return null; + } + + @Override + public RuntimeOptionGuiHandler getHandlerFor(RuntimeOptionCategoryElement runtimeOptionCategoryElement) { + return null; + } + + public static class WrappedMoulConfig extends GuiScreenElementWrapper { + + private final GuiScreen parent; + + public WrappedMoulConfig(GuiScreen parent) { + super(NEUConfigEditor.editor); + this.parent = parent; + } + + @Override + public void handleKeyboardInput() throws IOException { + if (Keyboard.getEventKeyState() && Keyboard.getEventKey() == Keyboard.KEY_ESCAPE) { + Minecraft.getMinecraft().displayGuiScreen(parent); + return; + } + super.handleKeyboardInput(); + } + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/Position.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Position.java index cf94664964..535c92bf5a 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/Position.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/Position.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config; import com.google.gson.annotations.Expose; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/PositionNew.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/PositionNew.java index 8f2b02d85a..cf756c912c 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/PositionNew.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/PositionNew.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config; import com.google.gson.annotations.Expose; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/Category.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/Category.java index b67d038363..e0a9585aa8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/Category.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/Category.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigAccordionId.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigAccordionId.java index 1c84785127..b11f7651dd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigAccordionId.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigAccordionId.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorAccordion.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorAccordion.java index 11b798f9cf..7491a94f34 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorAccordion.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorAccordion.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorBoolean.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorBoolean.java index a0ca1f386e..8e6f652c65 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorBoolean.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorBoolean.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; @@ -7,4 +26,6 @@ @Retention(RetentionPolicy.RUNTIME) @Target(ElementType.FIELD) -public @interface ConfigEditorBoolean {} +public @interface ConfigEditorBoolean { + int runnableId() default -1; +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorButton.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorButton.java index 455df65fb4..a2c56dc0f8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorButton.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorButton.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorColour.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorColour.java index 6640ade911..824b2eec01 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorColour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorColour.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java index e171e0ae43..d9707c9ba4 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDraggableList.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; @@ -9,4 +28,6 @@ @Target(ElementType.FIELD) public @interface ConfigEditorDraggableList { String[] exampleText(); + + boolean allowDeleting() default true; } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDropdown.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDropdown.java index ac766e934e..8d87064346 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDropdown.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorDropdown.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorFSR.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorFSR.java index 217df0c59a..ba45ae6881 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorFSR.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorFSR.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorKeybind.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorKeybind.java index 8d8de2ebed..f1a3e329f5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorKeybind.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorKeybind.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorSlider.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorSlider.java index abab37f914..b8db25bcbc 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorSlider.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorSlider.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorText.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorText.java index 1ff7e39e50..b6b32fb214 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorText.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigEditorText.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java index 2ee23dcf42..d51294e770 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/annotations/ConfigOption.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.annotations; import java.lang.annotation.ElementType; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java index d62c7ec7cf..c3969e3509 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditor.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.struct.ConfigProcessor; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorAccordion.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorAccordion.java index 8877cd03bd..dc1173efa5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorAccordion.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorAccordion.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.struct.ConfigProcessor; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorBoolean.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorBoolean.java index 9e2c912a2e..d12ec8e775 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorBoolean.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorBoolean.java @@ -1,15 +1,43 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.GuiElementBoolean; +import io.github.moulberry.notenoughupdates.core.config.Config; import io.github.moulberry.notenoughupdates.core.config.struct.ConfigProcessor; public class GuiOptionEditorBoolean extends GuiOptionEditor { + private final GuiElementBoolean bool; + private final Config config; + private final int runnableId; - public GuiOptionEditorBoolean(ConfigProcessor.ProcessedOption option) { + public GuiOptionEditorBoolean( + ConfigProcessor.ProcessedOption option, + int runnableId, + Config config + ) { super(option); - - bool = new GuiElementBoolean(0, 0, (boolean) option.get(), 10, option::set); + this.config = config; + this.runnableId = runnableId; + bool = new GuiElementBoolean(0, 0, (boolean) option.get(), 10, (value) -> onUpdate(option, value)); } @Override @@ -34,4 +62,10 @@ public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) { public boolean keyboardInput() { return false; } + + private void onUpdate(ConfigProcessor.ProcessedOption option, boolean value) { + if (option.set(value)) { + config.executeRunnable(runnableId); + } + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorButton.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorButton.java index 76944efad7..aef6318c25 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorButton.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorButton.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.Config; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorColour.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorColour.java index 80d2af4246..ca4087b549 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorColour.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorColour.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.ChromaColour; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java index 08a1024f90..63a932b5bb 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDraggableList.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.struct.ConfigProcessor; @@ -24,6 +43,7 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { private static final ResourceLocation DELETE = new ResourceLocation("notenoughupdates:core/delete.png"); private final String[] exampleText; + private final boolean enableDeleting; private final List activeText; private int currentDragging = -1; private int dragStartIndex = -1; @@ -35,9 +55,14 @@ public class GuiOptionEditorDraggableList extends GuiOptionEditor { private boolean dropdownOpen = false; - public GuiOptionEditorDraggableList(ConfigProcessor.ProcessedOption option, String[] exampleText) { + public GuiOptionEditorDraggableList( + ConfigProcessor.ProcessedOption option, + String[] exampleText, + boolean disableDeleting + ) { super(option); + this.enableDeleting = disableDeleting; this.exampleText = exampleText; this.activeText = (List) option.get(); } @@ -77,8 +102,11 @@ public void render(int x, int y, int width) { float greenBlue = LerpUtils.clampZeroOne((250 + trashHoverTime - currentTime) / 250f); GlStateManager.color(1, greenBlue, greenBlue, 1); } - Minecraft.getMinecraft().getTextureManager().bindTexture(DELETE); - Utils.drawTexturedRect(x + width / 6 + 27, y + 45 - 7 - 13, 11, 14, GL11.GL_NEAREST); + + if (enableDeleting) { + Minecraft.getMinecraft().getTextureManager().bindTexture(DELETE); + Utils.drawTexturedRect(x + width / 6 + 27, y + 45 - 7 - 13, 11, 14, GL11.GL_NEAREST); + } Gui.drawRect(x + 5, y + 45, x + width - 5, y + height - 5, 0xffdddddd); Gui.drawRect(x + 6, y + 46, x + width - 6, y + height - 6, 0xff000000); @@ -206,7 +234,9 @@ public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) { dragStartIndex >= 0 && Mouse.getEventButton() == 0 && mouseX >= x + width / 6 + 27 - 3 && mouseX <= x + width / 6 + 27 + 11 + 3 && mouseY >= y + 45 - 7 - 13 - 3 && mouseY <= y + 45 - 7 - 13 + 14 + 3) { - activeText.remove(dragStartIndex); + if (enableDeleting) { + activeText.remove(dragStartIndex); + } currentDragging = -1; dragStartIndex = -1; return false; @@ -215,13 +245,13 @@ public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) { if (!Mouse.isButtonDown(0) || dropdownOpen) { currentDragging = -1; dragStartIndex = -1; - if (trashHoverTime > 0) trashHoverTime = -System.currentTimeMillis(); + if (trashHoverTime > 0 && enableDeleting) trashHoverTime = -System.currentTimeMillis(); } else if (currentDragging >= 0 && mouseX >= x + width / 6 + 27 - 3 && mouseX <= x + width / 6 + 27 + 11 + 3 && mouseY >= y + 45 - 7 - 13 - 3 && mouseY <= y + 45 - 7 - 13 + 14 + 3) { - if (trashHoverTime < 0) trashHoverTime = System.currentTimeMillis(); + if (trashHoverTime < 0 && enableDeleting) trashHoverTime = System.currentTimeMillis(); } else { - if (trashHoverTime > 0) trashHoverTime = -System.currentTimeMillis(); + if (trashHoverTime > 0 && enableDeleting) trashHoverTime = -System.currentTimeMillis(); } if (Mouse.getEventButtonState()) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java index a17737e3a7..af6af27707 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorDropdown.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.struct.ConfigProcessor; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorFSR.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorFSR.java index b443b5f66d..048e261e9b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorFSR.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorFSR.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.Config; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorKeybind.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorKeybind.java index 5ff961a72c..6eb71d1e44 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorKeybind.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorKeybind.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.KeybindHelper; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorSlider.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorSlider.java index 45ae70d96c..7fceb92dbd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorSlider.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorSlider.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.GuiElementTextField; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorText.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorText.java index f98c87eeae..ad2fa4dbc2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorText.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiOptionEditorText.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.GuiElementTextField; @@ -68,7 +87,6 @@ public boolean mouseInput(int x, int y, int width, int mouseX, int mouseY) { @Override public boolean keyboardInput() { if (Keyboard.getEventKeyState() && textField.getFocus()) { - Keyboard.enableRepeatEvents(true); textField.keyTyped(Keyboard.getEventCharacter(), Keyboard.getEventKey()); try { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiPositionEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiPositionEditor.java index 651335ed3e..ed45bab638 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiPositionEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/gui/GuiPositionEditor.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.gui; import io.github.moulberry.notenoughupdates.core.config.Position; @@ -129,8 +148,6 @@ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) throws IOEx @Override protected void keyTyped(char typedChar, int keyCode) throws IOException { - Keyboard.enableRepeatEvents(true); - if (keyCode == Keyboard.KEY_R) { position.set(originalPosition); } else if (!clicked) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java index b5aa6ba875..75862069dd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/config/struct/ConfigProcessor.java @@ -1,9 +1,50 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.config.struct; import com.google.gson.annotations.Expose; import io.github.moulberry.notenoughupdates.core.config.Config; -import io.github.moulberry.notenoughupdates.core.config.annotations.*; -import io.github.moulberry.notenoughupdates.core.config.gui.*; +import io.github.moulberry.notenoughupdates.core.config.annotations.Category; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigAccordionId; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorAccordion; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorButton; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorColour; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDraggableList; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorDropdown; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorFSR; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorKeybind; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorSlider; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorText; +import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditor; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorAccordion; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorBoolean; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorButton; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorColour; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorDraggableList; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorDropdown; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorFSR; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorKeybind; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorSlider; +import io.github.moulberry.notenoughupdates.core.config.gui.GuiOptionEditorText; import java.lang.reflect.Field; import java.util.LinkedHashMap; @@ -130,7 +171,8 @@ public static LinkedHashMap create(Config config) { } if (optionType.isAssignableFrom(boolean.class) && optionField.isAnnotationPresent(ConfigEditorBoolean.class)) { - editor = new GuiOptionEditorBoolean(option); + ConfigEditorBoolean configEditorAnnotation = optionField.getAnnotation(ConfigEditorBoolean.class); + editor = new GuiOptionEditorBoolean(option, configEditorAnnotation.runnableId(), config); } if (optionType.isAssignableFrom(boolean.class) && optionField.isAnnotationPresent(ConfigEditorAccordion.class)) { @@ -147,7 +189,11 @@ public static LinkedHashMap create(Config config) { if (optionField.isAnnotationPresent(ConfigEditorDraggableList.class)) { ConfigEditorDraggableList configEditorAnnotation = optionField.getAnnotation(ConfigEditorDraggableList.class); - editor = new GuiOptionEditorDraggableList(option, configEditorAnnotation.exampleText()); + editor = new GuiOptionEditorDraggableList( + option, + configEditorAnnotation.exampleText(), + configEditorAnnotation.allowDeleting() + ); } } if (optionType.isAssignableFrom(String.class)) { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/GuiElementSlider.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/GuiElementSlider.java index c2252a97f8..3e982f9d2d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/GuiElementSlider.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/GuiElementSlider.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util; import io.github.moulberry.notenoughupdates.core.GuiElement; @@ -10,7 +29,13 @@ import java.util.function.Consumer; -import static io.github.moulberry.notenoughupdates.util.GuiTextures.*; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_button_new; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_off_cap; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_off_notch; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_off_segment; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_on_cap; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_on_notch; +import static io.github.moulberry.notenoughupdates.util.GuiTextures.slider_on_segment; public class GuiElementSlider extends GuiElement { public int x; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/Line.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Line.java new file mode 100644 index 0000000000..a5744a261e --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Line.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.core.util; + +import net.minecraft.util.Vec3; + +/** + * Represents a line using two points along the line or a segment with endpoints. + */ +public class Line { + private static final double DOUBLE_EPSILON = 4.94065645841247E-324; + public Vec3 point1; + public Vec3 point2; + + public Line(Vec3 first, Vec3 second) { + point1 = first; + point2 = second; + } + + public Vec3 getMidpoint() { + return new Vec3( + (point1.xCoord + point2.xCoord) / 2.0, + (point1.yCoord + point2.yCoord) / 2.0, + (point1.zCoord + point2.zCoord) / 2.0 + ); + } + + /** + * Calculates the intersection line segment between 2 lines + * Based on http://paulbourke.net/geometry/pointlineplane/calclineline.cs + * + * @return The intersection {@link Line} or {@code null} if no solution found + */ + public Line getIntersectionLineSegment(Line other) { + Vec3 p1 = this.point1; + Vec3 p2 = this.point2; + Vec3 p3 = other.point1; + Vec3 p4 = other.point2; + Vec3 p13 = p1.subtract(p3); + Vec3 p43 = p4.subtract(p3); + + if (lengthSquared(p43) < DOUBLE_EPSILON) { + return null; + } + + Vec3 p21 = p2.subtract(p1); + if (lengthSquared(p21) < DOUBLE_EPSILON) { + return null; + } + + double d1343 = p13.xCoord * p43.xCoord + p13.yCoord * p43.yCoord + p13.zCoord * p43.zCoord; + double d4321 = p43.xCoord * p21.xCoord + p43.yCoord * p21.yCoord + p43.zCoord * p21.zCoord; + double d1321 = p13.xCoord * p21.xCoord + p13.yCoord * p21.yCoord + p13.zCoord * p21.zCoord; + double d4343 = p43.xCoord * p43.xCoord + p43.yCoord * p43.yCoord + p43.zCoord * p43.zCoord; + double d2121 = p21.xCoord * p21.xCoord + p21.yCoord * p21.yCoord + p21.zCoord * p21.zCoord; + + double denom = d2121 * d4343 - d4321 * d4321; + if (Math.abs(denom) < DOUBLE_EPSILON) { + return null; + } + double numer = d1343 * d4321 - d1321 * d4343; + + double mua = numer / denom; + double mub = (d1343 + d4321 * (mua)) / d4343; + + Line resultSegment = new Line( + new Vec3( + (float) (p1.xCoord + mua * p21.xCoord), + (float) (p1.yCoord + mua * p21.yCoord), + (float) (p1.zCoord + mua * p21.zCoord) + ), + new Vec3( + (float) (p3.xCoord + mub * p43.xCoord), + (float) (p3.yCoord + mub * p43.yCoord), + (float) (p3.zCoord + mub * p43.zCoord) + ) + ); + + return resultSegment; + } + + public Line getImmutable() { + return new Line(point1, point2); + } + + private static double lengthSquared(Vec3 vec) { + return vec.dotProduct(vec); + } + + public String toString() { + return String.format( + "point1 = %s, point2 = %s, midpoint = %s", + point1 == null ? "NULL" : point1.toString(), + point2 == null ? "NULL" : point2.toString(), + (point1 == null || point2 == null) ? "NULL" : getMidpoint() + ); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/MiscUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/MiscUtils.java index 03a9483b89..4178014025 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/MiscUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/MiscUtils.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util; import net.minecraft.client.Minecraft; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/Splitters.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Splitters.java index 0bb858db1a..389991b4f3 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/Splitters.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Splitters.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util; import com.google.common.base.Splitter; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java index b0deadd25e..a4f814d140 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/StringUtils.java @@ -1,9 +1,31 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util; import com.google.common.collect.Sets; import net.minecraft.client.Minecraft; import net.minecraft.client.gui.FontRenderer; +import java.io.UnsupportedEncodingException; +import java.net.URLEncoder; +import java.nio.charset.StandardCharsets; import java.util.Set; public class StringUtils { @@ -34,4 +56,50 @@ public static String trimToWidth(String str, int len) { return trim; } + + public static String substringBetween(String str, String open, String close) { + return org.apache.commons.lang3.StringUtils.substringBetween(str, open, close); + } + + public static int cleanAndParseInt(String str) { + str = cleanColour(str); + str = str.replace(",", ""); + return Integer.parseInt(str); + } + + public static String shortNumberFormat(double n) { + return shortNumberFormat(n, 0); + } + + private static final char[] c = new char[] { 'k', 'm', 'b', 't' }; + + public static String shortNumberFormat(double n, int iteration) { + if (n < 1000) { + if (n % 1 == 0) { + return Integer.toString((int) n); + } else { + return String.format("%.2f", n); + } + } + + double d = ((long) n / 100) / 10.0; + boolean isRound = (d * 10) % 10 == 0; + return d < 1000 ? (isRound || d > 9.99 ? (int) d * 10 / 10 : d + "") + "" + c[iteration] : shortNumberFormat(d, iteration + 1); + } + + public static String urlEncode(String something) { + try { + return URLEncoder.encode(something, StandardCharsets.UTF_8.name()); + } catch (UnsupportedEncodingException e) { + throw new RuntimeException(e); // UTF 8 should always be present + } + } + + /** + * taken and modified from https://stackoverflow.com/a/23326014/5507634 + */ + public static String replaceLast(String string, String toReplace, String replacement) { + int start = string.lastIndexOf(toReplace); + return string.substring(0, start) + replacement + string.substring(start + toReplace.length()); + } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/Vec3Comparable.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Vec3Comparable.java new file mode 100644 index 0000000000..c9736b7750 --- /dev/null +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/Vec3Comparable.java @@ -0,0 +1,148 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + +package io.github.moulberry.notenoughupdates.core.util; + +import net.minecraft.util.BlockPos; +import net.minecraft.util.Vec3; +import net.minecraft.util.Vec3i; + +public class Vec3Comparable extends Vec3 implements Comparable { + public static final Vec3Comparable NULL_VECTOR = new Vec3Comparable(0.0, 0.0, 0.0); + + public Vec3Comparable(double x, double y, double z) { + super(x, y, z); + } + + public Vec3Comparable(Vec3i sourceVec) { + super(sourceVec); + } + + public Vec3Comparable(Vec3 source) { + super(source.xCoord, source.yCoord, source.zCoord); + } + + public Vec3Comparable(BlockPos source) { + + super(source.getX(), source.getY(), source.getZ()); + } + + public Vec3Comparable(Vec3Comparable source) { + super(source.xCoord, source.yCoord, source.zCoord); + } + + @Override + public Vec3Comparable subtractReverse(Vec3 vec) { + return new Vec3Comparable(super.subtractReverse(vec)); + } + + @Override + public Vec3Comparable normalize() { + return new Vec3Comparable(super.normalize()); + } + + @Override + public Vec3Comparable crossProduct(Vec3 vec) { + return new Vec3Comparable(super.crossProduct(vec)); + } + + @Override + public Vec3Comparable subtract(Vec3 vec) { + return new Vec3Comparable(super.subtract(vec)); + } + + @Override + public Vec3Comparable subtract(double x, double y, double z) { + return new Vec3Comparable(super.subtract(x, y, z)); + } + + @Override + public Vec3Comparable add(Vec3 other) { + return new Vec3Comparable(super.add(other)); + } + + @Override + public Vec3Comparable addVector(double x, double y, double z) { + return new Vec3Comparable(super.addVector(x, y, z)); + } + + @Override + public Vec3Comparable getIntermediateWithXValue(Vec3 vec, double x) { + return new Vec3Comparable(super.getIntermediateWithXValue(vec, x)); + } + + @Override + public Vec3Comparable getIntermediateWithYValue(Vec3 vec, double y) { + return new Vec3Comparable(super.getIntermediateWithYValue(vec, y)); + } + + @Override + public Vec3Comparable getIntermediateWithZValue(Vec3 vec, double z) { + return new Vec3Comparable(super.getIntermediateWithZValue(vec, z)); + } + + @Override + public Vec3Comparable rotatePitch(float pitch) { + return new Vec3Comparable(super.rotatePitch(pitch)); + } + + @Override + public Vec3Comparable rotateYaw(float yaw) { + return new Vec3Comparable(super.rotateYaw(yaw)); + } + + @Override + public boolean equals(Object other) { + if (this == other) { + return true; + } else if (!(other instanceof Vec3Comparable)) { + return false; + } else { + Vec3Comparable vec3c = (Vec3Comparable) other; + return this.xCoord == vec3c.xCoord && this.yCoord == vec3c.yCoord && this.zCoord == vec3c.zCoord; + } + } + + @Override + public int hashCode() { + long bits = 1L; + bits = 31L * bits + doubleToLongBits(xCoord); + bits = 31L * bits + doubleToLongBits(yCoord); + bits = 31L * bits + doubleToLongBits(zCoord); + return (int) (bits ^ (bits >> 32)); + } + + public int compareTo(Vec3Comparable other) { + return this.yCoord == other.yCoord ? + (this.zCoord == other.zCoord ? + (int) (this.xCoord - other.xCoord) + : (int) (this.zCoord - other.zCoord)) + : (int) (this.yCoord - other.yCoord); + } + + public boolean signumEquals(Vec3 other) { + return Math.signum(xCoord) == Math.signum(other.xCoord) && + Math.signum(yCoord) == Math.signum(other.yCoord) && + Math.signum(zCoord) == Math.signum(other.zCoord); + } + + private static long doubleToLongBits(double d) { + return d == 0.0 ? 0L : Double.doubleToLongBits(d); + } +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpUtils.java index 7e40195925..0e60ad9272 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpUtils.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util.lerp; public class LerpUtils { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingFloat.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingFloat.java index 3d9e778759..fb03140ce5 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingFloat.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingFloat.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util.lerp; public class LerpingFloat { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingInteger.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingInteger.java index 024455fd66..8462200fff 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingInteger.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/lerp/LerpingInteger.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util.lerp; public class LerpingInteger { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java index 9a4607edba..e7ce29c334 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/RenderUtils.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util.render; import io.github.moulberry.notenoughupdates.core.BackgroundBlur; @@ -13,11 +32,20 @@ import net.minecraft.client.renderer.WorldRenderer; import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.entity.Entity; -import net.minecraft.util.*; +import net.minecraft.util.AxisAlignedBB; +import net.minecraft.util.BlockPos; +import net.minecraft.util.EnumChatFormatting; +import net.minecraft.util.MathHelper; +import net.minecraft.util.ResourceLocation; +import net.minecraft.util.Vec3i; import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL14; import org.lwjgl.util.vector.Vector3f; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; + public class RenderUtils { public static void drawFloatingRectDark(int x, int y, int width, int height) { drawFloatingRectDark(x, y, width, height, true); @@ -228,7 +256,7 @@ private static void renderBeaconBeam( double d11 = 0.5D + Math.sin(d2 + 5.497787143782138D) * 0.2D; double d14 = -1.0D + d1; double d15 = (double) (height) * 2.5D + d14; - worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); + worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); worldrenderer.pos(x + d4, y + topOffset, z + d5).tex(1.0D, d15).color(r, g, b, 1.0F * alphaMult).endVertex(); worldrenderer.pos(x + d4, y + bottomOffset, z + d5).tex(1.0D, d14).color(r, g, b, 1.0F).endVertex(); worldrenderer.pos(x + d6, y + bottomOffset, z + d7).tex(0.0D, d14).color(r, g, b, 1.0F).endVertex(); @@ -251,7 +279,7 @@ private static void renderBeaconBeam( double d12 = -1.0D + d1; double d13 = height + d12; - worldrenderer.begin(7, DefaultVertexFormats.POSITION_TEX_COLOR); + worldrenderer.begin(GL11.GL_QUADS, DefaultVertexFormats.POSITION_TEX_COLOR); worldrenderer.pos(x + 0.2D, y + topOffset, z + 0.2D).tex(1.0D, d13).color(r, g, b, 0.25F * alphaMult).endVertex(); worldrenderer.pos(x + 0.2D, y + bottomOffset, z + 0.2D).tex(1.0D, d12).color(r, g, b, 0.25F).endVertex(); worldrenderer.pos(x + 0.8D, y + bottomOffset, z + 0.2D).tex(0.0D, d12).color(r, g, b, 0.25F).endVertex(); @@ -345,11 +373,19 @@ public static void renderBeaconBeamOrBoundingBox(BlockPos block, int rgb, float } } - public static void renderWayPoint(String str, BlockPos loc, float partialTicks) { + public static void renderWayPoint(String str, Vec3i loc, float partialTicks) { + renderWayPoint(str, new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks); + } + + public static void renderWayPoint(List str, Vec3i loc, float partialTicks) { renderWayPoint(str, new Vector3f(loc.getX(), loc.getY(), loc.getZ()), partialTicks); } public static void renderWayPoint(String str, Vector3f loc, float partialTicks) { + renderWayPoint(Arrays.asList(str), loc, partialTicks); + } + + public static void renderWayPoint(List lines, Vector3f loc, float partialTicks) { GlStateManager.alphaFunc(516, 0.1F); GlStateManager.pushMatrix(); @@ -373,15 +409,9 @@ public static void renderWayPoint(String str, Vector3f loc, float partialTicks) GlStateManager.translate(x, y, z); GlStateManager.translate(0, viewer.getEyeHeight(), 0); - renderNametag(str); - - GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); - GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); - GlStateManager.translate(0, -0.25f, 0); - GlStateManager.rotate(-Minecraft.getMinecraft().getRenderManager().playerViewX, 1.0F, 0.0F, 0.0F); - GlStateManager.rotate(Minecraft.getMinecraft().getRenderManager().playerViewY, 0.0F, 1.0F, 0.0F); - - renderNametag(EnumChatFormatting.YELLOW.toString() + Math.round(dist) + "m"); + lines = new ArrayList<>(lines); + lines.add(EnumChatFormatting.YELLOW.toString() + Math.round(dist) + "m"); + renderNametag(lines); GlStateManager.popMatrix(); @@ -389,6 +419,10 @@ public static void renderWayPoint(String str, Vector3f loc, float partialTicks) } public static void renderNametag(String str) { + renderNametag(Arrays.asList(str)); + } + + public static void renderNametag(List lines) { FontRenderer fontrenderer = Minecraft.getMinecraft().fontRendererObj; float f = 1.6F; float f1 = 0.016666668F * f; @@ -406,20 +440,23 @@ public static void renderNametag(String str) { WorldRenderer worldrenderer = tessellator.getWorldRenderer(); int i = 0; - int j = fontrenderer.getStringWidth(str) / 2; - GlStateManager.disableTexture2D(); - worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR); - worldrenderer.pos(-j - 1, -1 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - worldrenderer.pos(-j - 1, 8 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - worldrenderer.pos(j + 1, 8 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - worldrenderer.pos(j + 1, -1 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); - tessellator.draw(); - GlStateManager.enableTexture2D(); - fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, 553648127); - GlStateManager.depthMask(true); - - fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, -1); - + for (String str : lines) { + int j = fontrenderer.getStringWidth(str) / 2; + + GlStateManager.disableTexture2D(); + worldrenderer.begin(7, DefaultVertexFormats.POSITION_COLOR); + worldrenderer.pos(-j - 1, -1 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + worldrenderer.pos(-j - 1, 8 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + worldrenderer.pos(j + 1, 8 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + worldrenderer.pos(j + 1, -1 + i, 0.0D).color(0.0F, 0.0F, 0.0F, 0.25F).endVertex(); + tessellator.draw(); + GlStateManager.enableTexture2D(); + fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, 553648127); + GlStateManager.depthMask(true); + + fontrenderer.drawString(str, -fontrenderer.getStringWidth(str) / 2, i, -1); + GlStateManager.translate(0, 10f, 0); + } GlStateManager.enableDepth(); GlStateManager.enableBlend(); GlStateManager.color(1.0F, 1.0F, 1.0F, 1.0F); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/TextRenderUtils.java b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/TextRenderUtils.java index ff7ac53ac7..cee38ceae2 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/TextRenderUtils.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/core/util/render/TextRenderUtils.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.core.util.render; import io.github.moulberry.notenoughupdates.core.util.StringUtils; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java index 3f7476bd57..7a609a2ad9 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeManager.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.cosmetics; import com.google.common.collect.BiMap; @@ -67,6 +86,7 @@ public CapeData(String capeName, boolean special, boolean hidden) { new CapeData("lava", false, false), new CapeData("tunnel", false, false), new CapeData("planets", false, false), + new CapeData("screensaver", false, false), //Admins new CapeData("nullzee", true, false), @@ -125,46 +145,53 @@ public void tick() { } private void updateCapes() { - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync("activecapes.json", (jsonObject) -> { - if (jsonObject.get("success").getAsBoolean()) { - lastJsonSync = jsonObject; - - lastCapeSynced = System.currentTimeMillis(); - capeMap.clear(); - for (JsonElement active : jsonObject.get("active").getAsJsonArray()) { - if (active.isJsonObject()) { - JsonObject activeObj = (JsonObject) active; - setCape(activeObj.get("_id").getAsString(), activeObj.get("capeType").getAsString(), false); + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newMoulberryRequest("activecapes.json") + .requestJson() + .thenAccept(jsonObject -> { + if (jsonObject.get("success").getAsBoolean()) { + lastJsonSync = jsonObject; + + lastCapeSynced = System.currentTimeMillis(); + capeMap.clear(); + for (JsonElement active : jsonObject.get("active").getAsJsonArray()) { + if (active.isJsonObject()) { + JsonObject activeObj = (JsonObject) active; + setCape(activeObj.get("_id").getAsString(), activeObj.get("capeType").getAsString(), false); + } } } - } - }, () -> System.out.println("[MBAPI] Update capes errored")); + }); if (Minecraft.getMinecraft().thePlayer != null && permSyncTries > 0) { String uuid = Minecraft.getMinecraft().thePlayer.getUniqueID().toString().replace("-", ""); permSyncTries--; - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync("permscapes.json", (jsonObject) -> { - if (!jsonObject.get("success").getAsBoolean()) return; - - permSyncTries = 0; - availableCapes.clear(); - for (JsonElement permPlayer : jsonObject.get("perms").getAsJsonArray()) { - if (!permPlayer.isJsonObject()) continue; - String playerUuid = permPlayer.getAsJsonObject().get("_id").getAsString(); - if (!(playerUuid != null && playerUuid.equals(uuid))) continue; - for (JsonElement perm : permPlayer.getAsJsonObject().get("perms").getAsJsonArray()) { - if (!perm.isJsonPrimitive()) continue; - String cape = perm.getAsString(); - if (cape.equals("*")) { - allAvailable = true; - } else { - availableCapes.add(cape); - } + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newMoulberryRequest("permscapes.json") + .requestJson() + .thenAccept(jsonObject -> { + if (!jsonObject.get("success").getAsBoolean()) return; + + permSyncTries = 0; + availableCapes.clear(); + for (JsonElement permPlayer : jsonObject.get("perms").getAsJsonArray()) { + if (!permPlayer.isJsonObject()) continue; + String playerUuid = permPlayer.getAsJsonObject().get("_id").getAsString(); + if (!(playerUuid != null && playerUuid.equals(uuid))) continue; + for (JsonElement perm : permPlayer.getAsJsonObject().get("perms").getAsJsonArray()) { + if (!perm.isJsonPrimitive()) continue; + String cape = perm.getAsString(); + if (cape.equals("*")) { + allAvailable = true; + } else { + availableCapes.add(cape); + } + } + return; } - return; - } - }, () -> System.out.println("[MBAPI] Update capes errored - perms")); + + }); } } diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java index c32cc98f69..9bf0313b6d 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/CapeNode.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.cosmetics; import net.minecraft.client.renderer.Tessellator; @@ -391,4 +410,4 @@ public void renderEdge(CapeNode other, boolean lr) { .normal(otherSideNorm.x, otherSideNorm.y, otherSideNorm.z).endVertex(); tessellator.draw(); } -} \ No newline at end of file +} diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java index 1b33decff6..12d8c92dfd 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/GuiCosmetics.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.cosmetics; import com.google.gson.Gson; @@ -385,21 +404,14 @@ protected void mouseClicked(int mouseX, int mouseY, int mouseButton) { .getSession() .getProfile(), accessToken, serverId); - if (wantToEquipCape == null) { - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync( - "cgi-bin/changecape.py?capeType=null&serverId=" + - serverId + "&username=" + userName, - System.out::println, - () -> System.out.println("Change cape error") - ); - } else { - NotEnoughUpdates.INSTANCE.manager.hypixelApi.getMyApiAsync( - "cgi-bin/changecape.py?capeType=" + wantToEquipCape + "&serverId=" + - serverId + "&username=" + userName, - System.out::println, - () -> System.out.println("Change cape error") - ); - } + String toEquipName = wantToEquipCape == null ? "null" : wantToEquipCape; + NotEnoughUpdates.INSTANCE.manager.apiUtils + .newMoulberryRequest("cgi-bin/changecape.py") + .queryArgument("capeType", toEquipName) + .queryArgument("serverId", serverId) + .queryArgument("username", userName) + .requestString() + .thenAccept(System.out::println); } catch (Exception e) { System.out.println("Exception while generating mojang shared secret"); e.printStackTrace(); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java index da9d1f682a..d32abf64a8 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/NEUCape.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.cosmetics; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -18,13 +37,22 @@ import net.minecraftforge.fml.common.gameevent.TickEvent; import org.lwjgl.BufferUtils; import org.lwjgl.input.Keyboard; -import org.lwjgl.opengl.*; +import org.lwjgl.opengl.GL11; +import org.lwjgl.opengl.GL15; +import org.lwjgl.opengl.GL20; +import org.lwjgl.opengl.GL30; +import org.lwjgl.opengl.GL42; +import org.lwjgl.opengl.GL43; import org.lwjgl.util.vector.Vector2f; import org.lwjgl.util.vector.Vector3f; import java.nio.ByteBuffer; import java.nio.FloatBuffer; -import java.util.*; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Random; +import java.util.TreeMap; public class NEUCape { private int currentFrame = 0; @@ -43,6 +71,10 @@ public class NEUCape { private final Random random = new Random(); private long eventMillis; + private float dvdPositionX = 100; + private float dvdPositionY = 100; + private float dvdVelocityX = -10; + private float dvdVelocityY = 10; private float eventLength; private float eventRandom; @@ -101,6 +133,8 @@ public void setCapeTexture(String capeName) { shaderName = "tunnel"; } else if (capeName.equalsIgnoreCase("planets")) { shaderName = "planets"; + } else if (capeName.equalsIgnoreCase("screensaver")) { + shaderName = "screensaver"; } else { shaderName = "shiny_cape"; } @@ -322,6 +356,9 @@ private void loadShaderUniforms(ShaderManager shaderManager) { Minecraft.getMinecraft().displayWidth, Minecraft.getMinecraft().displayHeight )); + } else if (shaderName.equalsIgnoreCase("screensaver")) { + shaderManager.loadData(shaderId, "something", (int) ((System.currentTimeMillis() / 4) % 256)); + shaderManager.loadData(shaderId, "dvdPosition", new Vector2f(dvdPositionX, dvdPositionY)); } } @@ -530,6 +567,19 @@ private void updateFixedCapeNodesPartial(EntityPlayer player, float partialRende private int crouchTicks = 0; long startTime = 0; + public float deltaYComparedToLine(float x0, float y0, float x1, float y1) { + float m = (y1 - y0) / (x1 - x0); + float b = y0 - m * x0; + float lineAtX = dvdPositionX * m + b; + return dvdPositionY - lineAtX; + } + + public float projectOntoLine(float x0, float y0, float x1, float y1, float x) { + float m = (y1 - y0) / (x1 - x0); + float b = y0 - m * x0; + return x * m + b; + } + private void updateCape(EntityPlayer player) { Vector3f capeTranslation = updateFixedCapeNodes(player); @@ -546,6 +596,30 @@ private void updateCape(EntityPlayer player) { eventMillis = currentTime; eventLength = random.nextFloat() * 3000 + 3000; } + } else if (shaderName.equals("screensaver")) { + dvdPositionX += dvdVelocityX; + dvdPositionY += dvdVelocityY; + float diskSizeX = 162 / 2F, diskSizeY = 78 / 2F; + // Left line + if (deltaYComparedToLine(0, 404, 47, 0) < 0) { + dvdVelocityX = 10; + dvdPositionX = projectOntoLine(404, 0, 0, 47, dvdPositionY); + } + // Bottom line + if (deltaYComparedToLine(0, 404 - diskSizeY, 292, 404 - diskSizeY) > 0) { + dvdVelocityY = -10; + dvdPositionY = 404 - diskSizeY; + } + // Top line + if (deltaYComparedToLine(47, 0, 246, 0) < 0) { + dvdVelocityY = 10; + dvdPositionY = 0; + } + // Right line + if (deltaYComparedToLine(246 - diskSizeX, 0, 293 - diskSizeX, 404) < 0) { + dvdVelocityX = -10; + dvdPositionX = projectOntoLine(0, 246 - diskSizeX, 404, 293 - diskSizeX, dvdPositionY); + } } double playerAngle = getPlayerRenderAngle(player, 0); diff --git a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/ShaderManager.java b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/ShaderManager.java index 4e934e10b6..45db303b27 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/ShaderManager.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/cosmetics/ShaderManager.java @@ -1,6 +1,27 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.cosmetics; import net.minecraft.client.Minecraft; +import net.minecraft.client.resources.IResourceManager; +import net.minecraft.client.resources.IResourceManagerReloadListener; import net.minecraft.util.ResourceLocation; import org.lwjgl.opengl.GL20; import org.lwjgl.opengl.GL43; @@ -14,7 +35,7 @@ import java.io.InputStreamReader; import java.util.HashMap; -public class ShaderManager { +public class ShaderManager implements IResourceManagerReloadListener { private final ResourceLocation shaderLocation = new ResourceLocation("notenoughupdates:shaders"); private final HashMap shaderMap = new HashMap<>(); @@ -24,6 +45,14 @@ public static ShaderManager getInstance() { return INSTANCE; } + @Override + public void onResourceManagerReload(IResourceManager iResourceManager) { + shaderMap.values().forEach(it -> { + GL20.glDeleteProgram(it.program); + }); + shaderMap.clear(); + } + public static class Shader { public final int program; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonBlocks.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonBlocks.java index 0e7c59c724..7a2eb2b098 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonBlocks.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonBlocks.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.dungeons; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java index 592f5b19ab..a4c5a60a68 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonMap.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.dungeons; import com.google.common.collect.Iterables; @@ -660,17 +679,6 @@ public void render(int centerX, int centerY) { float deltaX = entityPos.getRenderX() - pos.getRenderX(); float deltaY = entityPos.getRenderY() - pos.getRenderY(); - /*if(deltaX > (renderRoomSize + renderConnSize)/2) { - deltaX -= (renderRoomSize + renderConnSize); - } else if(deltaX < -(renderRoomSize + renderConnSize)/2) { - deltaX += (renderRoomSize + renderConnSize); - } - if(deltaY > (renderRoomSize + renderConnSize)/2) { - deltaY -= (renderRoomSize + renderConnSize); - } else if(deltaY < -(renderRoomSize + renderConnSize)/2) { - deltaY += (renderRoomSize + renderConnSize); - }*/ - x += deltaX; y += deltaY; @@ -718,7 +726,7 @@ public void render(int centerX, int centerY) { } GlStateManager.color(1, 1, 1, 1); if ((!NotEnoughUpdates.INSTANCE.config.dungeons.showOwnHeadAsMarker || - playerMarkerMapPositions.size() <= 1 || minU != 1 / 4f) && + playerMarkerMapPositions.size() < 1 || minU != 1 / 4f) && NotEnoughUpdates.INSTANCE.config.dungeonMap.dmPlayerHeads >= 1 && playerSkinMap.containsKey(entry.getKey())) { Minecraft.getMinecraft().getTextureManager().bindTexture(playerSkinMap.get(entry.getKey())); @@ -1153,7 +1161,7 @@ public void renderMap( String line = ScorePlayerTeam.formatPlayerName(scoreplayerteam1, score.getPlayerName()); line = Utils.cleanColour(line); - if (line.contains("(F1)") || line.contains("(E0)") || line.contains("(M1)")) { + if (line.contains("(F1)") || line.contains("(E)") || line.contains("(M1)")) { isFloorOne = true; break; } @@ -1278,15 +1286,15 @@ public void renderMap( if (entity instanceof EntityPlayer) { EntityPlayer player = (EntityPlayer) entity; - float roomX = (float) player.posX / (roomSizeBlocks + 1); - float roomY = (float) player.posZ / (roomSizeBlocks + 1); + float roomX = (float) (player.posX + 200) / (roomSizeBlocks + 1); + float roomY = (float) (player.posZ + 200) / (roomSizeBlocks + 1); float playerRoomOffsetX = (float) Math.floor(roomX); float playerConnOffsetX = (float) Math.floor(roomX); float playerRoomOffsetY = (float) Math.floor(roomY); float playerConnOffsetY = (float) Math.floor(roomY); - float roomXInBlocks = (float) player.posX % (roomSizeBlocks + 1); + float roomXInBlocks = (float) (player.posX + 200) % (roomSizeBlocks + 1); if (roomXInBlocks < 2) { //0,1 playerConnOffsetX -= 2 / 5f - roomXInBlocks / 5f; } else if (roomXInBlocks > roomSizeBlocks - 2) { //31,30,29 @@ -1296,7 +1304,7 @@ public void renderMap( playerRoomOffsetX += (roomXInBlocks - 2) / (roomSizeBlocks - 4); } - float roomYInBlocks = (float) player.posZ % (roomSizeBlocks + 1); + float roomYInBlocks = (float) (player.posZ + 200) % (roomSizeBlocks + 1); if (roomYInBlocks < 2) { //0,1 playerConnOffsetY -= 2 / 5f - roomYInBlocks / 5f; } else if (roomYInBlocks > roomSizeBlocks - 2) { //31,30,29 @@ -1606,7 +1614,6 @@ public void onRenderOverlay(RenderGameOverlayEvent.Post event) { if(player.getUniqueID().toString().charAt(14) == '4') { actualPlayers.add(player.getName()); System.out.println(player.getName()); - } }*/ int players = 0; diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java index 976dfcf87c..a56a567992 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/DungeonWin.java @@ -1,3 +1,22 @@ +/* + * Copyright (C) 2022 NotEnoughUpdates contributors + * + * This file is part of NotEnoughUpdates. + * + * NotEnoughUpdates is free software: you can redistribute it + * and/or modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation, either + * version 3 of the License, or (at your option) any later version. + * + * NotEnoughUpdates 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 + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with NotEnoughUpdates. If not, see . + */ + package io.github.moulberry.notenoughupdates.dungeons; import io.github.moulberry.notenoughupdates.NotEnoughUpdates; @@ -14,7 +33,12 @@ import org.lwjgl.opengl.GL11; import org.lwjgl.opengl.GL14; -import java.util.*; +import java.util.ArrayList; +import java.util.ConcurrentModificationException; +import java.util.HashSet; +import java.util.List; +import java.util.Random; +import java.util.Set; import java.util.concurrent.Executors; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.TimeUnit; @@ -200,7 +224,17 @@ public static void onChatMessage(ClientChatReceivedEvent e) { displayWin(); } else { if (unformatted.trim().length() > 0) { - text.add(e.message.getFormattedText().substring(6).trim()); + if (unformatted.contains("The Catacombs") || unformatted.contains("Master Mode Catacombs") || + unformatted.contains("Team Score") || unformatted.contains("Defeated") || unformatted.contains( + "Total Damage") + || unformatted.contains("Ally Healing") || unformatted.contains("Enemies Killed") || unformatted.contains( + "Deaths") || unformatted.contains("Secrets Found")) { + text.add(e.message.getFormattedText().substring(6).trim()); + } else { + System.out.println( + "These messages would of showed on neu dungeon overlay but didnt, They are either bugged or i missed them: \"" + + e.message.getFormattedText().substring(6).trim() + "\""); + } } } } else { diff --git a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java index 41fa366311..8ce9d5056b 100644 --- a/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java +++ b/src/main/java/io/github/moulberry/notenoughupdates/dungeons/GuiDungeonMapEditor.java @@ -1,847 +1,872 @@ -package io.github.moulberry.notenoughupdates.dungeons; - -import io.github.moulberry.notenoughupdates.NotEnoughUpdates; -import io.github.moulberry.notenoughupdates.core.GuiElementColour; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigEditorSlider; -import io.github.moulberry.notenoughupdates.core.config.annotations.ConfigOption; -import io.github.moulberry.notenoughupdates.core.config.gui.GuiPositionEditor; -import io.github.moulberry.notenoughupdates.core.util.render.RenderUtils; -import io.github.moulberry.notenoughupdates.core.util.render.TextRenderUtils; -import io.github.moulberry.notenoughupdates.itemeditor.GuiElementTextField; -import io.github.moulberry.notenoughupdates.options.seperateSections.DungeonMapConfig; -import io.github.moulberry.notenoughupdates.util.SpecialColour; -import io.github.moulberry.notenoughupdates.util.Utils; -import net.minecraft.client.Minecraft; -import net.minecraft.client.gui.GuiScreen; -import net.minecraft.client.gui.ScaledResolution; -import net.minecraft.client.renderer.GlStateManager; -import net.minecraft.client.renderer.OpenGlHelper; -import net.minecraft.client.shader.Framebuffer; -import net.minecraft.client.shader.Shader; -import net.minecraft.util.EnumChatFormatting; -import net.minecraft.util.Matrix4f; -import net.minecraft.util.ResourceLocation; -import net.minecraft.util.Vec4b; -import org.lwjgl.input.Keyboard; -import org.lwjgl.input.Mouse; -import org.lwjgl.opengl.GL11; - -import java.awt.*; -import java.io.IOException; -import java.lang.reflect.Field; -import java.util.List; -import java.util.*; - -import static io.github.moulberry.notenoughupdates.util.GuiTextures.*; - -public class GuiDungeonMapEditor extends GuiScreen { - public static final ResourceLocation BACKGROUND = new ResourceLocation( - "notenoughupdates:dungeon_map/editor/background.png"); - public static final ResourceLocation BUTTON = new ResourceLocation("notenoughupdates:dungeon_map/editor/button.png"); - private static final DungeonMap demoMap = new DungeonMap(); - - private int sizeX; - private int sizeY; - private int guiLeft; - private int guiTop; - - private final List