Compare commits

..

126 Commits

Author SHA1 Message Date
Leijurv
4bea9dfb42 started on simultaneous dijkstra scaffolder, saving progress here for now 2023-04-10 00:14:13 -07:00
Leijurv
f039a9cff8 belongs at bottom 2023-04-07 22:12:57 -07:00
Leijurv
06d18c4500 shouldnt have been separated 2023-04-07 20:45:08 -07:00
Leijurv
cc6228dced better test 2023-04-07 20:44:04 -07:00
Leijurv
0ed1c31106 more test 2023-04-07 20:37:32 -07:00
Leijurv
8c118401f3 blip staircases work 2023-04-07 17:47:29 -07:00
Leijurv
3e17352e99 navigablesurface now relies on full playerphysics and somehow it's FASTER??? 2023-04-06 23:43:41 -07:00
Leijurv
d594b15e40 abstract away the specific attachment from the impl of a player physics tracking navigable surface 2023-04-06 22:08:54 -07:00
Leijurv
c48d47ff2c no longer required 2023-04-06 21:25:53 -07:00
Leijurv
361c769650 more testing 2023-04-05 23:32:40 -07:00
Leijurv
294e847f19 refactors 2023-04-05 00:22:15 -07:00
Leijurv
c9bfcb417e compare with/without random splays before/during connection tests 2023-04-04 01:44:43 -07:00
Leijurv
1fc3155e9c more explanation 2023-04-02 23:19:38 -07:00
Leijurv
a9d6aaebf3 misc 2023-04-02 15:12:07 -07:00
Leijurv
b2ffa7de1b improved playerphysicstest actually caught a real bug 2023-03-27 23:17:12 +09:00
Leijurv
5ad90997ff player physics with bidirectional movement with tests, intended for use in navigable surface (because euler tour forests require an undirected graph) 2023-03-27 09:14:30 +09:00
Leijurv
b3afa98958 got a little carried away testing navigable surface 2023-03-23 21:43:37 -07:00
Leijurv
d2a5199383 unzobrist test just to make sure 2023-03-23 21:19:49 -07:00
Leijurv
d32973cae4 equals and hashcode for navigable surface tree attachment 2023-03-21 00:42:09 -07:00
Leijurv
f5dc6a034b refactor conngraphtest since i wrote part of it 2023-03-21 00:37:51 -07:00
Leijurv
06590f487b refactor and integrate redblacknode repo 2023-03-21 00:36:43 -07:00
Leijurv
3549a55f1e Merge remote-tracking branch 'rbn/trimmed' into builder-2 2023-03-21 00:26:43 -07:00
Leijurv
b8608c98e7 deleting these files to make way for merge of unrelated git history 2023-03-21 00:26:11 -07:00
Leijurv
e15cf933aa don't need tree list 2023-03-21 00:25:23 -07:00
Leijurv
8812f3027b trimmed for merge 2023-03-21 00:22:45 -07:00
Leijurv
69b36eea4b only run once 2023-03-21 00:11:27 -07:00
Leijurv
af320bd052 refactor and integrate 2023-03-21 00:11:04 -07:00
Leijurv
317f07283e integrate betterblockpos 2023-03-21 00:00:53 -07:00
Leijurv
bce0d47f95 tweak for older version of fastutil 2023-03-20 23:58:25 -07:00
Leijurv
b8d4c72a92 Merge remote-tracking branch 'dyncon/trimmed' into builder-2 2023-03-20 23:55:09 -07:00
Leijurv
0f5ee85e19 trim for merge 2023-03-20 23:54:02 -07:00
Leijurv
e7f54ab81d switch from integer to custom tree attachment 2023-03-20 23:51:19 -07:00
Leijurv
6fea22dc9f this is incredibly cool and it does figure out the staircase pattern like i hoped 2023-03-16 00:42:23 -07:00
Leijurv
2cb46e0540 explanatory readme 2023-03-16 00:18:38 -07:00
Leijurv
79113cf9a0 Merge branch 'long-map' into baritone-testing 2023-03-15 22:41:46 -07:00
Leijurv
fe808a5f83 test 2023-03-15 22:41:42 -07:00
Leijurv
200e68a1b9 import from baritone builder-2 2023-03-15 22:35:40 -07:00
Leijurv
59be6b4606 dead link 2023-03-15 14:56:13 -07:00
Leijurv
236d171d15 just in case anyone is curious, check in my partial impl from last year of euler tour forests over splay nodes (it was too intimidating to fully reimpl on top of a red-black or avl tree) 2023-03-15 14:54:13 -07:00
Leijurv
7ee6b40815 and i guess this should also use long instead of connvertex 2023-03-15 14:12:14 -07:00
Leijurv
49b620a7cf just checking if a long map could be faster, doesnt seem to matter (yet?) 2023-03-15 13:59:57 -07:00
Leijurv
52f795c3ae ram usage of empty hashmap buckets doesn't affect my use case 2023-03-15 13:43:39 -07:00
Leijurv
c177d6c708 need more heap 2023-03-15 13:39:27 -07:00
Leijurv
9870cbddc3 supposedly need to bump junit 2023-03-15 13:33:22 -07:00
Leijurv
8ee36bcd46 reformat all code 2023-03-15 13:30:23 -07:00
Leijurv
2af6dec3df switch from maven to gradle 2023-03-15 13:26:44 -07:00
Leijurv
802c81d766 bring in red black node 2023-03-15 13:23:39 -07:00
Leijurv
3a8c6712b1 satisfied with benchmark 2023-03-15 13:16:14 -07:00
Leijurv
f378578ada misc intellij 2023-03-15 13:16:08 -07:00
Leijurv
92447c0b5c dijkstra tweaks 2023-03-14 18:13:21 -07:00
Leijurv
023bebee66 more tests and sanity checks around collapsing components 2023-03-08 16:17:18 -08:00
Leijurv
cadf7a06d0 refactor per state with scaffolding into place order dependency graph 2023-03-08 13:49:20 -08:00
Leijurv
19c9238ea2 comments and thoughts about component merge order 2023-03-08 00:59:00 -08:00
Leijurv
19eda1bfe5 scaffolder output 2023-03-07 00:52:39 -08:00
Leijurv
1ffadf0242 refactor out scaffolder strategy 2023-03-07 00:37:53 -08:00
Leijurv
5d0904b46e refactor dependencygraphscaffoldingoverlay to be only mutable inside scaffolder (this was bugging me) 2023-03-04 22:00:18 -08:00
William Jacobs
3eda7a57e8 Added assessment of ancestor pointers to optimization_ideas.txt
This adds my assessment of the performance of the ancestor pointers optimization in practice to optimization_ideas.txt.
2022-08-02 19:27:45 -04:00
William Jacobs
2031ed4bc3 Added ancestor pointers to optimization_ideas.txt
This adds the idea of using ancestor pointers to optimization_ideas.txt.
2022-07-19 12:12:57 -04:00
Leijurv
a448d97ec9 dont remember, misc changes 2021-11-01 17:41:29 -07:00
Leijurv
1a59427957 refactor out sneak position 2021-09-03 13:47:00 -07:00
Leijurv
217f6ecf28 refactor out zobrist world state cache 2021-09-03 13:29:29 -07:00
Leijurv
0fd91edb97 column system, sneaking nodes, connected up raytrace system, misc refactors 2021-09-01 16:22:59 -07:00
Leijurv
35c2d8ba24 refactors and begin on sneak nodes 2021-08-31 17:40:01 -07:00
Leijurv
b26d10e26e jump physics 2021-08-27 23:56:46 -07:00
Leijurv
9da3e09062 snow sucks 2021-08-27 19:01:31 -07:00
Leijurv
9fce9ef5e3 precompute scaffolding variants to remove branch in dependency graph lookup 2021-08-27 16:13:29 -07:00
Leijurv
e5773da108 that's what the mask is 2021-08-24 22:21:41 -07:00
Leijurv
554c0de188 misc progress hooking everything up into solver engine harness 2021-08-24 20:26:38 -07:00
Leijurv
bea31fe77d Merge branch 'master' into builder-2 2021-08-24 15:16:30 -07:00
Leijurv
bcd22dc91c debug 2021-08-24 10:51:38 -07:00
Leijurv
33082428f3 some progress and reworking of greedy solver 2021-08-24 00:17:55 -07:00
Leijurv
0b4e5f753a tweaked physics and begun core pathfinder loop 2021-08-20 16:27:36 -07:00
Leijurv
5aa0dfc98c started on greedy solver, using concept from the zobrist testing 2021-08-19 00:16:52 -07:00
Leijurv
164d0e07cd bounds refactor and start on solver engine interface 2021-08-18 21:50:41 -07:00
Leijurv
b608a8a1e0 misc 2021-08-17 16:04:23 -07:00
Leijurv
02f5d4efbe misc bounds benchmark, property extractor, scaffolder 2021-05-24 17:16:25 -07:00
Leijurv
a9b7b91a3c misc tweaks, forgot to commit last week 2021-05-24 12:52:34 -07:00
Leijurv
d501359857 progress on properties and entity oriented blocks 2021-05-18 00:16:30 -07:00
Leijurv
d9591e089d basic impl of place options 2021-05-17 02:12:51 -07:00
Leijurv
4848e901c9 progress on reachability cache and raytracer tweaks 2021-05-17 01:53:16 -07:00
Leijurv
65a650c1a6 readme 2021-05-15 22:30:51 -07:00
Leijurv
ca2e7c958a remove zoomy branchy 2021-05-15 21:41:47 -07:00
Leijurv
c97b089c61 rework placeagainstdata 2021-05-13 00:37:40 -07:00
Leijurv
5170b34962 blip 2021-05-12 01:10:25 -07:00
Leijurv
0a8b6e9427 many more blocks, physics attempt 2021-05-11 23:27:52 -07:00
Leijurv
efb0afcd6c switch to builder pattern for block state cached data 2021-05-10 02:18:59 -07:00
Leijurv
5c85d0cfd1 fixed up raytracer and placement option 2021-05-10 00:23:10 -07:00
Leijurv
fdf899eabf progress on raytracer 2021-04-21 11:42:56 -07:00
Leijurv
e62f480836 started on scaffolding 2021-04-16 20:43:24 -07:00
Leijurv
6ef6651ed6 more optim 2021-04-13 19:08:44 -07:00
Leijurv
21aaab1b9e optims 2021-04-13 18:03:33 -07:00
Leijurv
8450675401 saving progress here, incremental scaffolding works and is fast 2021-04-13 16:08:30 -07:00
Leijurv
96fd72e5b0 testing 2021-04-03 15:49:30 -07:00
btrekkie
5cfefbb9ec Merge pull request #2 from btrekkie/dependabot/maven/junit-junit-4.13.1
Bump junit from 4.12 to 4.13.1
2020-10-15 19:20:39 -04:00
btrekkie
1c8ccd4646 Merge pull request #1 from btrekkie/dependabot/maven/junit-junit-4.13.1
Bump junit from 4.12 to 4.13.1
2020-10-15 19:17:39 -04:00
dependabot[bot]
6f69316966 Bump junit from 4.12 to 4.13.1
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 12:15:30 +00:00
dependabot[bot]
5e77ef97e4 Bump junit from 4.12 to 4.13.1
Bumps [junit](https://github.com/junit-team/junit4) from 4.12 to 4.13.1.
- [Release notes](https://github.com/junit-team/junit4/releases)
- [Changelog](https://github.com/junit-team/junit4/blob/main/doc/ReleaseNotes4.12.md)
- [Commits](https://github.com/junit-team/junit4/compare/r4.12...r4.13.1)

Signed-off-by: dependabot[bot] <support@github.com>
2020-10-13 12:15:26 +00:00
William Jacobs
0fed0d4371 Removed outdated pointer to documentation
This removes the suggestion to check the source code for the documentation from README.md. Now that there is a website with the documentation, there is no need to look through the source code.
2020-06-26 10:51:11 -04:00
William Jacobs
1069dc9700 Increased minimum Java version and updated documentation
This increases the minimum Java version to 7.0, because Maven doesn't like Java 6.0, and it makes assorted improvements to the documentation.
2020-05-30 10:36:45 -04:00
William Jacobs
515a28dcfd Added reference to documentation webpage
This changes README.md to refer to the webpage containing the documentation for the project.
2020-05-30 10:33:13 -04:00
William Jacobs
426838f33e Added optimization_ideas.txt
This adds optimization_ideas.txt, a text file containing my thoughts on how to make ConnGraph faster.
2019-03-23 20:06:47 -04:00
William Jacobs
458cdd3ddd Fixed size calculation in optimizeForestEdges()
This fixes the code in ConnGraph.optimizeForestEdges() that computes the resulting size after combining two Euler tour trees into one. Technically, the old behavior was still correct, but only by accident; this change is still kind of a bug fix.
2019-03-18 13:21:26 -04:00
William Jacobs
05d678a189 Split removeEdge and optimize() into smaller methods
This moves a bit of functionality from ConnGraph.removeEdge and ConnGraph.optimize() into new methods, in order to improve readability.
2019-03-16 14:42:36 -04:00
William Jacobs
454a2b8ae7 Minor readability improvements
This makes various minor improvements to readability and implementation.
2019-03-16 14:17:40 -04:00
William Jacobs
1536209eb3 Optimization: don't push forest edges if there are no non-forest edges
This optimizes the process of searching for a replacement edge to refrain from pushing forest edges down when a tree does not have any same-level non-forest edges. If a tree doesn't have any such edges, then there definitely isn't a replacement edge at that level, so we can avoid doing extra work.

Interestingly, with this optimization, ConnGraph reduces to a single Euler tour forest if the graph is a forest, with addEdge and removeEdge taking O(log N) (non-amortized) time with high probability.
2019-03-06 22:24:50 -05:00
William Jacobs
a60eac5b6c Initial commit
This adds the initial contents of the repository.
2019-03-06 16:46:45 -05:00
btrekkie
7d95d5f991 Initial commit 2019-03-06 16:36:08 -05:00
William Jacobs
8cf1eb9230 Converted to Maven project
This changes RedBlackNode into a Maven project, by adding pom.xml and changing the directory structure. This should make it easier for other projects to include RedBlackNode as a dependency.
2019-03-06 15:20:01 -05:00
William Jacobs
148e9247d3 Clarified main documentation
This changes README.md and the comment for RedBlackNode to more clearly explain what the project is all about. It emphasizes the fact that RedBlackNode provides public access to the tree's structure. It changes the usage example in README.md from a short RedBlackNode subclass highlighting how easy augmentation is to a medium-length pair of tree and node classes that show how to use insertion, removal, and augmentation.

This change also makes minor improvements to comments for RedBlackNode methods.
2019-03-04 17:01:46 -05:00
Bill Jacobs
6d6b968fd6 Simplified if statements
This simplifies this:

if (a) {
    c;
}
if (b) {
    c;
}

to this:

if (a || b) {
    c;
}
2017-05-13 18:19:03 -05:00
Bill Jacobs
3c75a5e39e Moved TreeList.addAll test to TreeListTest.testAddAll
This moves some code that tests TreeList.addAll from TreeListTest.testAdd to TreeListTest.testAddAll
2016-07-22 17:13:19 -07:00
Bill Jacobs
9534c4ae06 Fixed RedBlackNode.concatenate on two one-node trees
This fixes RedBlackNode.concatenate to work on two one-node trees.  The check for determining which tree had the greater red-black height was incorrect in that case.
2016-07-22 17:03:36 -07:00
Bill Jacobs
5e23bd9c81 Changed SubArrayMinTest to use Integer.bitCount
This changes SubArrayMinTest to use the library method Integer.bitCount rather than a hand-rolled bit counting implementation.
2016-06-24 14:46:37 -07:00
Bill Jacobs
91b5ae633a Fixed SubArrayMin to check children
This fixes SubArrayMin to check the appropriate children of the endpoint nodes, in addition to the children of their ancestors.
2016-06-17 21:54:19 -07:00
Bill Jacobs
8c98d5cc42 Changed createTree to set root's parent to null
This changes createTree to set the "parent" field of the root node to null.
2016-06-06 14:55:58 -07:00
Bill Jacobs
cd4424b94a Fixed calls to augment() in fixSiblingDeletion()
This fixes fixSiblingDeletion() to call augment() in certain cases where augment() returns false.
2016-06-02 20:40:35 -07:00
Bill Jacobs
deb397ed1e Changed fixInsertion to always augment parent
This changes fixInsertion to always augment the node's parent, even if the initial call to augment() returns false, assuming "augment" is true.  When we insert a node, we are supposed to ignore its initial state; thus, we ignore the return value of augment().
2016-05-31 23:07:52 -07:00
Bill Jacobs
4e1fe67095 Updated RedBlackNode.jar to clear links after removing node
This updates RedBlackNode.jar to include the changes in dd0fd1959c.
2016-05-28 17:35:32 -07:00
Bill Jacobs
dd0fd1959c Clear links after removing node
This changes the remove methods to set the parent and child links to be null, so that we're more likely to encounter an exception if we attempt to access the node.
2016-05-28 10:56:08 -07:00
Bill Jacobs
a1dba8a58c Added test for "lca"
This adds SubArrayMinTest, which tests RedBlackNode.lca.
2016-05-26 14:47:27 -07:00
Bill Jacobs
f355e1ed2b Added LCA
This adds a RedBlackNode method for computing the lowest common ancestor of two nodes.
2016-05-26 12:22:32 -07:00
Bill Jacobs
82c1fbdc7b Made fixInsertion return the new root
This changes RedBlackNode.fixInsertion to return the root of the resulting tree.
2016-05-26 10:37:25 -07:00
Bill Jacobs
f7f14ff852 Added RedBlackNode.jar
This adds RedBlackNode.jar for using RedBlackNode in binary form.
2016-05-23 14:00:40 -07:00
Bill Jacobs
754e11ade7 Escaped "<" and ">"
This escapes the "<" and ">" characters in README.md.
2016-05-23 13:57:28 -07:00
Bill Jacobs
389f8ea4e2 Initial commit
This adds the initial contents of the repository.
2016-05-23 13:51:21 -07:00
btrekkie
d3e6f9ae02 Initial commit 2016-05-23 13:43:59 -07:00
266 changed files with 16875 additions and 8402 deletions

View File

@@ -13,12 +13,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up JDK 8 - name: Set up JDK 8
uses: actions/setup-java@v3 uses: actions/setup-java@v2
with: with:
java-version: '8' java-version: '8'
distribution: 'temurin' distribution: 'adopt'
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew
@@ -27,13 +27,13 @@ jobs:
run: ./gradlew build run: ./gradlew build
- name: Archive Artifacts - name: Archive Artifacts
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v2
with: with:
name: Artifacts name: Artifacts
path: dist/ path: dist/
- name: Archive mapping.txt - name: Archive mapping.txt
uses: actions/upload-artifact@v3 uses: actions/upload-artifact@v2
with: with:
name: Mappings name: Mappings
path: build/tmp/proguard/mapping.txt path: build/tmp/proguard/mapping.txt

View File

@@ -11,12 +11,12 @@ jobs:
runs-on: ubuntu-latest runs-on: ubuntu-latest
steps: steps:
- uses: actions/checkout@v3 - uses: actions/checkout@v2
- name: Set up JDK 8 - name: Set up JDK 9
uses: actions/setup-java@v3 uses: actions/setup-java@v2
with: with:
java-version: '8' java-version: '8'
distribution: 'temurin' distribution: 'adopt'
- name: Grant execute permission for gradlew - name: Grant execute permission for gradlew
run: chmod +x gradlew run: chmod +x gradlew

5
.gitignore vendored
View File

@@ -27,8 +27,3 @@ baritone_Client.launch
# Copyright Files # Copyright Files
!/.idea/copyright/Baritone.xml !/.idea/copyright/Baritone.xml
!/.idea/copyright/profiles_settings.xml !/.idea/copyright/profiles_settings.xml
.vscode/launch.json
libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar
libs/java-objc-bridge-1.1.jar

View File

@@ -4,23 +4,18 @@
</p> </p>
<p align="center"> <p align="center">
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a> <img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a> <img src="https://img.shields.io/badge/MC-1.13.2-brightgreen.svg" alt="Minecraft"/>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a> <img src="https://img.shields.io/badge/MC-1.14.4-brightgreen.svg" alt="Minecraft"/>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a> <img src="https://img.shields.io/badge/MC-1.15.2-brightgreen.svg" alt="Minecraft"/>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a> <img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.17.1-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.18.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.4-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.20.1-brightgreen.svg" alt="Minecraft"/></a>
</p> </p>
<p align="center"> <p align="center">
<a href="https://travis-ci.com/cabaletta/baritone/"><img src="https://travis-ci.com/cabaletta/baritone.svg?branch=master" alt="Build Status"/></a> <a href="https://travis-ci.com/cabaletta/baritone/"><img src="https://travis-ci.com/cabaletta/baritone.svg?branch=master" alt="Build Status"/></a>
<a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/release/cabaletta/baritone.svg" alt="Release"/></a> <a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/release/cabaletta/baritone.svg" alt="Release"/></a>
<a href="LICENSE"><img src="https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg" alt="License"/></a> <a href="LICENSE"><img src="https://img.shields.io/badge/license-LGPL--3.0%20with%20anime%20exception-green.svg" alt="License"/></a>
<a href="https://www.codacy.com/gh/cabaletta/baritone/dashboard?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade"><img src="https://app.codacy.com/project/badge/Grade/cadab857dab049438b6e28b3cfc5570e" alt="Codacy Badge"/></a> <a href="https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade"><img src="https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400" alt="Codacy Badge"/></a>
<a href="https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat" alt="Code of Conduct"/></a> <a href="https://github.com/cabaletta/baritone/blob/master/CODE_OF_CONDUCT.md"><img src="https://img.shields.io/badge/%E2%9D%A4-code%20of%20conduct-blue.svg?style=flat" alt="Code of Conduct"/></a>
<a href="https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle"><img src="https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle" alt="Known Vulnerabilities"/></a> <a href="https://snyk.io/test/github/cabaletta/baritone?targetFile=build.gradle"><img src="https://snyk.io/test/github/cabaletta/baritone/badge.svg?targetFile=build.gradle" alt="Known Vulnerabilities"/></a>
<a href="https://github.com/cabaletta/baritone/issues/"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="Contributions welcome"/></a> <a href="https://github.com/cabaletta/baritone/issues/"><img src="https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat" alt="Contributions welcome"/></a>
@@ -36,7 +31,7 @@
<p align="center"> <p align="center">
<a href="https://impactclient.net/"><img src="https://img.shields.io/badge/Impact%20integration-v1.2.14%20/%20v1.3.8%20/%20v1.4.6%20/%20v1.5.3%20/%20v1.6.3-brightgreen.svg" alt="Impact integration"/></a> <a href="https://impactclient.net/"><img src="https://img.shields.io/badge/Impact%20integration-v1.2.14%20/%20v1.3.8%20/%20v1.4.6%20/%20v1.5.3%20/%20v1.6.3-brightgreen.svg" alt="Impact integration"/></a>
<a href="https://github.com/lambda-client/lambda"><img src="https://img.shields.io/badge/Lambda%20integration-v1.2.17-brightgreen.svg" alt="Lambda integration"/></a> <a href="https://github.com/kami-blue/client"><img src="https://img.shields.io/badge/KAMI%20Blue%20integration-v1.2.14--master-green" alt="KAMI Blue integration"/></a>
<a href="https://github.com/fr1kin/ForgeHax/"><img src="https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg" alt="ForgeHax integration"/></a> <a href="https://github.com/fr1kin/ForgeHax/"><img src="https://img.shields.io/badge/ForgeHax%20%22integration%22-scuffed-yellow.svg" alt="ForgeHax integration"/></a>
<a href="https://aristois.net/"><img src="https://img.shields.io/badge/Aristois%20add--on%20integration-v1.6.3-green.svg" alt="Aristois add-on integration"/></a> <a href="https://aristois.net/"><img src="https://img.shields.io/badge/Aristois%20add--on%20integration-v1.6.3-green.svg" alt="Aristois add-on integration"/></a>
<a href="https://rootnet.dev/"><img src="https://img.shields.io/badge/rootNET%20integration-v1.2.14-green.svg" alt="rootNET integration"/></a> <a href="https://rootnet.dev/"><img src="https://img.shields.io/badge/rootNET%20integration-v1.2.14-green.svg" alt="rootNET integration"/></a>
@@ -51,29 +46,18 @@
A Minecraft pathfinder bot. A Minecraft pathfinder bot.
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do.
[**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr) [**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr)
**Quick download links:** Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#0730 on Baritone which I recommend. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do. [Tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa)
| Forge | Fabric | The easiest way to install Baritone is to install [Impact](https://impactclient.net/), which comes with Baritone. The second easiest way (for 1.12.2 only) is to install the v1.2.* `api-forge` jar from [releases](https://github.com/cabaletta/baritone/releases). **For 1.12.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.2.15/baritone-api-forge-1.2.15.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
| [1.12.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.2.17/baritone-api-forge-1.2.17.jar) | |
| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-forge-1.6.4.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.4/baritone-api-fabric-1.6.4.jar) |
| [1.17.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-forge-1.7.3.jar) | [1.17.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.7.3/baritone-api-fabric-1.7.3.jar) |
| [1.18.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-forge-1.8.4.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.4/baritone-api-fabric-1.8.4.jar) |
| [1.19.2 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-forge-1.9.4.jar) | [1.19.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.4/baritone-api-fabric-1.9.4.jar) |
| [1.19.3 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-forge-1.9.1.jar) | [1.19.3 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.1/baritone-api-fabric-1.9.1.jar) |
| [1.19.4 Forge](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-forge-1.9.3.jar) | [1.19.4 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.9.3/baritone-api-fabric-1.9.3.jar) |
| [1.20.1 Forge](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-forge-1.10.1.jar) | [1.20.1 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.10.1/baritone-api-fabric-1.10.1.jar) |
**How to immediately get started:** Type `#goto 1000 500` in chat to go to x=1000 z=500. Type `#mine diamond_ore` to mine diamond ore. Type `#stop` to stop. For more, read [the usage page](USAGE.md) and/or watch this [tutorial playlist](https://www.youtube.com/playlist?list=PLnwnJ1qsS7CoQl9Si-RTluuzCo_4Oulpa) For 1.15.2, [click here](https://www.youtube.com/watch?v=j1qKtCZFURM) and see description. If you need Forge 1.15.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.5.3), follow the instructions, and get the `api-forge` jar.
For other versions of Minecraft or more complicated situations or for development, see [Installation & setup](SETUP.md). Also consider just installing [Impact](https://impactclient.net/), which comes with Baritone and is easier to install than wrangling with version JSONs and zips. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it. There's a [showcase video](https://youtu.be/CZkLXWo4Fg4) made by @Adovin#6313 on Baritone which I recommend. For 1.16.5, [click here](https://www.youtube.com/watch?v=_4eVJ9Qz2J8) and see description. If you need Forge or Fabric 1.16.5, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.6.3) and get the `api-forge` or `api-fabric` jar. **For 1.16.5 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.6.3/baritone-api-fabric-1.6.3.jar)**.
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/), This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 onwards. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths). the original version of the bot for Minecraft 1.8.9, rebuilt for 1.12.2 through 1.16.5. Baritone focuses on reliability and particularly performance (it's over [30x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Have committed at least once a day from Aug 1, 2018, to Aug 1, 2019. Have committed at least once a day from Aug 1, 2018, to Aug 1, 2019.
@@ -105,7 +89,7 @@ jar.
Below is an example of basic usage for changing some settings, and then pathing to an X/Z goal. Below is an example of basic usage for changing some settings, and then pathing to an X/Z goal.
```java ```
BaritoneAPI.getSettings().allowSprint.value = true; BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L; BaritoneAPI.getSettings().primaryTimeoutMS.value = 2000L;

View File

@@ -11,7 +11,7 @@ These releases are not always completely up to date with latest features, and ar
Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases) Link to the releases page: [Releases](https://github.com/cabaletta/baritone/releases)
v1.2.* is for 1.12.2, v1.3.* is for 1.13.2, v1.4.* is for 1.14.4, v1.5.* is for 1.15.2, v1.6.* is for 1.16.5, v1.7.* is for 1.17.1, v1.8.* is for 1.18.1 v1.2.* is for 1.12.2, v1.3.* is for 1.13.2, v1.4.* is for 1.14.4, v1.5.* is for 1.15.2, v1.6.* is for 1.16.2 or 1.16.4 or 1.16.5 (LOL)
Any official release will be GPG signed by leijurv (44A3EA646EADAC6A). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by that public keys of `checksums.txt`. Any official release will be GPG signed by leijurv (44A3EA646EADAC6A). Please verify that the hash of the file you download is in `checksums.txt` and that `checksums_signed.asc` is a valid signature by that public keys of `checksums.txt`.
@@ -22,16 +22,15 @@ The build is fully deterministic and reproducible, and you can verify Travis did
Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases). Building Baritone will result in 5 artifacts created in the ``dist`` directory. These are the same as the artifacts created in the [releases](https://github.com/cabaletta/baritone/releases).
**The Forge and Fabric releases can simply be added as a Forge/Fabric mods.** **The Forge release can simply be added as a Forge mod.**
If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar` If another one of your Forge mods has a Baritone integration, you want `baritone-api-forge-VERSION.jar`. Otherwise, you want `baritone-standalone-forge-VERSION.jar`
- **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features. - **API**: Only the non-api packages are obfuscated. This should be used in environments where other mods would like to use Baritone's features.
- **Forge/Fabric API**: Same as API, but packaged for Forge/Fabric. This should be used where another mod has a Baritone integration. - **Forge API**: Same as API, but packaged for Forge. This should be used where another mod has a Baritone integration.
- **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features. - **Standalone**: Everything is obfuscated. This should be used in environments where there are no other mods present that would like to use Baritone's features.
- **Forge/Fabric Standalone**: Same as Standalone, but packaged for Forge/Fabric. This should be used when Baritone is your only Forge/Fabric mod, or none of your other Forge/Fabric mods integrate with Baritone. - **Forge Standalone**: Same as Standalone, but packaged for Forge. This should be used when Baritone is your only Forge mod, or none of your other Forge mods integrate with Baritone.
- **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production. - **Unoptimized**: Nothing is obfuscated. This shouldn't be used ever in production.
- **Forge/Fabric Unoptimized**: Same as Unoptimized, but packaged for Forge/Fabric.
## Build it yourself ## Build it yourself
- Clone or download Baritone - Clone or download Baritone
@@ -43,13 +42,13 @@ If another one of your Forge mods has a Baritone integration, you want `baritone
## Command Line ## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`. On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8 for 1.12.2-1.16.5, JDK 16+ for 1.17.1, and JDK 17+ for 1.18.1. If you have errors with a package missing please make sure you have setup your environment, and are using Oracle JDK 8.
To check which java you are using do To check which java you are using do
`java -version` in a command prompt or terminal. `java -version` in a command prompt or terminal.
If you are using anything above OpenJDK 8 for 1.12.2-1.16.5, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes. If you are using anything above OpenJDK 8, it might not work because the Java distributions above JDK 8 using may not have the needed javax classes.
Download java: https://adoptium.net/ Open JDK 8 download: https://openjdk.java.net/install/
#### macOS guide #### macOS guide
In order to get JDK 8, Try running the following command: In order to get JDK 8, Try running the following command:
`% /usr/libexec/java_home -V` `% /usr/libexec/java_home -V`
@@ -66,13 +65,62 @@ In order to get JDK 8 running in the **current terminal window** you will have t
To add OpenJDK 8 to your PATH add the export line to the end of your `.zshrc / .bashrc` if you want it to apply to each new terminal. If you're using bash change the .bachrc and if you're using zsh change the .zshrc To add OpenJDK 8 to your PATH add the export line to the end of your `.zshrc / .bashrc` if you want it to apply to each new terminal. If you're using bash change the .bachrc and if you're using zsh change the .zshrc
### Building Baritone Setting up the Environment:
These tasks depend on the minecraft version, but are (for the most part) standard for building mods. ```
$ gradlew setupDecompWorkspace
$ gradlew --refresh-dependencies
```
for more details, see [the build ci action](/.github/workflows/gradle_build.yml) Building Baritone:
```
$ gradlew build
```
For minecraft 1.15.2+, run the following instead to include the Forge jars:
```
$ gradlew build -Pbaritone.forge_build
```
Running Baritone:
```
$ gradlew runClient
```
For information on how to build baritone, see [Building Baritone](#building-baritone)
## IntelliJ ## IntelliJ
- Open the project in IntelliJ as a Gradle project - Open the project in IntelliJ as a Gradle project
![Image](https://i.imgur.com/jw7Q6vY.png)
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
![Image](https://i.imgur.com/QEfVvWP.png)
- Refresh the Gradle project (or, to be safe, just restart IntelliJ) - Refresh the Gradle project (or, to be safe, just restart IntelliJ)
- depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working
![Image](https://i.imgur.com/3V7EdWr.png)
- Select the "Minecraft Client" launch config
![Image](https://i.imgur.com/1qz2QGV.png)
- Click on ``Edit Configurations...`` from the same dropdown and select the "Minecraft Client" config
![Image](https://i.imgur.com/s4ly0ZF.png)
- In `Edit Configurations...` you need to select `baritone_launch` for `Use classpath of module:`.
![Image](https://i.imgur.com/hrLhG9u.png)
## IntelliJ
- Navigate to the gradle tasks on the right tab as follows
![Image](https://i.imgur.com/PE6r9iN.png)
- Double click on **build** to run it

View File

@@ -32,13 +32,13 @@ Watch this [showcase video](https://youtu.be/CZkLXWo4Fg4)!
To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`. To toggle a boolean setting, just say its name in chat (for example saying `allowBreak` toggles whether Baritone will consider breaking blocks). For a numeric setting, say its name then the new value (like `primaryTimeoutMS 250`). It's case insensitive. To reset a setting to its default value, say `acceptableThrowawayItems reset`. To reset all settings, say `reset`. To see all settings that have been modified from their default values, say `modified`.
Commands in Baritone: Some common examples:
- `thisway 1000` then `path` to go in the direction you're facing for a thousand blocks - `thisway 1000` then `path` to go in the direction you're facing for a thousand blocks
- `goal x y z` or `goal x z` or `goal y`, then `path` to set a goal to a certain coordinate then path to it - `goal x y z` or `goal x z` or `goal y`, then `path` to set a goal to a certain coordinate then path to it
- `goto x y z` or `goto x z` or `goto y` to go to a certain coordinate (in a single step, starts going immediately) - `goto x y z` or `goto x z` or `goto y` to go to a certain coordinate (in a single step, starts going immediately)
- `goal` to set the goal to your player's feet - `goal` to set the goal to your player's feet
- `goal clear` to clear the goal - `goal clear` to clear the goal
- `cancel` or `stop` to stop everything, `forcecancel` is also an option - `cancel` or `stop` to stop everything
- `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part) - `goto portal` or `goto ender_chest` or `goto block_type` to go to a block. (in Impact, `.goto` is an alias for `.b goto` for the most part)
- `mine diamond_ore iron_ore` to mine diamond ore or iron ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.) An amount of blocks can also be specified, for example, `mine 64 diamond_ore`. - `mine diamond_ore iron_ore` to mine diamond ore or iron ore (turn on the setting `legitMine` to only mine ores that it can actually see. It will explore randomly around y=11 until it finds them.) An amount of blocks can also be specified, for example, `mine 64 diamond_ore`.
- `click` to click your destination on the screen. Right click path to on top of the block, left click to path into it (either at foot level or eye level), and left click and drag to select an area (`#help sel` to see what you can do with that selection). - `click` to click your destination on the screen. Right click path to on top of the block, left click to path into it (either at foot level or eye level), and left click and drag to select an area (`#help sel` to see what you can do with that selection).
@@ -51,19 +51,11 @@ Commands in Baritone:
- `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120). - `axis` to go to an axis or diagonal axis at y=120 (`axisHeight` is a configurable setting, defaults to 120).
- `explore x z` to explore the world from the origin of x,z. Leave out x and z to default to player feet. This will continually path towards the closest chunk to the origin that it's never seen before. `explorefilter filter.json` with optional invert can be used to load in a list of chunks to load. - `explore x z` to explore the world from the origin of x,z. Leave out x and z to default to player feet. This will continually path towards the closest chunk to the origin that it's never seen before. `explorefilter filter.json` with optional invert can be used to load in a list of chunks to load.
- `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start. - `invert` to invert the current goal and path. This gets as far away from it as possible, instead of as close as possible. For example, do `goal` then `invert` to run as far as possible from where you're standing at the start.
- `come` tells Baritone to head towards your camera, useful when freecam doesn't move your player position.
- `blacklist` will stop baritone from going to the closest block so it won't attempt to get to it.
- `eta` to get information about the estimated time until the next segment and the goal, be aware that the ETA to your goal is really unprecise.
- `proc` to view miscellaneous information about the process currently controlling Baritone.
- `repack` to re-cache the chunks around you.
- `gc` to call `System.gc()` which may free up some memory.
- `render` to fix glitched chunk rendering without having to reload all of them.
- `reloadall` to reload Baritone's world cache or `saveall` to save Baritone's world cache.
- `find` to search through Baritone's cache and attempt to find the location of the block.
- `surface` or `top` to tell Baritone to head towards the closest surface-like area, this can be the surface or highest available air space.
- `version` to get the version of Baritone you're running - `version` to get the version of Baritone you're running
- `damn` daniel - `damn` daniel
For the rest of the commands, you can take a look at the code [here](https://baritone.leijurv.com/baritone/api/Settings.html).
All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>. If you find HTML easier to read than Javadoc, you can look <a href="https://baritone.leijurv.com/baritone/api/Settings.html#field.detail">here</a>. All the settings and documentation are <a href="https://github.com/cabaletta/baritone/blob/master/src/api/java/baritone/api/Settings.java">here</a>. If you find HTML easier to read than Javadoc, you can look <a href="https://baritone.leijurv.com/baritone/api/Settings.html#field.detail">here</a>.
There are about a hundred settings, but here are some fun / interesting / important ones that you might want to look at changing in normal usage of Baritone. The documentation for each can be found at the above links. There are about a hundred settings, but here are some fun / interesting / important ones that you might want to look at changing in normal usage of Baritone. The documentation for each can be found at the above links.

View File

@@ -16,13 +16,13 @@
*/ */
group 'baritone' group 'baritone'
version '1.2.17' version '1.2.15'
buildscript { buildscript {
repositories { repositories {
maven { maven {
name = 'forge' name = 'forge'
url = 'https://files.minecraftforge.net/maven' url = 'http://files.minecraftforge.net/maven'
} }
maven { maven {
name = 'SpongePowered' name = 'SpongePowered'
@@ -32,19 +32,18 @@ buildscript {
} }
dependencies { dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:4.+' // TODO: 5.+. `doHackyStuff` relies on 4.x internals. classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT' classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
} }
} }
import baritone.gradle.task.CreateDistTask import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask import baritone.gradle.task.ProguardTask
apply plugin: 'java' apply plugin: 'java'
apply plugin: 'maven-publish' apply plugin: 'maven'
apply plugin: 'net.minecraftforge.gradle' apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply from: 'hacks.gradle'
ext.doHackyStuff(Class.forName('net.minecraftforge.gradle.mcp.task.GenerateSRG')) // TODO: fg 5.0 - `ext.doHackyStuff(Class.forName('net.minecraftforge.gradle.mcp.tasks.GenerateSRG'))`
apply plugin: 'org.spongepowered.mixin' apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = '1.8' sourceCompatibility = targetCompatibility = '1.8'
@@ -54,19 +53,8 @@ compileJava {
} }
sourceSets { sourceSets {
api {
compileClasspath += main.compileClasspath
}
main {
compileClasspath += api.output
}
test {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
launch { launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
} }
schematica_api { schematica_api {
@@ -79,26 +67,13 @@ sourceSets {
} }
minecraft { minecraft {
mappings channel: 'stable', version: '39-1.12' version = '1.12.2'
runs { mappings = 'stable_39'
def nativesOutput = extractNatives.output // TODO: fg 5.0 - `def nativesOutput = extractNatives.output.get()` tweakClass = 'baritone.launch.BaritoneTweaker'
println("[Baritoe] Detected natives: ${nativesOutput}") runDir = 'run'
client {
workingDirectory project.file('run')
source sourceSets.launch
main 'net.minecraft.launchwrapper.Launch' // The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
args '--gameDir', '.'
args '--version', '1.12.2'
args '--assetsDir', downloadAssets.output
args '--assetIndex', '{asset_index}'
args '--accessToken', 'INVALID'
args '--tweakClass', 'baritone.launch.BaritoneTweaker'
jvmArgs "-Dorg.lwjgl.librarypath=${nativesOutput}"
}
}
} }
repositories { repositories {
@@ -113,74 +88,23 @@ repositories {
name = 'impactdevelopment-repo' name = 'impactdevelopment-repo'
url = 'https://impactdevelopment.github.io/maven/' url = 'https://impactdevelopment.github.io/maven/'
} }
maven {
name = 'babbaj-repo'
url = 'https://babbaj.github.io/maven/'
}
}
// fix forge gradle 4+ bug with 1.12.2
afterEvaluate {
configurations.minecraft {
exclude group: 'net.minecraftforge', module: 'mergetool'
}
}
// lwjgl2 hack for running game on arm64 mac os
afterEvaluate {
def os = org.gradle.internal.os.OperatingSystem.current()
if (os.isMacOsX()) {
def arch = System.getProperty("os.arch").toLowerCase()
println("Detected Mac OS X running on ${arch}")
if (arch == "aarch64") {
println("Configurating aarch64 dependencies.")
configurations.minecraft {
exclude group: 'ca.weblite', module: 'java-objc-bridge'
}
dependencies {
// https://github.com/MinecraftMachina/lwjgl/releases/download/2.9.4-20150209-mmachina.2/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar
minecraft files("libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar")
// TODO: use prism launcher maven
// https://github.com/MinecraftMachina/Java-Objective-C-Bridge/releases/download/1.1.0-mmachina.1/java-objc-bridge-1.1.jar
minecraft files("libs/java-objc-bridge-1.1.jar") // TODO: use prism launcher maven
minecraft(group: 'net.java.dev.jna', name: 'jna') {
version {
strictly '5.12.1'
}
}
}
}
}
} }
dependencies { dependencies {
minecraft group: 'net.minecraft', name: 'joined', version: '1.12.2' runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
implementation(group: 'net.minecraft', name: 'launchwrapper', version: '1.12') { runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
transitive = false
}
def asmVersion = '9.5'
implementation group: 'org.ow2.asm', name: 'asm', version: asmVersion
implementation group: 'org.ow2.asm', name: 'asm-tree', version: asmVersion
implementation group: 'org.ow2.asm', name: 'asm-commons', version: asmVersion
implementation group: 'org.ow2.asm', name: 'asm-analysis', version: asmVersion
implementation group: 'org.ow2.asm', name: 'asm-util', version: asmVersion
launchImplementation('com.github.ImpactDevelopment:SimpleTweaker:1.2')
launchImplementation('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
// Mixin includes a lot of dependencies that are too up-to-date // Mixin includes a lot of dependencies that are too up-to-date
transitive = false exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
} }
launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor'
launchImplementation('dev.babbaj:nether-pathfinder:0.34')
implementation 'dev.babbaj:nether-pathfinder:0.34'
testImplementation 'junit:junit:4.12' testImplementation 'junit:junit:4.12'
} }
mixin { mixin {
defaultObfuscationEnv searge
add sourceSets.launch, 'mixins.baritone.refmap.json' add sourceSets.launch, 'mixins.baritone.refmap.json'
} }
@@ -206,7 +130,7 @@ jar {
manifest { manifest {
attributes( attributes(
'MixinConfigs': 'mixins.baritone.json', 'MixinConfigs': 'mixins.baritone.json',
'TweakClass': 'baritone.launch.BaritoneTweaker',
'Implementation-Title': 'Baritone', 'Implementation-Title': 'Baritone',
'Implementation-Version': version 'Implementation-Version': version
) )
@@ -221,3 +145,25 @@ task proguard(type: ProguardTask) {
task createDist(type: CreateDistTask, dependsOn: proguard) task createDist(type: CreateDistTask, dependsOn: proguard)
build.finalizedBy(createDist) build.finalizedBy(createDist)
install {
def jarApiName = String.format("%s-api-%s", rootProject.name, version.toString())
def jarApiForgeName = String.format("%s-api-forge-%s", rootProject.name, version.toString())
def jarSAName = String.format("%s-standalone-%s", rootProject.name, version.toString())
def jarSAForgeName = String.format("%s-standalone-forge-%s", rootProject.name, version.toString())
artifacts {
archives file("$buildDir/libs/"+jarApiName+".jar")
archives file("$buildDir/libs/"+jarApiForgeName+".jar")
archives file("$buildDir/libs/"+jarSAName+".jar")
archives file("$buildDir/libs/"+jarSAForgeName+".jar")
}
repositories.mavenInstaller {
addFilter('api') { artifact, file -> artifact.name == "baritone-api" }
addFilter('api-forge') { artifact, file -> artifact.name == "baritone-api-forge" }
addFilter('standalone') { artifact, file -> artifact.name == "baritone-standalone" }
addFilter('standalone-forge') { artifact, file -> artifact.name == "baritone-standalone-forge" }
}
}
install.dependsOn(build)

View File

@@ -20,6 +20,6 @@ repositories {
} }
dependencies { dependencies {
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5' compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
implementation group: 'commons-io', name: 'commons-io', version: '2.6' compile group: 'commons-io', name: 'commons-io', version: '2.6'
} }

View File

@@ -32,21 +32,21 @@ import java.nio.file.Paths;
class BaritoneGradleTask extends DefaultTask { class BaritoneGradleTask extends DefaultTask {
protected static final String protected static final String
PROGUARD_ZIP = "proguard.zip", PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar", PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro", PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
PROGUARD_CONFIG_DEST = "template.pro", PROGUARD_CONFIG_DEST = "template.pro",
PROGUARD_API_CONFIG = "api.pro", PROGUARD_API_CONFIG = "api.pro",
PROGUARD_STANDALONE_CONFIG = "standalone.pro", PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar", PROGUARD_EXPORT_PATH = "proguard_out.jar",
TEMP_LIBRARY_DIR = "tempLibraries/", TEMP_LIBRARY_DIR = "tempLibraries/",
ARTIFACT_STANDARD = "%s-%s.jar", ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar", ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar", ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar", ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar", ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar"; ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
protected String artifactName, artifactVersion; protected String artifactName, artifactVersion;
@@ -56,17 +56,17 @@ class BaritoneGradleTask extends DefaultTask {
this.artifactName = getProject().getName(); this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString(); this.artifactVersion = getProject().getVersion().toString();
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD)); this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED)); this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API)); this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE)); this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API)); this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE)); this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH); this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
if (!Files.exists(this.artifactPath)) { if (!Files.exists(this.artifactPath)) {
throw new IllegalStateException("Artifact not found! Run build first! " + this.artifactPath); throw new IllegalStateException("Artifact not found! Run build first!");
} }
} }
@@ -82,7 +82,7 @@ class BaritoneGradleTask extends DefaultTask {
} }
protected Path getRelativeFile(String file) { protected Path getRelativeFile(String file) {
return Paths.get(this.getProject().file(file).getAbsolutePath()); return Paths.get(new File(file).getAbsolutePath());
} }
protected Path getTemporaryFile(String file) { protected Path getTemporaryFile(String file) {

View File

@@ -18,33 +18,39 @@
package baritone.gradle.task; package baritone.gradle.task;
import baritone.gradle.util.Determinizer; import baritone.gradle.util.Determinizer;
import baritone.gradle.util.MappingType;
import baritone.gradle.util.ReobfWrapper;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import org.gradle.api.Project; import org.gradle.api.JavaVersion;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.artifacts.Configuration; import org.gradle.api.artifacts.Configuration;
import org.gradle.api.artifacts.Dependency; import org.gradle.api.artifacts.Dependency;
import org.gradle.api.internal.file.IdentityFileResolver;
import org.gradle.api.internal.plugins.DefaultConvention;
import org.gradle.api.tasks.Input; import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.TaskAction; import org.gradle.api.tasks.TaskAction;
import org.gradle.api.tasks.TaskCollection; import org.gradle.api.tasks.TaskCollection;
import org.gradle.api.tasks.compile.ForkOptions; import org.gradle.api.tasks.compile.ForkOptions;
import org.gradle.api.tasks.compile.JavaCompile; import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.internal.Pair;
import org.gradle.internal.jvm.Jvm; import org.gradle.internal.jvm.Jvm;
import org.gradle.internal.jvm.inspection.DefaultJvmVersionDetector;
import java.io.File; import org.gradle.process.internal.DefaultExecActionFactory;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.nio.file.Path;
import java.nio.file.StandardCopyOption;
import java.util.Objects;
import java.io.*; import java.io.*;
import java.lang.reflect.Field;
import java.net.URL; import java.net.URL;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*; import java.util.*;
import java.util.regex.Matcher; import java.util.regex.Matcher;
import java.util.regex.Pattern; import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry; import java.util.zip.ZipEntry;
import java.util.zip.ZipFile; import java.util.zip.ZipFile;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/** /**
* @author Brady * @author Brady
* @since 10/11/2018 * @since 10/11/2018
@@ -62,18 +68,17 @@ public class ProguardTask extends BaritoneGradleTask {
private List<String> requiredLibraries; private List<String> requiredLibraries;
private File mixin; private File mixin;
private File pathfinder;
@TaskAction @TaskAction
protected void exec() throws Exception { protected void exec() throws Exception {
super.verifyArtifacts(); super.verifyArtifacts();
// "Haha brady why don't you make separate tasks" // "Haha brady why don't you make separate tasks"
processArtifact();
downloadProguard(); downloadProguard();
extractProguard(); extractProguard();
generateConfigs(); generateConfigs();
acquireDependencies(); acquireDependencies();
processArtifact();
proguardApi(); proguardApi();
proguardStandalone(); proguardStandalone();
cleanup(); cleanup();
@@ -84,7 +89,7 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.artifactUnoptimizedPath); Files.delete(this.artifactUnoptimizedPath);
} }
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Arrays.asList(pathfinder), false); Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
} }
private void downloadProguard() throws Exception { private void downloadProguard() throws Exception {
@@ -109,7 +114,8 @@ public class ProguardTask extends BaritoneGradleTask {
try { try {
path = findJavaPathByGradleConfig(); path = findJavaPathByGradleConfig();
if (path != null) return path; if (path != null) return path;
} catch (Exception ex) { }
catch (Exception ex) {
System.err.println("Unable to find java by javaCompile options"); System.err.println("Unable to find java by javaCompile options");
ex.printStackTrace(); ex.printStackTrace();
} }
@@ -117,7 +123,8 @@ public class ProguardTask extends BaritoneGradleTask {
try { try {
path = findJavaByJavaHome(); path = findJavaByJavaHome();
if (path != null) return path; if (path != null) return path;
} catch (Exception ex) { }
catch(Exception ex) {
System.err.println("Unable to find java by JAVA_HOME"); System.err.println("Unable to find java by JAVA_HOME");
ex.printStackTrace(); ex.printStackTrace();
} }
@@ -125,23 +132,30 @@ public class ProguardTask extends BaritoneGradleTask {
path = findJavaByGradleCurrentRuntime(); path = findJavaByGradleCurrentRuntime();
if (path != null) return path; if (path != null) return path;
throw new Exception("Unable to find java to determine ProGuard libraryjars. Please specify forkOptions.executable in javaCompile," + throw new Exception("Unable to find java to determine ProGuard libraryjars. Please specify forkOptions.executable in javaCompile," +
" JAVA_HOME environment variable, or make sure to run Gradle with the correct JDK (a v1.8 only)"); " JAVA_HOME environment variable, or make sure to run Gradle with the correct JDK (a v1.8 only)");
} }
private String findJavaByGradleCurrentRuntime() { private String findJavaByGradleCurrentRuntime() {
String path = Jvm.current().getJavaExecutable().getAbsolutePath(); String path = Jvm.current().getJavaExecutable().getAbsolutePath();
System.out.println("Using Gradle's runtime Java for ProGuard");
return path; if (this.validateJavaVersion(path)) {
System.out.println("Using Gradle's runtime Java for ProGuard");
return path;
}
return null;
} }
private String findJavaByJavaHome() { private String findJavaByJavaHome() {
final String javaHomeEnv = System.getenv("JAVA_HOME"); final String javaHomeEnv = System.getenv("JAVA_HOME");
if (javaHomeEnv != null) { if (javaHomeEnv != null) {
String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath(); String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath();
System.out.println("Detected Java path by JAVA_HOME"); if (this.validateJavaVersion(path)) {
return path; System.out.println("Detected Java path by JAVA_HOME");
return path;
}
} }
return null; return null;
} }
@@ -157,11 +171,19 @@ public class ProguardTask extends BaritoneGradleTask {
if (javacPath != null) { if (javacPath != null) {
File javacFile = new File(javacPath); File javacFile = new File(javacPath);
if (javacFile.exists()) { if (javacFile.exists()) {
File[] maybeJava = javacFile.getParentFile().listFiles((dir, name) -> name.equals("java")); File[] maybeJava = javacFile.getParentFile().listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.equals("java");
}
});
if (maybeJava != null && maybeJava.length > 0) { if (maybeJava != null && maybeJava.length > 0) {
String path = maybeJava[0].getAbsolutePath(); String path = maybeJava[0].getAbsolutePath();
System.out.println("Detected Java path by forkOptions"); if (this.validateJavaVersion(path)) {
return path; System.out.println("Detected Java path by forkOptions");
return path;
}
} }
} }
} }
@@ -169,13 +191,26 @@ public class ProguardTask extends BaritoneGradleTask {
return null; return null;
} }
private boolean validateJavaVersion(String java) {
final JavaVersion javaVersion = new DefaultJvmVersionDetector(new DefaultExecActionFactory(new IdentityFileResolver())).getJavaVersion(java);
if (!javaVersion.getMajorVersion().equals("8")) {
System.out.println("Failed to validate Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
// throw new RuntimeException("Java version incorrect: " + javaVersion.getMajorVersion() + " for " + java);
return false;
}
System.out.println("Validated Java version " + javaVersion.toString() + " [" + java + "] for ProGuard libraryjars");
return true;
}
private void generateConfigs() throws Exception { private void generateConfigs() throws Exception {
Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), StandardCopyOption.REPLACE_EXISTING); Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), REPLACE_EXISTING);
// Setup the template that will be used to derive the API and Standalone configs // Setup the template that will be used to derive the API and Standalone configs
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST)); List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
template.add(0, "-injars '" + this.artifactPath.toString() + "'"); template.add(0, "-injars " + this.artifactPath.toString());
template.add(1, "-outjars '" + this.getTemporaryFile(PROGUARD_EXPORT_PATH) + "'"); template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+ // Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start(); Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start();
@@ -202,37 +237,14 @@ public class ProguardTask extends BaritoneGradleTask {
}); });
} }
private static final class Pair<A, B> {
public final A a;
public final B b;
private Pair(final A a, final B b) {
this.a = a;
this.b = b;
}
@Override
public String toString() {
return "Pair{" +
"a=" + this.a +
", " +
"b=" + this.b +
'}';
}
}
private void acquireDependencies() throws Exception { private void acquireDependencies() throws Exception {
// Create a map of all of the dependencies that we are able to access in this project // Create a map of all of the dependencies that we are able to access in this project
// Likely a better way to do this, I just pair the dependency with the first valid configuration // Likely a better way to do this, I just pair the dependency with the first valid configuration
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>(); Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
Map<String, File> files = new HashMap<>(); getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config -> { config.getAllDependencies().forEach(dependency ->
for (File file : config.getFiles()) { dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
files.put(file.getName(), file);
}
config.getAllDependencies().forEach(dependency ->
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), new Pair<>(config, dependency)));
});
// Create the directory if it doesn't already exist // Create the directory if it doesn't already exist
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR); Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
@@ -247,7 +259,7 @@ public class ProguardTask extends BaritoneGradleTask {
Path cachedJar = getMinecraftJar(); Path cachedJar = getMinecraftJar();
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar"); Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
// TODO: maybe try not to copy every time // TODO: maybe try not to copy every time
Files.copy(cachedJar, inTempDir, StandardCopyOption.REPLACE_EXISTING); Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
continue; continue;
} }
@@ -259,77 +271,118 @@ public class ProguardTask extends BaritoneGradleTask {
pair = entry.getValue(); pair = entry.getValue();
} }
} }
// The pair must be non-null
Objects.requireNonNull(pair);
// Find the library jar file, and copy it to tempLibraries // Find the library jar file, and copy it to tempLibraries
if (pair == null) { for (File file : pair.getLeft().files(pair.getRight())) {
File libFile = files.get(lib + ".jar"); if (file.getName().startsWith(lib)) {
if (libFile == null) { if (lib.contains("mixin")) {
libFile = files.values().stream().filter(file -> file.getName().startsWith(lib)).findFirst().orElse(null); mixin = file;
if (libFile == null) {
throw new IllegalStateException(lib);
}
}
copyTempLib(lib, libFile);
} else {
for (File file : pair.a.files(pair.b)) {
if (file.getName().startsWith(lib)) {
copyTempLib(lib, file);
} }
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
} }
} }
} }
if (mixin == null) { if (mixin == null) {
throw new IllegalStateException("Unable to find mixin jar"); throw new IllegalStateException("Unable to find mixin jar");
} }
if (pathfinder == null) {
throw new IllegalStateException("Unable to find pathfinder jar");
}
}
private void copyTempLib(String lib, File libFile) throws IOException {
if (lib.contains("mixin")) {
mixin = libFile;
}
if (lib.contains("nether-pathfinder")) {
pathfinder = libFile;
}
Files.copy(libFile.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), StandardCopyOption.REPLACE_EXISTING);
} }
// a bunch of epic stuff to get the path to the cached jar // a bunch of epic stuff to get the path to the cached jar
private Path getMinecraftJar() throws Exception { private Path getMinecraftJar() throws Exception {
return getObfuscatedMinecraftJar(getProject(), false); // always notch jar for now. MappingType mappingType;
try {
mappingType = getMappingType();
} catch (Exception e) {
System.err.println("Failed to get mapping type, assuming NOTCH.");
mappingType = MappingType.NOTCH;
}
String suffix;
switch (mappingType) {
case NOTCH:
suffix = "";
break;
case SEARGE:
suffix = "-srgBin";
break;
case CUSTOM:
throw new IllegalStateException("Custom mappings not supported!");
default:
throw new IllegalStateException("Unknown mapping type: " + mappingType);
}
DefaultConvention convention = (DefaultConvention) this.getProject().getConvention();
Object extension = convention.getAsMap().get("minecraft");
Objects.requireNonNull(extension);
// for some reason cant use Class.forName
Class<?> class_baseExtension = extension.getClass().getSuperclass().getSuperclass().getSuperclass(); // <-- cursed
Field f_replacer = class_baseExtension.getDeclaredField("replacer");
f_replacer.setAccessible(true);
Object replacer = f_replacer.get(extension);
Class<?> class_replacementProvider = replacer.getClass();
Field replacement_replaceMap = class_replacementProvider.getDeclaredField("replaceMap");
replacement_replaceMap.setAccessible(true);
Map<String, Object> replacements = (Map) replacement_replaceMap.get(replacer);
String cacheDir = replacements.get("CACHE_DIR").toString() + "/net/minecraft";
String mcVersion = replacements.get("MC_VERSION").toString();
String mcpInsert = replacements.get("MAPPING_CHANNEL").toString() + "/" + replacements.get("MAPPING_VERSION").toString();
String fullJarName = "minecraft-" + mcVersion + suffix + ".jar";
String baseDir = String.format("%s/minecraft/%s/", cacheDir, mcVersion);
String jarPath;
if (mappingType == MappingType.SEARGE) {
jarPath = String.format("%s/%s/%s", baseDir, mcpInsert, fullJarName);
} else {
jarPath = baseDir + fullJarName;
}
jarPath = jarPath
.replace("/", File.separator)
.replace("\\", File.separator); // hecking regex
return new File(jarPath).toPath();
} }
private static Path getObfuscatedMinecraftJar(final Project project, final boolean srg) throws Exception { // throws IllegalStateException if mapping type is ambiguous or it fails to find it
final Object extension = Objects.requireNonNull(project.getExtensions().findByName("minecraft"), "Unable to find Minecraft extension."); private MappingType getMappingType() {
// if it fails to find this then its probably a forgegradle version problem
Set<Object> reobf = (NamedDomainObjectContainer<Object>) this.getProject().getExtensions().getByName("reobf");
final Class<?> mcpRepoClass = mcpRepoClass(extension.getClass().getClassLoader()); List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
final Field mcpRepoInstanceField = mcpRepoClass.getDeclaredField("INSTANCE"); long mappingTypesUsed = mappingTypes.size();
mcpRepoInstanceField.setAccessible(true); if (mappingTypesUsed == 0) {
final Method findMethod = mcpRepoClass.getDeclaredMethod(srg ? "findSrg" : "findRaw", String.class, String.class); throw new IllegalStateException("Failed to find mapping type (no jar task?)");
findMethod.setAccessible(true); }
if (mappingTypesUsed > 1) {
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
}
final Object mcpRepo = mcpRepoInstanceField.get(null); return mappingTypes.get(0);
final String mcpVersion = (String) Objects.requireNonNull(project.getExtensions().getExtraProperties().get("MCP_VERSION"), "Extra property \"MCP_VERSION\" not found");
return ((File) findMethod.invoke(mcpRepo, "joined", mcpVersion)).toPath();
} }
private static Class<?> mcpRepoClass(final ClassLoader loader) throws Exception { private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
final Method forName0 = Class.class.getDeclaredMethod("forName0", String.class, boolean.class, ClassLoader.class, Class.class); return reobf.stream()
forName0.setAccessible(true); .map(ReobfWrapper::new)
return (Class<?>) forName0.invoke(null, "net.minecraftforge.gradle.mcp.MCPRepo", true, loader, null); .map(ReobfWrapper::getMappingType)
.distinct()
.collect(Collectors.toList());
} }
private void proguardApi() throws Exception { private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG)); runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Arrays.asList(pathfinder), false); Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Arrays.asList(pathfinder, mixin), true); Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
} }
private void proguardStandalone() throws Exception { private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG)); runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Arrays.asList(pathfinder), false); Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Arrays.asList(pathfinder, mixin), true); Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
} }
private void cleanup() { private void cleanup() {
@@ -342,33 +395,19 @@ public class ProguardTask extends BaritoneGradleTask {
this.url = url; this.url = url;
} }
public String getUrl() {
return url;
}
public void setExtract(String extract) { public void setExtract(String extract) {
this.extract = extract; this.extract = extract;
} }
public String getExtract() {
return extract;
}
private void runProguard(Path config) throws Exception { private void runProguard(Path config) throws Exception {
// Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves // Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves
if (Files.exists(this.proguardOut)) { if (Files.exists(this.proguardOut)) {
Files.delete(this.proguardOut); Files.delete(this.proguardOut);
} }
// Make paths relative to work directory; fixes spaces in path to config, @"" doesn't work Path proguardJar = getTemporaryFile(PROGUARD_JAR);
Path workingDirectory = getTemporaryFile("");
Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR));
config = workingDirectory.relativize(config);
// Honestly, if you still have spaces in your path at this point, you're SOL.
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString()) Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
.directory(workingDirectory.toFile()) // Set the working directory to the temporary folder] .directory(getTemporaryFile("").toFile()) // Set the working directory to the temporary folder]
.start(); .start();
// We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this // We can't do output inherit process I/O with gradle for some reason and have it work, so we have to do this
@@ -378,7 +417,6 @@ public class ProguardTask extends BaritoneGradleTask {
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception // Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor(); int exitCode = p.waitFor();
if (exitCode != 0) { if (exitCode != 0) {
Thread.sleep(1000);
throw new IllegalStateException("Proguard exited with code " + exitCode); throw new IllegalStateException("Proguard exited with code " + exitCode);
} }
} }

View File

@@ -22,10 +22,7 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter; import com.google.gson.stream.JsonWriter;
import java.io.*; import java.io.*;
import java.util.ArrayList; import java.util.*;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry; import java.util.jar.JarEntry;
import java.util.jar.JarFile; import java.util.jar.JarFile;
import java.util.jar.JarOutputStream; import java.util.jar.JarOutputStream;
@@ -39,11 +36,10 @@ import java.util.stream.Collectors;
*/ */
public class Determinizer { public class Determinizer {
public static void determinize(String inputPath, String outputPath, List<File> toInclude, boolean doForgeReplacementOfMetaInf) throws IOException { public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
System.out.println("Running Determinizer"); System.out.println("Running Determinizer");
System.out.println(" Input path: " + inputPath); System.out.println(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath); System.out.println(" Output path: " + outputPath);
System.out.println(" Shade: " + toInclude);
try ( try (
JarFile jarFile = new JarFile(new File(inputPath)); JarFile jarFile = new JarFile(new File(inputPath));
@@ -64,10 +60,10 @@ public class Determinizer {
JarEntry clone = new JarEntry(entry.getName()); JarEntry clone = new JarEntry(entry.getName());
clone.setTime(42069); clone.setTime(42069);
jos.putNextEntry(clone); jos.putNextEntry(clone);
if (entry.getName().endsWith(".json")) { if (entry.getName().endsWith(".refmap.json")) {
JsonElement json = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))); JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
jos.write(writeSorted(json).getBytes()); jos.write(writeSorted(object).getBytes());
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && doForgeReplacementOfMetaInf) { // only replace for forge jar } else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
ByteArrayOutputStream cancer = new ByteArrayOutputStream(); ByteArrayOutputStream cancer = new ByteArrayOutputStream();
copy(jarFile.getInputStream(entry), cancer); copy(jarFile.getInputStream(entry), cancer);
String manifest = new String(cancer.toByteArray()); String manifest = new String(cancer.toByteArray());
@@ -80,8 +76,8 @@ public class Determinizer {
copy(jarFile.getInputStream(entry), jos); copy(jarFile.getInputStream(entry), jos);
} }
} }
for (File file : toInclude) { if (toInclude.isPresent()) {
try (JarFile mixin = new JarFile(file)) { try (JarFile mixin = new JarFile(toInclude.get())) {
for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) { for (JarEntry entry : mixin.stream().sorted(Comparator.comparing(JarEntry::getName)).collect(Collectors.toList())) {
if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) { if (entry.getName().startsWith("META-INF") && !entry.getName().startsWith("META-INF/services")) {
continue; continue;
@@ -93,7 +89,6 @@ public class Determinizer {
} }
jos.finish(); jos.finish();
} }
System.out.println("Done with determinizer");
} }
private static void copy(InputStream is, OutputStream os) throws IOException { private static void copy(InputStream is, OutputStream os) throws IOException {
@@ -104,7 +99,7 @@ public class Determinizer {
} }
} }
private static String writeSorted(JsonElement in) throws IOException { private static String writeSorted(JsonObject in) throws IOException {
StringWriter writer = new StringWriter(); StringWriter writer = new StringWriter();
JsonWriter jw = new JsonWriter(writer); JsonWriter jw = new JsonWriter(writer);
ORDERED_JSON_WRITER.write(jw, in); ORDERED_JSON_WRITER.write(jw, in);

View File

@@ -0,0 +1,29 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.util;
/**
* All credits go to AsmLibGradle and its contributors.
*
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/MappingType.java">Original Source</a>
*/
public enum MappingType {
SEARGE,
NOTCH,
CUSTOM // forgegradle
}

View File

@@ -0,0 +1,63 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.util;
import java.lang.reflect.Field;
import java.util.Objects;
/**
* All credits go to AsmLibGradle and its contributors.
*
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/ReobfWrapper.java">Original Source</a>
*/
public class ReobfWrapper {
private final Object instance;
private final Class<?> type;
public ReobfWrapper(Object instance) {
this.instance = instance;
Objects.requireNonNull(instance);
this.type = instance.getClass();
}
public String getName() {
try {
Field nameField = type.getDeclaredField("name");
nameField.setAccessible(true);
return (String) nameField.get(this.instance);
} catch (ReflectiveOperationException ex) {
throw new IllegalStateException(ex);
}
}
public MappingType getMappingType() {
try {
Field enumField = type.getDeclaredField("mappingType");
enumField.setAccessible(true);
Enum<?> aEnum = (Enum<?>) enumField.get(this.instance);
MappingType mappingType = MappingType.values()[aEnum.ordinal()];
if (!aEnum.name().equals(mappingType.name())) {
throw new IllegalStateException("ForgeGradle ReobfMappingType is not equivalent to MappingType (version error?)");
}
return mappingType;
} catch (ReflectiveOperationException ex) {
throw new IllegalStateException(ex);
}
}
}

Binary file not shown.

View File

@@ -1,5 +1,6 @@
#Tue Jul 31 21:56:56 PDT 2018
distributionBase=GRADLE_USER_HOME distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip

55
gradlew vendored
View File

@@ -1,21 +1,5 @@
#!/usr/bin/env sh #!/usr/bin/env sh
#
# Copyright 2015 the original author or 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 UN*X
@@ -44,7 +28,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # 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"' DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"
@@ -72,7 +56,7 @@ case "`uname`" in
Darwin* ) Darwin* )
darwin=true darwin=true
;; ;;
MSYS* | MINGW* ) MINGW* )
msys=true msys=true
;; ;;
NONSTOP* ) NONSTOP* )
@@ -82,7 +66,6 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -126,11 +109,10 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi fi
# For Cygwin or MSYS, switch paths to Windows format before running java # For Cygwin, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
@@ -156,19 +138,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
else else
eval `echo args$i`="\"$arg\"" eval `echo args$i`="\"$arg\""
fi fi
i=`expr $i + 1` i=$((i+1))
done done
case $i in case $i in
0) set -- ;; (0) set -- ;;
1) set -- "$args0" ;; (1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;; (2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;; (3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;; (4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; (5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; (6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; (7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; (8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; (9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
@@ -177,9 +159,14 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " " echo " "
} }
APP_ARGS=`save "$@"` APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules # Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

43
gradlew.bat vendored
View File

@@ -1,19 +1,3 @@
@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 @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@@ -29,18 +13,15 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% 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. @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" set DEFAULT_JVM_OPTS=
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute if "%ERRORLEVEL%" == "0" goto init
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -54,7 +35,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute if exist "%JAVA_EXE%" goto init
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,14 +45,28 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_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=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %* "%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %CMD_LINE_ARGS%
:end :end
@rem End local scope for the variables with windows NT shell @rem End local scope for the variables with windows NT shell

View File

@@ -1,161 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
ext.doHackyStuff = { final Class<?> clazz ->
def withExtension = { final File file, final String extension ->
def i = file.getName().lastIndexOf('.')
def name = file.getName().substring(0, i)
return new File(file.getParent(), "$name.$extension")
}
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/patcher/java/net/minecraftforge/gradle/patcher/PatcherPlugin.java#L545
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/userdev/java/net/minecraftforge/gradle/userdev/UserDevPlugin.java#L149
// create createMcp2Obf task
this.tasks.register('createMcpToObf', clazz)
.configure { task ->
task.setNotch(true)
task.setReverse(true)
}
afterEvaluate {
def createMcp2Obf = this.tasks.getByName('createMcpToObf')
def createMcp2Srg = this.tasks.getByName('createMcpToSrg')
// configure createMcp2Obf task
if (createMcp2Obf.getSrg() == null) {
createMcp2Obf.setSrg(createMcp2Srg.getSrg())
createMcp2Obf.setMappings(createMcp2Srg.getMappings())
createMcp2Obf.dependsOn(createMcp2Srg)
}
def createSrgCopyTask = { final Task tsrgTask ->
def srgCopyTask = this.tasks.register("${tsrgTask.name}Srg", tsrgTask.getClass())
tsrgTask.getDependsOn().forEach({ dep ->
srgCopyTask.get().dependsOn(dep)
})
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/mcp/java/net/minecraftforge/gradle/mcp/task/GenerateSRG.java#L39
srgCopyTask.configure { task ->
task.setSrg(tsrgTask.getSrg())
task.setMappings(tsrgTask.getMappings())
// https://github.com/MinecraftForge/SrgUtils/blob/bb2ca35bb8d349a122ef512dedd24f54f7cd0bdf/src/main/java/net/minecraftforge/srgutils/IMappingFile.java#L44
task.setFormat('SRG')
task.setNotch(tsrgTask.getNotch())
task.setReverse(tsrgTask.getReverse())
task.setOutput(withExtension(tsrgTask.getOutput(), 'srg'))
}
return srgCopyTask
}
def createMcp2ObfSrgCopyTask = createSrgCopyTask(createMcp2Obf)
createMcp2Obf.dependsOn(createMcp2ObfSrgCopyTask)
def createMcp2SrgSrgCopyTask = createSrgCopyTask(createMcp2Srg)
createMcp2Srg.dependsOn(createMcp2SrgSrgCopyTask)
this.sourceSets.forEach({ set ->
def compileTask = this.project.tasks[set.compileJavaTaskName]
if (!(compileTask instanceof JavaCompile)) {
println("[Baritoe] Non-java compile task for ${set} of type ${compileTask}")
return
}
compileTask.dependsOn(createMcp2Obf)
compileTask.doFirst {
// inject legacy notch srg file
def createMcp2ObfSrgCopy = createMcp2ObfSrgCopyTask.get()
def reobfNotchSrgFileArgument = "-AreobfNotchSrgFile=${createMcp2ObfSrgCopy.output.canonicalPath}"
compileTask.options.compilerArgs += reobfNotchSrgFileArgument
println("[Baritoe] Injecting compiler argument: ${reobfNotchSrgFileArgument}")
// inject legacy notch srg out file
def outTSrgFileArgument = '-AoutTsrgFile='
def compilerArgsIterator = compileTask.options.compilerArgs.listIterator()
while (compilerArgsIterator.hasNext()) {
def compilerArg = compilerArgsIterator.next()
if (compilerArg.startsWith(outTSrgFileArgument)) {
def argumentFileValue = new File(compilerArg.substring(outTSrgFileArgument.length(), compilerArg.length()))
def outNotchSrgFile = withExtension(argumentFileValue, 'notch.srg')
def outNotchSrgFileArgument = "-AoutNotchSrgFile=${outNotchSrgFile.canonicalPath}"
println("[Baritoe] Injecting compiler argument: ${outNotchSrgFileArgument}")
compilerArgsIterator.add(outNotchSrgFileArgument)
}
}
}
})
// register reobf jars
def reobfExtension = this.project.getExtensions().getByName('reobf')
if (!reobfExtension) {
throw new IllegalStateException("Could not find \"reobf\" extension")
}
def reobfNotchJar = reobfExtension.create(jar.getName())
reobfNotchJar.dependsOn(createMcp2Obf)
reobfNotchJar.setMappings(createMcp2Obf.getOutput())
// even more horrible hack :) for outNotchSrgFile injection
reobfNotchJar.doFirst {
// https://github.com/MinecraftForge/ForgeGradle/blob/6639464b29b0923187eee0a609e546ba9f1b998b/src/userdev/java/net/minecraftforge/gradle/userdev/tasks/RenameJar.java#L96
def extraMappings = reobfNotchJar.getExtraMappings()
println("[Baritoe] Extra mappings: ${extraMappings}")
def copy = new ArrayList<>()
extraMappings.forEach { extraMapping ->
copy.add(withExtension(extraMapping, 'notch.srg'))
}
println("[Baritoe] New extra mappings: ${copy}")
reobfNotchJar.setExtraMappings(copy)
}
}
}
// TODO: In-complete fg 5.0 port. Currently doesn't handle mixin notch srg mapping hack.
//ext.doHackyStuff = { final Class<?> clazz ->
// afterEvaluate {
// def createMcp2Srg = this.tasks.getByName('createMcpToSrg')
// def createMcpToObf = this.tasks.register('createMcpToObf', clazz)
// createMcpToObf.configure { task ->
// task.setNotch(true)
// task.setReverse(true)
// task.getSrg().set(createMcp2Srg.getSrg().get())
// task.getMappings().set(createMcp2Srg.getMappings().get())
// task.dependsOn(createMcp2Srg)
// }
// reobf {
// jar {
// dependsOn(createMcpToObf)
// getMappings().set(createMcpToObf.get().getOutput().get())
// }
// }
// this.sourceSets.forEach({ set ->
// def compileTask = this.project.tasks[set.compileJavaTaskName]
// if (!(compileTask instanceof JavaCompile)) {
// println("[Baritoe] Non-java compile task for ${set} of type ${compileTask}")
// return
// }
// compileTask.dependsOn(createMcpToObf)
// compileTask.doFirst {
// def reobfTSrgFile = '-AreobfTsrgFile='
// def compilerArgsIterator = compileTask.options.compilerArgs.listIterator()
// while (compilerArgsIterator.hasNext()) {
// def compilerArg = compilerArgsIterator.next()
// if (compilerArg.startsWith(reobfTSrgFile)) {
// compilerArgsIterator.remove()
// def toInject = "-AreobfTsrgFile=${createMcpToObf.get().output.get().asFile.canonicalPath}"
// compilerArgsIterator.add(toInject)
// println("[Baritoe] Injecting compiler argument: ${toInject}")
// }
// }
// println("[Baritoe] Compiler arguments: ${compileTask.options.compilerArgs}")
// }
// })
// }
//}

10
scripts/proguard.pro vendored
View File

@@ -1,6 +1,5 @@
-keepattributes Signature -keepattributes Signature
-keepattributes *Annotation* -keepattributes *Annotation*
-keepattributes InnerClasses
-optimizationpasses 5 -optimizationpasses 5
-verbose -verbose
@@ -23,7 +22,6 @@
-keep class baritone.api.IBaritoneProvider -keep class baritone.api.IBaritoneProvider
-keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect -keep class baritone.api.utils.MyChunkPos { *; } # even in standalone we need to keep this for gson reflect
-keepname class baritone.api.utils.BlockOptionalMeta # this name is exposed to the user, so we need to keep it in all builds
# Keep any class or member annotated with @KeepName so we dont have to put everything in the script # Keep any class or member annotated with @KeepName so we dont have to put everything in the script
-keep,allowobfuscation @interface baritone.KeepName -keep,allowobfuscation @interface baritone.KeepName
@@ -42,10 +40,8 @@
#try to keep usage of schematica in separate classes #try to keep usage of schematica in separate classes
-keep class baritone.utils.schematic.schematica.** -keep class baritone.utils.schematic.schematica.**
-keep class baritone.utils.schematic.litematica.**
#proguard doesnt like it when it cant find our fake schematica classes #proguard doesnt like it when it cant find our fake schematica classes
-dontwarn baritone.utils.schematic.schematica.** -dontwarn baritone.utils.schematic.schematica.**
-dontwarn baritone.utils.schematic.litematica.**
# copy all necessary libraries into tempLibraries to build # copy all necessary libraries into tempLibraries to build
@@ -85,16 +81,16 @@
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar' -libraryjars 'tempLibraries/netty-all-4.1.9.Final.jar'
-libraryjars 'tempLibraries/oshi-core-1.1.jar' -libraryjars 'tempLibraries/oshi-core-1.1.jar'
-libraryjars 'tempLibraries/patchy-1.3.9.jar' -libraryjars 'tempLibraries/patchy-1.2.jar'
-libraryjars 'tempLibraries/platform-3.4.0.jar' -libraryjars 'tempLibraries/platform-3.4.0.jar'
-libraryjars 'tempLibraries/realms-1.10.22.jar' -libraryjars 'tempLibraries/realms-1.10.22.jar'
-libraryjars 'tempLibraries/soundsystem-20120107.jar' -libraryjars 'tempLibraries/soundsystem-20120107.jar'
-libraryjars 'tempLibraries/text2speech-1.10.3.jar' -libraryjars 'tempLibraries/text2speech-1.10.3.jar'
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar' -libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
-libraryjars 'tempLibraries/launchwrapper-1.12.jar' -libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
-libraryjars 'tempLibraries/nether-pathfinder-.jar'
# Keep - Applications. Keep all application classes, along with their 'main' # Keep - Applications. Keep all application classes, along with their 'main'

View File

@@ -35,7 +35,7 @@ public final class BaritoneAPI {
static { static {
settings = new Settings(); settings = new Settings();
SettingsUtil.readAndApply(settings, SettingsUtil.SETTINGS_DEFAULT_NAME); SettingsUtil.readAndApply(settings);
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class); ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator(); Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();

View File

@@ -17,7 +17,6 @@
package baritone.api; package baritone.api;
import baritone.api.behavior.IElytraBehavior;
import baritone.api.behavior.ILookBehavior; import baritone.api.behavior.ILookBehavior;
import baritone.api.behavior.IPathingBehavior; import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IWorldProvider; import baritone.api.cache.IWorldProvider;
@@ -41,12 +40,6 @@ public interface IBaritone {
*/ */
IPathingBehavior getPathingBehavior(); IPathingBehavior getPathingBehavior();
/**
* @return The {@link IElytraBehavior} instance
* @see IElytraBehavior
*/
IElytraBehavior getElytraBehavior();
/** /**
* @return The {@link ILookBehavior} instance * @return The {@link ILookBehavior} instance
* @see ILookBehavior * @see ILookBehavior

View File

@@ -21,9 +21,7 @@ import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommand; import baritone.api.command.ICommand;
import baritone.api.command.ICommandSystem; import baritone.api.command.ICommandSystem;
import baritone.api.schematic.ISchematicSystem; import baritone.api.schematic.ISchematicSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.network.NetHandlerPlayClient;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -54,13 +52,15 @@ public interface IBaritoneProvider {
List<IBaritone> getAllBaritones(); List<IBaritone> getAllBaritones();
/** /**
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. * Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
* replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when
* {@code bot-system} is merged into {@code master}.
* *
* @param player The player * @param player The player
* @return The {@link IBaritone} instance. * @return The {@link IBaritone} instance.
*/ */
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) { default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
for (IBaritone baritone : this.getAllBaritones()) { for (IBaritone baritone : getAllBaritones()) {
if (Objects.equals(player, baritone.getPlayerContext().player())) { if (Objects.equals(player, baritone.getPlayerContext().player())) {
return baritone; return baritone;
} }
@@ -68,55 +68,6 @@ public interface IBaritoneProvider {
return null; return null;
} }
/**
* Provides the {@link IBaritone} instance for a given {@link Minecraft}.
*
* @param minecraft The minecraft
* @return The {@link IBaritone} instance.
*/
default IBaritone getBaritoneForMinecraft(Minecraft minecraft) {
for (IBaritone baritone : this.getAllBaritones()) {
if (Objects.equals(minecraft, baritone.getPlayerContext().minecraft())) {
return baritone;
}
}
return null;
}
/**
* Provides the {@link IBaritone} instance for the player with the specified connection.
*
* @param connection The connection
* @return The {@link IBaritone} instance.
*/
default IBaritone getBaritoneForConnection(NetHandlerPlayClient connection) {
for (IBaritone baritone : this.getAllBaritones()) {
final EntityPlayerSP player = baritone.getPlayerContext().player();
if (player != null && player.connection == connection) {
return baritone;
}
}
return null;
}
/**
* Creates and registers a new {@link IBaritone} instance using the specified {@link Minecraft}. The existing
* instance is returned if already registered.
*
* @param minecraft The minecraft
* @return The {@link IBaritone} instance
*/
IBaritone createBaritone(Minecraft minecraft);
/**
* Destroys and removes the specified {@link IBaritone} instance. If the specified instance is the
* {@link #getPrimaryBaritone() primary baritone}, this operation has no effect and will return {@code false}.
*
* @param baritone The baritone instance to remove
* @return Whether the baritone instance was removed
*/
boolean destroyBaritone(IBaritone baritone);
/** /**
* Returns the {@link IWorldScanner} instance. This is not a type returned by * Returns the {@link IWorldScanner} instance. This is not a type returned by
* {@link IBaritone} implementation, because it is not linked with {@link IBaritone}. * {@link IBaritone} implementation, because it is not linked with {@link IBaritone}.

View File

@@ -29,18 +29,13 @@ import net.minecraft.util.math.Vec3i;
import net.minecraft.util.text.ITextComponent; import net.minecraft.util.text.ITextComponent;
import java.awt.*; import java.awt.*;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field; import java.lang.reflect.Field;
import java.lang.reflect.ParameterizedType; import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
import java.util.function.BiConsumer;
/** /**
* Baritone's settings. Settings apply to all Baritone instances. * Baritone's settings. Settings apply to all Baritone instances.
@@ -54,11 +49,6 @@ public final class Settings {
*/ */
public final Setting<Boolean> allowBreak = new Setting<>(true); public final Setting<Boolean> allowBreak = new Setting<>(true);
/**
* Blocks that baritone will be allowed to break even with allowBreak set to false
*/
public final Setting<List<Block>> allowBreakAnyway = new Setting<>(new ArrayList<>());
/** /**
* Allow Baritone to sprint * Allow Baritone to sprint
*/ */
@@ -74,16 +64,6 @@ public final class Settings {
*/ */
public final Setting<Boolean> allowInventory = new Setting<>(false); public final Setting<Boolean> allowInventory = new Setting<>(false);
/**
* Wait this many ticks between InventoryBehavior moving inventory items
*/
public final Setting<Integer> ticksBetweenInventoryMoves = new Setting<>(1);
/**
* Come to a halt before doing any inventory moves. Intended for anticheat such as 2b2t
*/
public final Setting<Boolean> inventoryMoveOnlyIfStationary = new Setting<>(false);
/** /**
* Disable baritone's auto-tool at runtime, but still assume that another mod will provide auto tool functionality * Disable baritone's auto-tool at runtime, but still assume that another mod will provide auto tool functionality
* <p> * <p>
@@ -122,13 +102,6 @@ public final class Settings {
*/ */
public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D); public final Setting<Double> walkOnWaterOnePenalty = new Setting<>(3D);
/**
* Don't allow breaking blocks next to liquids.
* <p>
* Enable if you have mods adding custom fluid physics.
*/
public final Setting<Boolean> strictLiquidCheck = new Setting<>(false);
/** /**
* Allow Baritone to fall arbitrary distances and place a water bucket beneath it. * Allow Baritone to fall arbitrary distances and place a water bucket beneath it.
* Reliability: questionable. * Reliability: questionable.
@@ -138,8 +111,6 @@ public final class Settings {
/** /**
* Allow Baritone to assume it can walk on still water just like any other block. * Allow Baritone to assume it can walk on still water just like any other block.
* This functionality is assumed to be provided by a separate library that might have imported Baritone. * This functionality is assumed to be provided by a separate library that might have imported Baritone.
* <p>
* Note: This will prevent some usage of the frostwalker enchantment, like pillaring up from water.
*/ */
public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false); public final Setting<Boolean> assumeWalkOnWater = new Setting<>(false);
@@ -219,13 +190,6 @@ public final class Settings {
/** /**
* Blocks that Baritone is not allowed to break * Blocks that Baritone is not allowed to break
*/ */
public final Setting<List<Block>> blocksToDisallowBreaking = new Setting<>(new ArrayList<>(
// Leave Empty by Default
));
/**
* blocks that baritone shouldn't break, but can if it needs to.
*/
public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet? public final Setting<List<Block>> blocksToAvoidBreaking = new Setting<>(new ArrayList<>(Arrays.asList( // TODO can this be a HashSet or ImmutableSet?
Blocks.CRAFTING_TABLE, Blocks.CRAFTING_TABLE,
Blocks.FURNACE, Blocks.FURNACE,
@@ -236,11 +200,6 @@ public final class Settings {
Blocks.WALL_SIGN Blocks.WALL_SIGN
))); )));
/**
* this multiplies the break speed, if set above 1 it's "encourage breaking" instead
*/
public final Setting<Double> avoidBreakingMultiplier = new Setting<>(.1);
/** /**
* A list of blocks to be treated as if they're air. * A list of blocks to be treated as if they're air.
* <p> * <p>
@@ -263,8 +222,6 @@ public final class Settings {
* A mapping of blocks to blocks treated as correct in their position * A mapping of blocks to blocks treated as correct in their position
* <p> * <p>
* If a schematic asks for a block on this mapping, all blocks on the mapped list will be accepted at that location as well * If a schematic asks for a block on this mapping, all blocks on the mapped list will be accepted at that location as well
* <p>
* Syntax same as <a href="https://baritone.leijurv.com/baritone/api/Settings.html#buildSubstitutes">buildSubstitutes</a>
*/ */
public final Setting<Map<Block, List<Block>>> buildValidSubstitutes = new Setting<>(new HashMap<>()); public final Setting<Map<Block, List<Block>>> buildValidSubstitutes = new Setting<>(new HashMap<>());
@@ -272,15 +229,6 @@ public final class Settings {
* A mapping of blocks to blocks to be built instead * A mapping of blocks to blocks to be built instead
* <p> * <p>
* If a schematic asks for a block on this mapping, Baritone will place the first placeable block in the mapped list * If a schematic asks for a block on this mapping, Baritone will place the first placeable block in the mapped list
* <p>
* Usage Syntax:
* <pre>
* sourceblockA->blockToSubstituteA1,blockToSubstituteA2,...blockToSubstituteAN,sourceBlockB->blockToSubstituteB1,blockToSubstituteB2,...blockToSubstituteBN,...sourceBlockX->blockToSubstituteX1,blockToSubstituteX2...blockToSubstituteXN
* </pre>
* Example:
* <pre>
* stone->cobblestone,andesite,oak_planks->birch_planks,acacia_planks,glass
* </pre>
*/ */
public final Setting<Map<Block, List<Block>>> buildSubstitutes = new Setting<>(new HashMap<>()); public final Setting<Map<Block, List<Block>>> buildSubstitutes = new Setting<>(new HashMap<>());
@@ -298,17 +246,6 @@ public final class Settings {
*/ */
public final Setting<Boolean> buildIgnoreExisting = new Setting<>(false); public final Setting<Boolean> buildIgnoreExisting = new Setting<>(false);
/**
* If this is true, the builder will ignore directionality of certain blocks like glazed terracotta.
*/
public final Setting<Boolean> buildIgnoreDirection = new Setting<>(false);
/**
* A list of names of block properties the builder will ignore.
*/
public final Setting<List<String>> buildIgnoreProperties = new Setting<>(new ArrayList<>(Arrays.asList(
)));
/** /**
* If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block. * If this setting is true, Baritone will never break a block that is adjacent to an unsupported falling block.
* <p> * <p>
@@ -431,9 +368,6 @@ public final class Settings {
*/ */
public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0); public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
/**
* Distance to avoid mob spawners.
*/
public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16); public final Setting<Integer> mobSpawnerAvoidanceRadius = new Setting<>(16);
/** /**
@@ -443,9 +377,6 @@ public final class Settings {
*/ */
public final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5); public final Setting<Double> mobAvoidanceCoefficient = new Setting<>(1.5);
/**
* Distance to avoid mobs.
*/
public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8); public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
/** /**
@@ -596,17 +527,6 @@ public final class Settings {
*/ */
public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L); public final Setting<Long> slowPathTimeoutMS = new Setting<>(40000L);
/**
* allows baritone to save bed waypoints when interacting with beds
*/
public final Setting<Boolean> doBedWaypoints = new Setting<>(true);
/**
* allows baritone to save death waypoints
*/
public final Setting<Boolean> doDeathWaypoints = new Setting<>(true);
/** /**
* The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing. * The big one. Download all chunks in simplified 2-bit format and save them for better very-long-distance pathing.
*/ */
@@ -624,11 +544,11 @@ public final class Settings {
public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true); public final Setting<Boolean> pruneRegionsFromRAM = new Setting<>(true);
/** /**
* The chunk packer queue can never grow to larger than this, if it does, the oldest chunks are discarded * Remember the contents of containers (chests, echests, furnaces)
* <p> * <p>
* The newest chunks are kept, so that if you're moving in a straight line quickly then stop, your immediate render distance is still included * Really buggy since the packet stuff is multithreaded badly thanks to brady
*/ */
public final Setting<Integer> chunkPackerQueueMaxSize = new Setting<>(2000); public final Setting<Boolean> containerMemory = new Setting<>(false);
/** /**
* Fill in blocks behind you * Fill in blocks behind you
@@ -731,28 +651,6 @@ public final class Settings {
*/ */
public final Setting<Boolean> freeLook = new Setting<>(true); public final Setting<Boolean> freeLook = new Setting<>(true);
/**
* Break and place blocks without having to force the client-sided rotations. Requires {@link #freeLook}.
*/
public final Setting<Boolean> blockFreeLook = new Setting<>(false);
/**
* Automatically elytra fly without having to force the client-sided rotations. Requires {@link #freeLook}.
*/
public final Setting<Boolean> elytraFreeLook = new Setting<>(false);
/**
* Forces the client-sided rotations to an average of the last 10 ticks of server-sided rotations.
* Requires {@link #freeLook}.
*/
public final Setting<Boolean> smoothLook = new Setting<>(false);
/**
* When true, the player will remain with its existing look direction as often as possible.
* Although, in some cases this can get it stuck, hence this setting to disable that behavior.
*/
public final Setting<Boolean> remainWithExistingLookDirection = new Setting<>(true);
/** /**
* Will cause some minor behavioral differences to ensure that Baritone works on anticheats. * Will cause some minor behavioral differences to ensure that Baritone works on anticheats.
* <p> * <p>
@@ -887,11 +785,6 @@ public final class Settings {
*/ */
public final Setting<Integer> minYLevelWhileMining = new Setting<>(0); public final Setting<Integer> minYLevelWhileMining = new Setting<>(0);
/**
* Sets the maximum y level to mine ores at.
*/
public final Setting<Integer> maxYLevelWhileMining = new Setting<>(255); // 1.17+ defaults to maximum possible world height
/** /**
* This will only allow baritone to mine exposed ores, can be used to stop ore obfuscators on servers that use them. * This will only allow baritone to mine exposed ores, can be used to stop ore obfuscators on servers that use them.
*/ */
@@ -976,7 +869,7 @@ public final class Settings {
/** /**
* Only build the selected part of schematics * Only build the selected part of schematics
*/ */
public final Setting<Boolean> buildOnlySelection = new Setting<>(false); public final Setting<Boolean> buildOnlySelection = new Setting<>(false);
/** /**
* How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely * How far to move before repeating the build. 0 to disable repeating on a certain axis, 0,0,0 to disable entirely
@@ -1188,15 +1081,13 @@ public final class Settings {
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value}; * {@link Setting#value};
*/ */
@JavaOnly public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(msg -> Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg));
/** /**
* The function that is called when Baritone will send a desktop notification. This function can be added to * The function that is called when Baritone will send a desktop notification. This function can be added to
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value}; * {@link Setting#value};
*/ */
@JavaOnly
public final Setting<BiConsumer<String, Boolean>> notifier = new Setting<>(NotificationHelper::notify); public final Setting<BiConsumer<String, Boolean>> notifier = new Setting<>(NotificationHelper::notify);
/** /**
@@ -1204,7 +1095,6 @@ public final class Settings {
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting * via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value}; * {@link Setting#value};
*/ */
@JavaOnly
public final Setting<BiConsumer<ITextComponent, ITextComponent>> toaster = new Setting<>(BaritoneToast::addOrUpdate); public final Setting<BiConsumer<ITextComponent, ITextComponent>> toaster = new Setting<>(BaritoneToast::addOrUpdate);
/** /**
@@ -1332,89 +1222,6 @@ public final class Settings {
*/ */
public final Setting<Boolean> notificationOnMineFail = new Setting<>(true); public final Setting<Boolean> notificationOnMineFail = new Setting<>(true);
/**
* The number of ticks of elytra movement to simulate while firework boost is not active. Higher values are
* computationally more expensive.
*/
public final Setting<Integer> elytraSimulationTicks = new Setting<>(20);
/**
* The maximum allowed deviation in pitch from a direct line-of-sight to the flight target. Higher values are
* computationally more expensive.
*/
public final Setting<Integer> elytraPitchRange = new Setting<>(25);
/**
* The minimum speed that the player can drop to (in blocks/tick) before a firework is automatically deployed.
*/
public final Setting<Double> elytraFireworkSpeed = new Setting<>(0.6);
/**
* The delay after the player's position is set-back by the server that a firework may be automatically deployed.
* Value is in ticks.
*/
public final Setting<Integer> elytraFireworkSetbackUseDelay = new Setting<>(15);
/**
* The minimum padding value that is added to the player's hitbox when considering which point to fly to on the
* path. High values can result in points not being considered which are otherwise safe to fly to. Low values can
* result in flight paths which are extremely tight, and there's the possibility of crashing due to getting too low
* to the ground.
*/
public final Setting<Double> elytraMinimumAvoidance = new Setting<>(0.2);
/**
* If enabled, avoids using fireworks when descending along the flight path.
*/
public final Setting<Boolean> conserveFireworks = new Setting<>(true);
/**
* Renders the raytraces that are performed by the elytra fly calculation.
*/
public final Setting<Boolean> renderRaytraces = new Setting<>(false);
/**
* Renders the raytraces that are used in the hitbox part of the elytra fly calculation.
* Requires {@link #renderRaytraces}.
*/
public final Setting<Boolean> renderHitboxRaytraces = new Setting<>(false);
/**
* Renders the best elytra flight path that was simulated each tick.
*/
public final Setting<Boolean> renderElytraSimulation = new Setting<>(false);
/**
* Automatically path to and jump off of ledges to initiate elytra flight when grounded.
*/
public final Setting<Boolean> elytraAutoJump = new Setting<>(false);
/**
* The seed used to generate chunks for long distance elytra path-finding in the nether.
* Defaults to 2b2t's nether seed.
*/
public final Setting<Long> elytraNetherSeed = new Setting<>(146008555100680L);
/**
* Automatically swap the current elytra with a new one when the durability gets too low
*/
public final Setting<Boolean> elytraAutoSwap = new Setting<>(true);
/**
* The minimum durability an elytra can have before being swapped
*/
public final Setting<Integer> elytraMinimumDurability = new Setting<>(5);
/**
* Time between culling far away chunks from the nether pathfinder chunk cache
*/
public final Setting<Long> elytraTimeBetweenCacheCullSecs = new Setting<>(TimeUnit.MINUTES.toSeconds(3));
/**
* Maximum distance chunks can be before being culled from the nether pathfinder chunk cache
*/
public final Setting<Integer> elytraCacheCullDistance = new Setting<>(5000);
/** /**
* A map of lowercase setting field names to their respective setting * A map of lowercase setting field names to their respective setting
*/ */
@@ -1432,7 +1239,6 @@ public final class Settings {
public T value; public T value;
public final T defaultValue; public final T defaultValue;
private String name; private String name;
private boolean javaOnly;
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
private Setting(T value) { private Setting(T value) {
@@ -1441,7 +1247,6 @@ public final class Settings {
} }
this.value = value; this.value = value;
this.defaultValue = value; this.defaultValue = value;
this.javaOnly = false;
} }
/** /**
@@ -1478,25 +1283,8 @@ public final class Settings {
public final Type getType() { public final Type getType() {
return settingTypes.get(this); return settingTypes.get(this);
} }
/**
* This should always be the same as whether the setting can be parsed from or serialized to a string; in other
* words, the only way to modify it is by writing to {@link #value} programatically.
*
* @return {@code true} if the setting can not be set or read by the user
*/
public boolean isJavaOnly() {
return javaOnly;
}
} }
/**
* Marks a {@link Setting} field as being {@link Setting#isJavaOnly() Java-only}
*/
@Retention(RetentionPolicy.RUNTIME)
@Target(ElementType.FIELD)
private @interface JavaOnly {}
// here be dragons // here be dragons
Settings() { Settings() {
@@ -1512,7 +1300,6 @@ public final class Settings {
Setting<?> setting = (Setting<?>) field.get(this); Setting<?> setting = (Setting<?>) field.get(this);
String name = field.getName(); String name = field.getName();
setting.name = name; setting.name = name;
setting.javaOnly = field.isAnnotationPresent(JavaOnly.class);
name = name.toLowerCase(); name = name.toLowerCase();
if (tmpByName.containsKey(name)) { if (tmpByName.containsKey(name)) {
throw new IllegalStateException("Duplicate setting name"); throw new IllegalStateException("Duplicate setting name");

View File

@@ -27,10 +27,4 @@ import baritone.api.event.listener.IGameEventListener;
* @see IGameEventListener * @see IGameEventListener
* @since 9/23/2018 * @since 9/23/2018
*/ */
public interface IBehavior extends AbstractGameEventListener { public interface IBehavior extends AbstractGameEventListener {}
/**
* Called after Baritone's initialization is complete
*/
default void onLoad() {}
}

View File

@@ -1,54 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.behavior;
import net.minecraft.util.math.BlockPos;
import java.util.concurrent.CompletableFuture;
public interface IElytraBehavior extends IBehavior {
/**
* Marks the nether pathfinder context to be reset when it is safe to do so. Because this operation is not
* immediate, a {@link CompletableFuture} is returned that will complete after the context has been reset.
*
* @return A {@link CompletableFuture} that is completed when the context is reset
*/
CompletableFuture<Void> resetContext();
void repackChunks();
void pathTo(BlockPos destination);
void cancel();
/**
* Returns {@code true} if the current {@link IElytraBehavior} is actively pathing.
*/
boolean isActive();
/**
* @return {@code true} if the native library loaded and elytra is actually usable
*/
boolean isLoaded();
/*
* FOR INTERNAL USE ONLY. MAY BE REMOVED AT ANY TIME.
*/
boolean isSafeToCancel();
}

View File

@@ -17,8 +17,6 @@
package baritone.api.behavior; package baritone.api.behavior;
import baritone.api.Settings;
import baritone.api.behavior.look.IAimProcessor;
import baritone.api.utils.Rotation; import baritone.api.utils.Rotation;
/** /**
@@ -28,23 +26,14 @@ import baritone.api.utils.Rotation;
public interface ILookBehavior extends IBehavior { public interface ILookBehavior extends IBehavior {
/** /**
* Updates the current {@link ILookBehavior} target to target the specified rotations on the next tick. If any sort * Updates the current {@link ILookBehavior} target to target
* of block interaction is required, {@code blockInteract} should be {@code true}. It is not guaranteed that the * the specified rotations on the next tick. If force is {@code true},
* rotations set by the caller will be the exact rotations expressed by the client (This is due to settings like * then freeLook will be overriden and angles will be set regardless.
* {@link Settings#randomLooking}). If the rotations produced by this behavior are required, then the * If any sort of block interaction is required, force should be {@code true},
* {@link #getAimProcessor() aim processor} should be used. * otherwise, it should be {@code false};
* *
* @param rotation The target rotations * @param rotation The target rotations
* @param blockInteract Whether the target rotations are needed for a block interaction * @param force Whether or not to "force" the rotations
*/ */
void updateTarget(Rotation rotation, boolean blockInteract); void updateTarget(Rotation rotation, boolean force);
/**
* The aim processor instance for this {@link ILookBehavior}, which is responsible for applying additional,
* deterministic transformations to the target rotation set by {@link #updateTarget}.
*
* @return The aim processor
* @see IAimProcessor#fork
*/
IAimProcessor getAimProcessor();
} }

View File

@@ -1,45 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.behavior.look;
import baritone.api.utils.Rotation;
/**
* @author Brady
*/
public interface IAimProcessor {
/**
* Returns the actual rotation that will be used when the desired rotation is requested. The returned rotation
* always reflects what would happen in the upcoming tick. In other words, it is a pure function, and no internal
* state changes. If simulation of the rotation states beyond the next tick is required, then a
* {@link IAimProcessor#fork fork} should be created.
*
* @param desired The desired rotation to set
* @return The actual rotation
*/
Rotation peekRotation(Rotation desired);
/**
* Returns a copy of this {@link IAimProcessor} which has its own internal state and is manually tickable.
*
* @return The forked processor
* @see ITickableAimProcessor
*/
ITickableAimProcessor fork();
}

View File

@@ -1,47 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.behavior.look;
import baritone.api.utils.Rotation;
/**
* @author Brady
*/
public interface ITickableAimProcessor extends IAimProcessor {
/**
* Advances the internal state of this aim processor by a single tick.
*/
void tick();
/**
* Calls {@link #tick()} the specified number of times.
*
* @param ticks The number of calls
*/
void advance(int ticks);
/**
* Returns the actual rotation as provided by {@link #peekRotation(Rotation)}, and then automatically advances the
* internal state by one {@link #tick() tick}.
*
* @param rotation The desired rotation to set
* @return The actual rotation
*/
Rotation nextRotation(Rotation rotation);
}

View File

@@ -15,29 +15,30 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
package fi.dy.masa.litematica.schematic.placement; package baritone.api.cache;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable; import java.util.Map;
import java.io.File;
public class SchematicPlacementUnloaded { /**
protected String name = "?"; * @author Brady
@Nullable * @since 9/23/2018
protected File schematicFile; */
protected BlockPos origin = BlockPos.ORIGIN; public interface IContainerMemory {
public String getName() { /**
return this.name; * Gets a remembered inventory by its block position.
} *
* @param pos The position of the container block
* @return The remembered inventory
*/
IRememberedInventory getInventoryByPos(BlockPos pos);
@Nullable /**
public File getSchematicFile() { * Gets the map of all block positions to their remembered inventories.
return this.schematicFile; *
} * @return Map of block positions to their respective remembered inventories
*/
public BlockPos getOrigin() { Map<BlockPos, IRememberedInventory> getRememberedInventories();
return this.origin;
}
} }

View File

@@ -15,13 +15,25 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
package baritone.utils.accessor; package baritone.api.cache;
import net.minecraft.item.ItemStack;
import java.util.List;
/** /**
* @author rycbar * @author Brady
* @since 26.09.2022 * @since 9/23/2018
*/ */
public interface INBTTagLongArray { public interface IRememberedInventory {
long[] getLongArray(); /**
} * @return The contents of this inventory
*/
List<ItemStack> getContents();
/**
* @return The number of slots in this inventory
*/
int getSize();
}

View File

@@ -37,4 +37,9 @@ public interface IWorldData {
*/ */
IWaypointCollection getWaypoints(); IWaypointCollection getWaypoints();
/**
* @return The {@link IContainerMemory} instance
* @see IContainerMemory
*/
IContainerMemory getContainerMemory();
} }

View File

@@ -17,8 +17,6 @@
package baritone.api.cache; package baritone.api.cache;
import java.util.function.Consumer;
/** /**
* @author Brady * @author Brady
* @since 9/24/2018 * @since 9/24/2018
@@ -31,11 +29,4 @@ public interface IWorldProvider {
* @return The current world data * @return The current world data
*/ */
IWorldData getCurrentWorld(); IWorldData getCurrentWorld();
default void ifWorldLoaded(Consumer<IWorldData> callback) {
final IWorldData currentWorld = this.getCurrentWorld();
if (currentWorld != null) {
callback.accept(currentWorld);
}
}
} }

View File

@@ -23,17 +23,11 @@ import net.minecraft.block.Block;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import net.minecraft.util.ResourceLocation; import net.minecraft.util.ResourceLocation;
import java.util.regex.Pattern;
import java.util.stream.Stream; import java.util.stream.Stream;
public enum BlockById implements IDatatypeFor<Block> { public enum BlockById implements IDatatypeFor<Block> {
INSTANCE; INSTANCE;
/**
* Matches (domain:)?name? where domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ respectively.
*/
private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?[a-z0-9/_.-]*");
@Override @Override
public Block get(IDatatypeContext ctx) throws CommandException { public Block get(IDatatypeContext ctx) throws CommandException {
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString()); ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
@@ -46,19 +40,13 @@ public enum BlockById implements IDatatypeFor<Block> {
@Override @Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException { public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
String arg = ctx.getConsumer().getString();
if (!PATTERN.matcher(arg).matches()) {
return Stream.empty();
}
return new TabCompleteHelper() return new TabCompleteHelper()
.append( .append(
Block.REGISTRY.getKeys() Block.REGISTRY.getKeys()
.stream() .stream()
.map(Object::toString) .map(Object::toString)
) )
.filterPrefixNamespaced(arg) .filterPrefixNamespaced(ctx.getConsumer().getString())
.sortAlphabetically() .sortAlphabetically()
.stream(); .stream();
} }

View File

@@ -1,43 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.command.datatypes;
import baritone.api.command.exception.CommandException;
import baritone.api.command.helpers.TabCompleteHelper;
import net.minecraft.util.EnumFacing;
import java.util.Locale;
import java.util.stream.Stream;
public enum ForAxis implements IDatatypeFor<EnumFacing.Axis> {
INSTANCE;
@Override
public EnumFacing.Axis get(IDatatypeContext ctx) throws CommandException {
return EnumFacing.Axis.valueOf(ctx.getConsumer().getString().toUpperCase(Locale.US));
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
return new TabCompleteHelper()
.append(Stream.of(EnumFacing.Axis.values())
.map(EnumFacing.Axis::getName).map(String::toLowerCase))
.filterPrefix(ctx.getConsumer().getString())
.stream();
}
}

View File

@@ -18,136 +18,20 @@
package baritone.api.command.datatypes; package baritone.api.command.datatypes;
import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandException;
import baritone.api.command.helpers.TabCompleteHelper;
import baritone.api.utils.BlockOptionalMeta; import baritone.api.utils.BlockOptionalMeta;
import net.minecraft.block.Block;
import net.minecraft.block.properties.IProperty;
import net.minecraft.util.ResourceLocation;
import java.util.Set;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
public enum ForBlockOptionalMeta implements IDatatypeFor<BlockOptionalMeta> { public enum ForBlockOptionalMeta implements IDatatypeFor<BlockOptionalMeta> {
INSTANCE; INSTANCE;
/**
* Matches (domain:)?name([(property=value)*])? but the input can be truncated at any position.
* domain and name are [a-z0-9_.-]+ and [a-z0-9/_.-]+ because that's what mc 1.13+ accepts.
* property and value use the same format as domain.
*/
// Good luck reading this.
private static Pattern PATTERN = Pattern.compile("(?:[a-z0-9_.-]+:)?(?:[a-z0-9/_.-]+(?:\\[(?:(?:[a-z0-9_.-]+=[a-z0-9_.-]+,)*(?:[a-z0-9_.-]+(?:=(?:[a-z0-9_.-]+(?:\\])?)?)?)?|\\])?)?)?");
@Override @Override
public BlockOptionalMeta get(IDatatypeContext ctx) throws CommandException { public BlockOptionalMeta get(IDatatypeContext ctx) throws CommandException {
return new BlockOptionalMeta(ctx.getConsumer().getString()); return new BlockOptionalMeta(ctx.getConsumer().getString());
} }
@Override @Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException { public Stream<String> tabComplete(IDatatypeContext ctx) {
String arg = ctx.getConsumer().peekString(); return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE);
if (!PATTERN.matcher(arg).matches()) {
// Invalid format; we can't complete this.
ctx.getConsumer().getString();
return Stream.empty();
}
if (arg.endsWith("]")) {
// We are already done.
ctx.getConsumer().getString();
return Stream.empty();
}
if (!arg.contains("[")) {
// no properties so we are completing the block id
return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE);
}
ctx.getConsumer().getString();
// destructuring assignment? Please?
String blockId, properties;
{
String[] parts = splitLast(arg, '[');
blockId = parts[0];
properties = parts[1];
}
Block block = Block.REGISTRY.getObject(new ResourceLocation(blockId));
if (block == null) {
// This block doesn't exist so there's no properties to complete.
return Stream.empty();
}
String leadingProperties, lastProperty;
{
String[] parts = splitLast(properties, ',');
leadingProperties = parts[0];
lastProperty = parts[1];
}
if (!lastProperty.contains("=")) {
// The last property-value pair doesn't have a value yet so we are completing its name
Set<String> usedProps = Stream.of(leadingProperties.split(","))
.map(pair -> pair.split("=")[0])
.collect(Collectors.toSet());
String prefix = arg.substring(0, arg.length() - lastProperty.length());
return new TabCompleteHelper()
.append(
block.getBlockState()
.getProperties()
.stream()
.map(IProperty::getName)
)
.filter(prop -> !usedProps.contains(prop))
.filterPrefix(lastProperty)
.sortAlphabetically()
.map(prop -> prefix + prop)
.stream();
}
String lastName, lastValue;
{
String[] parts = splitLast(lastProperty, '=');
lastName = parts[0];
lastValue = parts[1];
}
// We are completing the value of a property
String prefix = arg.substring(0, arg.length() - lastValue.length());
IProperty<?> property = block.getBlockState().getProperty(lastName);
if (property == null) {
// The property does not exist so there's no values to complete
return Stream.empty();
}
return new TabCompleteHelper()
.append(getValues(property))
.filterPrefix(lastValue)
.sortAlphabetically()
.map(val -> prefix + val)
.stream();
}
/**
* Always returns exactly two strings.
* If the separator is not found the FIRST returned string is empty.
*/
private static String[] splitLast(String string, char chr) {
int idx = string.lastIndexOf(chr);
if (idx == -1) {
return new String[]{"", string};
}
return new String[]{string.substring(0, idx), string.substring(idx + 1)};
}
// this shouldn't need to be a separate method?
private static <T extends Comparable<T>> Stream<String> getValues(IProperty<T> property) {
return property.getAllowedValues().stream().map(property::getName);
} }
} }

View File

@@ -26,8 +26,7 @@ import java.util.stream.Stream;
public enum RelativeCoordinate implements IDatatypePost<Double, Double> { public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
INSTANCE; INSTANCE;
private static String ScalesAliasRegex = "[kKmM]"; private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)([k-k]?)|)$");
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(" + ScalesAliasRegex + "?)|)$");
@Override @Override
public Double apply(IDatatypeContext ctx, Double origin) throws CommandException { public Double apply(IDatatypeContext ctx, Double origin) throws CommandException {
@@ -42,15 +41,11 @@ public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
boolean isRelative = !matcher.group(1).isEmpty(); boolean isRelative = !matcher.group(1).isEmpty();
double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll(ScalesAliasRegex, "")); double offset = matcher.group(2).isEmpty() ? 0 : Double.parseDouble(matcher.group(2).replaceAll("k", ""));
if (matcher.group(2).toLowerCase().contains("k")) { if (matcher.group(2).contains("k")) {
offset *= 1000; offset *= 1000;
} }
if (matcher.group(2).toLowerCase().contains("m")) {
offset *= 1000000;
}
if (isRelative) { if (isRelative) {
return origin + offset; return origin + offset;

View File

@@ -19,8 +19,6 @@ package baritone.api.command.datatypes;
import baritone.api.command.argument.IArgConsumer; import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException; import baritone.api.command.exception.CommandException;
import baritone.api.utils.Helper;
import net.minecraft.client.Minecraft;
import java.io.File; import java.io.File;
import java.io.IOException; import java.io.IOException;
@@ -85,23 +83,18 @@ public enum RelativeFile implements IDatatypePost<File, File> {
boolean useParent = !currentPathStringThing.isEmpty() && !currentPathStringThing.endsWith(File.separator); boolean useParent = !currentPathStringThing.isEmpty() && !currentPathStringThing.endsWith(File.separator);
File currentFile = currentPath.isAbsolute() ? currentPath.toFile() : new File(base, currentPathStringThing); File currentFile = currentPath.isAbsolute() ? currentPath.toFile() : new File(base, currentPathStringThing);
return Stream.of(Objects.requireNonNull(getCanonicalFileUnchecked( return Stream.of(Objects.requireNonNull(getCanonicalFileUnchecked(
useParent useParent
? currentFile.getParentFile() ? currentFile.getParentFile()
: currentFile : currentFile
).listFiles())) ).listFiles()))
.map(f -> (currentPath.isAbsolute() ? f : basePath.relativize(f.toPath()).toString()) + .map(f -> (currentPath.isAbsolute() ? f : basePath.relativize(f.toPath()).toString()) +
(f.isDirectory() ? File.separator : "")) (f.isDirectory() ? File.separator : ""))
.filter(s -> s.toLowerCase(Locale.US).startsWith(currentPathStringThing.toLowerCase(Locale.US))) .filter(s -> s.toLowerCase(Locale.US).startsWith(currentPathStringThing.toLowerCase(Locale.US)))
.filter(s -> !s.contains(" ")); .filter(s -> !s.contains(" "));
} }
@Deprecated
public static File gameDir() { public static File gameDir() {
return gameDir(Helper.mc); File gameDir = HELPER.mc.gameDir.getAbsoluteFile();
}
public static File gameDir(Minecraft mc) {
File gameDir = mc.gameDir.getAbsoluteFile();
if (gameDir.getName().equals(".")) { if (gameDir.getName().equals(".")) {
return gameDir.getParentFile(); return gameDir.getParentFile();
} }

View File

@@ -19,6 +19,7 @@ package baritone.api.command.exception;
import baritone.api.command.ICommand; import baritone.api.command.ICommand;
import baritone.api.command.argument.ICommandArgument; import baritone.api.command.argument.ICommandArgument;
import net.minecraft.util.text.TextFormatting;
import java.util.List; import java.util.List;
@@ -36,6 +37,10 @@ public class CommandUnhandledException extends RuntimeException implements IComm
@Override @Override
public void handle(ICommand command, List<ICommandArgument> args) { public void handle(ICommand command, List<ICommandArgument> args) {
HELPER.logUnhandledException(this); HELPER.logDirect("An unhandled exception occurred. " +
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
TextFormatting.RED);
this.printStackTrace();
} }
} }

View File

@@ -253,7 +253,7 @@ public class TabCompleteHelper {
public TabCompleteHelper addSettings() { public TabCompleteHelper addSettings() {
return append( return append(
BaritoneAPI.getSettings().allSettings.stream() BaritoneAPI.getSettings().allSettings.stream()
.filter(s -> !s.isJavaOnly()) .filter(s -> !SettingsUtil.javaOnlySetting(s))
.map(Settings.Setting::getName) .map(Settings.Setting::getName)
.sorted(String.CASE_INSENSITIVE_ORDER) .sorted(String.CASE_INSENSITIVE_ORDER)
); );

View File

@@ -84,7 +84,7 @@ public class Registry<V> {
* @param entry The entry to unregister. * @param entry The entry to unregister.
*/ */
public void unregister(V entry) { public void unregister(V entry) {
if (!registered(entry)) { if (registered(entry)) {
return; return;
} }
_entries.remove(entry); _entries.remove(entry);

View File

@@ -1,49 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.event.events;
import baritone.api.utils.Pair;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Brady
*/
public final class BlockChangeEvent {
private final ChunkPos chunk;
private final List<Pair<BlockPos, IBlockState>> blocks;
public BlockChangeEvent(ChunkPos pos, List<Pair<BlockPos, IBlockState>> blocks) {
this.chunk = pos;
this.blocks = blocks;
}
public ChunkPos getChunkPos() {
return this.chunk;
}
public List<Pair<BlockPos, IBlockState>> getBlocks() {
return this.blocks;
}
}

View File

@@ -57,38 +57,31 @@ public final class ChunkEvent {
/** /**
* @return The state of the event * @return The state of the event
*/ */
public EventState getState() { public final EventState getState() {
return this.state; return this.state;
} }
/** /**
* @return The type of chunk event that occurred; * @return The type of chunk event that occurred;
*/ */
public Type getType() { public final Type getType() {
return this.type; return this.type;
} }
/** /**
* @return The Chunk X position. * @return The Chunk X position.
*/ */
public int getX() { public final int getX() {
return this.x; return this.x;
} }
/** /**
* @return The Chunk Z position. * @return The Chunk Z position.
*/ */
public int getZ() { public final int getZ() {
return this.z; return this.z;
} }
/**
* @return {@code true} if the event was fired after a chunk population
*/
public boolean isPostPopulate() {
return this.state == EventState.POST && this.type.isPopulate();
}
public enum Type { public enum Type {
/** /**
@@ -113,10 +106,6 @@ public final class ChunkEvent {
* <p> * <p>
* And it's a partial chunk * And it's a partial chunk
*/ */
POPULATE_PARTIAL; POPULATE_PARTIAL
public final boolean isPopulate() {
return this == POPULATE_FULL || this == POPULATE_PARTIAL;
}
} }
} }

View File

@@ -17,7 +17,6 @@
package baritone.api.event.events; package baritone.api.event.events;
import baritone.api.utils.Rotation;
import net.minecraft.entity.Entity; import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
@@ -32,27 +31,14 @@ public final class RotationMoveEvent {
*/ */
private final Type type; private final Type type;
private final Rotation original;
/** /**
* The yaw rotation * The yaw rotation
*/ */
private float yaw; private float yaw;
/** public RotationMoveEvent(Type type, float yaw) {
* The pitch rotation
*/
private float pitch;
public RotationMoveEvent(Type type, float yaw, float pitch) {
this.type = type; this.type = type;
this.original = new Rotation(yaw, pitch);
this.yaw = yaw; this.yaw = yaw;
this.pitch = pitch;
}
public Rotation getOriginal() {
return this.original;
} }
/** /**
@@ -60,37 +46,21 @@ public final class RotationMoveEvent {
* *
* @param yaw Yaw rotation * @param yaw Yaw rotation
*/ */
public void setYaw(float yaw) { public final void setYaw(float yaw) {
this.yaw = yaw; this.yaw = yaw;
} }
/** /**
* @return The yaw rotation * @return The yaw rotation
*/ */
public float getYaw() { public final float getYaw() {
return this.yaw; return this.yaw;
} }
/**
* Set the pitch movement rotation
*
* @param pitch Pitch rotation
*/
public void setPitch(float pitch) {
this.pitch = pitch;
}
/**
* @return The pitch rotation
*/
public float getPitch() {
return pitch;
}
/** /**
* @return The type of the event * @return The type of the event
*/ */
public Type getType() { public final Type getType() {
return this.type; return this.type;
} }

View File

@@ -18,18 +18,9 @@
package baritone.api.event.events; package baritone.api.event.events;
import baritone.api.event.events.type.EventState; import baritone.api.event.events.type.EventState;
import net.minecraft.client.Minecraft;
import java.util.function.BiFunction; import java.util.function.BiFunction;
/**
* Called on and after each game tick of the primary {@link Minecraft} instance and dispatched to all Baritone
* instances.
* <p>
* When {@link #state} is {@link EventState#PRE}, the event is being called just prior to when the current in-game
* screen is ticked. When {@link #state} is {@link EventState#POST}, the event is being called at the very end
* of the {@link Minecraft#runTick()} method.
*/
public final class TickEvent { public final class TickEvent {
private static int overallTickCount; private static int overallTickCount;

View File

@@ -33,9 +33,6 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override @Override
default void onTick(TickEvent event) {} default void onTick(TickEvent event) {}
@Override
default void onPostTick(TickEvent event) {}
@Override @Override
default void onPlayerUpdate(PlayerUpdateEvent event) {} default void onPlayerUpdate(PlayerUpdateEvent event) {}
@@ -48,9 +45,6 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override @Override
default void onChunkEvent(ChunkEvent event) {} default void onChunkEvent(ChunkEvent event) {}
@Override
default void onBlockChange(BlockChangeEvent event) {}
@Override @Override
default void onRenderPass(RenderEvent event) {} default void onRenderPass(RenderEvent event) {}

View File

@@ -41,14 +41,6 @@ public interface IGameEventListener {
*/ */
void onTick(TickEvent event); void onTick(TickEvent event);
/**
* Run once per game tick after the tick is completed
*
* @param event The event
* @see Minecraft#runTick()
*/
void onPostTick(TickEvent event);
/** /**
* Run once per game tick from before and after the player rotation is sent to the server. * Run once per game tick from before and after the player rotation is sent to the server.
* *
@@ -80,13 +72,6 @@ public interface IGameEventListener {
*/ */
void onChunkEvent(ChunkEvent event); void onChunkEvent(ChunkEvent event);
/**
* Runs after a single or multi block change packet is received and processed.
*
* @param event The event
*/
void onBlockChange(BlockChangeEvent event);
/** /**
* Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on. * Runs once per world render pass. Two passes are made when {@link GameSettings#anaglyph} is on.
* <p> * <p>

View File

@@ -42,16 +42,6 @@ public class GoalAxis implements Goal {
return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y); return flatAxisDistance * BaritoneAPI.getSettings().costHeuristic.value + GoalYLevel.calculate(BaritoneAPI.getSettings().axisHeight.value, y);
} }
@Override
public boolean equals(Object o) {
return o.getClass() == GoalAxis.class;
}
@Override
public int hashCode() {
return 201385781;
}
@Override @Override
public String toString() { public String toString() {
return "GoalAxis"; return "GoalAxis";

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals; package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -67,26 +66,6 @@ public class GoalBlock implements Goal, IGoalRenderPos {
return calculate(xDiff, yDiff, zDiff); return calculate(xDiff, yDiff, zDiff);
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalBlock goal = (GoalBlock) o;
return x == goal.x
&& y == goal.y
&& z == goal.z;
}
@Override
public int hashCode() {
return (int) BetterBlockPos.longHash(x, y, z) * 905165533;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(
@@ -108,9 +87,9 @@ public class GoalBlock implements Goal, IGoalRenderPos {
public static double calculate(double xDiff, int yDiff, double zDiff) { public static double calculate(double xDiff, int yDiff, double zDiff) {
double heuristic = 0; double heuristic = 0;
// if yDiff is 1 that means that currentY-goalY==1 which means that we're 1 block above where we should be // if yDiff is 1 that means that pos.getY()-this.y==1 which means that we're 1 block below where we should be
// therefore going from 0,yDiff,0 to a GoalYLevel of 0 is accurate // therefore going from 0,0,0 to a GoalYLevel of pos.getY()-this.y is accurate
heuristic += GoalYLevel.calculate(0, yDiff); heuristic += GoalYLevel.calculate(yDiff, 0);
//use the pythagorean and manhattan mixture from GoalXZ //use the pythagorean and manhattan mixture from GoalXZ
heuristic += GoalXZ.calculate(xDiff, zDiff); heuristic += GoalXZ.calculate(xDiff, zDiff);

View File

@@ -67,24 +67,6 @@ public class GoalComposite implements Goal {
return min; return min;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalComposite goal = (GoalComposite) o;
return Arrays.equals(goals, goal.goals);
}
@Override
public int hashCode() {
return Arrays.hashCode(goals);
}
@Override @Override
public String toString() { public String toString() {
return "GoalComposite" + Arrays.toString(goals); return "GoalComposite" + Arrays.toString(goals);

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals; package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -61,26 +60,6 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff); return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalGetToBlock goal = (GoalGetToBlock) o;
return x == goal.x
&& y == goal.y
&& z == goal.z;
}
@Override
public int hashCode() {
return (int) BetterBlockPos.longHash(x, y, z) * -49639096;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(

View File

@@ -17,8 +17,6 @@
package baritone.api.pathing.goals; package baritone.api.pathing.goals;
import java.util.Objects;
/** /**
* Invert any goal. * Invert any goal.
* <p> * <p>
@@ -52,24 +50,6 @@ public class GoalInverted implements Goal {
return Double.NEGATIVE_INFINITY; return Double.NEGATIVE_INFINITY;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalInverted goal = (GoalInverted) o;
return Objects.equals(origin, goal.origin);
}
@Override
public int hashCode() {
return origin.hashCode() * 495796690;
}
@Override @Override
public String toString() { public String toString() {
return String.format("GoalInverted{%s}", origin.toString()); return String.format("GoalInverted{%s}", origin.toString());

View File

@@ -17,11 +17,10 @@
package baritone.api.pathing.goals; package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.api.utils.interfaces.IGoalRenderPos;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet; import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
public class GoalNear implements Goal, IGoalRenderPos { public class GoalNear implements Goal, IGoalRenderPos {
@@ -87,27 +86,6 @@ public class GoalNear implements Goal, IGoalRenderPos {
return new BlockPos(x, y, z); return new BlockPos(x, y, z);
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalNear goal = (GoalNear) o;
return x == goal.x
&& y == goal.y
&& z == goal.z
&& rangeSq == goal.rangeSq;
}
@Override
public int hashCode() {
return (int) BetterBlockPos.longHash(x, y, z) + rangeSq;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(

View File

@@ -18,12 +18,11 @@
package baritone.api.pathing.goals; package baritone.api.pathing.goals;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet; import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
import it.unimi.dsi.fastutil.doubles.DoubleIterator;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import java.util.Arrays; import java.util.Arrays;
import java.util.Objects;
/** /**
* Useful for automated combat (retreating specifically) * Useful for automated combat (retreating specifically)
@@ -125,29 +124,6 @@ public class GoalRunAway implements Goal {
return maxInside; return maxInside;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalRunAway goal = (GoalRunAway) o;
return distanceSq == goal.distanceSq
&& Arrays.equals(from, goal.from)
&& Objects.equals(maintainY, goal.maintainY);
}
@Override
public int hashCode() {
int hash = Arrays.hashCode(from);
hash = hash * 1196803141 + distanceSq;
hash = hash * -2053788840 + maintainY;
return hash;
}
@Override @Override
public String toString() { public String toString() {
if (maintainY != null) { if (maintainY != null) {

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals; package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -70,31 +69,6 @@ public class GoalStrictDirection implements Goal {
return Double.NEGATIVE_INFINITY; return Double.NEGATIVE_INFINITY;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalStrictDirection goal = (GoalStrictDirection) o;
return x == goal.x
&& y == goal.y
&& z == goal.z
&& dx == goal.dx
&& dz == goal.dz;
}
@Override
public int hashCode() {
int hash = (int) BetterBlockPos.longHash(x, y, z);
hash = hash * 630627507 + dx;
hash = hash * -283028380 + dz;
return hash;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals; package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil; import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos; import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
@@ -73,26 +72,6 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
return new BlockPos(x, y, z); return new BlockPos(x, y, z);
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalTwoBlocks goal = (GoalTwoBlocks) o;
return x == goal.x
&& y == goal.y
&& z == goal.z;
}
@Override
public int hashCode() {
return (int) BetterBlockPos.longHash(x, y, z) * 516508351;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(

View File

@@ -64,27 +64,6 @@ public class GoalXZ implements Goal {
return calculate(xDiff, zDiff); return calculate(xDiff, zDiff);
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalXZ goal = (GoalXZ) o;
return x == goal.x && z == goal.z;
}
@Override
public int hashCode() {
int hash = 1791873246;
hash = hash * 222601791 + x;
hash = hash * -1331679453 + z;
return hash;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(

View File

@@ -58,24 +58,6 @@ public class GoalYLevel implements Goal, ActionCosts {
return 0; return 0;
} }
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
GoalYLevel goal = (GoalYLevel) o;
return level == goal.level;
}
@Override
public int hashCode() {
return level * 1271009915;
}
@Override @Override
public String toString() { public String toString() {
return String.format( return String.format(

View File

@@ -51,7 +51,6 @@ public interface IBuilderProcess extends IBaritoneProcess {
*/ */
boolean build(String name, File schematic, Vec3i origin); boolean build(String name, File schematic, Vec3i origin);
@Deprecated
default boolean build(String schematicFile, BlockPos origin) { default boolean build(String schematicFile, BlockPos origin) {
File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile); File file = new File(new File(Minecraft.getMinecraft().gameDir, "schematics"), schematicFile);
return build(schematicFile, file, origin); return build(schematicFile, file, origin);
@@ -59,8 +58,6 @@ public interface IBuilderProcess extends IBaritoneProcess {
void buildOpenSchematic(); void buildOpenSchematic();
void buildOpenLitematic(int i);
void pause(); void pause();
boolean isPaused(); boolean isPaused();

View File

@@ -38,11 +38,6 @@ public interface ICustomGoalProcess extends IBaritoneProcess {
*/ */
Goal getGoal(); Goal getGoal();
/**
* @return The most recent set goal, which doesn't invalidate upon {@link #onLostControl()}
*/
Goal mostRecentGoal();
/** /**
* Sets the goal and begins the path execution. * Sets the goal and begins the path execution.
* *

View File

@@ -56,10 +56,5 @@ public enum PathingCommandType {
/** /**
* Go and ask the next process what to do * Go and ask the next process what to do
*/ */
DEFER, DEFER
/**
* Sets the goal and calculates a path, but pauses instead of immediately starting the path.
*/
SET_GOAL_AND_PAUSE
} }

View File

@@ -17,7 +17,6 @@
package baritone.api.schematic; package baritone.api.schematic;
import baritone.api.schematic.mask.Mask;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import java.util.List; import java.util.List;
@@ -42,14 +41,4 @@ public abstract class MaskSchematic extends AbstractSchematic {
public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) { public IBlockState desiredState(int x, int y, int z, IBlockState current, List<IBlockState> approxPlaceable) {
return schematic.desiredState(x, y, z, current, approxPlaceable); return schematic.desiredState(x, y, z, current, approxPlaceable);
} }
public static MaskSchematic create(ISchematic schematic, Mask function) {
return new MaskSchematic(schematic) {
@Override
protected boolean partOfMask(int x, int y, int z, IBlockState currentState) {
return function.partOfMask(x, y, z, currentState);
}
};
}
} }

View File

@@ -22,7 +22,6 @@ import net.minecraft.block.BlockAir;
import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks; import net.minecraft.init.Blocks;
import java.util.Collection; import java.util.Collection;
import java.util.HashMap; import java.util.HashMap;
import java.util.List; import java.util.List;
@@ -34,7 +33,7 @@ public class SubstituteSchematic extends AbstractSchematic {
private final Map<Block, List<Block>> substitutions; private final Map<Block, List<Block>> substitutions;
private final Map<IBlockState, Map<Block, IBlockState>> blockStateCache = new HashMap<>(); private final Map<IBlockState, Map<Block, IBlockState>> blockStateCache = new HashMap<>();
public SubstituteSchematic(ISchematic schematic, Map<Block, List<Block>> substitutions) { public SubstituteSchematic(ISchematic schematic, Map<Block,List<Block>> substitutions) {
super(schematic.widthX(), schematic.heightY(), schematic.lengthZ()); super(schematic.widthX(), schematic.heightY(), schematic.lengthZ());
this.schematic = schematic; this.schematic = schematic;
this.substitutions = substitutions; this.substitutions = substitutions;
@@ -81,10 +80,9 @@ public class SubstituteSchematic extends AbstractSchematic {
} catch (IllegalArgumentException e) { //property does not exist for target block } catch (IllegalArgumentException e) { //property does not exist for target block
} }
} }
blockStateCache.computeIfAbsent(state, s -> new HashMap<Block, IBlockState>()).put(block, newState); blockStateCache.computeIfAbsent(state, s -> new HashMap<Block,IBlockState>()).put(block, newState);
return newState; return newState;
} }
private <T extends Comparable<T>> IBlockState copySingleProp(IBlockState fromState, IBlockState toState, IProperty<T> prop) { private <T extends Comparable<T>> IBlockState copySingleProp(IBlockState fromState, IBlockState toState, IProperty<T> prop) {
return toState.withProperty(prop, fromState.getValue(prop)); return toState.withProperty(prop, fromState.getValue(prop));
} }

View File

@@ -1,49 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.mask;
/**
* @author Brady
*/
public abstract class AbstractMask implements Mask {
private final int widthX;
private final int heightY;
private final int lengthZ;
public AbstractMask(int widthX, int heightY, int lengthZ) {
this.widthX = widthX;
this.heightY = heightY;
this.lengthZ = lengthZ;
}
@Override
public int widthX() {
return this.widthX;
}
@Override
public int heightY() {
return this.heightY;
}
@Override
public int lengthZ() {
return this.lengthZ;
}
}

View File

@@ -1,60 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.mask;
import baritone.api.schematic.mask.operator.BinaryOperatorMask;
import baritone.api.schematic.mask.operator.NotMask;
import baritone.api.utils.BooleanBinaryOperators;
import net.minecraft.block.state.IBlockState;
/**
* @author Brady
*/
public interface Mask {
/**
* @param x The relative x position of the block
* @param y The relative y position of the block
* @param z The relative z position of the block
* @param currentState The current state of that block in the world, may be {@code null}
* @return Whether the given position is included in this mask
*/
boolean partOfMask(int x, int y, int z, IBlockState currentState);
int widthX();
int heightY();
int lengthZ();
default Mask not() {
return new NotMask(this);
}
default Mask union(Mask other) {
return new BinaryOperatorMask(this, other, BooleanBinaryOperators.OR);
}
default Mask intersection(Mask other) {
return new BinaryOperatorMask(this, other, BooleanBinaryOperators.AND);
}
default Mask xor(Mask other) {
return new BinaryOperatorMask(this, other, BooleanBinaryOperators.XOR);
}
}

View File

@@ -1,82 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.mask;
import baritone.api.schematic.mask.operator.BinaryOperatorMask;
import baritone.api.schematic.mask.operator.NotMask;
import baritone.api.utils.BooleanBinaryOperators;
import net.minecraft.block.state.IBlockState;
/**
* A mask that is context-free. In other words, it doesn't require the current block state to determine if a relative
* position is a part of the mask.
*
* @author Brady
*/
public interface StaticMask extends Mask {
/**
* Determines if a given relative coordinate is included in this mask, without the need for the current block state.
*
* @param x The relative x position of the block
* @param y The relative y position of the block
* @param z The relative z position of the block
* @return Whether the given position is included in this mask
*/
boolean partOfMask(int x, int y, int z);
/**
* Implements the parent {@link Mask#partOfMask partOfMask function} by calling the static function
* provided in this functional interface without needing the {@link IBlockState} argument. This {@code default}
* implementation should <b><u>NOT</u></b> be overriden.
*
* @param x The relative x position of the block
* @param y The relative y position of the block
* @param z The relative z position of the block
* @param currentState The current state of that block in the world, may be {@code null}
* @return Whether the given position is included in this mask
*/
@Override
default boolean partOfMask(int x, int y, int z, IBlockState currentState) {
return this.partOfMask(x, y, z);
}
@Override
default StaticMask not() {
return new NotMask.Static(this);
}
default StaticMask union(StaticMask other) {
return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.OR);
}
default StaticMask intersection(StaticMask other) {
return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.AND);
}
default StaticMask xor(StaticMask other) {
return new BinaryOperatorMask.Static(this, other, BooleanBinaryOperators.XOR);
}
/**
* Returns a pre-computed mask using {@code this} function, with the specified size parameters.
*/
default StaticMask compute() {
return new PreComputedMask(this);
}
}

View File

@@ -1,79 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.mask.operator;
import baritone.api.schematic.mask.AbstractMask;
import baritone.api.schematic.mask.Mask;
import baritone.api.schematic.mask.StaticMask;
import baritone.api.utils.BooleanBinaryOperator;
import net.minecraft.block.state.IBlockState;
/**
* @author Brady
*/
public final class BinaryOperatorMask extends AbstractMask {
private final Mask a;
private final Mask b;
private final BooleanBinaryOperator operator;
public BinaryOperatorMask(Mask a, Mask b, BooleanBinaryOperator operator) {
super(Math.max(a.widthX(), b.widthX()), Math.max(a.heightY(), b.heightY()), Math.max(a.lengthZ(), b.lengthZ()));
this.a = a;
this.b = b;
this.operator = operator;
}
@Override
public boolean partOfMask(int x, int y, int z, IBlockState currentState) {
return this.operator.applyAsBoolean(
partOfMask(a, x, y, z, currentState),
partOfMask(b, x, y, z, currentState)
);
}
private static boolean partOfMask(Mask mask, int x, int y, int z, IBlockState currentState) {
return x < mask.widthX() && y < mask.heightY() && z < mask.lengthZ() && mask.partOfMask(x, y, z, currentState);
}
public static final class Static extends AbstractMask implements StaticMask {
private final StaticMask a;
private final StaticMask b;
private final BooleanBinaryOperator operator;
public Static(StaticMask a, StaticMask b, BooleanBinaryOperator operator) {
super(Math.max(a.widthX(), b.widthX()), Math.max(a.heightY(), b.heightY()), Math.max(a.lengthZ(), b.lengthZ()));
this.a = a;
this.b = b;
this.operator = operator;
}
@Override
public boolean partOfMask(int x, int y, int z) {
return this.operator.applyAsBoolean(
partOfMask(a, x, y, z),
partOfMask(b, x, y, z)
);
}
private static boolean partOfMask(StaticMask mask, int x, int y, int z) {
return x < mask.widthX() && y < mask.heightY() && z < mask.lengthZ() && mask.partOfMask(x, y, z);
}
}
}

View File

@@ -1,56 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.mask.operator;
import baritone.api.schematic.mask.AbstractMask;
import baritone.api.schematic.mask.Mask;
import baritone.api.schematic.mask.StaticMask;
import net.minecraft.block.state.IBlockState;
/**
* @author Brady
*/
public final class NotMask extends AbstractMask {
private final Mask source;
public NotMask(Mask source) {
super(source.widthX(), source.heightY(), source.lengthZ());
this.source = source;
}
@Override
public boolean partOfMask(int x, int y, int z, IBlockState currentState) {
return !this.source.partOfMask(x, y, z, currentState);
}
public static final class Static extends AbstractMask implements StaticMask {
private final StaticMask source;
public Static(StaticMask source) {
super(source.widthX(), source.heightY(), source.lengthZ());
this.source = source;
}
@Override
public boolean partOfMask(int x, int y, int z) {
return !this.source.partOfMask(x, y, z);
}
}
}

View File

@@ -1,69 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.mask.shape;
import baritone.api.schematic.mask.AbstractMask;
import baritone.api.schematic.mask.StaticMask;
import net.minecraft.util.EnumFacing;
/**
* @author Brady
*/
public final class CylinderMask extends AbstractMask implements StaticMask {
private final double centerA;
private final double centerB;
private final double radiusSqA;
private final double radiusSqB;
private final boolean filled;
private final EnumFacing.Axis alignment;
public CylinderMask(int widthX, int heightY, int lengthZ, boolean filled, EnumFacing.Axis alignment) {
super(widthX, heightY, lengthZ);
this.centerA = this.getA(widthX, heightY, alignment) / 2.0;
this.centerB = this.getB(heightY, lengthZ, alignment) / 2.0;
this.radiusSqA = (this.centerA - 1) * (this.centerA - 1);
this.radiusSqB = (this.centerB - 1) * (this.centerB - 1);
this.filled = filled;
this.alignment = alignment;
}
@Override
public boolean partOfMask(int x, int y, int z) {
double da = Math.abs((this.getA(x, y, this.alignment) + 0.5) - this.centerA);
double db = Math.abs((this.getB(y, z, this.alignment) + 0.5) - this.centerB);
if (this.outside(da, db)) {
return false;
}
return this.filled
|| this.outside(da + 1, db)
|| this.outside(da, db + 1);
}
private boolean outside(double da, double db) {
return da * da / this.radiusSqA + db * db / this.radiusSqB > 1;
}
private static int getA(int x, int y, EnumFacing.Axis alignment) {
return alignment == EnumFacing.Axis.X ? y : x;
}
private static int getB(int y, int z, EnumFacing.Axis alignment) {
return alignment == EnumFacing.Axis.Z ? y : z;
}
}

View File

@@ -1,64 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.schematic.mask.shape;
import baritone.api.schematic.mask.AbstractMask;
import baritone.api.schematic.mask.StaticMask;
/**
* @author Brady
*/
public final class SphereMask extends AbstractMask implements StaticMask {
private final double centerX;
private final double centerY;
private final double centerZ;
private final double radiusSqX;
private final double radiusSqY;
private final double radiusSqZ;
private final boolean filled;
public SphereMask(int widthX, int heightY, int lengthZ, boolean filled) {
super(widthX, heightY, lengthZ);
this.centerX = widthX / 2.0;
this.centerY = heightY / 2.0;
this.centerZ = lengthZ / 2.0;
this.radiusSqX = this.centerX * this.centerX;
this.radiusSqY = this.centerY * this.centerY;
this.radiusSqZ = this.centerZ * this.centerZ;
this.filled = filled;
}
@Override
public boolean partOfMask(int x, int y, int z) {
double dx = Math.abs((x + 0.5) - this.centerX);
double dy = Math.abs((y + 0.5) - this.centerY);
double dz = Math.abs((z + 0.5) - this.centerZ);
if (this.outside(dx, dy, dz)) {
return false;
}
return this.filled
|| this.outside(dx + 1, dy, dz)
|| this.outside(dx, dy + 1, dz)
|| this.outside(dx, dy, dz + 1);
}
private boolean outside(double dx, double dy, double dz) {
return dx * dx / this.radiusSqX + dy * dy / this.radiusSqY + dz * dz / this.radiusSqZ > 1;
}
}

View File

@@ -17,6 +17,7 @@
package baritone.api.utils; package baritone.api.utils;
import it.unimi.dsi.fastutil.HashCommon;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
@@ -35,15 +36,6 @@ import javax.annotation.Nonnull;
*/ */
public final class BetterBlockPos extends BlockPos { public final class BetterBlockPos extends BlockPos {
private static final int NUM_X_BITS = 26;
private static final int NUM_Z_BITS = NUM_X_BITS;
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
private static final int Y_SHIFT = NUM_Z_BITS;
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
public static final BetterBlockPos ORIGIN = new BetterBlockPos(0, 0, 0); public static final BetterBlockPos ORIGIN = new BetterBlockPos(0, 0, 0);
public final int x; public final int x;
@@ -88,25 +80,98 @@ public final class BetterBlockPos extends BlockPos {
return longHash(pos.x, pos.y, pos.z); return longHash(pos.x, pos.y, pos.z);
} }
public static final int NUM_X_BITS = 26;
public static final int NUM_Z_BITS = NUM_X_BITS;
public static final int NUM_Y_BITS = 9; // note: even though Y goes from 0 to 255, that doesn't mean 8 bits will "just work" because the deserializer assumes signed. i could change it for just Y to assume unsigned and leave X and Z as signed, however, we know that in 1.17 they plan to add negative Y. for that reason, the better approach is to give the extra bits to Y and leave it as signed.
// also, if 1.17 sticks with the current plan which is -64 to +320, we could have 9 bits for Y and a constant offset of -64 to change it to -128 to +256.
// that would result in the packed long representation of any valid coordinate still being a positive integer
// i like that property, so i will keep num_y_bits at 9 and plan for an offset in 1.17
// it also gives 1 bit of wiggle room in case anything else happens in the future, so we are only using 63 out of 64 bits at the moment
public static final int Z_SHIFT = 0;
public static final int Y_SHIFT = Z_SHIFT + NUM_Z_BITS + 1; // 1 padding bit to make twos complement not overflow
public static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS + 1; // and also here too
public static final long X_MASK = (1L << NUM_X_BITS) - 1L; // X doesn't need padding as the overflow carry bit is just discarded, like a normal long (-1) + (1) = 0
public static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
public static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
public static final long POST_ADDITION_MASK = X_MASK << X_SHIFT | Y_MASK << Y_SHIFT | Z_MASK << Z_SHIFT; // required to "manually inline" toLong(-1, -1, -1) here so that javac inserts proper ldc2_w instructions at usage points instead of getstatic
// what's this ^ mask for?
// it allows for efficient offsetting and manipulation of a long packed coordinate
// if we had three ints, x y z, it would be easy to do "y += 1" or "x -= 1"
// but how do you do those things if you have a long with x y and z all stuffed into one primitive?
// adding together two long coordinates actually works perfectly if both sides have X, Y, and Z as all positive, no issues at all
// but when Y or Z is negative, we run into an issue. consider 8 bits: negative one is 11111111 and one is 00000001
// adding them together gives 00000000, zero, **but only because there isn't a 9th bit to carry into**
// if we had, instead, 00000000 11111111 + 00000000 00000001 we would rightly get 00000001 00000000 with the 1 being carried into the 9th position there
// this is exactly what happens. "toLong(0, 1, 0) + toLong(0, -1, 0)" ends up equaling toLong(1, 0, 0) while we'd rather it equal toLong(0, 0, 0)
// so, we simply mask out the unwanted result of the carry by inserting 1 bit of padding space (as added above) between each
// it used to be 000XXXXXXXXXXXXXXXXXXXXXXXXXXYYYYYYYYYZZZZZZZZZZZZZZZZZZZZZZZZZZ
// and now it is 0XXXXXXXXXXXXXXXXXXXXXXXXXX0YYYYYYYYY0ZZZZZZZZZZZZZZZZZZZZZZZZZZ
// we simply place the X Y and Z in slightly different sections of the long, putting a bit of space between each
// the mask ^ is 0111111111111111111111111110111111111011111111111111111111111111
// using that example of (0,1,0) + (0,-1,0), here's what happens
// 0000000000000000000000000000000000001000000000000000000000000000 (this is X=0 Y=1 Z=0)
// + 0000000000000000000000000000111111111000000000000000000000000000 (this is X=0 Y=-1 Z=0)
// = 0000000000000000000000000001000000000000000000000000000000000000
// the unwanted carry bit here ^ is no longer corrupting the least significant bit of X and making it 1!
// now it's just turning on the unused padding bit that we don't care about
// using the mask and bitwise and, we can easily and branchlessly turn off the padding bits just in case something overflow carried into them!
// 0000000000000000000000000001000000000000000000000000000000000000 (the result of the addition from earlier)
// & 0111111111111111111111111110111111111011111111111111111111111111 (this is POST_ADDITION_MASK)
// = 0000000000000000000000000000000000000000000000000000000000000000
// POST_ADDITION_MASK retains the bits that actually form X, Y, and Z, but intentionally turns off the padding bits
// so, we can simply do "(toLong(0, 1, 0) + toLong(0, -1, 0)) & POST_ADDITION_MASK" and correctly get toLong(0, 0, 0)
// which is incredibly fast and efficient, an add then a bitwise AND against a constant
// and it doesn't require us to pull out X, Y, and Z, modify one of them, and put them all back into the long
// that's what the point of the mask is
static {
if (POST_ADDITION_MASK != toLong(-1, -1, -1)) {
throw new IllegalStateException(POST_ADDITION_MASK + " " + toLong(-1, -1, -1)); // sanity check
}
}
public long toLong() {
return toLong(this.x, this.y, this.z);
}
public static BetterBlockPos fromLong(long serialized) {
return new BetterBlockPos(XfromLong(serialized), YfromLong(serialized), ZfromLong(serialized));
}
public static int XfromLong(long serialized) {
return (int) (serialized << (64 - X_SHIFT - NUM_X_BITS) >> (64 - NUM_X_BITS));
}
public static int YfromLong(long serialized) {
return (int) (serialized << (64 - Y_SHIFT - NUM_Y_BITS) >> (64 - NUM_Y_BITS));
}
public static int ZfromLong(long serialized) {
return (int) (serialized << (64 - Z_SHIFT - NUM_Z_BITS) >> (64 - NUM_Z_BITS));
}
public static long toLong(final int x, final int y, final int z) {
return ((long) x & X_MASK) << X_SHIFT | ((long) y & Y_MASK) << Y_SHIFT | ((long) z & Z_MASK) << Z_SHIFT;
}
public static long offsetBy(long pos, int x, int y, int z) {
return (pos + toLong(x, y, z)) & BetterBlockPos.POST_ADDITION_MASK;
}
public static final long HASHCODE_MURMUR_MASK = murmur64(-1);
public static final long ZOBRIST_MURMUR_MASK = murmur64(-2);
public static long longHash(int x, int y, int z) { public static long longHash(int x, int y, int z) {
// TODO use the same thing as BlockPos.fromLong(); return longHash(toLong(x, y, z));
// invertibility would be incredibly useful }
/*
* This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name) public static long longHash(long packed) {
* return murmur64(HASHCODE_MURMUR_MASK ^ packed);
* public int hashCode() { }
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
* } public static long murmur64(long h) {
* return HashCommon.murmurHash3(h);
* That is terrible and has tons of collisions and makes the HashMap terribly inefficient.
*
* That's why we grab out the X, Y, Z and calculate our own hashcode
*/
long hash = 3241;
hash = 3457689L * hash + x;
hash = 8734625L * hash + y;
hash = 2873465L * hash + z;
return hash;
} }
@Override @Override
@@ -211,39 +276,14 @@ public final class BetterBlockPos extends BlockPos {
return amt == 0 ? this : new BetterBlockPos(x - amt, y, z); return amt == 0 ? this : new BetterBlockPos(x - amt, y, z);
} }
public double distanceSq(final BetterBlockPos to) {
double dx = (double) this.x - to.x;
double dy = (double) this.y - to.y;
double dz = (double) this.z - to.z;
return dx * dx + dy * dy + dz * dz;
}
public double distanceTo(final BetterBlockPos to) {
double dx = (double) this.x - to.x;
double dy = (double) this.y - to.y;
double dz = (double) this.z - to.z;
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
@Override @Override
@Nonnull @Nonnull
public String toString() { public String toString() {
return String.format( return String.format(
"BetterBlockPos{x=%s,y=%s,z=%s}", "BetterBlockPos{x=%d,y=%d,z=%d}",
SettingsUtil.maybeCensor(x), x,
SettingsUtil.maybeCensor(y), y,
SettingsUtil.maybeCensor(z) z
); );
} }
public static long serializeToLong(final int x, final int y, final int z) {
return ((long) x & X_MASK) << X_SHIFT | ((long) y & Y_MASK) << Y_SHIFT | ((long) z & Z_MASK);
}
public static BetterBlockPos deserializeFromLong(final long serialized) {
final int x = (int) (serialized << 64 - X_SHIFT - NUM_X_BITS >> 64 - NUM_X_BITS);
final int y = (int) (serialized << 64 - Y_SHIFT - NUM_Y_BITS >> 64 - NUM_Y_BITS);
final int z = (int) (serialized << 64 - NUM_Z_BITS >> 64 - NUM_Z_BITS);
return new BetterBlockPos(x, y, z);
}
} }

View File

@@ -19,7 +19,6 @@ package baritone.api.utils;
import baritone.api.utils.accessor.IItemStack; import baritone.api.utils.accessor.IItemStack;
import com.google.common.collect.ImmutableSet; import com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.*; import net.minecraft.block.*;
import net.minecraft.block.properties.IProperty; import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
@@ -37,24 +36,21 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
public final class BlockOptionalMeta { public final class BlockOptionalMeta {
// id:meta or id[] or id[properties] where id and properties are any text with at least one character and meta is a one or two digit number
private static final Pattern PATTERN = Pattern.compile("^(?<id>.+?)(?::(?<meta>\\d\\d?)|\\[(?<properties>.+?)?\\])?$");
private final Block block; private final Block block;
private final int meta; private final int meta;
private final boolean noMeta; private final boolean noMeta;
private final String propertiesDescription; // exists so toString() can return something more useful than a list of all blockstates
private final Set<IBlockState> blockstates; private final Set<IBlockState> blockstates;
private final Set<Integer> stateHashes; private final ImmutableSet<Integer> stateHashes;
private final Set<Integer> stackHashes; private final ImmutableSet<Integer> stackHashes;
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
private static final Map<Object, Object> normalizations; private static final Map<Object, Object> normalizations;
public BlockOptionalMeta(@Nonnull Block block, @Nullable Integer meta) { public BlockOptionalMeta(@Nonnull Block block, @Nullable Integer meta) {
this.block = block; this.block = block;
this.noMeta = meta == null; this.noMeta = meta == null;
this.meta = noMeta ? 0 : meta; this.meta = noMeta ? 0 : meta;
this.propertiesDescription = "{}"; this.blockstates = getStates(block, meta);
this.blockstates = getStates(block, meta, Collections.emptyMap());
this.stateHashes = getStateHashes(blockstates); this.stateHashes = getStateHashes(blockstates);
this.stackHashes = getStackHashes(blockstates); this.stackHashes = getStackHashes(blockstates);
} }
@@ -64,27 +60,24 @@ public final class BlockOptionalMeta {
} }
public BlockOptionalMeta(@Nonnull String selector) { public BlockOptionalMeta(@Nonnull String selector) {
Matcher matcher = PATTERN.matcher(selector); Matcher matcher = pattern.matcher(selector);
if (!matcher.find()) { if (!matcher.find()) {
throw new IllegalArgumentException("invalid block selector"); throw new IllegalArgumentException("invalid block selector");
} }
noMeta = matcher.group("meta") == null; MatchResult matchResult = matcher.toMatchResult();
noMeta = matchResult.group(2) == null;
ResourceLocation id = new ResourceLocation(matcher.group("id")); ResourceLocation id = new ResourceLocation(matchResult.group(1));
if (!Block.REGISTRY.containsKey(id)) { if (!Block.REGISTRY.containsKey(id)) {
throw new IllegalArgumentException("Invalid block ID"); throw new IllegalArgumentException("Invalid block ID");
} }
block = Block.REGISTRY.getObject(id); block = Block.REGISTRY.getObject(id);
meta = noMeta ? 0 : Integer.parseInt(matchResult.group(2));
String props = matcher.group("properties"); blockstates = getStates(block, getMeta());
Map<IProperty<?>, ?> properties = props == null || props.equals("") ? Collections.emptyMap() : parseProperties(block, props);
propertiesDescription = props == null ? "{}" : "{" + props.replace("=", ":") + "}";
meta = noMeta ? 0 : Integer.parseInt(matcher.group("meta"));
blockstates = getStates(block, getMeta(), properties);
stateHashes = getStateHashes(blockstates); stateHashes = getStateHashes(blockstates);
stackHashes = getStackHashes(blockstates); stackHashes = getStackHashes(blockstates);
} }
@@ -250,32 +243,9 @@ public final class BlockOptionalMeta {
return state.getBlock().getMetaFromState(normalize(state)); return state.getBlock().getMetaFromState(normalize(state));
} }
private static Map<IProperty<?>, ?> parseProperties(Block block, String raw) { private static Set<IBlockState> getStates(@Nonnull Block block, @Nullable Integer meta) {
ImmutableMap.Builder<IProperty<?>, Object> builder = ImmutableMap.builder();
for (String pair : raw.split(",")) {
String[] parts = pair.split("=");
if (parts.length != 2) {
throw new IllegalArgumentException(String.format("\"%s\" is not a valid property-value pair", pair));
}
String rawKey = parts[0];
String rawValue = parts[1];
IProperty<?> key = block.getBlockState().getProperty(rawKey);
Comparable<?> value = castToIProperty(key).parseValue(rawValue)
.toJavaUtil().orElseThrow(() -> new IllegalArgumentException(String.format(
"\"%s\" is not a valid value for %s on %s",
rawValue, key, block
)));
builder.put(key, value);
}
return builder.build();
}
private static Set<IBlockState> getStates(@Nonnull Block block, @Nullable Integer meta, @Nonnull Map<IProperty<?>, ?> properties) {
return block.getBlockState().getValidStates().stream() return block.getBlockState().getValidStates().stream()
.filter(blockstate -> meta == null || stateMeta(blockstate) == meta) .filter(blockstate -> meta == null || stateMeta(blockstate) == meta)
.filter(blockstate -> properties.entrySet().stream().allMatch(entry ->
blockstate.getValue(entry.getKey()) == entry.getValue()
))
.collect(Collectors.toSet()); .collect(Collectors.toSet());
} }
@@ -304,7 +274,6 @@ public final class BlockOptionalMeta {
return block; return block;
} }
@Deprecated // deprecated because getMeta() == null no longer implies that this BOM only cares about the block
public Integer getMeta() { public Integer getMeta() {
return noMeta ? null : meta; return noMeta ? null : meta;
} }
@@ -331,11 +300,7 @@ public final class BlockOptionalMeta {
@Override @Override
public String toString() { public String toString() {
if (noMeta) { return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
return String.format("BlockOptionalMeta{block=%s,properties=%s}", block, propertiesDescription);
} else {
return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
}
} }
public static IBlockState blockStateFromStack(ItemStack stack) { public static IBlockState blockStateFromStack(ItemStack stack) {
@@ -350,12 +315,4 @@ public final class BlockOptionalMeta {
return null; return null;
} }
public Set<IBlockState> getAllBlockStates() {
return blockstates;
}
public Set<Integer> stackHashes() {
return stackHashes;
}
} }

View File

@@ -17,70 +17,68 @@
package baritone.api.utils; package baritone.api.utils;
import baritone.api.utils.accessor.IItemStack;
import com.google.common.collect.ImmutableSet;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
import net.minecraft.item.ItemStack; import net.minecraft.item.ItemStack;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set;
import java.util.stream.Stream; import java.util.stream.Stream;
public class BlockOptionalMetaLookup { public class BlockOptionalMetaLookup {
private final ImmutableSet<Block> blockSet;
private final ImmutableSet<IBlockState> blockStateSet;
private final ImmutableSet<Integer> stackHashes;
private final BlockOptionalMeta[] boms; private final BlockOptionalMeta[] boms;
public BlockOptionalMetaLookup(BlockOptionalMeta... boms) { public BlockOptionalMetaLookup(BlockOptionalMeta... boms) {
this.boms = boms; this.boms = boms;
Set<Block> blocks = new HashSet<>();
Set<IBlockState> blockStates = new HashSet<>();
Set<Integer> stacks = new HashSet<>();
for (BlockOptionalMeta bom : boms) {
blocks.add(bom.getBlock());
blockStates.addAll(bom.getAllBlockStates());
stacks.addAll(bom.stackHashes());
}
this.blockSet = ImmutableSet.copyOf(blocks);
this.blockStateSet = ImmutableSet.copyOf(blockStates);
this.stackHashes = ImmutableSet.copyOf(stacks);
} }
public BlockOptionalMetaLookup(Block... blocks) { public BlockOptionalMetaLookup(Block... blocks) {
this(Stream.of(blocks) this.boms = Stream.of(blocks)
.map(BlockOptionalMeta::new) .map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new)); .toArray(BlockOptionalMeta[]::new);
} }
public BlockOptionalMetaLookup(List<Block> blocks) { public BlockOptionalMetaLookup(List<Block> blocks) {
this(blocks.stream() this.boms = blocks.stream()
.map(BlockOptionalMeta::new) .map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new)); .toArray(BlockOptionalMeta[]::new);
} }
public BlockOptionalMetaLookup(String... blocks) { public BlockOptionalMetaLookup(String... blocks) {
this(Stream.of(blocks) this.boms = Stream.of(blocks)
.map(BlockOptionalMeta::new) .map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new)); .toArray(BlockOptionalMeta[]::new);
} }
public boolean has(Block block) { public boolean has(Block block) {
return blockSet.contains(block); for (BlockOptionalMeta bom : boms) {
if (bom.getBlock() == block) {
return true;
}
}
return false;
} }
public boolean has(IBlockState state) { public boolean has(IBlockState state) {
return blockStateSet.contains(state); for (BlockOptionalMeta bom : boms) {
if (bom.matches(state)) {
return true;
}
}
return false;
} }
public boolean has(ItemStack stack) { public boolean has(ItemStack stack) {
int hash = ((IItemStack) (Object) stack).getBaritoneHash(); for (BlockOptionalMeta bom : boms) {
return stackHashes.contains(hash) if (bom.matches(stack)) {
|| stackHashes.contains(hash - stack.getItemDamage()); return true;
}
}
return false;
} }
public List<BlockOptionalMeta> blocks() { public List<BlockOptionalMeta> blocks() {

View File

@@ -42,10 +42,8 @@ public interface Helper {
Helper HELPER = new Helper() {}; Helper HELPER = new Helper() {};
/** /**
* The main game instance returned by {@link Minecraft#getMinecraft()}. * Instance of the game
* Deprecated since {@link IPlayerContext#minecraft()} should be used instead (In the majority of cases).
*/ */
@Deprecated
Minecraft mc = Minecraft.getMinecraft(); Minecraft mc = Minecraft.getMinecraft();
static ITextComponent getPrefix() { static ITextComponent getPrefix() {
@@ -72,7 +70,7 @@ public interface Helper {
* @param message The message to display in the popup * @param message The message to display in the popup
*/ */
default void logToast(ITextComponent title, ITextComponent message) { default void logToast(ITextComponent title, ITextComponent message) {
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message)); mc.addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
} }
/** /**
@@ -133,7 +131,7 @@ public interface Helper {
* @param error Whether to log as an error * @param error Whether to log as an error
*/ */
default void logNotificationDirect(String message, boolean error) { default void logNotificationDirect(String message, boolean error) {
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error)); mc.addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
} }
/** /**
@@ -170,7 +168,7 @@ public interface Helper {
if (logAsToast) { if (logAsToast) {
logToast(getPrefix(), component); logToast(getPrefix(), component);
} else { } else {
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component)); mc.addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
} }
} }
@@ -230,11 +228,4 @@ public interface Helper {
default void logDirect(String message) { default void logDirect(String message) {
logDirect(message, BaritoneAPI.getSettings().logAsToast.value); logDirect(message, BaritoneAPI.getSettings().logAsToast.value);
} }
default void logUnhandledException(final Throwable exception) {
HELPER.logDirect("An unhandled exception occurred. " +
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
TextFormatting.RED);
exception.printStackTrace();
}
} }

View File

@@ -19,7 +19,6 @@ package baritone.api.utils;
import baritone.api.cache.IWorldData; import baritone.api.cache.IWorldData;
import net.minecraft.block.BlockSlab; import net.minecraft.block.BlockSlab;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult; import net.minecraft.util.math.RayTraceResult;
@@ -34,8 +33,6 @@ import java.util.Optional;
*/ */
public interface IPlayerContext { public interface IPlayerContext {
Minecraft minecraft();
EntityPlayerSP player(); EntityPlayerSP player();
IPlayerController playerController(); IPlayerController playerController();
@@ -75,12 +72,6 @@ public interface IPlayerContext {
return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ); return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ);
} }
default Vec3d playerMotion() {
return new Vec3d(player().motionX, player().motionY, player().motionZ);
}
BetterBlockPos viewerPos();
default Rotation playerRotations() { default Rotation playerRotations() {
return new Rotation(player().rotationYaw, player().rotationPitch); return new Rotation(player().rotationYaw, player().rotationPitch);
} }

View File

@@ -1,59 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import java.util.Objects;
/**
* @author Brady
*/
public final class Pair<A, B> {
private final A a;
private final B b;
public Pair(A a, B b) {
this.a = a;
this.b = b;
}
public A first() {
return this.a;
}
public B second() {
return this.b;
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || o.getClass() != Pair.class) {
return false;
}
Pair<?, ?> pair = (Pair<?, ?>) o;
return Objects.equals(this.a, pair.a) && Objects.equals(this.b, pair.b);
}
@Override
public int hashCode() {
return 31 * Objects.hashCode(this.a) + Objects.hashCode(this.b);
}
}

View File

@@ -50,7 +50,7 @@ public final class RayTraceUtils {
} else { } else {
start = entity.getPositionEyes(1.0F); // do whatever is correct start = entity.getPositionEyes(1.0F); // do whatever is correct
} }
Vec3d direction = RotationUtils.calcLookDirectionFromRotation(rotation); Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
Vec3d end = start.add( Vec3d end = start.add(
direction.x * blockReachDistance, direction.x * blockReachDistance,
direction.y * blockReachDistance, direction.y * blockReachDistance,

View File

@@ -26,12 +26,12 @@ public class Rotation {
/** /**
* The yaw angle of this Rotation * The yaw angle of this Rotation
*/ */
private final float yaw; private float yaw;
/** /**
* The pitch angle of this Rotation * The pitch angle of this Rotation
*/ */
private final float pitch; private float pitch;
public Rotation(float yaw, float pitch) { public Rotation(float yaw, float pitch) {
this.yaw = yaw; this.yaw = yaw;
@@ -110,10 +110,6 @@ public class Rotation {
); );
} }
public Rotation withPitch(float pitch) {
return new Rotation(this.yaw, pitch);
}
/** /**
* Is really close to * Is really close to
* *

View File

@@ -37,13 +37,11 @@ public final class RotationUtils {
* Constant that a degree value is multiplied by to get the equivalent radian value * Constant that a degree value is multiplied by to get the equivalent radian value
*/ */
public static final double DEG_TO_RAD = Math.PI / 180.0; public static final double DEG_TO_RAD = Math.PI / 180.0;
public static final float DEG_TO_RAD_F = (float) DEG_TO_RAD;
/** /**
* Constant that a radian value is multiplied by to get the equivalent degree value * Constant that a radian value is multiplied by to get the equivalent degree value
*/ */
public static final double RAD_TO_DEG = 180.0 / Math.PI; public static final double RAD_TO_DEG = 180.0 / Math.PI;
public static final float RAD_TO_DEG_F = (float) RAD_TO_DEG;
/** /**
* Offsets from the root block position to the center of each side. * Offsets from the root block position to the center of each side.
@@ -124,31 +122,26 @@ public final class RotationUtils {
* @param rotation The input rotation * @param rotation The input rotation
* @return Look vector for the rotation * @return Look vector for the rotation
*/ */
public static Vec3d calcLookDirectionFromRotation(Rotation rotation) {
float flatZ = MathHelper.cos((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
float flatX = MathHelper.sin((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
float pitchBase = -MathHelper.cos(-rotation.getPitch() * DEG_TO_RAD_F);
float pitchHeight = MathHelper.sin(-rotation.getPitch() * DEG_TO_RAD_F);
return new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase);
}
@Deprecated
public static Vec3d calcVec3dFromRotation(Rotation rotation) { public static Vec3d calcVec3dFromRotation(Rotation rotation) {
return calcLookDirectionFromRotation(rotation); float f = MathHelper.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
float f1 = MathHelper.sin(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI);
float f2 = -MathHelper.cos(-rotation.getPitch() * (float) DEG_TO_RAD);
float f3 = MathHelper.sin(-rotation.getPitch() * (float) DEG_TO_RAD);
return new Vec3d((double) (f1 * f2), (double) f3, (double) (f * f2));
} }
/** /**
* @param ctx Context for the viewing entity * @param ctx Context for the viewing entity
* @param pos The target block position * @param pos The target block position
* @return The optional rotation * @return The optional rotation
* @see #reachable(IPlayerContext, BlockPos, double) * @see #reachable(EntityPlayerSP, BlockPos, double)
*/ */
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos) { public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos) {
return reachable(ctx, pos, false); return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
} }
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, boolean wouldSneak) { public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, boolean wouldSneak) {
return reachable(ctx, pos, ctx.playerController().getBlockReachDistance(), wouldSneak); return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance(), wouldSneak);
} }
/** /**
@@ -158,17 +151,18 @@ public final class RotationUtils {
* side that is reachable. The return type will be {@link Optional#empty()} if the entity is * side that is reachable. The return type will be {@link Optional#empty()} if the entity is
* unable to reach any of the sides of the block. * unable to reach any of the sides of the block.
* *
* @param ctx Context for the viewing entity * @param entity The viewing entity
* @param pos The target block position * @param pos The target block position
* @param blockReachDistance The block reach distance of the entity * @param blockReachDistance The block reach distance of the entity
* @return The optional rotation * @return The optional rotation
*/ */
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance) { public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
return reachable(ctx, pos, blockReachDistance, false); return reachable(entity, pos, blockReachDistance, false);
} }
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) { public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
if (BaritoneAPI.getSettings().remainWithExistingLookDirection.value && ctx.isLookingAt(pos)) { IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (baritone.getPlayerContext().isLookingAt(pos)) {
/* /*
* why add 0.0001? * why add 0.0001?
* to indicate that we actually have a desired pitch * to indicate that we actually have a desired pitch
@@ -179,10 +173,10 @@ public final class RotationUtils {
* *
* or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level * or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level
*/ */
Rotation hypothetical = ctx.playerRotations().add(new Rotation(0, 0.0001F)); Rotation hypothetical = new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F);
if (wouldSneak) { if (wouldSneak) {
// the concern here is: what if we're looking at it now, but as soon as we start sneaking we no longer are // the concern here is: what if we're looking at it now, but as soon as we start sneaking we no longer are
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), hypothetical, blockReachDistance, true); RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, hypothetical, blockReachDistance, true);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(pos)) { if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK && result.getBlockPos().equals(pos)) {
return Optional.of(hypothetical); // yes, if we sneaked we would still be looking at the block return Optional.of(hypothetical); // yes, if we sneaked we would still be looking at the block
} }
@@ -190,19 +184,19 @@ public final class RotationUtils {
return Optional.of(hypothetical); return Optional.of(hypothetical);
} }
} }
Optional<Rotation> possibleRotation = reachableCenter(ctx, pos, blockReachDistance, wouldSneak); Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance, wouldSneak);
//System.out.println("center: " + possibleRotation); //System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) { if (possibleRotation.isPresent()) {
return possibleRotation; return possibleRotation;
} }
IBlockState state = ctx.world().getBlockState(pos); IBlockState state = entity.world.getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(ctx.world(), pos); AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) { for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x); double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y); double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z); double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
possibleRotation = reachableOffset(ctx, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak); possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak);
if (possibleRotation.isPresent()) { if (possibleRotation.isPresent()) {
return possibleRotation; return possibleRotation;
} }
@@ -215,55 +209,12 @@ public final class RotationUtils {
* the given offsetted position. The return type will be {@link Optional#empty()} if * the given offsetted position. The return type will be {@link Optional#empty()} if
* the entity is unable to reach the block with the offset applied. * the entity is unable to reach the block with the offset applied.
* *
* @param ctx Context for the viewing entity * @param entity The viewing entity
* @param pos The target block position * @param pos The target block position
* @param offsetPos The position of the block with the offset applied. * @param offsetPos The position of the block with the offset applied.
* @param blockReachDistance The block reach distance of the entity * @param blockReachDistance The block reach distance of the entity
* @return The optional rotation * @return The optional rotation
*/ */
public static Optional<Rotation> reachableOffset(IPlayerContext ctx, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) {
Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(ctx.player()) : ctx.player().getPositionEyes(1.0F);
Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, ctx.playerRotations());
Rotation actualRotation = BaritoneAPI.getProvider().getBaritoneForPlayer(ctx.player()).getLookBehavior().getAimProcessor().peekRotation(rotation);
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), actualRotation, blockReachDistance, wouldSneak);
//System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation);
}
if (ctx.world().getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) {
return Optional.of(rotation);
}
}
return Optional.empty();
}
/**
* Determines if the specified entity is able to reach the specified block where it is
* looking at the direct center of it's hitbox.
*
* @param ctx Context for the viewing entity
* @param pos The target block position
* @param blockReachDistance The block reach distance of the entity
* @return The optional rotation
*/
public static Optional<Rotation> reachableCenter(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
return reachableOffset(ctx, pos, VecUtils.calculateBlockCenter(ctx.world(), pos), blockReachDistance, wouldSneak);
}
@Deprecated
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
return reachable(entity, pos, blockReachDistance, false);
}
@Deprecated
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
IPlayerContext ctx = baritone.getPlayerContext();
return reachable(ctx, pos, blockReachDistance, wouldSneak);
}
@Deprecated
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) { public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance, boolean wouldSneak) {
Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F); Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F);
Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch)); Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
@@ -280,7 +231,15 @@ public final class RotationUtils {
return Optional.empty(); return Optional.empty();
} }
@Deprecated /**
* Determines if the specified entity is able to reach the specified block where it is
* looking at the direct center of it's hitbox.
*
* @param entity The viewing entity
* @param pos The target block position
* @param blockReachDistance The block reach distance of the entity
* @return The optional rotation
*/
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) { public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance, wouldSneak); return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance, wouldSneak);
} }

