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

View File

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

5
.gitignore vendored
View File

@@ -27,8 +27,3 @@ baritone_Client.launch
# Copyright Files
!/.idea/copyright/Baritone.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 align="center">
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a>
<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>
<img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/>
<img src="https://img.shields.io/badge/MC-1.13.2-brightgreen.svg" alt="Minecraft"/>
<img src="https://img.shields.io/badge/MC-1.14.4-brightgreen.svg" alt="Minecraft"/>
<img src="https://img.shields.io/badge/MC-1.15.2-brightgreen.svg" alt="Minecraft"/>
<img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/>
</p>
<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://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="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://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>
@@ -36,7 +31,7 @@
<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://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://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>
@@ -51,29 +46,18 @@
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)
**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 |
|---------------------------------------------------------------------------------------------------------------|---------------------------------------------------------------------------------------------------------------|
| [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) |
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.
**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/),
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.
@@ -105,7 +89,7 @@ jar.
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().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)
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`.
@@ -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).
**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`
- **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.
- **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.
- **Forge/Fabric Unoptimized**: Same as Unoptimized, but packaged for Forge/Fabric.
## Build it yourself
- Clone or download Baritone
@@ -43,13 +42,13 @@ If another one of your Forge mods has a Baritone integration, you want `baritone
## Command Line
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
`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
In order to get JDK 8, Try running the following command:
`% /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
### 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
- 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)
- 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`.
Commands in Baritone:
Some common examples:
- `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
- `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 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)
- `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).
@@ -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).
- `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.
- `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
- `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>.
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'
version '1.2.17'
version '1.2.15'
buildscript {
repositories {
maven {
name = 'forge'
url = 'https://files.minecraftforge.net/maven'
url = 'http://files.minecraftforge.net/maven'
}
maven {
name = 'SpongePowered'
@@ -32,19 +32,18 @@ buildscript {
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:4.+' // TODO: 5.+. `doHackyStuff` relies on 4.x internals.
classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
}
}
import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
apply plugin: 'java'
apply plugin: 'maven-publish'
apply plugin: 'net.minecraftforge.gradle'
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: 'maven'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
apply plugin: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = '1.8'
@@ -54,19 +53,8 @@ compileJava {
}
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 {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
runtimeClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
schematica_api {
@@ -79,26 +67,13 @@ sourceSets {
}
minecraft {
mappings channel: 'stable', version: '39-1.12'
runs {
def nativesOutput = extractNatives.output // TODO: fg 5.0 - `def nativesOutput = extractNatives.output.get()`
println("[Baritoe] Detected natives: ${nativesOutput}")
client {
workingDirectory project.file('run')
source sourceSets.launch
version = '1.12.2'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
main 'net.minecraft.launchwrapper.Launch'
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}"
}
}
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
}
repositories {
@@ -113,74 +88,23 @@ repositories {
name = 'impactdevelopment-repo'
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 {
minecraft group: 'net.minecraft', name: 'joined', version: '1.12.2'
implementation(group: 'net.minecraft', name: 'launchwrapper', version: '1.12') {
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') {
runtime launchCompile('com.github.ImpactDevelopment:SimpleTweaker:1.2')
runtime launchCompile('org.spongepowered:mixin:0.7.11-SNAPSHOT') {
// 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'
}
mixin {
defaultObfuscationEnv searge
add sourceSets.launch, 'mixins.baritone.refmap.json'
}
@@ -206,7 +130,7 @@ jar {
manifest {
attributes(
'MixinConfigs': 'mixins.baritone.json',
'TweakClass': 'baritone.launch.BaritoneTweaker',
'Implementation-Title': 'Baritone',
'Implementation-Version': version
)
@@ -221,3 +145,25 @@ task proguard(type: ProguardTask) {
task createDist(type: CreateDistTask, dependsOn: proguard)
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 {
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
implementation group: 'commons-io', name: 'commons-io', version: '2.6'
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
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 {
protected static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
PROGUARD_CONFIG_DEST = "template.pro",
PROGUARD_API_CONFIG = "api.pro",
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar",
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
PROGUARD_CONFIG_DEST = "template.pro",
PROGUARD_API_CONFIG = "api.pro",
PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar",
TEMP_LIBRARY_DIR = "tempLibraries/",
TEMP_LIBRARY_DIR = "tempLibraries/",
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
protected String artifactName, artifactVersion;
@@ -56,17 +56,17 @@ class BaritoneGradleTask extends DefaultTask {
this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString();
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
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) {
return Paths.get(this.getProject().file(file).getAbsolutePath());
return Paths.get(new File(file).getAbsolutePath());
}
protected Path getTemporaryFile(String file) {

View File

@@ -18,33 +18,39 @@
package baritone.gradle.task;
import baritone.gradle.util.Determinizer;
import baritone.gradle.util.MappingType;
import baritone.gradle.util.ReobfWrapper;
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.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.TaskAction;
import org.gradle.api.tasks.TaskCollection;
import org.gradle.api.tasks.compile.ForkOptions;
import org.gradle.api.tasks.compile.JavaCompile;
import org.gradle.internal.Pair;
import org.gradle.internal.jvm.Jvm;
import java.io.File;
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 org.gradle.internal.jvm.inspection.DefaultJvmVersionDetector;
import org.gradle.process.internal.DefaultExecActionFactory;
import java.io.*;
import java.lang.reflect.Field;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.zip.ZipEntry;
import java.util.zip.ZipFile;
import static java.nio.file.StandardCopyOption.REPLACE_EXISTING;
/**
* @author Brady
* @since 10/11/2018
@@ -62,18 +68,17 @@ public class ProguardTask extends BaritoneGradleTask {
private List<String> requiredLibraries;
private File mixin;
private File pathfinder;
@TaskAction
protected void exec() throws Exception {
super.verifyArtifacts();
// "Haha brady why don't you make separate tasks"
processArtifact();
downloadProguard();
extractProguard();
generateConfigs();
acquireDependencies();
processArtifact();
proguardApi();
proguardStandalone();
cleanup();
@@ -84,7 +89,7 @@ public class ProguardTask extends BaritoneGradleTask {
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 {
@@ -109,7 +114,8 @@ public class ProguardTask extends BaritoneGradleTask {
try {
path = findJavaPathByGradleConfig();
if (path != null) return path;
} catch (Exception ex) {
}
catch (Exception ex) {
System.err.println("Unable to find java by javaCompile options");
ex.printStackTrace();
}
@@ -117,7 +123,8 @@ public class ProguardTask extends BaritoneGradleTask {
try {
path = findJavaByJavaHome();
if (path != null) return path;
} catch (Exception ex) {
}
catch(Exception ex) {
System.err.println("Unable to find java by JAVA_HOME");
ex.printStackTrace();
}
@@ -125,23 +132,30 @@ public class ProguardTask extends BaritoneGradleTask {
path = findJavaByGradleCurrentRuntime();
if (path != null) return path;
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)");
}
private String findJavaByGradleCurrentRuntime() {
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() {
final String javaHomeEnv = System.getenv("JAVA_HOME");
if (javaHomeEnv != null) {
String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath();
System.out.println("Detected Java path by JAVA_HOME");
return path;
if (this.validateJavaVersion(path)) {
System.out.println("Detected Java path by JAVA_HOME");
return path;
}
}
return null;
}
@@ -157,11 +171,19 @@ public class ProguardTask extends BaritoneGradleTask {
if (javacPath != null) {
File javacFile = new File(javacPath);
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) {
String path = maybeJava[0].getAbsolutePath();
System.out.println("Detected Java path by forkOptions");
return path;
if (this.validateJavaVersion(path)) {
System.out.println("Detected Java path by forkOptions");
return path;
}
}
}
}
@@ -169,13 +191,26 @@ public class ProguardTask extends BaritoneGradleTask {
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 {
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
List<String> template = Files.readAllLines(getTemporaryFile(PROGUARD_CONFIG_DEST));
template.add(0, "-injars '" + this.artifactPath.toString() + "'");
template.add(1, "-outjars '" + this.getTemporaryFile(PROGUARD_EXPORT_PATH) + "'");
template.add(0, "-injars " + this.artifactPath.toString());
template.add(1, "-outjars " + this.getTemporaryFile(PROGUARD_EXPORT_PATH));
// Acquire the RT jar using "java -verbose". This doesn't work on Java 9+
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 {
// 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
Map<String, Pair<Configuration, Dependency>> dependencyLookupMap = new HashMap<>();
Map<String, File> files = new HashMap<>();
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config -> {
for (File file : config.getFiles()) {
files.put(file.getName(), file);
}
config.getAllDependencies().forEach(dependency ->
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), new Pair<>(config, dependency)));
});
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
config.getAllDependencies().forEach(dependency ->
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
// Create the directory if it doesn't already exist
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
@@ -247,7 +259,7 @@ public class ProguardTask extends BaritoneGradleTask {
Path cachedJar = getMinecraftJar();
Path inTempDir = getTemporaryFile("tempLibraries/minecraft.jar");
// TODO: maybe try not to copy every time
Files.copy(cachedJar, inTempDir, StandardCopyOption.REPLACE_EXISTING);
Files.copy(cachedJar, inTempDir, REPLACE_EXISTING);
continue;
}
@@ -259,77 +271,118 @@ public class ProguardTask extends BaritoneGradleTask {
pair = entry.getValue();
}
}
// The pair must be non-null
Objects.requireNonNull(pair);
// Find the library jar file, and copy it to tempLibraries
if (pair == null) {
File libFile = files.get(lib + ".jar");
if (libFile == null) {
libFile = files.values().stream().filter(file -> file.getName().startsWith(lib)).findFirst().orElse(null);
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);
for (File file : pair.getLeft().files(pair.getRight())) {
if (file.getName().startsWith(lib)) {
if (lib.contains("mixin")) {
mixin = file;
}
Files.copy(file.toPath(), getTemporaryFile("tempLibraries/" + lib + ".jar"), REPLACE_EXISTING);
}
}
}
if (mixin == null) {
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
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 {
final Object extension = Objects.requireNonNull(project.getExtensions().findByName("minecraft"), "Unable to find Minecraft extension.");
// throws IllegalStateException if mapping type is ambiguous or it fails to find it
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());
final Field mcpRepoInstanceField = mcpRepoClass.getDeclaredField("INSTANCE");
mcpRepoInstanceField.setAccessible(true);
final Method findMethod = mcpRepoClass.getDeclaredMethod(srg ? "findSrg" : "findRaw", String.class, String.class);
findMethod.setAccessible(true);
List<MappingType> mappingTypes = getUsedMappingTypes(reobf);
long mappingTypesUsed = mappingTypes.size();
if (mappingTypesUsed == 0) {
throw new IllegalStateException("Failed to find mapping type (no jar task?)");
}
if (mappingTypesUsed > 1) {
throw new IllegalStateException("Ambiguous mapping type (multiple jars with different mapping types?)");
}
final Object mcpRepo = mcpRepoInstanceField.get(null);
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();
return mappingTypes.get(0);
}
private static Class<?> mcpRepoClass(final ClassLoader loader) throws Exception {
final Method forName0 = Class.class.getDeclaredMethod("forName0", String.class, boolean.class, ClassLoader.class, Class.class);
forName0.setAccessible(true);
return (Class<?>) forName0.invoke(null, "net.minecraftforge.gradle.mcp.MCPRepo", true, loader, null);
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
return reobf.stream()
.map(ReobfWrapper::new)
.map(ReobfWrapper::getMappingType)
.distinct()
.collect(Collectors.toList());
}
private void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Arrays.asList(pathfinder), false);
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Arrays.asList(pathfinder, mixin), true);
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Arrays.asList(pathfinder), false);
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Arrays.asList(pathfinder, mixin), true);
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
}
private void cleanup() {
@@ -342,33 +395,19 @@ public class ProguardTask extends BaritoneGradleTask {
this.url = url;
}
public String getUrl() {
return url;
}
public void setExtract(String extract) {
this.extract = extract;
}
public String getExtract() {
return extract;
}
private void runProguard(Path config) throws Exception {
// Delete the existing proguard output file. Proguard probably handles this already, but why not do it ourselves
if (Files.exists(this.proguardOut)) {
Files.delete(this.proguardOut);
}
// Make paths relative to work directory; fixes spaces in path to config, @"" doesn't work
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.
Path proguardJar = getTemporaryFile(PROGUARD_JAR);
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();
// 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
int exitCode = p.waitFor();
if (exitCode != 0) {
Thread.sleep(1000);
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 java.io.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.*;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -39,11 +36,10 @@ import java.util.stream.Collectors;
*/
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(" Input path: " + inputPath);
System.out.println(" Output path: " + outputPath);
System.out.println(" Shade: " + toInclude);
try (
JarFile jarFile = new JarFile(new File(inputPath));
@@ -64,10 +60,10 @@ public class Determinizer {
JarEntry clone = new JarEntry(entry.getName());
clone.setTime(42069);
jos.putNextEntry(clone);
if (entry.getName().endsWith(".json")) {
JsonElement json = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry)));
jos.write(writeSorted(json).getBytes());
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && doForgeReplacementOfMetaInf) { // only replace for forge jar
if (entry.getName().endsWith(".refmap.json")) {
JsonObject object = new JsonParser().parse(new InputStreamReader(jarFile.getInputStream(entry))).getAsJsonObject();
jos.write(writeSorted(object).getBytes());
} else if (entry.getName().equals("META-INF/MANIFEST.MF") && toInclude.isPresent()) { // only replace for forge jar
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
copy(jarFile.getInputStream(entry), cancer);
String manifest = new String(cancer.toByteArray());
@@ -80,8 +76,8 @@ public class Determinizer {
copy(jarFile.getInputStream(entry), jos);
}
}
for (File file : toInclude) {
try (JarFile mixin = new JarFile(file)) {
if (toInclude.isPresent()) {
try (JarFile mixin = new JarFile(toInclude.get())) {
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")) {
continue;
@@ -93,7 +89,6 @@ public class Determinizer {
}
jos.finish();
}
System.out.println("Done with determinizer");
}
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();
JsonWriter jw = new JsonWriter(writer);
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
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-all.zip
zipStoreBase=GRADLE_USER_HOME
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
#
# 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
@@ -44,7 +28,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
DEFAULT_JVM_OPTS=""
# Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum"
@@ -72,7 +56,7 @@ case "`uname`" in
Darwin* )
darwin=true
;;
MSYS* | MINGW* )
MINGW* )
msys=true
;;
NONSTOP* )
@@ -82,7 +66,6 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -126,11 +109,10 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi
# For Cygwin or MSYS, switch paths to Windows format before running java
if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
# For Cygwin, switch paths to Windows format before running java
if $cygwin ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath
@@ -156,19 +138,19 @@ if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
else
eval `echo args$i`="\"$arg\""
fi
i=`expr $i + 1`
i=$((i+1))
done
case $i in
0) set -- ;;
1) set -- "$args0" ;;
2) set -- "$args0" "$args1" ;;
3) set -- "$args0" "$args1" "$args2" ;;
4) set -- "$args0" "$args1" "$args2" "$args3" ;;
5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
(0) set -- ;;
(1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac
fi
@@ -177,9 +159,14 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " "
}
APP_ARGS=`save "$@"`
APP_ARGS=$(save "$@")
# Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@"

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
@rem ##########################################################################
@rem
@@ -29,18 +13,15 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
set DEFAULT_JVM_OPTS=
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto execute
if "%ERRORLEVEL%" == "0" goto init
echo.
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_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto execute
if exist "%JAVA_EXE%" goto init
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -64,14 +45,28 @@ echo location of your Java installation.
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
@rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
"%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
@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 *Annotation*
-keepattributes InnerClasses
-optimizationpasses 5
-verbose
@@ -23,7 +22,6 @@
-keep class baritone.api.IBaritoneProvider
-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,allowobfuscation @interface baritone.KeepName
@@ -42,10 +40,8 @@
#try to keep usage of schematica in separate classes
-keep class baritone.utils.schematic.schematica.**
-keep class baritone.utils.schematic.litematica.**
#proguard doesnt like it when it cant find our fake schematica classes
-dontwarn baritone.utils.schematic.schematica.**
-dontwarn baritone.utils.schematic.litematica.**
# copy all necessary libraries into tempLibraries to build
@@ -85,16 +81,16 @@
-libraryjars 'tempLibraries/netty-all-4.1.9.Final.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/realms-1.10.22.jar'
-libraryjars 'tempLibraries/soundsystem-20120107.jar'
-libraryjars 'tempLibraries/text2speech-1.10.3.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'

View File

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

View File

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

View File

@@ -21,9 +21,7 @@ import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommand;
import baritone.api.command.ICommandSystem;
import baritone.api.schematic.ISchematicSystem;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.network.NetHandlerPlayClient;
import java.util.List;
import java.util.Objects;
@@ -54,13 +52,15 @@ public interface IBaritoneProvider {
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
* @return The {@link IBaritone} instance.
*/
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
for (IBaritone baritone : this.getAllBaritones()) {
for (IBaritone baritone : getAllBaritones()) {
if (Objects.equals(player, baritone.getPlayerContext().player())) {
return baritone;
}
@@ -68,55 +68,6 @@ public interface IBaritoneProvider {
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
* {@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 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.ParameterizedType;
import java.lang.reflect.Type;
import java.util.List;
import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer;
import java.util.function.Consumer;
import java.util.function.BiConsumer;
/**
* 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);
/**
* 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
*/
@@ -74,16 +64,6 @@ public final class Settings {
*/
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
* <p>
@@ -122,13 +102,6 @@ public final class Settings {
*/
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.
* 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.
* 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);
@@ -219,13 +190,6 @@ public final class Settings {
/**
* 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?
Blocks.CRAFTING_TABLE,
Blocks.FURNACE,
@@ -236,11 +200,6 @@ public final class Settings {
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.
* <p>
@@ -263,8 +222,6 @@ public final class Settings {
* A mapping of blocks to blocks treated as correct in their position
* <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
* <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<>());
@@ -272,15 +229,6 @@ public final class Settings {
* A mapping of blocks to blocks to be built instead
* <p>
* 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<>());
@@ -298,17 +246,6 @@ public final class Settings {
*/
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.
* <p>
@@ -431,9 +368,6 @@ public final class Settings {
*/
public final Setting<Double> mobSpawnerAvoidanceCoefficient = new Setting<>(2.0);
/**
* Distance to avoid mob spawners.
*/
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);
/**
* Distance to avoid mobs.
*/
public final Setting<Integer> mobAvoidanceRadius = new Setting<>(8);
/**
@@ -596,17 +527,6 @@ public final class Settings {
*/
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.
*/
@@ -624,11 +544,11 @@ public final class Settings {
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>
* 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
@@ -731,28 +651,6 @@ public final class Settings {
*/
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.
* <p>
@@ -887,11 +785,6 @@ public final class Settings {
*/
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.
*/
@@ -976,7 +869,7 @@ public final class Settings {
/**
* 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
@@ -1188,15 +1081,13 @@ public final class Settings {
* via {@link Consumer#andThen(Consumer)} or it can completely be overriden via setting
* {@link Setting#value};
*/
@JavaOnly
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(msg -> Minecraft.getMinecraft().ingameGUI.getChatGUI().printChatMessage(msg));
public final Setting<Consumer<ITextComponent>> logger = new Setting<>(Minecraft.getMinecraft().ingameGUI.getChatGUI()::printChatMessage);
/**
* 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
* {@link Setting#value};
*/
@JavaOnly
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
* {@link Setting#value};
*/
@JavaOnly
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);
/**
* 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
*/
@@ -1432,7 +1239,6 @@ public final class Settings {
public T value;
public final T defaultValue;
private String name;
private boolean javaOnly;
@SuppressWarnings("unchecked")
private Setting(T value) {
@@ -1441,7 +1247,6 @@ public final class Settings {
}
this.value = value;
this.defaultValue = value;
this.javaOnly = false;
}
/**
@@ -1478,25 +1283,8 @@ public final class Settings {
public final Type getType() {
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
Settings() {
@@ -1512,7 +1300,6 @@ public final class Settings {
Setting<?> setting = (Setting<?>) field.get(this);
String name = field.getName();
setting.name = name;
setting.javaOnly = field.isAnnotationPresent(JavaOnly.class);
name = name.toLowerCase();
if (tmpByName.containsKey(name)) {
throw new IllegalStateException("Duplicate setting name");

View File

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

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

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/>.
*/
package fi.dy.masa.litematica.schematic.placement;
package baritone.api.cache;
import net.minecraft.util.math.BlockPos;
import javax.annotation.Nullable;
import java.io.File;
import java.util.Map;
public class SchematicPlacementUnloaded {
protected String name = "?";
@Nullable
protected File schematicFile;
protected BlockPos origin = BlockPos.ORIGIN;
/**
* @author Brady
* @since 9/23/2018
*/
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() {
return this.schematicFile;
}
public BlockPos getOrigin() {
return this.origin;
}
/**
* Gets the map of all block positions to their remembered inventories.
*
* @return Map of block positions to their respective remembered inventories
*/
Map<BlockPos, IRememberedInventory> getRememberedInventories();
}

View File

@@ -15,13 +15,25 @@
* 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
* @since 26.09.2022
* @author Brady
* @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();
/**
* @return The {@link IContainerMemory} instance
* @see IContainerMemory
*/
IContainerMemory getContainerMemory();
}

View File

@@ -17,8 +17,6 @@
package baritone.api.cache;
import java.util.function.Consumer;
/**
* @author Brady
* @since 9/24/2018
@@ -31,11 +29,4 @@ public interface IWorldProvider {
* @return The current world data
*/
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.util.ResourceLocation;
import java.util.regex.Pattern;
import java.util.stream.Stream;
public enum BlockById implements IDatatypeFor<Block> {
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
public Block get(IDatatypeContext ctx) throws CommandException {
ResourceLocation id = new ResourceLocation(ctx.getConsumer().getString());
@@ -46,19 +40,13 @@ public enum BlockById implements IDatatypeFor<Block> {
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
String arg = ctx.getConsumer().getString();
if (!PATTERN.matcher(arg).matches()) {
return Stream.empty();
}
return new TabCompleteHelper()
.append(
Block.REGISTRY.getKeys()
.stream()
.map(Object::toString)
)
.filterPrefixNamespaced(arg)
.filterPrefixNamespaced(ctx.getConsumer().getString())
.sortAlphabetically()
.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;
import baritone.api.command.exception.CommandException;
import baritone.api.command.helpers.TabCompleteHelper;
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;
public enum ForBlockOptionalMeta implements IDatatypeFor<BlockOptionalMeta> {
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
public BlockOptionalMeta get(IDatatypeContext ctx) throws CommandException {
return new BlockOptionalMeta(ctx.getConsumer().getString());
}
@Override
public Stream<String> tabComplete(IDatatypeContext ctx) throws CommandException {
String arg = ctx.getConsumer().peekString();
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);
public Stream<String> tabComplete(IDatatypeContext ctx) {
return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE);
}
}

View File

@@ -26,8 +26,7 @@ import java.util.stream.Stream;
public enum RelativeCoordinate implements IDatatypePost<Double, Double> {
INSTANCE;
private static String ScalesAliasRegex = "[kKmM]";
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)(" + ScalesAliasRegex + "?)|)$");
private static Pattern PATTERN = Pattern.compile("^(~?)([+-]?(?:\\d+(?:\\.\\d*)?|\\.\\d+)([k-k]?)|)$");
@Override
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();
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;
}
if (matcher.group(2).toLowerCase().contains("m")) {
offset *= 1000000;
}
if (isRelative) {
return origin + offset;

View File

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

View File

@@ -19,6 +19,7 @@ package baritone.api.command.exception;
import baritone.api.command.ICommand;
import baritone.api.command.argument.ICommandArgument;
import net.minecraft.util.text.TextFormatting;
import java.util.List;
@@ -36,6 +37,10 @@ public class CommandUnhandledException extends RuntimeException implements IComm
@Override
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() {
return append(
BaritoneAPI.getSettings().allSettings.stream()
.filter(s -> !s.isJavaOnly())
.filter(s -> !SettingsUtil.javaOnlySetting(s))
.map(Settings.Setting::getName)
.sorted(String.CASE_INSENSITIVE_ORDER)
);

View File

@@ -84,7 +84,7 @@ public class Registry<V> {
* @param entry The entry to unregister.
*/
public void unregister(V entry) {
if (!registered(entry)) {
if (registered(entry)) {
return;
}
_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
*/
public EventState getState() {
public final EventState getState() {
return this.state;
}
/**
* @return The type of chunk event that occurred;
*/
public Type getType() {
public final Type getType() {
return this.type;
}
/**
* @return The Chunk X position.
*/
public int getX() {
public final int getX() {
return this.x;
}
/**
* @return The Chunk Z position.
*/
public int getZ() {
public final int getZ() {
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 {
/**
@@ -113,10 +106,6 @@ public final class ChunkEvent {
* <p>
* And it's a partial chunk
*/
POPULATE_PARTIAL;
public final boolean isPopulate() {
return this == POPULATE_FULL || this == POPULATE_PARTIAL;
}
POPULATE_PARTIAL
}
}

View File

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

View File

@@ -18,18 +18,9 @@
package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.Minecraft;
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 {
private static int overallTickCount;

View File

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

View File

@@ -41,14 +41,6 @@ public interface IGameEventListener {
*/
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.
*
@@ -80,13 +72,6 @@ public interface IGameEventListener {
*/
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.
* <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);
}
@Override
public boolean equals(Object o) {
return o.getClass() == GoalAxis.class;
}
@Override
public int hashCode() {
return 201385781;
}
@Override
public String toString() {
return "GoalAxis";

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos;
@@ -67,26 +66,6 @@ public class GoalBlock implements Goal, IGoalRenderPos {
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
public String toString() {
return String.format(
@@ -108,9 +87,9 @@ public class GoalBlock implements Goal, IGoalRenderPos {
public static double calculate(double xDiff, int yDiff, double zDiff) {
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
// therefore going from 0,yDiff,0 to a GoalYLevel of 0 is accurate
heuristic += GoalYLevel.calculate(0, yDiff);
// 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,0,0 to a GoalYLevel of pos.getY()-this.y is accurate
heuristic += GoalYLevel.calculate(yDiff, 0);
//use the pythagorean and manhattan mixture from GoalXZ
heuristic += GoalXZ.calculate(xDiff, zDiff);

View File

@@ -67,24 +67,6 @@ public class GoalComposite implements Goal {
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
public String toString() {
return "GoalComposite" + Arrays.toString(goals);

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
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);
}
@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
public String toString() {
return String.format(

View File

@@ -17,8 +17,6 @@
package baritone.api.pathing.goals;
import java.util.Objects;
/**
* Invert any goal.
* <p>
@@ -52,24 +50,6 @@ public class GoalInverted implements Goal {
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
public String toString() {
return String.format("GoalInverted{%s}", origin.toString());

View File

@@ -17,11 +17,10 @@
package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
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.DoubleIterator;
import net.minecraft.util.math.BlockPos;
public class GoalNear implements Goal, IGoalRenderPos {
@@ -87,27 +86,6 @@ public class GoalNear implements Goal, IGoalRenderPos {
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
public String toString() {
return String.format(

View File

@@ -18,12 +18,11 @@
package baritone.api.pathing.goals;
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.DoubleIterator;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
import java.util.Objects;
/**
* Useful for automated combat (retreating specifically)
@@ -125,29 +124,6 @@ public class GoalRunAway implements Goal {
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
public String toString() {
if (maintainY != null) {

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
@@ -70,31 +69,6 @@ public class GoalStrictDirection implements Goal {
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
public String toString() {
return String.format(

View File

@@ -17,7 +17,6 @@
package baritone.api.pathing.goals;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.SettingsUtil;
import baritone.api.utils.interfaces.IGoalRenderPos;
import net.minecraft.util.math.BlockPos;
@@ -73,26 +72,6 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
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
public String toString() {
return String.format(

View File

@@ -64,27 +64,6 @@ public class GoalXZ implements Goal {
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
public String toString() {
return String.format(

View File

@@ -58,24 +58,6 @@ public class GoalYLevel implements Goal, ActionCosts {
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
public String toString() {
return String.format(

View File

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

View File

@@ -38,11 +38,6 @@ public interface ICustomGoalProcess extends IBaritoneProcess {
*/
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.
*

View File

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

View File

@@ -17,7 +17,6 @@
package baritone.api.schematic;
import baritone.api.schematic.mask.Mask;
import net.minecraft.block.state.IBlockState;
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) {
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.state.IBlockState;
import net.minecraft.init.Blocks;
import java.util.Collection;
import java.util.HashMap;
import java.util.List;
@@ -34,7 +33,7 @@ public class SubstituteSchematic extends AbstractSchematic {
private final Map<Block, List<Block>> substitutions;
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());
this.schematic = schematic;
this.substitutions = substitutions;
@@ -81,10 +80,9 @@ public class SubstituteSchematic extends AbstractSchematic {
} 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;
}
private <T extends Comparable<T>> IBlockState copySingleProp(IBlockState fromState, IBlockState toState, IProperty<T> 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;
import it.unimi.dsi.fastutil.HashCommon;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper;
@@ -35,15 +36,6 @@ import javax.annotation.Nonnull;
*/
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 final int x;
@@ -88,25 +80,98 @@ public final class BetterBlockPos extends BlockPos {
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) {
// TODO use the same thing as BlockPos.fromLong();
// invertibility would be incredibly useful
/*
* This is the hashcode implementation of Vec3i (the superclass of the class which I shall not name)
*
* public int hashCode() {
* return (this.getY() + this.getZ() * 31) * 31 + this.getX();
* }
*
* 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;
return longHash(toLong(x, y, z));
}
public static long longHash(long packed) {
return murmur64(HASHCODE_MURMUR_MASK ^ packed);
}
public static long murmur64(long h) {
return HashCommon.murmurHash3(h);
}
@Override
@@ -211,39 +276,14 @@ public final class BetterBlockPos extends BlockPos {
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
@Nonnull
public String toString() {
return String.format(
"BetterBlockPos{x=%s,y=%s,z=%s}",
SettingsUtil.maybeCensor(x),
SettingsUtil.maybeCensor(y),
SettingsUtil.maybeCensor(z)
"BetterBlockPos{x=%d,y=%d,z=%d}",
x,
y,
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 com.google.common.collect.ImmutableSet;
import com.google.common.collect.ImmutableMap;
import net.minecraft.block.*;
import net.minecraft.block.properties.IProperty;
import net.minecraft.block.state.IBlockState;
@@ -37,24 +36,21 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
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 int meta;
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<Integer> stateHashes;
private final Set<Integer> stackHashes;
private final ImmutableSet<Integer> stateHashes;
private final ImmutableSet<Integer> stackHashes;
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
private static final Map<Object, Object> normalizations;
public BlockOptionalMeta(@Nonnull Block block, @Nullable Integer meta) {
this.block = block;
this.noMeta = meta == null;
this.meta = noMeta ? 0 : meta;
this.propertiesDescription = "{}";
this.blockstates = getStates(block, meta, Collections.emptyMap());
this.blockstates = getStates(block, meta);
this.stateHashes = getStateHashes(blockstates);
this.stackHashes = getStackHashes(blockstates);
}
@@ -64,27 +60,24 @@ public final class BlockOptionalMeta {
}
public BlockOptionalMeta(@Nonnull String selector) {
Matcher matcher = PATTERN.matcher(selector);
Matcher matcher = pattern.matcher(selector);
if (!matcher.find()) {
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)) {
throw new IllegalArgumentException("Invalid block ID");
}
block = Block.REGISTRY.getObject(id);
String props = matcher.group("properties");
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);
meta = noMeta ? 0 : Integer.parseInt(matchResult.group(2));
blockstates = getStates(block, getMeta());
stateHashes = getStateHashes(blockstates);
stackHashes = getStackHashes(blockstates);
}
@@ -250,32 +243,9 @@ public final class BlockOptionalMeta {
return state.getBlock().getMetaFromState(normalize(state));
}
private static Map<IProperty<?>, ?> parseProperties(Block block, String raw) {
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) {
private static Set<IBlockState> getStates(@Nonnull Block block, @Nullable Integer meta) {
return block.getBlockState().getValidStates().stream()
.filter(blockstate -> meta == null || stateMeta(blockstate) == meta)
.filter(blockstate -> properties.entrySet().stream().allMatch(entry ->
blockstate.getValue(entry.getKey()) == entry.getValue()
))
.collect(Collectors.toSet());
}
@@ -304,7 +274,6 @@ public final class BlockOptionalMeta {
return block;
}
@Deprecated // deprecated because getMeta() == null no longer implies that this BOM only cares about the block
public Integer getMeta() {
return noMeta ? null : meta;
}
@@ -331,11 +300,7 @@ public final class BlockOptionalMeta {
@Override
public String toString() {
if (noMeta) {
return String.format("BlockOptionalMeta{block=%s,properties=%s}", block, propertiesDescription);
} else {
return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
}
return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
}
public static IBlockState blockStateFromStack(ItemStack stack) {
@@ -350,12 +315,4 @@ public final class BlockOptionalMeta {
return null;
}
public Set<IBlockState> getAllBlockStates() {
return blockstates;
}
public Set<Integer> stackHashes() {
return stackHashes;
}
}

View File

@@ -17,70 +17,68 @@
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.state.IBlockState;
import net.minecraft.item.ItemStack;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Stream;
public class BlockOptionalMetaLookup {
private final ImmutableSet<Block> blockSet;
private final ImmutableSet<IBlockState> blockStateSet;
private final ImmutableSet<Integer> stackHashes;
private final BlockOptionalMeta[] boms;
public BlockOptionalMetaLookup(BlockOptionalMeta... 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) {
this(Stream.of(blocks)
this.boms = Stream.of(blocks)
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new));
.toArray(BlockOptionalMeta[]::new);
}
public BlockOptionalMetaLookup(List<Block> blocks) {
this(blocks.stream()
this.boms = blocks.stream()
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new));
.toArray(BlockOptionalMeta[]::new);
}
public BlockOptionalMetaLookup(String... blocks) {
this(Stream.of(blocks)
this.boms = Stream.of(blocks)
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new));
.toArray(BlockOptionalMeta[]::new);
}
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) {
return blockStateSet.contains(state);
for (BlockOptionalMeta bom : boms) {
if (bom.matches(state)) {
return true;
}
}
return false;
}
public boolean has(ItemStack stack) {
int hash = ((IItemStack) (Object) stack).getBaritoneHash();
return stackHashes.contains(hash)
|| stackHashes.contains(hash - stack.getItemDamage());
for (BlockOptionalMeta bom : boms) {
if (bom.matches(stack)) {
return true;
}
}
return false;
}
public List<BlockOptionalMeta> blocks() {

View File

@@ -42,10 +42,8 @@ public interface Helper {
Helper HELPER = new Helper() {};
/**
* The main game instance returned by {@link Minecraft#getMinecraft()}.
* Deprecated since {@link IPlayerContext#minecraft()} should be used instead (In the majority of cases).
* Instance of the game
*/
@Deprecated
Minecraft mc = Minecraft.getMinecraft();
static ITextComponent getPrefix() {
@@ -72,7 +70,7 @@ public interface Helper {
* @param message The message to display in the popup
*/
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
*/
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) {
logToast(getPrefix(), component);
} 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) {
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 net.minecraft.block.BlockSlab;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
@@ -34,8 +33,6 @@ import java.util.Optional;
*/
public interface IPlayerContext {
Minecraft minecraft();
EntityPlayerSP player();
IPlayerController playerController();
@@ -75,12 +72,6 @@ public interface IPlayerContext {
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() {
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 {
start = entity.getPositionEyes(1.0F); // do whatever is correct
}
Vec3d direction = RotationUtils.calcLookDirectionFromRotation(rotation);
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
Vec3d end = start.add(
direction.x * blockReachDistance,
direction.y * blockReachDistance,

View File

@@ -26,12 +26,12 @@ public class Rotation {
/**
* The yaw angle of this Rotation
*/
private final float yaw;
private float yaw;
/**
* The pitch angle of this Rotation
*/
private final float pitch;
private float pitch;
public Rotation(float yaw, float pitch) {
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
*

View File

@@ -37,13 +37,11 @@ public final class RotationUtils {
* 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 float DEG_TO_RAD_F = (float) DEG_TO_RAD;
/**
* 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 float RAD_TO_DEG_F = (float) RAD_TO_DEG;
/**
* 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
* @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) {
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 pos The target block position
* @return The optional rotation
* @see #reachable(IPlayerContext, BlockPos, double)
* @see #reachable(EntityPlayerSP, BlockPos, double)
*/
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) {
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
* 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 blockReachDistance The block reach distance of the entity
* @return The optional rotation
*/
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance) {
return reachable(ctx, pos, blockReachDistance, false);
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
return reachable(entity, pos, blockReachDistance, false);
}
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
if (BaritoneAPI.getSettings().remainWithExistingLookDirection.value && ctx.isLookingAt(pos)) {
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (baritone.getPlayerContext().isLookingAt(pos)) {
/*
* why add 0.0001?
* 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
*/
Rotation hypothetical = ctx.playerRotations().add(new Rotation(0, 0.0001F));
Rotation hypothetical = new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F);
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
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)) {
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);
}
}
Optional<Rotation> possibleRotation = reachableCenter(ctx, pos, blockReachDistance, wouldSneak);
Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance, wouldSneak);
//System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
IBlockState state = ctx.world().getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(ctx.world(), pos);
IBlockState state = entity.world.getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
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()) {
return possibleRotation;
}
@@ -215,55 +209,12 @@ public final class RotationUtils {
* 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.
*
* @param ctx Context for the viewing entity
* @param entity The viewing entity
* @param pos The target block position
* @param offsetPos The position of the block with the offset applied.
* @param blockReachDistance The block reach distance of the entity
* @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) {
Vec3d eyes = wouldSneak ? RayTraceUtils.inferSneakingEyePosition(entity) : entity.getPositionEyes(1.0F);
Rotation rotation = calcRotationFromVec3d(eyes, offsetPos, new Rotation(entity.rotationYaw, entity.rotationPitch));
@@ -280,7 +231,15 @@ public final class RotationUtils {
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) {
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.Settings;
import net.minecraft.block.Block;
import net.minecraft.client.Minecraft;
import net.minecraft.item.Item;
import net.minecraft.util.EnumFacing;
import net.minecraft.util.math.Vec3i;
@@ -45,10 +44,13 @@ import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static net.minecraft.client.Minecraft.getMinecraft;
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 String[] JAVA_ONLY_SETTINGS = {"logger", "notifier", "toaster"};
private static boolean isComment(String line) {
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 {
forEachLine(settingsByName(settingsName), line -> {
forEachLine(SETTINGS_PATH, line -> {
Matcher matcher = SETTING_PATTERN.matcher(line);
if (!matcher.matches()) {
Helper.HELPER.logDirect("Invalid syntax in setting file: " + line);
System.out.println("Invalid syntax in setting file: " + line);
return;
}
@@ -80,33 +82,29 @@ public class SettingsUtil {
try {
parseAndApply(settings, settingName, settingValue);
} catch (Exception ex) {
Helper.HELPER.logDirect("Unable to parse line " + line);
System.out.println("Unable to parse line " + line);
ex.printStackTrace();
}
});
} catch (NoSuchFileException ignored) {
Helper.HELPER.logDirect("Baritone settings file not found, resetting.");
System.out.println("Baritone settings file not found, resetting.");
} 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();
}
}
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)) {
out.write(settingToString(setting) + "\n");
}
} catch (Exception ex) {
Helper.HELPER.logDirect("Exception thrown while saving Baritone settings!");
System.out.println("Exception thrown while saving Baritone settings!");
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) {
List<Settings.Setting> modified = new ArrayList<>();
for (Settings.Setting setting : settings.allSettings) {
@@ -114,7 +112,7 @@ public class SettingsUtil {
System.out.println("NULL SETTING?" + setting.getName());
continue;
}
if (setting.isJavaOnly()) {
if (javaOnlySetting(setting)) {
continue; // NO
}
if (setting.value == setting.defaultValue) {
@@ -168,7 +166,7 @@ public class SettingsUtil {
}
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
if (setting.isJavaOnly()) {
if (javaOnlySetting(setting)) {
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
*/
@Deprecated
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 {
@@ -297,7 +299,7 @@ public class SettingsUtil {
Parser keyParser = Parser.getParser(keyType);
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()))
.collect(Collectors.joining(","));
}

View File

@@ -17,7 +17,6 @@
package baritone.api.utils.gui;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.toasts.GuiToast;
import net.minecraft.client.gui.toasts.IToast;
import net.minecraft.client.renderer.GlStateManager;
@@ -74,6 +73,6 @@ public class BaritoneToast implements IToast {
}
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;
}
@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
protected IBlockStatePalette palette;
@Override
public IBlockStatePalette getPalette() {
return palette;
}
@Override
public BitArray getStorage() {
return storage;
}
@Override
public IBlockState getAtPalette(int 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.world.World;
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.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import java.util.Optional;
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
*/
@Unique
private RotationMoveEvent jumpRotationEvent;
@Unique
private RotationMoveEvent elytraRotationEvent;
private MixinEntityLivingBase(World worldIn) {
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
super(worldIn);
this.jumpRotationEvent = jumpRotationEvent;
}
@Inject(
@@ -60,10 +54,14 @@ public abstract class MixinEntityLivingBase extends Entity {
at = @At("HEAD")
)
private void preMoveRelative(CallbackInfo ci) {
this.getBaritone().ifPresent(baritone -> {
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw, this.rotationPitch);
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
});
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
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(
@@ -81,38 +79,6 @@ public abstract class MixinEntityLivingBase extends Entity {
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(
method = "travel",
at = @At(
@@ -120,33 +86,17 @@ public abstract class MixinEntityLivingBase extends Entity {
target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V"
)
)
private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) {
Optional<IBaritone> baritone = this.getBaritone();
if (!baritone.isPresent()) {
// If a shadow is used here it breaks on Forge
this.moveRelative(strafe, up, forward, friction);
private void travel(EntityLivingBase self, float strafe, float up, float forward, float friction) {
// noinspection ConstantConditions
if (!EntityPlayerSP.class.isInstance(this) || BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this) == null) {
moveRelative(strafe, up, forward, friction);
return;
}
RotationMoveEvent event = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw, this.rotationPitch);
baritone.get().getGameEventHandler().onPlayerRotationMove(event);
this.rotationYaw = event.getYaw();
this.rotationPitch = event.getPitch();
RotationMoveEvent motionUpdateRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(motionUpdateRotationEvent);
float originalYaw = this.rotationYaw;
this.rotationYaw = motionUpdateRotationEvent.getYaw();
this.moveRelative(strafe, up, forward, friction);
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();
}
this.rotationYaw = originalYaw;
}
}

View File

@@ -61,8 +61,9 @@ public class MixinEntityPlayerSP {
method = "onUpdate",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/entity/AbstractClientPlayer.onUpdate()V",
shift = At.Shift.AFTER
target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z",
shift = At.Shift.BY,
by = -3
)
)
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(
method = "onLivingUpdate",
at = @At(

View File

@@ -20,7 +20,6 @@ package baritone.launch.mixins;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.WorldEvent;
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.mixin.Mixin;
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.Inject;
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.LocalCapture;
@@ -54,13 +51,9 @@ public class MixinMinecraft {
@Shadow
public EntityPlayerSP player;
@Shadow
public WorldClient world;
@Unique
private BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider;
@Inject(
method = "init",
at = @At("RETURN")
@@ -75,62 +68,23 @@ public class MixinMinecraft {
value = "FIELD",
opcode = Opcodes.GETFIELD,
target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;",
ordinal = 0,
shift = At.Shift.BEFORE
),
slice = @Slice(
from = @At(
value = "FIELD",
opcode = Opcodes.PUTFIELD,
target = "net/minecraft/client/Minecraft.leftClickCounter:I"
)
ordinal = 5,
shift = At.Shift.BY,
by = -3
)
)
private void runTick(CallbackInfo ci) {
this.tickProvider = TickEvent.createNextProvider();
final BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider = TickEvent.createNextProvider();
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().onTick(this.tickProvider.apply(EventState.PRE, type));
}
}
@Inject(
method = "runTick",
at = @At("RETURN")
)
private void postRunTick(CallbackInfo ci) {
if (this.tickProvider == null) {
return;
baritone.getGameEventHandler().onTick(tickProvider.apply(EventState.PRE, type));
}
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(

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

View File

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

View File

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

View File

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

View File

@@ -35,5 +35,6 @@ public class Behavior implements IBehavior {
protected Behavior(Baritone baritone) {
this.baritone = baritone;
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;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.TickEvent;
import baritone.api.utils.Helper;
import baritone.utils.ToolSet;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
@@ -35,10 +35,7 @@ import java.util.OptionalInt;
import java.util.Random;
import java.util.function.Predicate;
public final class InventoryBehavior extends Behavior implements Helper {
int ticksSinceLastInventoryMove;
int[] lastTickRequestedMove; // not everything asks every tick, so remember the request while coming to a halt
public final class InventoryBehavior extends Behavior {
public InventoryBehavior(Baritone 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
return;
}
ticksSinceLastInventoryMove++;
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);
if (pick >= 9) {
requestSwapWithHotBar(pick, 0);
}
if (lastTickRequestedMove != null) {
logDebug("Remembering to move " + lastTickRequestedMove[0] + " " + lastTickRequestedMove[1] + " from a previous tick");
requestSwapWithHotBar(lastTickRequestedMove[0], lastTickRequestedMove[1]);
swapWithHotBar(pick, 0);
}
}
public boolean attemptToPutOnHotbar(int inMainInvy, Predicate<Integer> disallowedHotbar) {
public void attemptToPutOnHotbar(int inMainInvy, Predicate<Integer> disallowedHotbar) {
OptionalInt destination = getTempHotbarSlot(disallowedHotbar);
if (destination.isPresent()) {
if (!requestSwapWithHotBar(inMainInvy, destination.getAsInt())) {
return false;
}
swapWithHotBar(inMainInvy, destination.getAsInt());
}
return true;
}
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())));
}
private boolean requestSwapWithHotBar(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;
}
private void swapWithHotBar(int inInventory, int inHotbar) {
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
@@ -216,8 +193,8 @@ public final class InventoryBehavior extends Behavior implements Helper {
if (allowInventory) {
for (int i = 9; i < 36; i++) {
if (desired.test(inv.get(i))) {
swapWithHotBar(i, 7);
if (select) {
requestSwapWithHotBar(i, 7);
p.inventory.currentItem = 7;
}
return true;

View File

@@ -20,61 +20,40 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.Settings;
import baritone.api.behavior.ILookBehavior;
import baritone.api.behavior.look.IAimProcessor;
import baritone.api.behavior.look.ITickableAimProcessor;
import baritone.api.event.events.*;
import baritone.api.utils.IPlayerContext;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.RotationMoveEvent;
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 {
/**
* 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
*/
private Rotation prevRotation;
private final AimProcessor processor;
private final EvictingQueue<Float> smoothYawBuffer;
private float lastYaw;
public LookBehavior(Baritone baritone) {
super(baritone);
this.processor = new AimProcessor(baritone.getPlayerContext());
this.smoothYawBuffer = EvictingQueue.create(10);
}
@Override
public void updateTarget(Rotation rotation, boolean blockInteract) {
this.target = new Target(rotation, Target.Mode.resolve(ctx, blockInteract));
}
@Override
public IAimProcessor getAimProcessor() {
return this.processor;
}
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.IN) {
this.processor.tick();
}
public void updateTarget(Rotation target, boolean force) {
this.target = target;
this.force = force || !Baritone.settings().freeLook.value;
}
@Override
@@ -82,37 +61,35 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
if (this.target == null) {
return;
}
// Whether or not we're going to silently set our angles
boolean silent = Baritone.settings().antiCheatCompatibility.value && !this.force;
switch (event.getState()) {
case PRE: {
if (this.target.mode == Target.Mode.NONE) {
// Just return for PRE, we still want to set target to null on POST
return;
if (this.force) {
ctx.player().rotationYaw = this.target.getYaw();
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) {
this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch);
if (silent) {
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;
}
case POST: {
// Reset the player's rotations back to their original values
if (this.prevRotation != null) {
if (Baritone.settings().smoothLook.value) {
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;
if (silent) {
ctx.player().rotationYaw = this.lastYaw;
this.target = null;
}
// The target is done being used for this game tick, so it can be invalidated
this.target = null;
break;
}
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() {
if (this.target != null) {
final Rotation actual = this.processor.peekRotation(this.target.rotation);
ctx.player().rotationYaw = actual.getYaw();
ctx.player().rotationYaw = this.target.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
public void onPlayerRotationMove(RotationMoveEvent event) {
if (this.target != null) {
final Rotation actual = this.processor.peekRotation(this.target.rotation);
event.setYaw(actual.getYaw());
event.setPitch(actual.getPitch());
event.setYaw(this.target.getYaw());
// 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 {
public AimProcessor(final IPlayerContext ctx) {
super(ctx);
}
@Override
protected Rotation getPrevRotation() {
// 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;
}
/**
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
*/
private void nudgeToLevel() {
if (ctx.player().rotationPitch < -20) {
ctx.player().rotationPitch++;
} else if (ctx.player().rotationPitch > 10) {
ctx.player().rotationPitch--;
}
}
}

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