View File

@@ -20,7 +20,6 @@ package baritone.api.utils;
import baritone.api.BaritoneAPI; import baritone.api.BaritoneAPI;
import baritone.api.Settings; import baritone.api.Settings;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item; import net.minecraft.item.Item;
import net.minecraft.util.EnumFacing; import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3i; import net.minecraft.util.math.Vec3i;
@@ -45,10 +44,13 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors; import java.util.stream.Collectors;
import java.util.stream.Stream; import java.util.stream.Stream;
import static net.minecraft.client.Minecraft.getMinecraft;
public class SettingsUtil { public class SettingsUtil {
public static final String SETTINGS_DEFAULT_NAME = "settings.txt"; private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space private static final Pattern SETTING_PATTERN = Pattern.compile("^(?<setting>[^ ]+) +(?<value>.+)"); // key and value split by the first space
private static final String[] JAVA_ONLY_SETTINGS = {"logger", "notifier", "toaster"};
private static boolean isComment(String line) { private static boolean isComment(String line) {
return line.startsWith("#") || line.startsWith("//"); return line.startsWith("#") || line.startsWith("//");
@@ -66,12 +68,12 @@ public class SettingsUtil {
} }
} }
public static void readAndApply(Settings settings, String settingsName) { public static void readAndApply(Settings settings) {
try { try {
forEachLine(settingsByName(settingsName), line -> { forEachLine(SETTINGS_PATH, line -> {
Matcher matcher = SETTING_PATTERN.matcher(line); Matcher matcher = SETTING_PATTERN.matcher(line);
if (!matcher.matches()) { if (!matcher.matches()) {
Helper.HELPER.logDirect("Invalid syntax in setting file: " + line); System.out.println("Invalid syntax in setting file: " + line);
return; return;
} }
@@ -80,33 +82,29 @@ public class SettingsUtil {
try { try {
parseAndApply(settings, settingName, settingValue); parseAndApply(settings, settingName, settingValue);
} catch (Exception ex) { } catch (Exception ex) {
Helper.HELPER.logDirect("Unable to parse line " + line); System.out.println("Unable to parse line " + line);
ex.printStackTrace(); ex.printStackTrace();
} }
}); });
} catch (NoSuchFileException ignored) { } catch (NoSuchFileException ignored) {
Helper.HELPER.logDirect("Baritone settings file not found, resetting."); System.out.println("Baritone settings file not found, resetting.");
} catch (Exception ex) { } catch (Exception ex) {
Helper.HELPER.logDirect("Exception while reading Baritone settings, some settings may be reset to default values!"); System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
ex.printStackTrace(); ex.printStackTrace();
} }
} }
public static synchronized void save(Settings settings) { public static synchronized void save(Settings settings) {
try (BufferedWriter out = Files.newBufferedWriter(settingsByName(SETTINGS_DEFAULT_NAME))) { try (BufferedWriter out = Files.newBufferedWriter(SETTINGS_PATH)) {
for (Settings.Setting setting : modifiedSettings(settings)) { for (Settings.Setting setting : modifiedSettings(settings)) {
out.write(settingToString(setting) + "\n"); out.write(settingToString(setting) + "\n");
} }
} catch (Exception ex) { } catch (Exception ex) {
Helper.HELPER.logDirect("Exception thrown while saving Baritone settings!"); System.out.println("Exception thrown while saving Baritone settings!");
ex.printStackTrace(); ex.printStackTrace();
} }
} }
private static Path settingsByName(String name) {
return Minecraft.getMinecraft().gameDir.toPath().resolve("baritone").resolve(name);
}
public static List<Settings.Setting> modifiedSettings(Settings settings) { public static List<Settings.Setting> modifiedSettings(Settings settings) {
List<Settings.Setting> modified = new ArrayList<>(); List<Settings.Setting> modified = new ArrayList<>();
for (Settings.Setting setting : settings.allSettings) { for (Settings.Setting setting : settings.allSettings) {
@@ -114,7 +112,7 @@ public class SettingsUtil {
System.out.println("NULL SETTING?" + setting.getName()); System.out.println("NULL SETTING?" + setting.getName());
continue; continue;
} }
if (setting.isJavaOnly()) { if (javaOnlySetting(setting)) {
continue; // NO continue; // NO
} }
if (setting.value == setting.defaultValue) { if (setting.value == setting.defaultValue) {
@@ -168,7 +166,7 @@ public class SettingsUtil {
} }
public static String settingToString(Settings.Setting setting) throws IllegalStateException { public static String settingToString(Settings.Setting setting) throws IllegalStateException {
if (setting.isJavaOnly()) { if (javaOnlySetting(setting)) {
return setting.getName(); return setting.getName();
} }
@@ -176,14 +174,18 @@ public class SettingsUtil {
} }
/** /**
* Deprecated. Use {@link Settings.Setting#isJavaOnly()} instead. * This should always be the same as whether the setting can be parsed from or serialized to a string
* *
* @param setting The Setting * @param the setting
* @return true if the setting can not be set or read by the user * @return true if the setting can not be set or read by the user
*/ */
@Deprecated
public static boolean javaOnlySetting(Settings.Setting setting) { public static boolean javaOnlySetting(Settings.Setting setting) {
return setting.isJavaOnly(); for (String name : JAVA_ONLY_SETTINGS) { // no JAVA_ONLY_SETTINGS.contains(...) because that would be case sensitive
if (setting.getName().equalsIgnoreCase(name)) {
return true;
}
}
return false;
} }
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException { public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {
@@ -297,7 +299,7 @@ public class SettingsUtil {
Parser keyParser = Parser.getParser(keyType); Parser keyParser = Parser.getParser(keyType);
Parser valueParser = Parser.getParser(valueType); Parser valueParser = Parser.getParser(valueType);
return ((Map<?, ?>) value).entrySet().stream() return ((Map<?,?>) value).entrySet().stream()
.map(o -> keyParser.toString(context, o.getKey()) + "->" + valueParser.toString(context, o.getValue())) .map(o -> keyParser.toString(context, o.getKey()) + "->" + valueParser.toString(context, o.getValue()))
.collect(Collectors.joining(",")); .collect(Collectors.joining(","));
} }

View File

@@ -17,7 +17,6 @@
package baritone.api.utils.gui; package baritone.api.utils.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.toasts.GuiToast; import net.minecraft.client.gui.toasts.GuiToast;
import net.minecraft.client.gui.toasts.IToast; import net.minecraft.client.gui.toasts.IToast;
import net.minecraft.client.renderer.GlStateManager; import net.minecraft.client.renderer.GlStateManager;
@@ -74,6 +73,6 @@ public class BaritoneToast implements IToast {
} }
public static void addOrUpdate(ITextComponent title, ITextComponent subtitle) { public static void addOrUpdate(ITextComponent title, ITextComponent subtitle) {
addOrUpdate(Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value); addOrUpdate(net.minecraft.client.Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value);
} }
} }

View File

@@ -64,14 +64,4 @@ public abstract class MixinBitArray implements IBitArray {
return out; return out;
} }
@Override
public long getMaxEntryValue() {
return maxEntryValue;
}
@Override
public int getBitsPerEntry() {
return bitsPerEntry;
}
} }

View File

@@ -35,16 +35,6 @@ public abstract class MixinBlockStateContainer implements IBlockStateContainer {
@Shadow @Shadow
protected IBlockStatePalette palette; protected IBlockStatePalette palette;
@Override
public IBlockStatePalette getPalette() {
return palette;
}
@Override
public BitArray getStorage() {
return storage;
}
@Override @Override
public IBlockState getAtPalette(int index) { public IBlockState getAtPalette(int index) {
return palette.getBlockState(index); return palette.getBlockState(index);

View File

@@ -1,57 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.utils.accessor.IEntityFireworkRocket;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.entity.item.EntityFireworkRocket;
import net.minecraft.network.datasync.DataParameter;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(EntityFireworkRocket.class)
public abstract class MixinEntityFireworkRocket extends Entity implements IEntityFireworkRocket {
@Shadow
@Final
private static DataParameter<Integer> BOOSTED_ENTITY_ID;
@Shadow
private EntityLivingBase boostedEntity;
@Shadow
public abstract boolean isAttachedToEntity();
private MixinEntityFireworkRocket(World worldIn) {
super(worldIn);
}
@Override
public EntityLivingBase getBoostedEntity() {
if (this.isAttachedToEntity() && this.boostedEntity == null) {
final Entity entity = this.world.getEntityByID(this.dataManager.get(BOOSTED_ENTITY_ID));
if (entity instanceof EntityLivingBase) {
this.boostedEntity = (EntityLivingBase) entity;
}
}
return this.boostedEntity;
}
}

View File

@@ -25,14 +25,11 @@ import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase; import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World; import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
import static org.spongepowered.asm.lib.Opcodes.GETFIELD; import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
/** /**
@@ -45,14 +42,11 @@ public abstract class MixinEntityLivingBase extends Entity {
/** /**
* Event called to override the movement direction when jumping * Event called to override the movement direction when jumping
*/ */
@Unique
private RotationMoveEvent jumpRotationEvent; private RotationMoveEvent jumpRotationEvent;
@Unique public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
private RotationMoveEvent elytraRotationEvent;
private MixinEntityLivingBase(World worldIn) {
super(worldIn); super(worldIn);
this.jumpRotationEvent = jumpRotationEvent;
} }
@Inject( @Inject(
@@ -60,10 +54,14 @@ public abstract class MixinEntityLivingBase extends Entity {
at = @At("HEAD") at = @At("HEAD")
) )
private void preMoveRelative(CallbackInfo ci) { private void preMoveRelative(CallbackInfo ci) {
this.getBaritone().ifPresent(baritone -> { // noinspection ConstantConditions
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw, this.rotationPitch); if (EntityPlayerSP.class.isInstance(this)) {
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent); IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
}); if (baritone != null) {
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw);
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
}
}
} }
@Redirect( @Redirect(
@@ -81,38 +79,6 @@ public abstract class MixinEntityLivingBase extends Entity {
return self.rotationYaw; return self.rotationYaw;
} }
@Inject(
method = "travel",
at = @At(
value = "INVOKE",
target = "net/minecraft/entity/EntityLivingBase.getLookVec()Lnet/minecraft/util/math/Vec3d;"
)
)
private void onPreElytraMove(float strafe, float vertical, float forward, CallbackInfo ci) {
this.getBaritone().ifPresent(baritone -> {
this.elytraRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch);
baritone.getGameEventHandler().onPlayerRotationMove(this.elytraRotationEvent);
this.rotationYaw = this.elytraRotationEvent.getYaw();
this.rotationPitch = this.elytraRotationEvent.getPitch();
});
}
@Inject(
method = "travel",
at = @At(
value = "INVOKE",
target = "net/minecraft/entity/EntityLivingBase.move(Lnet/minecraft/entity/MoverType;DDD)V",
shift = At.Shift.AFTER
)
)
private void onPostElytraMove(float strafe, float vertical, float forward, CallbackInfo ci) {
if (this.elytraRotationEvent != null) {
this.rotationYaw = this.elytraRotationEvent.getOriginal().getYaw();
this.rotationPitch = this.elytraRotationEvent.getOriginal().getPitch();
this.elytraRotationEvent = null;
}
}
@Redirect( @Redirect(
method = "travel", method = "travel",
at = @At( at = @At(
@@ -120,33 +86,17 @@ public abstract class MixinEntityLivingBase extends Entity {
target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V" target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V"
) )
) )
private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) { private void travel(EntityLivingBase self, float strafe, float up, float forward, float friction) {
Optional<IBaritone> baritone = this.getBaritone(); // noinspection ConstantConditions
if (!baritone.isPresent()) { if (!EntityPlayerSP.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) == null) {
// If a shadow is used here it breaks on Forge moveRelative(strafe, up, forward, friction);
this.moveRelative(strafe, up, forward, friction);
return; return;
} }
RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
RotationMoveEvent event = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch); BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent);
baritone.get().getGameEventHandler().onPlayerRotationMove(event); float originalYaw = this.rotationYaw;
this.rotationYaw = motionUpdateRotationEvent.getYaw();
this.rotationYaw = event.getYaw();
this.rotationPitch = event.getPitch();
this.moveRelative(strafe, up, forward, friction); this.moveRelative(strafe, up, forward, friction);
this.rotationYaw = originalYaw;
this.rotationYaw = event.getOriginal().getYaw();
this.rotationPitch = event.getOriginal().getPitch();
}
@Unique
private Optional<IBaritone> getBaritone() {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
return Optional.ofNullable(BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this));
} else {
return Optional.empty();
}
} }
} }

View File

@@ -61,8 +61,9 @@ public class MixinEntityPlayerSP {
method = "onUpdate", method = "onUpdate",
at = @At( at = @At(
value = "INVOKE", value = "INVOKE",
target = "net/minecraft/client/entity/AbstractClientPlayer.onUpdate()V", target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z",
shift = At.Shift.AFTER shift = At.Shift.BY,
by = -3
) )
) )
private void onPreUpdate(CallbackInfo ci) { private void onPreUpdate(CallbackInfo ci) {
@@ -72,6 +73,22 @@ public class MixinEntityPlayerSP {
} }
} }
@Inject(
method = "onUpdate",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/entity/EntityPlayerSP.onUpdateWalkingPlayer()V",
shift = At.Shift.BY,
by = 2
)
)
private void onPostUpdate(CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null) {
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
}
}
@Redirect( @Redirect(
method = "onLivingUpdate", method = "onLivingUpdate",
at = @At( at = @At(

View File

@@ -20,7 +20,6 @@ package baritone.launch.mixins;
import baritone.api.BaritoneAPI; import baritone.api.BaritoneAPI;
import baritone.api.IBaritone; import baritone.api.IBaritone;
import baritone.api.event.events.BlockInteractEvent; import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent; import baritone.api.event.events.TickEvent;
import baritone.api.event.events.WorldEvent; import baritone.api.event.events.WorldEvent;
import baritone.api.event.events.type.EventState; import baritone.api.event.events.type.EventState;
@@ -35,11 +34,9 @@ import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@@ -54,13 +51,9 @@ public class MixinMinecraft {
@Shadow @Shadow
public EntityPlayerSP player; public EntityPlayerSP player;
@Shadow @Shadow
public WorldClient world; public WorldClient world;
@Unique
private BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider;
@Inject( @Inject(
method = "init", method = "init",
at = @At("RETURN") at = @At("RETURN")
@@ -75,62 +68,23 @@ public class MixinMinecraft {
value = "FIELD", value = "FIELD",
opcode = Opcodes.GETFIELD, opcode = Opcodes.GETFIELD,
target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;", target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;",
ordinal = 0, ordinal = 5,
shift = At.Shift.BEFORE shift = At.Shift.BY,
), by = -3
slice = @Slice(
from = @At(
value = "FIELD",
opcode = Opcodes.PUTFIELD,
target = "net/minecraft/client/Minecraft.leftClickCounter:I"
)
) )
) )
private void runTick(CallbackInfo ci) { private void runTick(CallbackInfo ci) {
this.tickProvider = TickEvent.createNextProvider(); final BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider = TickEvent.createNextProvider();
for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) { for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
? TickEvent.Type.IN ? TickEvent.Type.IN
: TickEvent.Type.OUT; : TickEvent.Type.OUT;
baritone.getGameEventHandler().onTick(this.tickProvider.apply(EventState.PRE, type));
}
}
@Inject( baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type));
method = "runTick",
at = @At("RETURN")
)
private void postRunTick(CallbackInfo ci) {
if (this.tickProvider == null) {
return;
} }
for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
? TickEvent.Type.IN
: TickEvent.Type.OUT;
baritone.getGameEventHandler().onPostTick(this.tickProvider.apply(EventState.POST, type));
}
this.tickProvider = null;
}
@Inject(
method = "runTick",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/multiplayer/WorldClient.updateEntities()V",
shift = At.Shift.AFTER
)
)
private void postUpdateEntities(CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.player);
if (baritone != null) {
// Intentionally call this after all entities have been updated. That way, any modification to rotations
// can be recognized by other entity code. (Fireworks and Pigs, for example)
baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
}
} }
@Inject( @Inject(

View File

@@ -1,35 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.utils.accessor.INBTTagLongArray;
import net.minecraft.nbt.NBTTagLongArray;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
/**
* @author rycbar
* @since 26.09.2022
*/
@Mixin(NBTTagLongArray.class)
public abstract class MixinNBTTagLongArray implements INBTTagLongArray {
@Accessor("data")
@Override
public abstract long[] getLongArray();
}

View File

@@ -17,29 +17,24 @@
package baritone.launch.mixins; package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI; import baritone.api.BaritoneAPI;
import baritone.api.IBaritone; import baritone.api.IBaritone;
import baritone.api.event.events.BlockChangeEvent;
import baritone.api.event.events.ChunkEvent; import baritone.api.event.events.ChunkEvent;
import baritone.api.event.events.type.EventState; import baritone.api.event.events.type.EventState;
import baritone.api.utils.Pair; import baritone.cache.CachedChunk;
import net.minecraft.block.state.IBlockState; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.network.NetHandlerPlayClient; import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.SPacketBlockChange; import net.minecraft.network.play.server.SPacketBlockChange;
import net.minecraft.network.play.server.SPacketChunkData; import net.minecraft.network.play.server.SPacketChunkData;
import net.minecraft.network.play.server.SPacketCombatEvent; import net.minecraft.network.play.server.SPacketCombatEvent;
import net.minecraft.network.play.server.SPacketMultiBlockChange; import net.minecraft.network.play.server.SPacketMultiBlockChange;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos; import net.minecraft.util.math.ChunkPos;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Collectors;
/** /**
* @author Brady * @author Brady
* @since 8/3/2018 * @since 8/3/2018
@@ -55,18 +50,19 @@ public class MixinNetHandlerPlayClient {
) )
) )
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) { private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (baritone == null) { EntityPlayerSP player = ibaritone.getPlayerContext().player();
return; if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
}
} }
baritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
} }
@Inject( @Inject(
@@ -74,18 +70,19 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN") at = @At("RETURN")
) )
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) { private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (baritone == null) { EntityPlayerSP player = ibaritone.getPlayerContext().player();
return; if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
}
} }
baritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
} }
@Inject( @Inject(
@@ -93,14 +90,25 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN") at = @At("RETURN")
) )
private void postHandleBlockChange(SPacketBlockChange packetIn, CallbackInfo ci) { private void postHandleBlockChange(SPacketBlockChange packetIn, CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); if (!Baritone.settings().repackOnAnyBlockChange.value) {
if (baritone == null) {
return; return;
} }
if (!CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(packetIn.getBlockState().getBlock())) {
final ChunkPos pos = new ChunkPos(packetIn.getBlockPosition().getX() >> 4, packetIn.getBlockPosition().getZ() >> 4); return;
final Pair<BlockPos, IBlockState> changed = new Pair<>(packetIn.getBlockPosition(), packetIn.getBlockState()); }
baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent(pos, Collections.singletonList(changed))); for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
EntityPlayerSP player = ibaritone.getPlayerContext().player();
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
ChunkEvent.Type.POPULATE_FULL,
packetIn.getBlockPosition().getX() >> 4,
packetIn.getBlockPosition().getZ() >> 4
)
);
}
}
} }
@Inject( @Inject(
@@ -108,20 +116,35 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN") at = @At("RETURN")
) )
private void postHandleMultiBlockChange(SPacketMultiBlockChange packetIn, CallbackInfo ci) { private void postHandleMultiBlockChange(SPacketMultiBlockChange packetIn, CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); if (!Baritone.settings().repackOnAnyBlockChange.value) {
if (baritone == null) {
return; return;
} }
if (packetIn.getChangedBlocks().length == 0) {
// All blocks have the same ChunkPos return;
final ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos()); }
https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.15
baritone.getGameEventHandler().onBlockChange(new BlockChangeEvent( {
pos, for (SPacketMultiBlockChange.BlockUpdateData update : packetIn.getChangedBlocks()) {
Arrays.stream(packetIn.getChangedBlocks()) if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(update.getBlockState().getBlock())) {
.map(data -> new Pair<>(data.getPos(), data.getBlockState())) break https;
.collect(Collectors.toList()) }
)); }
return;
}
ChunkPos pos = new ChunkPos(packetIn.getChangedBlocks()[0].getPos());
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
EntityPlayerSP player = ibaritone.getPlayerContext().player();
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
ChunkEvent.Type.POPULATE_FULL,
pos.x,
pos.z
)
);
}
}
} }
@Inject( @Inject(
@@ -132,10 +155,11 @@ public class MixinNetHandlerPlayClient {
) )
) )
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) { private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this); for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (baritone == null) { EntityPlayerSP player = ibaritone.getPlayerContext().player();
return; if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onPlayerDeath();
}
} }
baritone.getGameEventHandler().onPlayerDeath();
} }
} }

View File

@@ -16,15 +16,12 @@
"MixinChunkProviderServer", "MixinChunkProviderServer",
"MixinChunkRenderContainer", "MixinChunkRenderContainer",
"MixinChunkRenderWorker", "MixinChunkRenderWorker",
"MixinEntityFireworkRocket",
"MixinEntityLivingBase", "MixinEntityLivingBase",
"MixinEntityPlayerSP", "MixinEntityPlayerSP",
"MixinEntityRenderer", "MixinEntityRenderer",
"MixinGuiScreen", "MixinGuiScreen",
"MixinItemStack", "MixinItemStack",
"MixinItemTool",
"MixinMinecraft", "MixinMinecraft",
"MixinNBTTagLongArray",
"MixinNetHandlerPlayClient", "MixinNetHandlerPlayClient",
"MixinNetworkManager", "MixinNetworkManager",
"MixinPlayerControllerMP", "MixinPlayerControllerMP",
@@ -35,4 +32,4 @@
"MixinVboRenderList", "MixinVboRenderList",
"MixinWorldClient" "MixinWorldClient"
] ]
} }

View File

@@ -20,12 +20,11 @@ package baritone;
import baritone.api.BaritoneAPI; import baritone.api.BaritoneAPI;
import baritone.api.IBaritone; import baritone.api.IBaritone;
import baritone.api.Settings; import baritone.api.Settings;
import baritone.api.behavior.IBehavior;
import baritone.api.behavior.IElytraBehavior;
import baritone.api.event.listener.IEventBus; import baritone.api.event.listener.IEventBus;
import baritone.api.process.IBaritoneProcess; import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import baritone.behavior.*; import baritone.behavior.*;
import baritone.builder.Main;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import baritone.command.manager.CommandManager; import baritone.command.manager.CommandManager;
import baritone.event.GameEventHandler; import baritone.event.GameEventHandler;
@@ -35,19 +34,16 @@ import baritone.utils.BlockStateInterface;
import baritone.utils.GuiClick; import baritone.utils.GuiClick;
import baritone.utils.InputOverrideHandler; import baritone.utils.InputOverrideHandler;
import baritone.utils.PathingControlManager; import baritone.utils.PathingControlManager;
import baritone.utils.player.BaritonePlayerContext; import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import java.io.File;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue; import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit; import java.util.concurrent.TimeUnit;
import java.util.function.Function;
/** /**
* @author Brady * @author Brady
@@ -55,101 +51,85 @@ import java.util.function.Function;
*/ */
public class Baritone implements IBaritone { public class Baritone implements IBaritone {
private static final ThreadPoolExecutor threadPool; private static ThreadPoolExecutor threadPool;
private static File dir;
static { static {
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>()); threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
if (!Files.exists(dir.toPath())) {
try {
Files.createDirectories(dir.toPath());
} catch (IOException ignored) {}
}
} }
private final Minecraft mc; private GameEventHandler gameEventHandler;
private final Path directory;
private final GameEventHandler gameEventHandler; private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private InventoryBehavior inventoryBehavior;
private InputOverrideHandler inputOverrideHandler;
private final List<IBehavior> behaviors; private FollowProcess followProcess;
private final PathingBehavior pathingBehavior; private MineProcess mineProcess;
private final IElytraBehavior elytraBehavior; private GetToBlockProcess getToBlockProcess;
private final LookBehavior lookBehavior; private CustomGoalProcess customGoalProcess;
private final InventoryBehavior inventoryBehavior; private BuilderProcess builderProcess;
private final InputOverrideHandler inputOverrideHandler; private ExploreProcess exploreProcess;
private BackfillProcess backfillProcess;
private FarmProcess farmProcess;
private final FollowProcess followProcess; private PathingControlManager pathingControlManager;
private final MineProcess mineProcess; private SelectionManager selectionManager;
private final GetToBlockProcess getToBlockProcess; private CommandManager commandManager;
private final CustomGoalProcess customGoalProcess;
private final BuilderProcess builderProcess;
private final ExploreProcess exploreProcess;
private final FarmProcess farmProcess;
private final InventoryPauserProcess inventoryPauserProcess;
private final PathingControlManager pathingControlManager; private IPlayerContext playerContext;
private final SelectionManager selectionManager; private WorldProvider worldProvider;
private final CommandManager commandManager;
private final IPlayerContext playerContext;
private final WorldProvider worldProvider;
public BlockStateInterface bsi; public BlockStateInterface bsi;
Baritone(Minecraft mc) { Baritone() {
this.mc = mc;
this.behaviors = new ArrayList<>();
this.gameEventHandler = new GameEventHandler(this); this.gameEventHandler = new GameEventHandler(this);
this.directory = mc.gameDir.toPath().resolve("baritone");
if (!Files.exists(this.directory)) {
try {
Files.createDirectories(this.directory);
} catch (IOException ignored) {}
}
// Define this before behaviors try and get it, or else it will be null and the builds will fail! // Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = new BaritonePlayerContext(this, mc); this.playerContext = PrimaryPlayerContext.INSTANCE;
{ {
this.lookBehavior = this.registerBehavior(LookBehavior::new); // the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
this.elytraBehavior = this.registerBehavior(ElytraBehavior::create); pathingBehavior = new PathingBehavior(this);
this.pathingBehavior = this.registerBehavior(PathingBehavior::new); lookBehavior = new LookBehavior(this);
this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); memoryBehavior = new MemoryBehavior(this);
this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); inventoryBehavior = new InventoryBehavior(this);
this.registerBehavior(WaypointBehavior::new); inputOverrideHandler = new InputOverrideHandler(this);
} }
this.pathingControlManager = new PathingControlManager(this); this.pathingControlManager = new PathingControlManager(this);
{ {
this.followProcess = this.registerProcess(FollowProcess::new); this.pathingControlManager.registerProcess(followProcess = new FollowProcess(this));
this.mineProcess = this.registerProcess(MineProcess::new); this.pathingControlManager.registerProcess(mineProcess = new MineProcess(this));
this.customGoalProcess = this.registerProcess(CustomGoalProcess::new); // very high iq this.pathingControlManager.registerProcess(customGoalProcess = new CustomGoalProcess(this)); // very high iq
this.getToBlockProcess = this.registerProcess(GetToBlockProcess::new); this.pathingControlManager.registerProcess(getToBlockProcess = new GetToBlockProcess(this));
this.builderProcess = this.registerProcess(BuilderProcess::new); this.pathingControlManager.registerProcess(builderProcess = new BuilderProcess(this));
this.exploreProcess = this.registerProcess(ExploreProcess::new); this.pathingControlManager.registerProcess(exploreProcess = new ExploreProcess(this));
this.farmProcess = this.registerProcess(FarmProcess::new); this.pathingControlManager.registerProcess(backfillProcess = new BackfillProcess(this));
this.inventoryPauserProcess = this.registerProcess(InventoryPauserProcess::new); this.pathingControlManager.registerProcess(farmProcess = new FarmProcess(this));
this.registerProcess(BackfillProcess::new);
} }
this.worldProvider = new WorldProvider(this); this.worldProvider = new WorldProvider();
this.selectionManager = new SelectionManager(this); this.selectionManager = new SelectionManager(this);
this.commandManager = new CommandManager(this); this.commandManager = new CommandManager(this);
this.behaviors.forEach(IBehavior::onLoad); try {
} Main.main();
} catch (InterruptedException e) {
public void registerBehavior(IBehavior behavior) { e.printStackTrace();
this.behaviors.add(behavior); } catch (Throwable th) {
this.gameEventHandler.registerEventListener(behavior); th.printStackTrace();
} throw th;
}
public <T extends IBehavior> T registerBehavior(Function<Baritone, T> constructor) {
final T behavior = constructor.apply(this);
this.registerBehavior(behavior);
return behavior;
}
public <T extends IBaritoneProcess> T registerProcess(Function<Baritone, T> constructor) {
final T behavior = constructor.apply(this);
this.pathingControlManager.registerProcess(behavior);
return behavior;
} }
@Override @Override
@@ -157,6 +137,10 @@ public class Baritone implements IBaritone {
return this.pathingControlManager; return this.pathingControlManager;
} }
public void registerBehavior(Behavior behavior) {
this.gameEventHandler.registerEventListener(behavior);
}
@Override @Override
public InputOverrideHandler getInputOverrideHandler() { public InputOverrideHandler getInputOverrideHandler() {
return this.inputOverrideHandler; return this.inputOverrideHandler;
@@ -177,6 +161,10 @@ public class Baritone implements IBaritone {
return this.playerContext; return this.playerContext;
} }
public MemoryBehavior getMemoryBehavior() {
return this.memoryBehavior;
}
@Override @Override
public FollowProcess getFollowProcess() { public FollowProcess getFollowProcess() {
return this.followProcess; return this.followProcess;
@@ -196,7 +184,6 @@ public class Baritone implements IBaritone {
return this.lookBehavior; return this.lookBehavior;
} }
@Override
public ExploreProcess getExploreProcess() { public ExploreProcess getExploreProcess() {
return this.exploreProcess; return this.exploreProcess;
} }
@@ -206,15 +193,10 @@ public class Baritone implements IBaritone {
return this.mineProcess; return this.mineProcess;
} }
@Override
public FarmProcess getFarmProcess() { public FarmProcess getFarmProcess() {
return this.farmProcess; return this.farmProcess;
} }
public InventoryPauserProcess getInventoryPauserProcess() {
return this.inventoryPauserProcess;
}
@Override @Override
public PathingBehavior getPathingBehavior() { public PathingBehavior getPathingBehavior() {
return this.pathingBehavior; return this.pathingBehavior;
@@ -240,29 +222,24 @@ public class Baritone implements IBaritone {
return this.commandManager; return this.commandManager;
} }
@Override
public IElytraBehavior getElytraBehavior() {
return this.elytraBehavior;
}
@Override @Override
public void openClick() { public void openClick() {
new Thread(() -> { new Thread(() -> {
try { try {
Thread.sleep(100); Thread.sleep(100);
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick())); Helper.mc.addScheduledTask(() -> Helper.mc.displayGuiScreen(new GuiClick()));
} catch (Exception ignored) {} } catch (Exception ignored) {}
}).start(); }).start();
} }
public Path getDirectory() {
return this.directory;
}
public static Settings settings() { public static Settings settings() {
return BaritoneAPI.getSettings(); return BaritoneAPI.getSettings();
} }
public static File getDir() {
return dir;
}
public static Executor getExecutor() { public static Executor getExecutor() {
return threadPool; return threadPool;
} }

View File

@@ -22,15 +22,13 @@ import baritone.api.IBaritoneProvider;
import baritone.api.cache.IWorldScanner; import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommandSystem; import baritone.api.command.ICommandSystem;
import baritone.api.schematic.ISchematicSystem; import baritone.api.schematic.ISchematicSystem;
import baritone.cache.FasterWorldScanner; import baritone.cache.WorldScanner;
import baritone.command.CommandSystem; import baritone.command.CommandSystem;
import baritone.command.ExampleBaritoneControl; import baritone.command.ExampleBaritoneControl;
import baritone.utils.schematic.SchematicSystem; import baritone.utils.schematic.SchematicSystem;
import net.minecraft.client.Minecraft;
import java.util.Collections; import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
/** /**
* @author Brady * @author Brady
@@ -38,45 +36,30 @@ import java.util.concurrent.CopyOnWriteArrayList;
*/ */
public final class BaritoneProvider implements IBaritoneProvider { public final class BaritoneProvider implements IBaritoneProvider {
private final Baritone primary;
private final List<IBaritone> all; private final List<IBaritone> all;
private final List<IBaritone> allView;
public BaritoneProvider() { {
this.all = new CopyOnWriteArrayList<>(); this.primary = new Baritone();
this.allView = Collections.unmodifiableList(this.all); this.all = Collections.singletonList(this.primary);
// Setup chat control, just for the primary instance // Setup chat control, just for the primary instance
final Baritone primary = (Baritone) this.createBaritone(Minecraft.getMinecraft()); new ExampleBaritoneControl(this.primary);
primary.registerBehavior(ExampleBaritoneControl::new);
} }
@Override @Override
public IBaritone getPrimaryBaritone() { public IBaritone getPrimaryBaritone() {
return this.all.get(0); return primary;
} }
@Override @Override
public List<IBaritone> getAllBaritones() { public List<IBaritone> getAllBaritones() {
return this.allView; return all;
}
@Override
public synchronized IBaritone createBaritone(Minecraft minecraft) {
IBaritone baritone = this.getBaritoneForMinecraft(minecraft);
if (baritone == null) {
this.all.add(baritone = new Baritone(minecraft));
}
return baritone;
}
@Override
public synchronized boolean destroyBaritone(IBaritone baritone) {
return baritone != this.getPrimaryBaritone() && this.all.remove(baritone);
} }
@Override @Override
public IWorldScanner getWorldScanner() { public IWorldScanner getWorldScanner() {
return FasterWorldScanner.INSTANCE; return WorldScanner.INSTANCE;
} }
@Override @Override

View File

@@ -35,5 +35,6 @@ public class Behavior implements IBehavior {
protected Behavior(Baritone baritone) { protected Behavior(Baritone baritone) {
this.baritone = baritone; this.baritone = baritone;
this.ctx = baritone.getPlayerContext(); this.ctx = baritone.getPlayerContext();
baritone.registerBehavior(this);
} }
} }

File diff suppressed because it is too large Load Diff

View File

@@ -18,8 +18,8 @@
package baritone.behavior; package baritone.behavior;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.TickEvent; import baritone.api.event.events.TickEvent;
import baritone.api.utils.Helper;
import baritone.utils.ToolSet; import baritone.utils.ToolSet;
import net.minecraft.block.Block; import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState; import net.minecraft.block.state.IBlockState;
@@ -35,10 +35,7 @@ import java.util.OptionalInt;
import java.util.Random; import java.util.Random;
import java.util.function.Predicate; import java.util.function.Predicate;
public final class InventoryBehavior extends Behavior implements Helper { public final class InventoryBehavior extends Behavior {
int ticksSinceLastInventoryMove;
int[] lastTickRequestedMove; // not everything asks every tick, so remember the request while coming to a halt
public InventoryBehavior(Baritone baritone) { public InventoryBehavior(Baritone baritone) {
super(baritone); super(baritone);
@@ -56,28 +53,20 @@ public final class InventoryBehavior extends Behavior implements Helper {
// we have a crafting table or a chest or something open // we have a crafting table or a chest or something open
return; return;
} }
ticksSinceLastInventoryMove++;
if (firstValidThrowaway() >= 9) { // aka there are none on the hotbar, but there are some in main inventory if (firstValidThrowaway() >= 9) { // aka there are none on the hotbar, but there are some in main inventory
requestSwapWithHotBar(firstValidThrowaway(), 8); swapWithHotBar(firstValidThrowaway(), 8);
} }
int pick = bestToolAgainst(Blocks.STONE, ItemPickaxe.class); int pick = bestToolAgainst(Blocks.STONE, ItemPickaxe.class);
if (pick >= 9) { if (pick >= 9) {
requestSwapWithHotBar(pick, 0); swapWithHotBar(pick, 0);
}
if (lastTickRequestedMove != null) {
logDebug("Remembering to move " + lastTickRequestedMove[0] + " " + lastTickRequestedMove[1] + " from a previous tick");
requestSwapWithHotBar(lastTickRequestedMove[0], lastTickRequestedMove[1]);
} }
} }
public boolean attemptToPutOnHotbar(int inMainInvy, Predicate<Integer> disallowedHotbar) { public void attemptToPutOnHotbar(int inMainInvy, Predicate<Integer> disallowedHotbar) {
OptionalInt destination = getTempHotbarSlot(disallowedHotbar); OptionalInt destination = getTempHotbarSlot(disallowedHotbar);
if (destination.isPresent()) { if (destination.isPresent()) {
if (!requestSwapWithHotBar(inMainInvy, destination.getAsInt())) { swapWithHotBar(inMainInvy, destination.getAsInt());
return false;
}
} }
return true;
} }
public OptionalInt getTempHotbarSlot(Predicate<Integer> disallowedHotbar) { public OptionalInt getTempHotbarSlot(Predicate<Integer> disallowedHotbar) {
@@ -101,20 +90,8 @@ public final class InventoryBehavior extends Behavior implements Helper {
return OptionalInt.of(candidates.get(new Random().nextInt(candidates.size()))); return OptionalInt.of(candidates.get(new Random().nextInt(candidates.size())));
} }
private boolean requestSwapWithHotBar(int inInventory, int inHotbar) { private void swapWithHotBar(int inInventory, int inHotbar) {
lastTickRequestedMove = new int[]{inInventory, inHotbar};
if (ticksSinceLastInventoryMove < Baritone.settings().ticksBetweenInventoryMoves.value) {
logDebug("Inventory move requested but delaying " + ticksSinceLastInventoryMove + " " + Baritone.settings().ticksBetweenInventoryMoves.value);
return false;
}
if (Baritone.settings().inventoryMoveOnlyIfStationary.value && !baritone.getInventoryPauserProcess().stationaryForInventoryMove()) {
logDebug("Inventory move requested but delaying until stationary");
return false;
}
ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player()); ctx.playerController().windowClick(ctx.player().inventoryContainer.windowId, inInventory < 9 ? inInventory + 36 : inInventory, inHotbar, ClickType.SWAP, ctx.player());
ticksSinceLastInventoryMove = 0;
lastTickRequestedMove = null;
return true;
} }
private int firstValidThrowaway() { // TODO offhand idk private int firstValidThrowaway() { // TODO offhand idk
@@ -216,8 +193,8 @@ public final class InventoryBehavior extends Behavior implements Helper {
if (allowInventory) { if (allowInventory) {
for (int i = 9; i < 36; i++) { for (int i = 9; i < 36; i++) {
if (desired.test(inv.get(i))) { if (desired.test(inv.get(i))) {
swapWithHotBar(i, 7);
if (select) { if (select) {
requestSwapWithHotBar(i, 7);
p.inventory.currentItem = 7; p.inventory.currentItem = 7;
} }
return true; return true;

View File

@@ -20,61 +20,40 @@ package baritone.behavior;
import baritone.Baritone; import baritone.Baritone;
import baritone.api.Settings; import baritone.api.Settings;
import baritone.api.behavior.ILookBehavior; import baritone.api.behavior.ILookBehavior;
import baritone.api.behavior.look.IAimProcessor; import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.behavior.look.ITickableAimProcessor; import baritone.api.event.events.RotationMoveEvent;
import baritone.api.event.events.*;
import baritone.api.utils.IPlayerContext;
import baritone.api.utils.Rotation; import baritone.api.utils.Rotation;
import baritone.behavior.look.ForkableRandom;
import com.google.common.collect.EvictingQueue;
import net.minecraft.network.play.client.CPacketPlayer;
import java.util.Optional;
public final class LookBehavior extends Behavior implements ILookBehavior { public final class LookBehavior extends Behavior implements ILookBehavior {
/** /**
* The current look target, may be {@code null}. * Target's values are as follows:
* <p>
* getFirst() -> yaw
* getSecond() -> pitch
*/ */
private Target target; private Rotation target;
/** /**
* The rotation known to the server. Returned by {@link #getEffectiveRotation()} for use in {@link IPlayerContext}. * Whether or not rotations are currently being forced
*/ */
private Rotation serverRotation; private boolean force;
/** /**
* The last player rotation. Used to restore the player's angle when using free look. * The last player yaw angle. Used when free looking
* *
* @see Settings#freeLook * @see Settings#freeLook
*/ */
private Rotation prevRotation; private float lastYaw;
private final AimProcessor processor;
private final EvictingQueue<Float> smoothYawBuffer;
public LookBehavior(Baritone baritone) { public LookBehavior(Baritone baritone) {
super(baritone); super(baritone);
this.processor = new AimProcessor(baritone.getPlayerContext());
this.smoothYawBuffer = EvictingQueue.create(10);
} }
@Override @Override
public void updateTarget(Rotation rotation, boolean blockInteract) { public void updateTarget(Rotation target, boolean force) {
this.target = new Target(rotation, Target.Mode.resolve(ctx, blockInteract)); this.target = target;
} this.force = force || !Baritone.settings().freeLook.value;
@Override
public IAimProcessor getAimProcessor() {
return this.processor;
}
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.IN) {
this.processor.tick();
}
} }
@Override @Override
@@ -82,37 +61,35 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
if (this.target == null) { if (this.target == null) {
return; return;
} }
// Whether or not we're going to silently set our angles
boolean silent = Baritone.settings().antiCheatCompatibility.value && !this.force;
switch (event.getState()) { switch (event.getState()) {
case PRE: { case PRE: {
if (this.target.mode == Target.Mode.NONE) { if (this.force) {
// Just return for PRE, we still want to set target to null on POST ctx.player().rotationYaw = this.target.getYaw();
return; float oldPitch = ctx.player().rotationPitch;
float desiredPitch = this.target.getPitch();
ctx.player().rotationPitch = desiredPitch;
ctx.player().rotationYaw += (Math.random() - 0.5) * Baritone.settings().randomLooking.value;
ctx.player().rotationPitch += (Math.random() - 0.5) * Baritone.settings().randomLooking.value;
if (desiredPitch == oldPitch && !Baritone.settings().freeLook.value) {
nudgeToLevel();
}
this.target = null;
} }
if (this.target.mode == Target.Mode.SERVER) { if (silent) {
this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch); this.lastYaw = ctx.player().rotationYaw;
ctx.player().rotationYaw = this.target.getYaw();
} }
final Rotation actual = this.processor.peekRotation(this.target.rotation);
ctx.player().rotationYaw = actual.getYaw();
ctx.player().rotationPitch = actual.getPitch();
break; break;
} }
case POST: { case POST: {
// Reset the player's rotations back to their original values if (silent) {
if (this.prevRotation != null) { ctx.player().rotationYaw = this.lastYaw;
if (Baritone.settings().smoothLook.value) { this.target = null;
this.smoothYawBuffer.add(this.target.rotation.getYaw());
ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream()
.mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw);
ctx.player().rotationPitch = this.prevRotation.getPitch();
} else {
ctx.player().rotationYaw = this.prevRotation.getYaw();
ctx.player().rotationPitch = this.prevRotation.getPitch();
}
this.prevRotation = null;
} }
// The target is done being used for this game tick, so it can be invalidated
this.target = null;
break; break;
} }
default: default:
@@ -120,218 +97,34 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
} }
} }
@Override
public void onSendPacket(PacketEvent event) {
if (!(event.getPacket() instanceof CPacketPlayer)) {
return;
}
final CPacketPlayer packet = (CPacketPlayer) event.getPacket();
if (packet instanceof CPacketPlayer.Rotation || packet instanceof CPacketPlayer.PositionRotation) {
this.serverRotation = new Rotation(packet.getYaw(0.0f), packet.getPitch(0.0f));
}
}
@Override
public void onWorldEvent(WorldEvent event) {
this.serverRotation = null;
this.target = null;
}
public void pig() { public void pig() {
if (this.target != null) { if (this.target != null) {
final Rotation actual = this.processor.peekRotation(this.target.rotation); ctx.player().rotationYaw = this.target.getYaw();
ctx.player().rotationYaw = actual.getYaw();
} }
} }
public Optional<Rotation> getEffectiveRotation() {
if (Baritone.settings().freeLook.value) {
return Optional.ofNullable(this.serverRotation);
}
// If freeLook isn't on, just defer to the player's actual rotations
return Optional.empty();
}
@Override @Override
public void onPlayerRotationMove(RotationMoveEvent event) { public void onPlayerRotationMove(RotationMoveEvent event) {
if (this.target != null) { if (this.target != null) {
final Rotation actual = this.processor.peekRotation(this.target.rotation);
event.setYaw(actual.getYaw()); event.setYaw(this.target.getYaw());
event.setPitch(actual.getPitch());
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
// Also the type has to be MOTION_UPDATE because that is called after JUMP
if (!Baritone.settings().antiCheatCompatibility.value && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE && !this.force) {
this.target = null;
}
} }
} }
private static final class AimProcessor extends AbstractAimProcessor { /**
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
public AimProcessor(final IPlayerContext ctx) { */
super(ctx); private void nudgeToLevel() {
} if (ctx.player().rotationPitch < -20) {
ctx.player().rotationPitch++;
@Override } else if (ctx.player().rotationPitch > 10) {
protected Rotation getPrevRotation() { ctx.player().rotationPitch--;
// Implementation will use LookBehavior.serverRotation
return ctx.playerRotations();
}
}
private static abstract class AbstractAimProcessor implements ITickableAimProcessor {
protected final IPlayerContext ctx;
private final ForkableRandom rand;
private double randomYawOffset;
private double randomPitchOffset;
public AbstractAimProcessor(IPlayerContext ctx) {
this.ctx = ctx;
this.rand = new ForkableRandom();
}
private AbstractAimProcessor(final AbstractAimProcessor source) {
this.ctx = source.ctx;
this.rand = source.rand.fork();
this.randomYawOffset = source.randomYawOffset;
this.randomPitchOffset = source.randomPitchOffset;
}
@Override
public final Rotation peekRotation(final Rotation rotation) {
final Rotation prev = this.getPrevRotation();
float desiredYaw = rotation.getYaw();
float desiredPitch = rotation.getPitch();
// In other words, the target doesn't care about the pitch, so it used playerRotations().getPitch()
// and it's safe to adjust it to a normal level
if (desiredPitch == prev.getPitch()) {
desiredPitch = nudgeToLevel(desiredPitch);
}
desiredYaw += this.randomYawOffset;
desiredPitch += this.randomPitchOffset;
return new Rotation(
this.calculateMouseMove(prev.getYaw(), desiredYaw),
this.calculateMouseMove(prev.getPitch(), desiredPitch)
).clamp();
}
@Override
public final void tick() {
this.randomYawOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value;
this.randomPitchOffset = (this.rand.nextDouble() - 0.5) * Baritone.settings().randomLooking.value;
}
@Override
public final void advance(int ticks) {
for (int i = 0; i < ticks; i++) {
this.tick();
}
}
@Override
public Rotation nextRotation(final Rotation rotation) {
final Rotation actual = this.peekRotation(rotation);
this.tick();
return actual;
}
@Override
public final ITickableAimProcessor fork() {
return new AbstractAimProcessor(this) {
private Rotation prev = AbstractAimProcessor.this.getPrevRotation();
@Override
public Rotation nextRotation(final Rotation rotation) {
return (this.prev = super.nextRotation(rotation));
}
@Override
protected Rotation getPrevRotation() {
return this.prev;
}
};
}
protected abstract Rotation getPrevRotation();
/**
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
*/
private float nudgeToLevel(float pitch) {
if (pitch < -20) {
return pitch + 1;
} else if (pitch > 10) {
return pitch - 1;
}
return pitch;
}
private float calculateMouseMove(float current, float target) {
final float delta = target - current;
final int deltaPx = angleToMouse(delta);
return current + mouseToAngle(deltaPx);
}
private int angleToMouse(float angleDelta) {
final float minAngleChange = mouseToAngle(1);
return Math.round(angleDelta / minAngleChange);
}
private float mouseToAngle(int mouseDelta) {
final float f = ctx.minecraft().gameSettings.mouseSensitivity * 0.6f + 0.2f;
return mouseDelta * f * f * f * 8.0f * 0.15f;
}
}
private static class Target {
public final Rotation rotation;
public final Mode mode;
public Target(Rotation rotation, Mode mode) {
this.rotation = rotation;
this.mode = mode;
}
enum Mode {
/**
* Rotation will be set client-side and is visual to the player
*/
CLIENT,
/**
* Rotation will be set server-side and is silent to the player
*/
SERVER,
/**
* Rotation will remain unaffected on both the client and server
*/
NONE;
static Mode resolve(IPlayerContext ctx, boolean blockInteract) {
final Settings settings = Baritone.settings();
final boolean antiCheat = settings.antiCheatCompatibility.value;
final boolean blockFreeLook = settings.blockFreeLook.value;
final boolean freeLook = settings.freeLook.value;
if (!freeLook) return CLIENT;
if (!blockFreeLook && blockInteract) return CLIENT;
if (ctx.player().isElytraFlying()) {
return settings.elytraFreeLook.value ? SERVER : CLIENT;
}
// Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player
// rotation needs to be set somehow, otherwise Baritone will halt since objectMouseOver() will just be
// whatever the player is mousing over visually. Let's just settle for setting it silently.
if (antiCheat || blockInteract) return SERVER;
// Pathing regularly without antiCheatCompatibility, don't set the player rotation
return NONE;
}
} }
} }
} }

View File

@@ -0,0 +1,319 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.Baritone;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.type.EventState;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.cache.ContainerMemory;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.Block;
import net.minecraft.block.BlockBed;
import net.minecraft.init.Blocks;
import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet;
import net.minecraft.network.play.client.CPacketCloseWindow;
import net.minecraft.network.play.client.CPacketPlayerTryUseItemOnBlock;
import net.minecraft.network.play.server.SPacketCloseWindow;
import net.minecraft.network.play.server.SPacketOpenWindow;
import net.minecraft.tileentity.TileEntity;
import net.minecraft.tileentity.TileEntityLockable;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextComponentTranslation;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
/**
* doesn't work for horse inventories :^)
*
* @author Brady
* @since 8/6/2018
*/
public final class MemoryBehavior extends Behavior {
private final List<FutureInventory> futureInventories = new ArrayList<>(); // this is per-bot
private Integer enderChestWindowId; // nae nae
public MemoryBehavior(Baritone baritone) {
super(baritone);
}
@Override
public synchronized void onTick(TickEvent event) {
if (!Baritone.settings().containerMemory.value) {
return;
}
if (event.getType() == TickEvent.Type.OUT) {
enderChestWindowId = null;
futureInventories.clear();
}
}
@Override
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
if (event.getState() == EventState.PRE) {
updateInventory();
}
}
@Override
public synchronized void onSendPacket(PacketEvent event) {
if (!Baritone.settings().containerMemory.value) {
return;
}
Packet p = event.getPacket();
if (event.getState() == EventState.PRE) {
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
CPacketPlayerTryUseItemOnBlock packet = event.cast();
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
// if tileEntity is an ender chest, we don't need to do anything. ender chests are treated the same regardless of what coordinate right clicked
// Ensure the TileEntity is a container of some sort
if (tileEntity instanceof TileEntityLockable) {
TileEntityLockable lockable = (TileEntityLockable) tileEntity;
int size = lockable.getSizeInventory();
BetterBlockPos position = BetterBlockPos.from(tileEntity.getPos());
BetterBlockPos adj = BetterBlockPos.from(neighboringConnectedBlock(position));
System.out.println(position + " " + adj);
if (adj != null) {
size *= 2; // double chest or double trapped chest
if (adj.getX() < position.getX() || adj.getZ() < position.getZ()) {
position = adj; // standardize on the lower coordinate, regardless of which side of the large chest we right clicked
}
}
this.futureInventories.add(new FutureInventory(System.nanoTime() / 1000000L, size, lockable.getGuiID(), position));
}
}
if (p instanceof CPacketCloseWindow) {
getCurrent().save();
}
}
}
@Override
public synchronized void onReceivePacket(PacketEvent event) {
if (!Baritone.settings().containerMemory.value) {
return;
}
Packet p = event.getPacket();
if (event.getState() == EventState.PRE) {
if (p instanceof SPacketOpenWindow) {
SPacketOpenWindow packet = event.cast();
// Remove any entries that were created over a second ago, this should make up for INSANE latency
futureInventories.removeIf(i -> System.nanoTime() / 1000000L - i.time > 1000);
System.out.println("Received packet " + packet.getGuiId() + " " + packet.getEntityId() + " " + packet.getSlotCount() + " " + packet.getWindowId());
System.out.println(packet.getWindowTitle());
if (packet.getWindowTitle() instanceof TextComponentTranslation && ((TextComponentTranslation) packet.getWindowTitle()).getKey().equals("container.enderchest")) {
// title is not customized (i.e. this isn't just a renamed shulker)
enderChestWindowId = packet.getWindowId();
return;
}
futureInventories.stream()
.filter(i -> i.type.equals(packet.getGuiId()) && i.slots == packet.getSlotCount())
.findFirst().ifPresent(matched -> {
// Remove the future inventory
futureInventories.remove(matched);
// Setup the remembered inventory
getCurrentContainer().setup(matched.pos, packet.getWindowId(), packet.getSlotCount());
});
}
if (p instanceof SPacketCloseWindow) {
getCurrent().save();
}
}
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, BetterBlockPos.from(event.getPos())));
}
}
@Override
public void onPlayerDeath() {
Waypoint deathWaypoint = new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet());
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(deathWaypoint);
ITextComponent component = new TextComponentString("Death position saved.");
component.getStyle()
.setColor(TextFormatting.WHITE)
.setHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new TextComponentString("Click to goto death")
))
.setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s goto %s @ %d",
FORCE_COMMAND_PREFIX,
"wp",
deathWaypoint.getTag().getName(),
deathWaypoint.getCreationTimestamp()
)
));
Helper.HELPER.logDirect(component);
}
private void updateInventory() {
if (!Baritone.settings().containerMemory.value) {
return;
}
int windowId = ctx.player().openContainer.windowId;
if (enderChestWindowId != null) {
if (windowId == enderChestWindowId) {
getCurrent().contents = ctx.player().openContainer.getInventory().subList(0, 27);
} else {
getCurrent().save();
enderChestWindowId = null;
}
}
if (getCurrentContainer() != null) {
getCurrentContainer().getInventoryFromWindow(windowId).ifPresent(inventory -> inventory.updateFromOpenWindow(ctx));
}
}
private ContainerMemory getCurrentContainer() {
if (baritone.getWorldProvider().getCurrentWorld() == null) {
return null;
}
return (ContainerMemory) baritone.getWorldProvider().getCurrentWorld().getContainerMemory();
}
private BlockPos neighboringConnectedBlock(BlockPos in) {
BlockStateInterface bsi = baritone.bsi;
Block block = bsi.get0(in).getBlock();
if (block != Blocks.TRAPPED_CHEST && block != Blocks.CHEST) {
return null; // other things that have contents, but can be placed adjacent without combining
}
for (int i = 0; i < 4; i++) {
BlockPos adj = in.offset(EnumFacing.byHorizontalIndex(i));
if (bsi.get0(adj).getBlock() == block) {
return adj;
}
}
return null;
}
/**
* An inventory that we are not yet fully aware of, but are expecting to exist at some point in the future.
*/
private static final class FutureInventory {
/**
* The time that we initially expected the inventory to be provided, in milliseconds
*/
private final long time;
/**
* The amount of slots in the inventory
*/
private final int slots;
/**
* The type of inventory
*/
private final String type;
/**
* The position of the inventory container
*/
private final BlockPos pos;
private FutureInventory(long time, int slots, String type, BlockPos pos) {
this.time = time;
this.slots = slots;
this.type = type;
this.pos = pos;
// betterblockpos has censoring
System.out.println("Future inventory created " + time + " " + slots + " " + type + " " + BetterBlockPos.from(pos));
}
}
public Optional<List<ItemStack>> echest() {
return Optional.ofNullable(getCurrent().contents).map(Collections::unmodifiableList);
}
public EnderChestMemory getCurrent() {
Path path = baritone.getWorldProvider().getCurrentWorld().directory;
return EnderChestMemory.getByServerAndPlayer(path.getParent(), ctx.player().getUniqueID());
}
public static class EnderChestMemory {
private static final Map<Path, EnderChestMemory> memory = new HashMap<>();
private final Path enderChest;
private List<ItemStack> contents;
private EnderChestMemory(Path enderChest) {
this.enderChest = enderChest;
System.out.println("Echest storing in " + enderChest);
try {
this.contents = ContainerMemory.readItemStacks(Files.readAllBytes(enderChest));
} catch (IOException e) {
e.printStackTrace();
System.out.println("CANNOT read echest =( =(");
this.contents = null;
}
}
public synchronized void save() {
System.out.println("Saving");
if (contents != null) {
try {
enderChest.getParent().toFile().mkdir();
Files.write(enderChest, ContainerMemory.writeItemStacks(contents));
} catch (IOException e) {
e.printStackTrace();
System.out.println("CANNOT save echest =( =(");
}
}
}
private static synchronized EnderChestMemory getByServerAndPlayer(Path serverStorage, UUID player) {
return memory.computeIfAbsent(serverStorage.resolve("echests").resolve(player.toString()), EnderChestMemory::new);
}
}
}

View File

@@ -99,7 +99,6 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
baritone.getPathingControlManager().cancelEverything(); baritone.getPathingControlManager().cancelEverything();
return; return;
} }
expectedSegmentStart = pathStart(); expectedSegmentStart = pathStart();
baritone.getPathingControlManager().preTick(); baritone.getPathingControlManager().preTick();
tickPath(); tickPath();
@@ -239,11 +238,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (current != null) { if (current != null) {
switch (event.getState()) { switch (event.getState()) {
case PRE: case PRE:
lastAutoJump = ctx.minecraft().gameSettings.autoJump; lastAutoJump = mc.gameSettings.autoJump;
ctx.minecraft().gameSettings.autoJump = false; mc.gameSettings.autoJump = false;
break; break;
case POST: case POST:
ctx.minecraft().gameSettings.autoJump = lastAutoJump; mc.gameSettings.autoJump = lastAutoJump;
break; break;
default: default:
break; break;
@@ -309,10 +308,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} }
public boolean isSafeToCancel() { public boolean isSafeToCancel() {
if (current == null) { return current == null || safeToCancel;
return !baritone.getElytraBehavior().isActive() || baritone.getElytraBehavior().isSafeToCancel();
}
return safeToCancel;
} }
public void requestPause() { public void requestPause() {
@@ -355,7 +351,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} }
// just cancel the current path // just cancel the current path
public void secretInternalSegmentCancel() { private void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED); queuePathEvent(PathEvent.CANCELED);
synchronized (pathPlanLock) { synchronized (pathPlanLock) {
getInProgress().ifPresent(AbstractNodeCostSearch::cancel); getInProgress().ifPresent(AbstractNodeCostSearch::cancel);

View File

@@ -1,92 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.Baritone;
import baritone.api.cache.IWaypoint;
import baritone.api.cache.Waypoint;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.Helper;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.BlockBed;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.util.text.TextComponentString;
import net.minecraft.util.text.TextFormatting;
import net.minecraft.util.text.event.ClickEvent;
import net.minecraft.util.text.event.HoverEvent;
import java.util.Set;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class WaypointBehavior extends Behavior {
public WaypointBehavior(Baritone baritone) {
super(baritone);
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (!Baritone.settings().doBedWaypoints.value)
return;
if (event.getType() == BlockInteractEvent.Type.USE) {
BetterBlockPos pos = BetterBlockPos.from(event.getPos());
IBlockState state = BlockStateInterface.get(ctx, pos);
if (state.getBlock() instanceof BlockBed) {
if (state.getValue(BlockBed.PART) == BlockBed.EnumPartType.FOOT) {
pos = pos.offset(state.getValue(BlockBed.FACING));
}
Set<IWaypoint> waypoints = baritone.getWorldProvider().getCurrentWorld().getWaypoints().getByTag(IWaypoint.Tag.BED);
boolean exists = waypoints.stream().map(IWaypoint::getLocation).filter(pos::equals).findFirst().isPresent();
if (!exists) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, pos));
}
}
}
}
@Override
public void onPlayerDeath() {
if (!Baritone.settings().doDeathWaypoints.value)
return;
Waypoint deathWaypoint = new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet());
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(deathWaypoint);
ITextComponent component = new TextComponentString("Death position saved.");
component.getStyle()
.setColor(TextFormatting.WHITE)
.setHoverEvent(new HoverEvent(
HoverEvent.Action.SHOW_TEXT,
new TextComponentString("Click to goto death")
))
.setClickEvent(new ClickEvent(
ClickEvent.Action.RUN_COMMAND,
String.format(
"%s%s goto %s @ %d",
FORCE_COMMAND_PREFIX,
"wp",
deathWaypoint.getTag().getName(),
deathWaypoint.getCreationTimestamp()
)
));
Helper.HELPER.logDirect(component);
}
}

View File

@@ -1,57 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior.elytra;
import dev.babbaj.pathfinder.NetherPathfinder;
import dev.babbaj.pathfinder.Octree;
/**
* @author Brady
*/
public final class BlockStateOctreeInterface {
private final NetherPathfinderContext context;
private final long contextPtr;
volatile long chunkPtr;
// Guarantee that the first lookup will fetch the context by setting MAX_VALUE
private int prevChunkX = Integer.MAX_VALUE;
private int prevChunkZ = Integer.MAX_VALUE;
public BlockStateOctreeInterface(final NetherPathfinderContext context) {
this.context = context;
this.contextPtr = context.context;
}
public boolean get0(final int x, final int y, final int z) {
if ((y | (128 - y)) < 0) {
return false;
}
final int chunkX = x >> 4;
final int chunkZ = z >> 4;
long pointer = this.chunkPtr;
if (pointer == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) {
this.prevChunkX = chunkX;
this.prevChunkZ = chunkZ;
synchronized (this.context.cacheLock) {
this.chunkPtr = pointer = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ);
}
}
return Octree.getBlock(pointer, x & 0xF, y & 0x7F, z & 0xF);
}
}

View File

@@ -1,65 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone 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.
*
* Baritone 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 Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior.elytra;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
/**
* @author Brady
*/
public final class NetherPath extends AbstractList<BetterBlockPos> {
private static final NetherPath EMPTY_PATH = new NetherPath(Collections.emptyList());
private final List<BetterBlockPos> backing;
NetherPath(List<BetterBlockPos> backing) {
this.backing = backing;
}
@Override
public BetterBlockPos get(int index) {
return this.backing.get(index);
}
@Override
public int size() {
return this.backing.size();
}
/**
* @return The last position in the path, or {@code null} if empty
*/
public BetterBlockPos getLast() {
return this.isEmpty() ? null : this.backing.get(this.backing.size() - 1);
}
public Vec3d getVec(int index) {
final BetterBlockPos pos = this.get(index);
return new Vec3d(pos.x, pos.y, pos.z);
}
public static NetherPath emptyPath() {
return EMPTY_PATH;
}
}

Some files were not shown because too many files have changed in this diff Show More