Compare commits

...

457 Commits

Author SHA1 Message Date
Leijurv
f2679bea29 hopefully actually fix backtracking 2023-08-22 13:28:11 -07:00
leijurv
301ad40350 link to latest 2023-08-18 19:36:12 -07:00
leijurv
aee36e4d85 deprecate 1.12.2 2023-08-18 19:35:30 -07:00
Leijurv
4efa2b1272 fix backtracking bad behavior when render distance is tiny 2023-08-18 15:02:13 -07:00
Leijurv
c2308c650a mapping 2023-08-18 14:35:02 -07:00
leijurv
75b8554a11 bump readme 2023-08-17 17:14:33 -07:00
leijurv
d9cb2d91a0 v1.2.19 2023-08-17 16:57:11 -07:00
leijurv
d4b95110f5 fml 2023-08-17 16:56:22 -07:00
leijurv
8a2a20a1b3 1.16 and 1.18 deprecated 2023-08-17 14:40:26 -07:00
leijurv
7daf1022c0 Merge pull request #4100 from babbaj/fix-proguard-lol
proguard: get java from gradle runtime before JAVA_HOME
2023-08-15 21:33:42 -07:00
Babbaj
60d6791f0c proguard: get java from gradle runtime before JAVA_HOME 2023-08-16 00:27:23 -04:00
Leijurv
ca4385da7a update readme 2023-08-14 22:34:38 -07:00
Leijurv
661b16af7e v1.2.18 2023-08-14 22:20:42 -07:00
leijurv
f36072c8d3 Merge pull request #4099 from babbaj/elytra
make raytracer collide with unknown chunks
2023-08-14 22:16:27 -07:00
Babbaj
b1be4f29ad make raytracer collide with unknown chunks 2023-08-15 01:14:53 -04:00
Leijurv
7b911aa0a7 clean up elytra given 2b2t status 2023-08-14 20:51:39 -07:00
Brady
9ecb416bf3 Merge branch 'elytra' 2023-08-14 14:38:44 -05:00
Leijurv
f35e55ef66 unused 2023-08-14 12:34:24 -07:00
leijurv
b0929991b1 typo 2023-08-14 01:40:47 -07:00
leijurv
bd263e1bf8 message for 2b players just in case the update actually happens 2023-08-14 01:40:15 -07:00
Leijurv
535eccfc24 no longer applies 2023-08-13 22:46:51 -07:00
Leijurv
81e004380f thanks lamp! i love lamp! 2023-08-13 22:42:51 -07:00
Leijurv
d67a3d8bbc much better safety 2023-08-13 22:37:47 -07:00
Leijurv
36534eeb2d vastly more helpful 2023-08-13 22:13:33 -07:00
Leijurv
4e3a7abac9 recompute on change 2023-08-13 19:29:19 -07:00
leijurv
f331124895 Merge pull request #4096 from babbaj/elytra
add setting that makes unknown chunks air
2023-08-13 19:08:12 -07:00
Babbaj
15a38c4871 add setting that makes unknown chunks air 2023-08-13 21:58:07 -04:00
leijurv
070523511a Merge pull request #4092 from wagyourtail/master-1
fix badges
2023-08-07 14:43:35 -07:00
William Gray
0edcf65044 fix badges 2023-08-07 21:33:42 +00:00
Brady Hahn
139fd03470 Update lines of code badge to match style 2023-08-02 17:07:03 -05:00
leijurv
3215824a9e Merge pull request #4085 from TheAlan404/patch-1
Add badge count badge
2023-08-02 15:04:24 -07:00
Dennis
f5bd737ee9 add badge count badge 2023-08-02 21:19:35 +03:00
Leijurv
70640246b6 fix infinite memory usage / crash 2023-08-01 14:11:25 -07:00
Leijurv
8c1ccd6c19 reduce dumb behavior 2023-08-01 11:45:53 -07:00
Leijurv
7813a9caba looks better 2023-08-01 11:30:30 -07:00
Brady Hahn
231d3a376b Merge pull request #4084 from babbaj/elytra
more intuitive smooth look/free look settings
2023-08-01 00:19:08 -05:00
Babbaj
3791569519 refactor so that Target.Mode is not a lie
fine

yes honey
2023-08-01 01:12:38 -04:00
Babbaj
7aa3eda3f6 fix nudgeToLevel with smoothLook 2023-07-31 19:13:53 -04:00
Babbaj
0ca173f5dc separate smooth look setting for elytra 2023-07-31 19:13:53 -04:00
Babbaj
c0a1e6540f simplify smoothLook into one setting and separate smoothLook from freeLook 2023-07-31 19:13:52 -04:00
Leijurv
46f38f2ce7 orderly shutdown 2023-07-31 15:06:25 -07:00
Leijurv
64a881f990 elytra warning 2023-07-31 01:36:01 -07:00
Leijurv
541b710ea7 too aggressive 2023-07-31 00:27:50 -07:00
Leijurv
cc8afe95c5 setting for nether fortress 2023-07-31 00:18:43 -07:00
Leijurv
83feddf6be recalc if all points out of view 2023-07-31 00:12:15 -07:00
Leijurv
7662810405 add back unsegmenting 2023-07-31 00:12:01 -07:00
Leijurv
d921d2e367 live a little 2023-07-30 23:33:49 -07:00
Leijurv
9630224e78 whatever 2023-07-30 23:26:46 -07:00
Leijurv
134bfb2a16 fix two cases where it could get stuck indefinitely 2023-07-30 23:24:04 -07:00
Leijurv
36df7b17f8 destroy async 2023-07-30 22:56:33 -07:00
Leijurv
7e9cf2e1e9 ok its based now 2023-07-30 22:47:39 -07:00
leijurv
54511f13d9 Merge pull request #4081 from babbaj/elytra
increase air bubble radius, append destination to path when landing
2023-07-30 22:30:07 -07:00
Babbaj
27e45b816d increase air bubble radius, append destination to path when landing 2023-07-30 19:45:25 -04:00
Brady
3a6e5541fb Don't deploy elytra while PathingBehavior is active 2023-07-30 17:48:53 -05:00
Leijurv
a83d275622 forgot 2023-07-30 15:47:43 -07:00
Leijurv
d6adb52718 tweaks 2023-07-30 15:46:18 -07:00
leijurv
976f3439eb Merge pull request #4077 from babbaj/elytra
safer elytra landing
2023-07-30 14:23:33 -07:00
Babbaj
2e2c0ecc0b use MutableBlockPos 2023-07-29 11:52:37 -04:00
Babbaj
31d1656c48 safer landing 2023-07-29 00:22:52 -04:00
Brady
4b5a094f30 Render fields can be private now 2023-07-28 01:41:03 -05:00
Brady
6b611cf4c7 Move more state into SolverContext 2023-07-28 01:30:54 -05:00
Brady
90f2b39fba Remove glPushAttrib/glPopAttrib usage 2023-07-26 19:52:25 -05:00
leijurv
2164857408 Merge pull request #4070 from babbaj/elytra
fixes for comments in elytra pr
2023-07-26 13:13:03 -07:00
Babbaj
601a781983 improve control flow (fixes behavior.onTick() being called twice) 2023-07-24 08:21:46 -04:00
Babbaj
f14bb282f0 add null check to resetState 2023-07-24 04:41:19 -04:00
Babbaj
1e0dce8f41 127 instead of 128 2023-07-24 03:30:38 -04:00
Babbaj
45400a9685 fix concurrency concerns 2023-07-24 03:30:06 -04:00
leijurv
6ffe31b59e Merge pull request #4068 from babbaj/elytra
add dimension checks to elytra
2023-07-23 17:47:46 -07:00
Babbaj
293b556b56 add dimension checks 2023-07-23 20:46:12 -04:00
leijurv
dbf38efd83 Merge pull request #4067 from babbaj/elytra
elytra command improvements
2023-07-23 12:11:37 -07:00
Babbaj
e63aad7825 elytra command improvements 2023-07-23 15:09:56 -04:00
Leijurv
212ef4d4cc waste fireworks smiling_imp 2023-07-23 11:44:29 -07:00
leijurv
31e082b8dc Merge pull request #4066 from babbaj/elytra
safe landing improvements
2023-07-23 11:29:40 -07:00
Babbaj
75e8035551 safe landing improvements 2023-07-23 14:26:31 -04:00
Leijurv
f7f0521093 not legacy 2023-07-22 23:29:07 -07:00
leijurv
684fda2d1b Merge pull request #4063 from babbaj/elytra
make elytra play nice with CustomGoalProcess
2023-07-22 23:12:07 -07:00
leijurv
886091df50 Merge branch 'elytra' into elytra 2023-07-22 23:08:45 -07:00
Leijurv
9707dd7ce8 redo checkedpositions given y descending iteration order 2023-07-22 23:02:29 -07:00
Babbaj
b81d712a33 higher priority is good enough lol 2023-07-23 01:57:27 -04:00
leijurv
3ffacbf375 Merge pull request #4064 from babbaj/safe-landing
find safe landing spot for elytra
2023-07-22 22:48:00 -07:00
Babbaj
eec85b20be fix bias in comparator 2023-07-23 01:45:39 -04:00
Babbaj
c0ead0147a use priority queue to bias upwards 2023-07-23 01:38:07 -04:00
Babbaj
9bfa2025d5 memoize isSafeLandingSPot 2023-07-23 01:14:19 -04:00
Babbaj
bf63ffbc1d cringe fence hater 😭 2023-07-23 01:01:59 -04:00
Babbaj
985148b49a check for specific blocks to land on and anything non air is lava 2023-07-23 01:00:23 -04:00
Babbaj
9e78443595 resolve comment 2023-07-23 00:53:26 -04:00
Babbaj
58723a33ca hate cherry pick now 2023-07-23 00:05:11 -04:00
Babbaj
c9aa1658b2 improvements/fixes 2023-07-23 00:03:31 -04:00
Babbaj
7f9e50bbe2 initial safe landing impl 2023-07-23 00:02:46 -04:00
Babbaj
664375a678 make elytra play nice with CustomGoalProcess 2023-07-22 01:55:12 -04:00
Brady
097e30850f Move WalkOffCalculationContext into ElytraProcess 2023-07-18 23:35:09 -05:00
Brady Hahn
a63cbab013 Merge pull request #4060 from babbaj/elytra
refactor elytra into process
2023-07-18 23:23:25 -05:00
Brady
218de1cb98 Requested changes 2023-07-18 16:48:00 -05:00
Babbaj
0239a2cad4 notificationOnPathComplete and disconnectOnArrival 2023-07-18 15:36:29 -04:00
Babbaj
38553b3324 behavior can't be null in onTick 2023-07-18 14:52:09 -04:00
Babbaj
ba78c48a75 shutdown solverExecutor 2023-07-18 13:36:55 -04:00
Babbaj
f4996137a3 minor code improvements 2023-07-18 13:36:55 -04:00
Babbaj
ccd80dfc8f that isn't necessary 2023-07-18 13:36:55 -04:00
Babbaj
ff1b3e7c5f simplify management of elytra state 2023-07-18 13:36:55 -04:00
Babbaj
2f0497756b simplify icky code 2023-07-18 13:36:54 -04:00
Babbaj
afe9359d3e don't call onTick if we are pawsed 2023-07-18 13:36:54 -04:00
Babbaj
4b5d629df6 fix off by one error (causing the last point to be stuck in terrain) 2023-07-18 13:36:54 -04:00
Babbaj
dbc0a46b10 call elytra event handlers from ElytraProcess 2023-07-18 13:36:54 -04:00
Babbaj
9a6241af8a refactor elytra into being just a process 2023-07-18 13:36:53 -04:00
Brady
1b82bd1f33 pitch smooth look and setting for ticks 2023-07-17 17:58:08 -05:00
Brady Hahn
90cfd82810 Merge pull request #4056 from babbaj/elytra
consistent elytra setting naming
2023-07-16 20:30:35 -05:00
Brady
108dbdae5d partially appease codacy 2023-07-16 20:29:30 -05:00
Brady
32a4c4644e Move cull code 2023-07-16 20:21:40 -05:00
Leijurv
edc92753cf Revert "shrimple"
This reverts commit 0e567f2f90.
2023-07-16 18:17:53 -07:00
Leijurv
0e567f2f90 shrimple 2023-07-16 18:17:15 -07:00
Babbaj
41e8c69db9 consistent elytra setting naming 2023-07-16 18:58:42 -04:00
Brady Hahn
a83d1901f2 Merge pull request #4055 from babbaj/elytra
cull far away chunks from the cache
2023-07-16 17:00:42 -05:00
Babbaj
f3bb5a0cb2 make sure BlockStateOctreeInterface doesn't use freed chunk pointers 2023-07-16 13:53:02 -04:00
Babbaj
76d3a13f58 cull far away chunks from the cache 2023-07-16 01:19:51 -04:00
Brady Hahn
6f99f891dc Merge pull request #4054 from babbaj/elytra
simple way to land at the goal
2023-07-15 22:24:42 -05:00
Brady Hahn
e579bf980d Update NetherPath.java 2023-07-15 22:23:59 -05:00
Brady Hahn
716b3ae0d2 Update ElytraBehavior.java
i love github web editor
2023-07-15 22:23:35 -05:00
Babbaj
b468b8eb95 landing procedure 2023-07-15 22:17:21 -04:00
Brady
1d109d4b9f crucial performance optimization 2023-07-13 14:47:19 -05:00
Brady
29bf046aa8 BlockStateOctreeInterface 2023-07-13 14:28:51 -05:00
Brady Hahn
4399b7c2fb Merge pull request #4053 from babbaj/elytra
auto swap elytra
2023-07-13 13:37:30 -05:00
Babbaj
d35571923f appease brady 2023-07-13 14:35:33 -04:00
Babbaj
461f56c4d6 countdown instead of count up 2023-07-13 14:21:15 -04:00
Babbaj
0b5d5b8176 use ticksBetweenInventoryMoves 2023-07-12 22:54:04 -04:00
Babbaj
42771686c6 auto swap elytra 2023-07-12 16:42:14 -04:00
Brady
8f5105c454 trolled pt2 2023-07-11 22:50:35 -05:00
Brady
7c696b7055 trolled 2023-07-11 22:49:51 -05:00
Brady
349c951b55 Better handling of unsupported systems 2023-07-11 22:47:09 -05:00
Leijurv
5dc403e643 crucial performance optimization 2023-07-10 00:12:10 -07:00
Brady Hahn
a8e1b16dee Merge pull request #4048 from babbaj/elytra
don't send the whole chunk for small changes
2023-07-09 22:31:42 -07:00
Babbaj
dc53a95bef don't send the whole chunk for small changes 2023-07-10 00:45:12 -04:00
Brady
eec4edea05 Remove old pack method 2023-07-09 20:00:35 -07:00
Brady Hahn
70249e5fa7 Merge pull request #4047 from babbaj/elytra
optimize uploading chunk data
2023-07-09 19:58:59 -07:00
Babbaj
96a64b454e optimize uploading chunk data 2023-07-09 22:29:31 -04:00
Brady
7a935fb2ea Fix simulation not respecting ignoreLava 2023-07-09 09:12:21 -07:00
Brady
c0cdfb7781 Add commands for pathfinder reset and chunk repack 2023-07-07 19:44:59 -07:00
Brady
487b3a759a mostRecentGoal, fixes immediate goal clear 2023-07-07 18:35:02 -07:00
Brady
fe67489419 Combine VALIDATE_PATH and LOCATE_JUMP states 2023-07-07 14:38:11 -07:00
Brady
308b9bbfea Apply minimum fall height to regular falls too 2023-07-07 13:26:43 -07:00
Brady
bfb4ffcafc Reset context on world load/unload 2023-07-07 11:19:18 -07:00
Brady
537100a5e5 Nether seed setting and automatic context reset 2023-07-07 10:44:56 -07:00
Brady
b6bf4427ef Use soft references for nether chunk packing queue 2023-07-07 00:30:07 -07:00
Brady
8de239f468 Use soft references for chunks queued for packing 2023-07-06 23:15:35 -07:00
Brady
ecfd664f30 Fix isSafeToCancel() return value 2023-07-06 20:11:50 -07:00
Brady
c4ac23837f Set safeToCancel to false while flying 2023-07-06 19:31:37 -07:00
Brady
aeeb001205 Fix some codacy issues 2023-07-06 19:02:13 -07:00
Brady
2552eb8dca Add setting documentation 2023-07-06 18:57:51 -07:00
Brady
4c0c263d11 trolling 2023-07-03 13:28:53 -05:00
Brady
c8259d3e90 ZOOM 2023-07-03 13:27:23 -05:00
Brady
d892ef54f0 Merge branch 'master' into elytra 2023-07-02 20:04:04 -05:00
Brady
6654476da4 Make blockFreeLook depend on freeLook 2023-07-02 19:59:26 -05:00
Brady
fc209599af Update nether-pathfinder to 0.21 2023-07-02 01:03:34 -05:00
Brady
dee7df1534 I HATE OLD MIXIN!!!!
awesome buggy 0.7.11 hates referencing shadows in mixin superclasses wooooooo
2023-07-01 19:38:38 -05:00
Brady
ccd737d0a1 Actually fix Forge by reverting Mixin change completely 2023-07-01 18:38:13 -05:00
Brady
14b5a0cec3 Fix Forge support 2023-07-01 17:28:23 -05:00
Brady
2f7dc2397e Better start position selection and validation 2023-07-01 01:32:03 -05:00
Brady
3498082f2b Better state switch and start path halfway down fall 2023-06-30 20:53:42 -05:00
Brady
83066fc57c Find jump off spot using INSANE custom CalculationContext 2023-06-30 20:42:03 -05:00
Brady
d32f1b2a16 Add hit pos raytrace method to context 2023-06-30 20:38:45 -05:00
Leijurv
8211ae4af5 memory leaks are joever 2023-06-29 21:59:31 -07:00
Brady
4590ba3ff8 Use separate executor for solver 2023-06-29 23:35:12 -05:00
Brady
b4578931d3 Reduce passing around of ignoreLava 2023-06-29 22:59:15 -05:00
Brady
b8ede0a652 Remove unnecessary IPlayerContext argument 2023-06-29 22:54:55 -05:00
Brady
3eb7610f89 Block lookup optimization 2023-06-29 20:45:59 -05:00
Brady
5a48f4119e Reduce number of raytraces when validating simulation 2023-06-29 19:15:06 -05:00
Brady
974b86aac1 Bump nether-pathfinder to 0.20 2023-06-29 18:50:29 -05:00
Brady
f30cb916bd Remove addressed TODO 2023-06-29 14:53:55 -05:00
Brady
494ebfa10d More accurate isActive return value 2023-06-29 14:53:12 -05:00
Brady
222f53b105 Use Arrays.fill 2023-06-29 14:46:42 -05:00
Brady
12898df2f1 Reduce main thread recalculations after using a firework 2023-06-29 14:46:04 -05:00
Brady
fbb66a0586 Tweaks 2023-06-29 14:14:49 -05:00
Brady
48462da473 Disable interp on relaxation 0 2023-06-28 21:47:37 -05:00
Brady
4b689bd946 Fix Supplier meme 2023-06-28 17:55:47 -05:00
Brady
5126ec9c36 interp double 2023-06-28 17:49:33 -05:00
Brady
d640ebb02d Reliability improvements 2023-06-28 17:47:01 -05:00
Brady
0bb6f1b094 Invalidate pendingSolution 2023-06-28 01:05:22 -05:00
Brady
bb39fea415 Considerations 2023-06-28 01:04:08 -05:00
Brady
7a61ab8137 We need event priorities. 2023-06-28 00:58:51 -05:00
Brady
7861860187 Clarify 2023-06-28 00:48:28 -05:00
Brady
70166f385d That should be in the other tick method 2023-06-28 00:47:20 -05:00
Brady
03ee30bca9 Call elytra tick() from the process 2023-06-28 00:46:14 -05:00
Brady
c48de32860 PitchResult 2023-06-27 16:31:08 -05:00
Brady
3b31387092 Render simulation line from player pos 2023-06-27 13:02:01 -05:00
Brady
ff12832a21 whoops 2023-06-27 12:30:41 -05:00
Brady
4ccaf681c5 Somewhat functional elytraAutoJump, but mostly scuffed 2023-06-27 02:54:53 -05:00
Brady
02fc62f1c4 Stop simulation when goal reached 2023-06-26 18:37:06 -05:00
Brady
04a5a1a620 Replace bool firework with ticksBoosted in solvePitch 2023-06-26 16:58:29 -05:00
Brady
3e94cac567 clarity 2023-06-26 16:25:21 -05:00
Brady
452b2c278b Fix renderElytraSimulation 2023-06-26 16:21:15 -05:00
Brady
db0bfbe722 Move elytra simulation into new method 2023-06-26 16:12:56 -05:00
Brady
f0148a625e Move steps into solvePitch 2023-06-26 16:04:05 -05:00
Brady
0b5a310f18 Move firework boost calculation into solvePitch 2023-06-26 15:35:40 -05:00
Brady
c18715b8d7 Reset minimumBoostTicks to 0 earlier 2023-06-26 14:00:38 -05:00
Brady
d244a39040 Make MixinEntityLivingBase extend MixinEntity 2023-06-26 13:57:24 -05:00
Brady
0981114b78 Create FireworkBoost class for additional boost context
Also initialize `boostedEntity` in `EntityFireworkRocket` if `null` since it's lazily initialized in `onUpdate()`
2023-06-26 13:55:18 -05:00
Brady
9bd0856445 lol 2023-06-25 15:32:02 -07:00
Brady
9d1addd114 Add smoothLook setting 2023-06-25 15:28:06 -07:00
Brady
1902e6c1f3 Reset minimumBoostTicks to 0 when not boosted 2023-06-24 22:37:21 -07:00
Brady
a1a3d93dc1 Add renderElytraSimulation setting 2023-06-24 22:27:38 -07:00
Brady
32b7c82650 Add renderHitboxRaytraces setting 2023-06-24 22:11:08 -07:00
Brady
615266ed96 Replace manual calculation with util method 2023-06-24 21:57:00 -07:00
Brady
15f4253b3d Clamp pitch to normal range 2023-06-24 21:48:44 -07:00
Brady
2ccd464a49 Utilize aim processor API for correct elytra simulation 2023-06-24 21:44:08 -07:00
Brady
f2374edd8b Merge branch 'master' into elytra
# Conflicts:
#	src/launch/java/baritone/launch/mixins/MixinMinecraft.java
#	src/main/java/baritone/Baritone.java
#	src/main/java/baritone/behavior/LookBehavior.java
2023-06-23 23:31:43 -07:00
leijurv
24b0bd2edf Merge pull request #4019 from ZacSharp/pr/misc/rotation/fixMouseStuck
Fix getting stuck due to impossible rotations
2023-06-23 21:59:34 -07:00
Brady
f56e0569a2 Add minimumBoostTicks 2023-06-23 16:30:10 -07:00
Brady
c10903be69 Remove firstFireworks from InventoryBehavior 2023-06-23 16:17:59 -07:00
ZacSharp
e3a1ac85cc Fix waiting for impossible rotations 2023-06-23 04:22:35 +02:00
leijurv
1ea071de09 Merge pull request #4015 from cabaletta/pr/deterministicLookTarget
API for rotations produced by LookBehavior
2023-06-22 19:21:02 -07:00
Brady
c9a18caf49 Register LookBehavior first
Since there's no event priority system, this is necessary to ensure anything else listening to the PRE `TickEvent` can accurately simulate rotations.
2023-06-22 20:38:00 -05:00
Brady
bfae100cb9 Create ITickableAimProcessor 2023-06-22 20:35:22 -05:00
Brady
878a32228a Add avoidance setting 2023-06-22 18:22:40 -05:00
Brady
bce2c74a8e NO MORE CONCUSSIONS! 2023-06-22 18:07:11 -05:00
Brady
90434b3178 A bit more flexibility 2023-06-22 12:54:30 -05:00
Brady
9cf5538058 Improve stepper collision detection 2023-06-22 12:50:06 -05:00
Brady
f4a99253f4 Prevent head bonks 2023-06-22 12:08:30 -05:00
Brady
b366b1b1d1 Fix other null checks 2023-06-22 11:40:45 -05:00
Brady Hahn
a90e720956 Merge pull request #4017 from babbaj/elytra
simplify null check
2023-06-22 11:40:08 -05:00
Babbaj
535fd17a42 simplify null check 2023-06-22 08:30:25 -04:00
Brady
47dc0f9b94 Add missing exception null check to async completed callback 2023-06-21 21:30:04 -05:00
Brady
4776fa1876 Don't update playerNear on an empty path 2023-06-21 21:19:12 -05:00
leijurv
b0ebbf4dfb Merge pull request #4007 from ZacSharp/pr/schematics/mask/fixBinaryOperatorMaskOOB
Don't call `partOfMask` out of bounds in `BinaryOperatorMask`
2023-06-21 18:53:58 -07:00
leijurv
9d12a4ba3d Merge pull request #4008 from ZacSharp/pr/pathing/goals/implHashCode
Implement `hashCode` for goals
2023-06-21 18:53:36 -07:00
leijurv
6dc953631b Merge pull request #4006 from ZacSharp/pr/blockOptionalMeta/tabCompleteProperties
Tab completion improvements
2023-06-21 18:53:06 -07:00
Brady
0aff31b768 Perfect elytra simulation 2023-06-21 18:59:44 -05:00
Brady
0682e63707 Apply processor to RotationMoveEvent 2023-06-21 17:39:04 -05:00
Brady
7e426bd2e8 AimProcessor API 2023-06-21 17:35:47 -05:00
Brady
367ce5fa17 cherry pick Allow freeLook when using elytra 2023-06-21 14:55:40 -05:00
Brady
877fd25608 Distinguish unexpected exceptions in path calc 2023-06-21 00:52:43 -05:00
Brady
cfd9a69052 Revert how PathManager tick works 2023-06-21 00:21:37 -05:00
Brady
d42bfcfa53 Fix NPE 2023-06-20 23:15:45 -05:00
Brady
defa6399e2 Tweak hitbox constraints 2023-06-20 23:01:07 -05:00
Brady
699e8bdea6 troll concurrency fix for rn 2023-06-20 22:36:27 -05:00
Brady
2eb912835a Restore interp values 2023-06-20 21:28:30 -05:00
Brady
bd7a57f7aa We do a little trolling 2023-06-20 21:27:54 -05:00
Brady
e76f79214e Replace pathAt with NetherPath 2023-06-20 21:07:21 -05:00
Brady
141a48a15e Some refactoring, more precise goingTo 2023-06-20 20:30:10 -05:00
Brady
fa158c6e67 Remove unnecessary conversions to Vec3d 2023-06-20 20:18:56 -05:00
Brady
7a12ef530c Cancel solver on behavior cancel 2023-06-20 20:11:34 -05:00
Brady
1d092a7165 Compute angles on another thread between ticks 2023-06-20 20:09:53 -05:00
Brady
57a17e907e Add missing CallbackInfo 2023-06-20 17:30:38 -05:00
Brady
2a82f6048a Implement POST TickEvent with new onPostTick callback 2023-06-20 17:18:30 -05:00
Brady
4076263afa Un-scuff PRE TickEvent injector 2023-06-20 17:00:42 -05:00
Brady
e3c8283158 Move solver into separate method 2023-06-20 15:15:02 -05:00
Brady
0aad3470d9 Differ between no pitch solution and no solution at all 2023-06-20 15:05:59 -05:00
Brady Hahn
553c85f0f6 Merge pull request #4011 from babbaj/elytra
fix 0.5 offset in elytra path rendering
2023-06-20 14:49:00 -05:00
Babbaj
c057081f07 fix 0.5 offset in elytra path rendering 2023-06-20 15:48:12 -04:00
Brady
7d22a71507 Only count unchanged ticks when using elytra 2023-06-20 13:50:26 -05:00
Brady
0ecabdd047 Update nether-pathfinder to 0.18 2023-06-20 13:43:42 -05:00
Brady
6c6b44ee65 Recalculate path if stuck 2023-06-20 13:43:14 -05:00
Brady
14ff90ccf1 remaining ticks mojang incident 2023-06-19 23:12:46 -05:00
Brady
5d7655fbdf Fix silly 0x integer wraparound trolle 2023-06-19 22:52:27 -05:00
Brady
ee0a6c2523 Use new single trace isVisible api 2023-06-19 21:45:52 -05:00
Brady
753b1cf1c3 Interpolate path positions
- Update `nether-pathfinder` to 0.17
- Utilize new batched visibility raytracing to efficiently trace bounding box paths
2023-06-19 21:38:08 -05:00
0x22
cd1c07deef added elytraFireworkSetbackUseDelay setting. 2023-06-19 22:22:57 -04:00
ZacSharp
41d730fb04 Forgot to include target pos 2023-06-20 03:20:44 +02:00
ZacSharp
30278a1c52 Implement hashCode for goals 2023-06-20 02:44:29 +02:00
ZacSharp
d87d1ab9b5 Don't call partOfMask out of bounds 2023-06-20 02:00:08 +02:00
ZacSharp
31c9072970 Forgot to git add 2023-06-20 01:36:09 +02:00
ZacSharp
f7a20a3acf Don't swallow random exceptions, don't bother with CommandExceptions 2023-06-20 01:32:18 +02:00
Brady Hahn
9d05043fa0 Merge pull request #4005 from babbaj/elytra
use legacy raytrace with ignore liquid to get out of lava
2023-06-19 18:04:14 -05:00
Babbaj
5f709eef9c use world raytrace 2023-06-19 18:26:00 -04:00
ZacSharp
b111fd2f3e Don't construct malformed ResourceLocations
Later mc versions throw an exception when you construct a malformed `ResourceLocation`.
2023-06-20 00:02:56 +02:00
ZacSharp
84777c2437 Don't complete more than what's supported 2023-06-20 00:01:33 +02:00
ZacSharp
13742df877 Complete the last argument, not the first one 2023-06-20 00:00:52 +02:00
Babbaj
e57a84ded4 use legacy raytrace with ignore liquid to get out of lava 2023-06-19 17:58:06 -04:00
ZacSharp
f55f7f19b4 Tab complete the datatype which will be parsed 2023-06-19 23:50:42 +02:00
ZacSharp
e43200865c Move this to the right place 2023-06-19 23:48:07 +02:00
ZacSharp
1de2d55965 Tab complete block properties 2023-06-19 23:05:46 +02:00
Brady
959b4cddbd Remove unneeded while (true) 2023-06-19 15:29:30 -05:00
Brady
82156250df Update nether-pathfinder to 0.16 2023-06-19 15:20:04 -05:00
Brady
90f401a067 Remove legacy raytracing methods 2023-06-19 15:19:32 -05:00
Brady
c6a6624045 Reorder fields 2023-06-19 15:16:11 -05:00
Brady
7d17ace15d Reset recalculating flag on clear 2023-06-19 15:15:29 -05:00
Brady
8d3b0c8f07 Always enforce sinceFirework 2023-06-19 14:10:41 -05:00
0x22
6741dff12b replaced (PI / 180) constants, RotationUtils calcVec3dFromRotation->calcLookDirectionFromRotation and named local variables. 2023-06-19 14:17:54 -04:00
Brady
9e10faa4c5 Elytra inventory modifications
- Use `throwaway` to switch items
- Remove inventory settings
- Prioritizes boost fireworks, but works without
- Avoids explosion fireworks
2023-06-19 12:32:25 -05:00
Brady Hahn
579e6d6e4c Merge pull request #4003 from rycbar0/elytra
prevent <player> went off with a bang
2023-06-19 12:12:15 -05:00
rycbar0
a32ac59ec1 prevent <player> went off with a bang 2023-06-19 12:44:32 +02:00
Leijurv
2b259d6dee cuter debug 2023-06-18 23:09:43 -07:00
Brady
67efb7a5b6 Add experimentalRaytrace setting for native raytrace
Update `nether-pathfinder` to 0.15
2023-06-19 00:34:22 -05:00
Brady
1da7ab2c22 Fix raytracer rendering 2023-06-18 23:58:20 -05:00
Brady
1257a0128c Remove unnecessary Baritone casts 2023-06-18 21:46:56 -05:00
Brady
0886f176b3 Make elytra API changes 2023-06-18 21:46:03 -05:00
Brady
7a8f8e8d47 fix noob error from resolving merge conflicts 2023-06-18 21:42:04 -05:00
Brady Hahn
7046927394 Merge pull request #3996 from rfresh2/elytra
firework inv management + pause/resume
2023-06-18 21:41:11 -05:00
Brady Hahn
d2b1398cea Merge branch 'elytra' into elytra 2023-06-18 21:39:09 -05:00
Leijurv
6c8f2698d6 cherry pick remainWithExistingLookDirection from fork 2023-06-18 19:31:51 -07:00
Brady
9808f62fe4 Send chunks to nether-pathfinder on BlockUpdateEvent 2023-06-18 21:25:00 -05:00
Brady
1837b66bb5 Add BlockChangeEvent
Moves the cache repack on block change functionality into `GameEventHandler`
2023-06-18 21:24:13 -05:00
Leijurv
efae476bc0 solved 2023-06-18 18:16:13 -07:00
Leijurv
a236031435 fix raytracer 2023-06-18 18:09:45 -07:00
Leijurv
812be14375 debug 2023-06-18 18:06:32 -07:00
Brady
1dbfc9abe3 optimize block lookups and move goingTo to local 2023-06-18 19:57:29 -05:00
leijurv
411c43d90e Merge pull request #3992 from ZacSharp/pr/blockOptionalMeta/useStackHashesInBlockOptionalMetaLookup
Actually use stack hashes
2023-06-18 17:25:53 -07:00
leijurv
bac5fd7438 Merge pull request #3999 from ZacSharp/pr/setting/tabCompleteSetingsLoadPath
Tab complete the file argument for `#settings load`
2023-06-18 17:25:27 -07:00
Brady Hahn
4df31a3fbb Merge pull request #4000 from ZacSharp/pr/selection/fixHorizontalCylinders
Fix `CylinderMask` with horizontal alignment
2023-06-18 19:02:07 -05:00
rfresh2
8dc32ae03c firework inv management + pause/resume 2023-06-18 13:34:55 -07:00
ZacSharp
5fd915ab8a Tab complete the file argument for #settings load 2023-06-18 22:27:57 +02:00
Brady
68901695ca Add experimental takeoff feature 2023-06-18 13:23:41 -05:00
ZacSharp
6aeb73b5bd Fix CylinderMask with horizontal alignment 2023-06-18 19:18:46 +02:00
0x22
aec683d80f fast raytrace 2023-06-18 12:21:01 -04:00
Brady
d4e6a84ec9 Remove usage of realms Pair class 2023-06-18 10:57:13 -05:00
Brady
d66b8f1dd8 Extract currentSpeed into variable 2023-06-18 00:13:55 -05:00
Brady
688bbb83c8 Rename wasteFireworks to conserveFireworks and invert 2023-06-18 00:11:40 -05:00
Brady
da31a643b3 unscuff 2023-06-17 23:56:08 -05:00
Babbaj
76c5c1155f Fix ElytraCommand throwing exception for invalid goals 2023-06-18 00:51:07 -04:00
Leijurv
94027d17f2 gaming 2023-06-17 20:12:05 -07:00
Leijurv
fef7ba4701 tweaks 2023-06-17 20:03:30 -07:00
Brady
fcf8cd35d2 Handle exception to ensure recalculating is reset 2023-06-17 19:58:19 -05:00
Brady
91609f4ebf Use player bounding box in isClear 2023-06-17 19:36:29 -05:00
Brady
64a5ceabd8 Fix the regular pathfinder issue 2023-06-17 15:35:26 -05:00
Brady
4c2984a9a0 Consistent path prefix for methods 2023-06-17 14:21:32 -05:00
Brady
d1a6de06e2 😼 PathManager 2023-06-17 14:15:57 -05:00
Brady
0290b344dc Cancel before shutting down executor 2023-06-17 02:33:43 -05:00
Brady
395706edc9 move context wrapper to new class 2023-06-17 02:02:26 -05:00
Brady
a67889ab42 refactoring 2023-06-17 01:55:07 -05:00
Brady
97e91ed680 one var 2023-06-17 01:42:49 -05:00
Brady
424f27c798 remove debug msg 2023-06-17 01:41:17 -05:00
Brady
c5475498ca so cute 2023-06-17 01:39:21 -05:00
Leijurv
157e4db7c5 fireworks hack 2023-06-16 22:39:50 -07:00
Leijurv
1f303e69b0 cut at render distance 2023-06-16 22:21:52 -07:00
Leijurv
dc53c79393 gaming 2023-06-16 21:35:56 -07:00
Brady
37167746b5 Merge remote-tracking branch 'origin/master' into elytra 2023-06-16 22:52:24 -05:00
Brady
a046708867 Merge remote-tracking branch 'origin/elytra-buildScriptOverhaul' into elytra 2023-06-16 22:41:14 -05:00
Brady
f798ff26f6 fixed seed 2023-06-16 22:31:53 -05:00
leijurv
a665605a5a Merge pull request #3991 from ZacSharp/pr/guiclick/fixSelectionPreview
Fix `GuiClick` not rendering the outline of the selection being made
2023-06-16 20:29:25 -07:00
Brady
071e6164fe Fix nether-pathfinder on Windows 2023-06-16 21:55:08 -05:00
0x22
b72bbfce5e make all json deterministic 2023-06-16 22:36:58 -04:00
0x22
cb7c2d7171 1.12.2 build script overhaul.
- Updated to ForgeGradle 4.0, MixinGradle 0.7 and Gradle 6.9.4
- Added a hack to run the game on arm64 on Mac OS X natively.
2023-06-16 22:04:16 -04:00
Brady
800cb2e747 Replace sublist troll in PathRenderer with visiblePath 2023-06-16 20:53:53 -05:00
Brady
5b39eb5041 clean up 2023-06-16 20:38:29 -05:00
Brady
53a0069704 Remove Java pathfinder in preparation for insertChunkData 2023-06-16 19:54:37 -05:00
Brady
8c12416348 Use new nether-pathfinder API
Doesn't stitch segments, just partially functional
2023-06-16 18:59:57 -05:00
ZacSharp
e00e0032b4 Actually use stack hashes 2023-06-17 01:40:19 +02:00
ZacSharp
f1bf1e8663 Use IRenderer setup methods 2023-06-17 00:36:35 +02:00
ZacSharp
ef4cdfd646 Fix render bug caused by color bug fix 2023-06-16 19:22:37 +02:00
Leijurv
e01093eb9a build with pathfinder 2023-06-15 20:59:15 -07:00
Brady
a9e9cd978d cancel lol 2023-06-15 22:59:01 -05:00
Brady
fe8ec19b6d Fix renderRaytraces crash 2023-06-15 22:07:44 -05:00
leijurv
0e87f350b3 Merge pull request #3990 from cabaletta/elytra-freelook
Merge `elytra-freelook` into `elytra`
2023-06-15 20:00:45 -07:00
leijurv
c86643874d Merge pull request #3936 from ZacSharp/pr/builder/fixPlaceableComparison
Fix considering states unplaceable regardless of buildIgnoreProperties
2023-06-15 19:36:25 -07:00
Leijurv
8df6778641 sort of integrated nether pathfinder 2023-06-15 00:32:26 -07:00
Brady
26a2945696 remove comment 2023-06-14 19:13:07 -05:00
leijurv
04b09fbfbd Merge pull request #3985 from cabaletta/pr/deprecateHelperMc
Deprecate `Helper.mc`
2023-06-14 16:20:38 -07:00
Brady
f14caa3778 Fix cringe shift by injector 2023-06-14 17:32:47 -05:00
Brady
06d11c1874 Revert file path 2023-06-14 16:59:03 -05:00
Brady
91bf7d726b Un-scuff and add setting 2023-06-14 16:32:56 -05:00
Brady
bde0c620ad Allow freeLook when using elytra 2023-06-14 16:11:11 -05:00
Brady
9672bd2c6d Fix compile 2023-06-14 16:08:34 -05:00
Brady
7b6f9b3eb6 Merge remote-tracking branch 'origin/master' into elytra 2023-06-14 15:48:16 -05:00
Brady
ea9245ad26 missed that 😩 2023-06-14 14:23:24 -05:00
Brady
8534e1ba55 💚 appease codacy 2023-06-14 14:04:34 -05:00
Brady
ae66004b80 Custom registration of Baritone instances from Minecraft 2023-06-14 13:52:27 -05:00
Brady
5b39c0dd96 Remove getMinecraft() from BlockStateInterface 2023-06-14 12:18:50 -05:00
Brady
2db2d8be59 Steal BaritoneList from bot-system 2023-06-14 02:00:10 -05:00
Brady
75d47bb110 Fix all usages of Helper.mc 2023-06-14 01:53:29 -05:00
leijurv
3662b3fdf1 nope 2023-06-13 21:33:12 -07:00
leijurv
b03d31e990 will github let me do this 2023-06-13 21:32:57 -07:00
leijurv
54f0a3c14c marginally better 2023-06-13 21:32:21 -07:00
leijurv
6a80b0d4ff forgot github markdown is stupid 2023-06-13 21:31:49 -07:00
leijurv
5e724c1e3a making these clickable was a mistake 2023-06-13 21:31:10 -07:00
leijurv
88e604426c 1.20.1 2023-06-13 21:30:31 -07:00
Brady
dd7b492b0c registerBehavior is called explicitly now 2023-06-13 23:21:20 -05:00
Brady
c7f4e366e2 Remove mc references from WorldProvider
Also refactored a bit, should be a lot easier to merge upwards to new game versions
2023-06-13 23:07:26 -05:00
Brady
382f82b0e0 Move Minecraft to IPlayerContext 2023-06-13 21:17:42 -05:00
Brady
ab3d9e9c47 I LOVE final 2023-06-13 21:13:34 -05:00
Brady
714ebb2c2d Deprecate Helper.mc and begin to replace usages 2023-06-13 18:24:31 -05:00
leijurv
1b254a4811 Merge pull request #3979 from cabaletta/pr/feature/blockFreeLook
Allow free looking when breaking and placing blocks
2023-06-13 10:32:18 -07:00
Leijurv
92509f07e9 normal raytracer skips flowing lava (aka lavafalls) which is no good 2023-06-12 22:00:23 -07:00
Leijurv
44cd5dcd41 go around glowstone and nether fortresses 2023-06-12 21:43:10 -07:00
Brady
76fe0d14d3 Simplify some player context references 2023-06-12 21:13:10 -05:00
Brady
2022d33d03 Fix incorrect references to player and world 2023-06-12 21:12:49 -05:00
Brady
c8b8deb3d6 Ensure angle delta is producible with mouse movement 2023-06-12 21:04:30 -05:00
Brady
4885d49d20 Reorganize code 2023-06-12 20:00:03 -05:00
Brady
13fc58933d Don't bother returning serverRotations if no free look 2023-06-12 19:03:03 -05:00
Brady
c217a34f13 🐛 fix batch render color bug by backporting 1.17+ render code 2023-06-12 17:06:11 -05:00
leijurv
15182cb151 Merge pull request #3984 from cabaletta/pr/bugfix/censorCoordinatesRecalc
Fix `censorCoordinates` recalc bug
2023-06-12 14:57:02 -07:00
Brady
8a65a1cfc5 🐛 fix incorrect comparison operator 2023-06-12 16:52:20 -05:00
Brady
5bdd5b0c0d 👌 appease leijurv 2023-06-12 16:50:02 -05:00
Brady
7da802a238 Fix censorCoordinates recalc bug
Adds `equals` and `toString` implementations where needed
Replaces `toString` equality check with actual `equals` check in `forceRevalidate`
2023-06-12 16:21:05 -05:00
leijurv
e334aae608 Merge pull request #3974 from cabaletta/pr/sel-shape-masks
Add sphere and cylinder build commands to sel
2023-06-12 12:57:01 -07:00
leijurv
c48a9d98b4 Merge pull request #3982 from cabaletta/pr/batchRender
Batch Rendering
2023-06-12 12:56:05 -07:00
Brady
ed34ae73c0 Fix Mode.NONE target invalidation 2023-06-12 13:46:10 -05:00
Brady
c8a0ae9e10 Do nudgeToLevel and randomLooking when using freeLook 2023-06-12 13:44:08 -05:00
Brady
67a085c95f Batch together GL_LINES draw calls 2023-06-12 13:16:37 -05:00
Brady
1d5ee079b4 Read serverRotation from packet and invalidate on world load 2023-06-12 12:11:50 -05:00
Leijurv
410cfcf21a typo, fix crash at end of path 2023-06-11 22:40:35 -07:00
Leijurv
4148b98187 typo 2023-06-11 22:22:49 -07:00
Leijurv
b9054cdfc9 use more fireworks 2023-06-11 22:22:01 -07:00
Leijurv
35a996e2b0 firework more often 2023-06-11 20:59:28 -07:00
Brady
bb36ebfc0c Use IPlayerContext for all RotationUtils methods
Deprecates all old overloads
2023-06-11 20:09:37 -05:00
Brady
a7d15d1e32 Consistent naming and comments for clarification 2023-06-11 18:43:48 -05:00
Brady
4317dca024 Determine target mode (client/server) in updateTarget 2023-06-11 18:35:34 -05:00
Leijurv
c48c2aa45c allow even more desperate motion 2023-06-11 13:57:21 -07:00
Brady
77ca36c794 Use playerRotations in reachableOffset 2023-06-11 15:49:04 -05:00
Leijurv
a602863426 better elytra 2023-06-11 12:49:31 -07:00
Brady
a09e63d6aa appease codacy 2023-06-11 13:14:52 -05:00
Brady
fbe28e397e Make setting disabled by default 2023-06-11 12:38:13 -05:00
Brady
364ae87ef8 Add blockFreeLook setting 2023-06-11 12:36:53 -05:00
Brady
ffd00080f2 Mask binary operators 2023-06-11 11:27:51 -05:00
Brady
94d757104b Clean ups 2023-06-11 11:24:31 -05:00
Leijurv
705a5a0712 elytra prototype mvp 2023-06-11 00:33:35 -07:00
Brady
9729e63d98 Create and utilize new Mask type
Added factory method to `MaskSchematic` for creation using a `Mask`
Sort-of mocks the schematic structure, without the block states ofc
2023-06-09 17:25:29 -05:00
Brady
f232bbdb15 Clean up formatting 2023-06-08 16:36:32 -05:00
Brady
26574b4a9b Add optional axis parameter for #sel cyl 2023-06-08 16:32:33 -05:00
Brady
a1b1ef88cf Use a Supplier to mimic a switch expression 2023-06-08 15:46:32 -05:00
Brady
b6c52cd8e1 Cache mask in a boolean[][][] 2023-06-08 11:52:13 -05:00
Brady
34abbfb5da appease codacy 2023-06-07 17:38:26 -05:00
Brady
0d14bde583 Working sphere/cylinder build commands for #sel 2023-06-07 16:31:52 -05:00
leijurv
4b0a8eb166 Merge pull request #3966 from cabaletta/pr/setting-metadata
Setting Field Metadata
2023-06-04 16:59:14 -07:00
Brady
80ec9023ce Replace JAVA_ONLY_SETTINGS array with @JavaOnly annotation 2023-06-04 12:31:34 -05:00
leijurv
5dd10b6e81 Merge pull request #3946 from ZacSharp/pr/farm/addCocoa
Make cocoa farmable
2023-05-23 17:31:06 -07:00
leijurv
415fa048ba Merge pull request #3924 from ZacSharp/pr/blockOptionalMetaProperties
Extend BlockOptionalMeta parsing to parse block properties
2023-05-23 15:57:10 -07:00
leijurv
a1661e94b5 Merge pull request #3923 from ZacSharp/pr/mine/maxYLevelWhileMining
 Add maxYLevelWhileMining setting
2023-05-23 15:56:11 -07:00
ZacSharp
c45a714b77 Fix considering states unplaceable even if buildIgnoreProperties allows it 2023-05-08 03:51:38 +02:00
ZacSharp
271c2ff636 Extend BlockOptionalMeta parsing to parse block properties 2023-04-24 23:49:23 +02:00
ZacSharp
e4cd35ac33 Add maxYLevelWhileMining setting 2023-04-24 23:11:55 +02:00
ZacSharp
e8a4a9fdac Make cocoa farmable 2023-04-24 16:23:38 +02:00
leijurv
5f2eadbfa6 download links for 1.19.2 2023-04-11 20:36:29 -07:00
leijurv
35ab687d5e 1.9.3 download links 2023-04-11 16:00:22 -07:00
leijurv
3ff2bd4f17 Merge pull request #3908 from wagyourtail/patch-3
Update Setup.md
2023-04-11 14:47:59 -07:00
Wagyourtail
f334b3b765 update setup.md 2023-04-10 18:40:48 -07:00
leijurv
ff1732011e vid is outdated and doesn't get to the point fast enough, so let's move it lower down 2023-03-20 22:07:51 -07:00
leijurv
c5721fb7e3 Merge pull request #3878 from wagyourtail/1.12/fix-wp-c
make wp c not throw npe on invalid tag name
2023-03-14 18:40:41 -07:00
leijurv
3200d976d7 1.19.4 2023-03-14 18:35:15 -07:00
Wagyourtail
6698505dd8 make wp c not throw npe on invalid tag name 2023-03-13 15:31:18 -07:00
Leijurv
790a4f6769 command to load settings from a specific file 2023-03-01 00:25:49 -08:00
leijurv
c9d7a5bea6 kami blue to lambda 2023-02-28 23:56:34 -08:00
Leijurv
f1ead19b6e option to only move inventory when stationary 2023-02-28 23:44:33 -08:00
Leijurv
174bdd2307 overhaul readme 2023-02-18 16:42:05 -08:00
Leijurv
814c17522a changed it back to the old way by manually renaming the release files 2023-02-18 15:20:50 -08:00
Leijurv
b622adf300 ugh why was this changed since 1.18 2023-02-18 15:13:15 -08:00
Leijurv
c1b58f8a01 link 1.19 2023-02-18 15:12:17 -08:00
leijurv
c1a9621dfa Merge pull request #3768 from wagyourtail/1.12/fasterworldscanner
replace the world scanner with a 500x faster one
2023-01-28 10:18:59 -08:00
Wagyourtail
6de266a106 remove extra method call 2023-01-28 01:39:58 -07:00
Wagyourtail
334d9c119b remove the allocation of an intlist per section 2023-01-28 00:44:54 -07:00
leijurv
1a2c30b4e3 Merge pull request #3803 from Entropy5/master
Litematica x BuildOnlySelection support
2023-01-27 23:34:35 -08:00
Entropy5
413cc1469f zac suggestion (number 2), test ongoing 2023-01-27 14:23:08 +01:00
Wagyourtail
7404414e7a less impure 2023-01-20 23:43:00 -07:00
Entropy5
49b1f3528b Merge remote-tracking branch 'origin/master' 2023-01-17 06:33:09 +01:00
Entropy5
26cceede15 litematica support for buildonlyselection, mostly rycbars 2023-01-17 06:33:01 +01:00
Wagyourtail
b71c9e776a oops didn't mean to commit that 2022-12-28 01:09:46 -07:00
Wagyourtail
746faf6df6 faster section reorder 2022-12-28 01:05:17 -07:00
Wagyourtail
a367031fe2 Revert "sacrifice a bit of speed for better block ordering"
This reverts commit e55db05f20.
2022-12-28 00:03:58 -07:00
Wagyourtail
853dadd906 Merge remote-tracking branch 'origin/master' into 1.12/fasterworldscanner 2022-12-27 23:58:13 -07:00
Wagyourtail
e55db05f20 sacrifice a bit of speed for better block ordering 2022-12-27 23:30:35 -07:00
Wagyourtail
98a748afb3 fix stream limit. immutable's in BOML 2022-12-27 22:42:38 -07:00
William Gray
c04eb066cb Update src/main/java/baritone/cache/FasterWorldScanner.java
Co-authored-by: ZacSharp <68165024+ZacSharp@users.noreply.github.com>
2022-12-28 01:06:10 +00:00
Wagyourtail
6260c6d3d7 apply suggestions 2022-12-24 12:11:26 -07:00
Wagyourtail
ce1fb49252 spiral always pick closest chunk first now 2022-12-24 11:52:48 -07:00
Wagyourtail
ecdec87e7a fix using wrong functions in scan 2022-12-24 11:43:54 -07:00
Wagyourtail
96f432d2d5 add comment 2022-12-23 17:26:46 -07:00
Wagyourtail
0ae59755e3 make limit not happen if it shouldn't 2022-12-23 17:25:23 -07:00
Wagyourtail
12b596e536 fix spiral 2022-12-23 17:10:37 -07:00
Wagyourtail
0b6088cd2d fix getting the block from the pallete, and change the chunk scan order to spiral out 2022-12-23 16:58:10 -07:00
Wagyourtail
1736f2ffc7 replace the world scanner with a 500x faster one 2022-12-23 16:34:49 -07:00
144 changed files with 7023 additions and 1159 deletions

4
.gitignore vendored
View File

@@ -30,3 +30,7 @@ baritone_Client.launch
.vscode/launch.json
libs/lwjgl-platform-2.9.4-nightly-20150209-natives-osx.jar
libs/java-objc-bridge-1.1.jar
mapping

View File

@@ -1,16 +1,29 @@
# Warning: Old Branch!!
**Click [here](https://github.com/cabaletta/baritone) to go to the current Baritone readme.**
**This branch (`master`) is Baritone for Minecraft 1.12.2. This is the original version of Minecraft that Baritone was written for, and it was the primary development branch for over 5 years. As such, it's quite mature, and arguably more reliable than Baritone for newer versions of Minecraft. Nevertheless, as of August 2023, with [2b2t's update from 1.12.2 to 1.19.4](https://2b2t.org/update/), I decided to move Baritone's primary development branch accordingly. PRs should now be made against the `1.19.4` branch going forward. This branch might see some fixes going forward, particularly to newer features such as `#elytra`, but it won't be the primary focus anymore.**
The other intermediary branches (`1.13.2`, `1.14.4`, `1.15.2`, `1.16.5`, `1.17.1`, `1.18.2`, `1.19.2`, and `1.19.3`) will probably not receive any updates at all. You can find their last releases in the releases tab, or in the quick download links table.
For `1.16.5` and `1.18.2`, the latest release is fully up to date with the code. ZacSharp merged master into some of those versions even after they were deprecated, if you are for some reason really interested in the latest Baritone bugfixes on these versions of Minecraft, you can build from source as of these commits: [1.13.2](https://github.com/cabaletta/baritone/commit/be54b8ee5b5639f80e3d6809ed1abd52444d8a08), [1.14.4](https://github.com/cabaletta/baritone/commit/be54b8ee5b5639f80e3d6809ed1abd52444d8a08), [1.15.2](https://github.com/cabaletta/baritone/commit/45abbb7fa1062cefc26abbb006a02a4edd6faa32), [1.17.1](https://github.com/cabaletta/baritone/commit/cbf0d79c9c5f7454071dc0a5289261ec9ca4373f), [1.19.2](https://github.com/cabaletta/baritone/commit/217dca53633610edc9483fda7a234e46c839fd99). For `1.19.3`, merging [this](https://github.com/cabaletta/baritone/commit/217dca53633610edc9483fda7a234e46c839fd99) commit into it is trivial and is left as an exercise for the reader. For other versions in between these (for example people always ask in the Discord for 1.16.1), you'll have to figure it out yourself.
# Baritone
<p align="center">
<a href="https://github.com/cabaletta/baritone/releases/"><img src="https://img.shields.io/github/downloads/cabaletta/baritone/total.svg" alt="GitHub All Releases"/></a>
</p>
<p align="center">
<a href="https://github.com/cabaletta/baritone/tree/master"><img src="https://img.shields.io/badge/MC-1.12.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.13.2"><img src="https://img.shields.io/badge/MC-1.13.2-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.14.4"><img src="https://img.shields.io/badge/MC-1.14.4-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.15.2"><img src="https://img.shields.io/badge/MC-1.15.2-yellow.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.16.5"><img src="https://img.shields.io/badge/MC-1.16.5-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.17.1"><img src="https://img.shields.io/badge/MC-1.17.1-brightgreen.svg" alt="Minecraft"/></a>
<a href="https://github.com/cabaletta/baritone/tree/1.18.2"><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.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-yellow.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-yellow.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.2-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.19.4-brightgreen.svg" alt="Minecraft"/></a>
<a href="#Baritone"><img src="https://img.shields.io/badge/MC-1.20.1-brightgreen.svg" alt="Minecraft"/></a>
</p>
<p align="center">
@@ -28,12 +41,13 @@
<a href="https://github.com/cabaletta/baritone/commit/"><img src="https://img.shields.io/github/commits-since/cabaletta/baritone/v1.0.0.svg" alt="GitHub commits"/></a>
<img src="https://img.shields.io/github/languages/code-size/cabaletta/baritone.svg" alt="Code size"/>
<img src="https://img.shields.io/github/repo-size/cabaletta/baritone.svg" alt="GitHub repo size"/>
<img src="https://tokei.rs/b1/github/cabaletta/baritone?category=code" alt="Lines of Code"/>
<img src="https://tokei.rs/b1/github/cabaletta/baritone?category=code&style=flat" alt="Lines of Code"/>
<img src="https://img.shields.io/badge/Badges-36-blue.svg" alt="yes"/>
</p>
<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/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/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/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>
@@ -42,27 +56,34 @@
</p>
<p align="center">
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/built-with-swag.svg" alt="forthebadge"/></a>
<a href="http://forthebadge.com/"><img src="https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg" alt="forthebadge"/></a>
<a href="http://forthebadge.com/"><img src="https://web.archive.org/web/20230604002050/https://forthebadge.com/images/badges/built-with-swag.svg" alt="forthebadge"/></a>
<a href="http://forthebadge.com/"><img src="https://web.archive.org/web/20230604002050/https://forthebadge.com/images/badges/mom-made-pizza-rolls.svg" alt="forthebadge"/></a>
</p>
A Minecraft pathfinder bot.
Baritone is the pathfinding system used in [Impact](https://impactclient.net/) since 4.4. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a (very old!) video I made showing off what it can do.
[**Baritone Discord Server**](http://discord.gg/s6fRBAUpmr)
Baritone 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.
**Quick download links:**
[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.19/baritone-api-forge-1.2.19.jar) | |
| [1.16.5 Forge](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-forge-1.6.5.jar) | [1.16.5 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.6.5/baritone-api-fabric-1.6.5.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.5/baritone-api-forge-1.8.5.jar) | [1.18.2 Fabric](https://github.com/cabaletta/baritone/releases/download/v1.8.5/baritone-api-fabric-1.8.5.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.17/baritone-api-forge-1.2.17.jar)**. Otherwise, see [Installation & setup](SETUP.md). Once Baritone is installed, look [here](USAGE.md) for instructions on how to use it.
**Message for 2b2t players looking for 1.19/1.20 Baritone** Download it from right above ^. But also please check back in a few days for Baritone Elytra ([vid 1](https://youtu.be/4bGGPo8yiHo) [vid 2](https://www.youtube.com/watch?v=pUN9nmINe3I)), which will be ported to 1.19/1.20 soon! It will work on 2b2t with its anticheat, that was the whole point of Baritone Elytra (it's fully vanilla compatible). Also join [**the discord**](http://discord.gg/s6fRBAUpmr). Thanks!
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)**.
**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). Also try `#elytra` for Elytra flying in the Nether using fireworks.
If you need Forge or Fabric 1.17.1, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.7.2) and get the `api-forge` or `api-fabric` jar. **For 1.17.1 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.7.2/baritone-api-fabric-1.7.2.jar)**.
If you need Forge or Fabric 1.18.2, look [here](https://github.com/cabaletta/baritone/releases/tag/v1.8.3) and get the `api-forge` or `api-fabric` jar. **For 1.18.2 Fabric, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-fabric-1.8.3.jar)**. **For 1.18.2 Forge, just click [here](https://github.com/cabaletta/baritone/releases/download/v1.8.3/baritone-api-forge-1.8.3.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.
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).

View File

@@ -43,13 +43,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 for 1.12.2-1.16.5, JDK 16+ for 1.17.1, and JDK 17+ for 1.18.1.
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.
Open JDK download: https://openjdk.java.net/install/
Download java: https://adoptium.net/
#### macOS guide
In order to get JDK 8, Try running the following command:
`% /usr/libexec/java_home -V`
@@ -66,68 +66,13 @@ 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
Setting up the Environment:
### Building Baritone
```
$ gradlew setupDecompWorkspace
$ gradlew --refresh-dependencies
```
These tasks depend on the minecraft version, but are (for the most part) standard for building mods.
Building Baritone:
```
$ gradlew build
```
For minecraft 1.15.2+, run the following instead to include the Forge jars:
```
$ gradlew build -Pbaritone.forge_build
```
Do this instead for Fabric jars:
```
$ gradlew build -Pbaritone.fabric_build
```
Running Baritone:
```
$ gradlew runClient
```
For information on how to build baritone, see [Building Baritone](#building-baritone)
for more details, see [the build ci action](/.github/workflows/gradle_build.yml)
## 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)
![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
- depending on the minecraft version, you may need to run `setupDecompWorkspace` or `genIntellijRuns` in order to get everything working

View File

@@ -16,13 +16,13 @@
*/
group 'baritone'
version '1.2.17'
version '1.2.19'
buildscript {
repositories {
maven {
name = 'forge'
url = 'http://files.minecraftforge.net/maven'
url = 'https://files.minecraftforge.net/maven'
}
maven {
name = 'SpongePowered'
@@ -32,18 +32,19 @@ buildscript {
}
dependencies {
classpath 'net.minecraftforge.gradle:ForgeGradle:2.3-SNAPSHOT'
classpath 'org.spongepowered:mixingradle:0.6-SNAPSHOT'
classpath 'net.minecraftforge.gradle:ForgeGradle:4.+' // TODO: 5.+. `doHackyStuff` relies on 4.x internals.
classpath 'org.spongepowered:mixingradle:0.7-SNAPSHOT'
}
}
import baritone.gradle.task.CreateDistTask
import baritone.gradle.task.ProguardTask
apply plugin: 'java'
apply plugin: 'maven'
apply plugin: 'net.minecraftforge.gradle.tweaker-client'
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: 'org.spongepowered.mixin'
sourceCompatibility = targetCompatibility = '1.8'
@@ -53,8 +54,19 @@ 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 {
@@ -67,13 +79,26 @@ sourceSets {
}
minecraft {
version = '1.12.2'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
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
// The sources jar should use SRG names not MCP to ensure compatibility with all mappings
makeObfSourceJar = true
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}"
}
}
}
repositories {
@@ -88,23 +113,74 @@ 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 {
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
exclude module: 'launchwrapper'
exclude module: 'guava'
exclude module: 'gson'
exclude module: 'commons-io'
exclude module: 'log4j-core'
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') {
// Mixin includes a lot of dependencies that are too up-to-date
transitive = false
}
launchAnnotationProcessor 'org.spongepowered:mixin:0.8.4-SNAPSHOT:processor'
launchImplementation('dev.babbaj:nether-pathfinder:1.3.0')
implementation 'dev.babbaj:nether-pathfinder:1.3.0'
testImplementation 'junit:junit:4.12'
}
mixin {
defaultObfuscationEnv searge
add sourceSets.launch, 'mixins.baritone.refmap.json'
}
@@ -130,7 +206,7 @@ jar {
manifest {
attributes(
'MixinConfigs': 'mixins.baritone.json',
'TweakClass': 'baritone.launch.BaritoneTweaker',
'Implementation-Title': 'Baritone',
'Implementation-Version': version
)
@@ -145,25 +221,3 @@ 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 {
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
compile group: 'commons-io', name: 'commons-io', version: '2.6'
implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
implementation 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!");
throw new IllegalStateException("Artifact not found! Run build first! " + this.artifactPath);
}
}
@@ -82,7 +82,7 @@ class BaritoneGradleTask extends DefaultTask {
}
protected Path getRelativeFile(String file) {
return Paths.get(new File(file).getAbsolutePath());
return Paths.get(this.getProject().file(file).getAbsolutePath());
}
protected Path getTemporaryFile(String file) {

View File

@@ -18,39 +18,33 @@
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.JavaVersion;
import org.gradle.api.NamedDomainObjectContainer;
import org.gradle.api.Project;
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 org.gradle.internal.jvm.inspection.DefaultJvmVersionDetector;
import org.gradle.process.internal.DefaultExecActionFactory;
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 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
@@ -68,17 +62,18 @@ 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();
@@ -89,7 +84,7 @@ public class ProguardTask extends BaritoneGradleTask {
Files.delete(this.artifactUnoptimizedPath);
}
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Optional.empty());
Determinizer.determinize(this.artifactPath.toString(), this.artifactUnoptimizedPath.toString(), Arrays.asList(pathfinder), false);
}
private void downloadProguard() throws Exception {
@@ -114,48 +109,38 @@ 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();
}
path = findJavaByGradleCurrentRuntime();
if (path != null) return path;
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();
}
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();
if (this.validateJavaVersion(path)) {
System.out.println("Using Gradle's runtime Java for ProGuard");
return path;
}
return null;
System.out.println("Using Gradle's runtime Java for ProGuard");
return path;
}
private String findJavaByJavaHome() {
final String javaHomeEnv = System.getenv("JAVA_HOME");
if (javaHomeEnv != null) {
String path = Jvm.forHome(new File(javaHomeEnv)).getJavaExecutable().getAbsolutePath();
if (this.validateJavaVersion(path)) {
System.out.println("Detected Java path by JAVA_HOME");
return path;
}
System.out.println("Detected Java path by JAVA_HOME");
return path;
}
return null;
}
@@ -171,19 +156,11 @@ public class ProguardTask extends BaritoneGradleTask {
if (javacPath != null) {
File javacFile = new File(javacPath);
if (javacFile.exists()) {
File[] maybeJava = javacFile.getParentFile().listFiles(new FilenameFilter() {
@Override
public boolean accept(File dir, String name) {
return name.equals("java");
}
});
File[] maybeJava = javacFile.getParentFile().listFiles((dir, name) -> name.equals("java"));
if (maybeJava != null && maybeJava.length > 0) {
String path = maybeJava[0].getAbsolutePath();
if (this.validateJavaVersion(path)) {
System.out.println("Detected Java path by forkOptions");
return path;
}
System.out.println("Detected Java path by forkOptions");
return path;
}
}
}
@@ -191,21 +168,8 @@ 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), REPLACE_EXISTING);
Files.copy(getRelativeFile(PROGUARD_CONFIG_TEMPLATE), getTemporaryFile(PROGUARD_CONFIG_DEST), StandardCopyOption.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));
@@ -237,14 +201,37 @@ public class ProguardTask extends BaritoneGradleTask {
});
}
private void acquireDependencies() throws Exception {
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<>();
getProject().getConfigurations().stream().filter(Configuration::isCanBeResolved).forEach(config ->
config.getAllDependencies().forEach(dependency ->
dependencyLookupMap.putIfAbsent(dependency.getName() + "-" + dependency.getVersion(), Pair.of(config, dependency))));
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)));
});
// Create the directory if it doesn't already exist
Path tempLibraries = getTemporaryFile(TEMP_LIBRARY_DIR);
@@ -259,7 +246,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, REPLACE_EXISTING);
Files.copy(cachedJar, inTempDir, StandardCopyOption.REPLACE_EXISTING);
continue;
}
@@ -271,118 +258,77 @@ 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
for (File file : pair.getLeft().files(pair.getRight())) {
if (file.getName().startsWith(lib)) {
if (lib.contains("mixin")) {
mixin = file;
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);
}
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 {
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();
return getObfuscatedMinecraftJar(getProject(), false); // always notch jar for now.
}
// 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");
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.");
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 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);
return mappingTypes.get(0);
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();
}
private List<MappingType> getUsedMappingTypes(Set<Object> reobf) {
return reobf.stream()
.map(ReobfWrapper::new)
.map(ReobfWrapper::getMappingType)
.distinct()
.collect(Collectors.toList());
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 void proguardApi() throws Exception {
runProguard(getTemporaryFile(PROGUARD_API_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactApiPath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeApiPath.toString(), Optional.of(mixin));
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);
}
private void proguardStandalone() throws Exception {
runProguard(getTemporaryFile(PROGUARD_STANDALONE_CONFIG));
Determinizer.determinize(this.proguardOut.toString(), this.artifactStandalonePath.toString(), Optional.empty());
Determinizer.determinize(this.proguardOut.toString(), this.artifactForgeStandalonePath.toString(), Optional.of(mixin));
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);
}
private void cleanup() {
@@ -395,10 +341,18 @@ 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)) {
@@ -409,7 +363,7 @@ public class ProguardTask extends BaritoneGradleTask {
Path workingDirectory = getTemporaryFile("");
Path proguardJar = workingDirectory.relativize(getTemporaryFile(PROGUARD_JAR));
config = workingDirectory.relativize(config);
// Honestly, if you still have spaces in your path at this point, you're SOL.
Process p = new ProcessBuilder("java", "-jar", proguardJar.toString(), "@" + config.toString())
@@ -423,6 +377,7 @@ 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,7 +22,10 @@ import com.google.gson.stream.JsonReader;
import com.google.gson.stream.JsonWriter;
import java.io.*;
import java.util.*;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import java.util.jar.JarOutputStream;
@@ -36,10 +39,11 @@ import java.util.stream.Collectors;
*/
public class Determinizer {
public static void determinize(String inputPath, String outputPath, Optional<File> toInclude) throws IOException {
public static void determinize(String inputPath, String outputPath, List<File> toInclude, boolean doForgeReplacementOfMetaInf) 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));
@@ -60,10 +64,10 @@ public class Determinizer {
JarEntry clone = new JarEntry(entry.getName());
clone.setTime(42069);
jos.putNextEntry(clone);
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
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
ByteArrayOutputStream cancer = new ByteArrayOutputStream();
copy(jarFile.getInputStream(entry), cancer);
String manifest = new String(cancer.toByteArray());
@@ -76,8 +80,8 @@ public class Determinizer {
copy(jarFile.getInputStream(entry), jos);
}
}
if (toInclude.isPresent()) {
try (JarFile mixin = new JarFile(toInclude.get())) {
for (File file : toInclude) {
try (JarFile mixin = new JarFile(file)) {
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;
@@ -89,6 +93,7 @@ public class Determinizer {
}
jos.finish();
}
System.out.println("Done with determinizer");
}
private static void copy(InputStream is, OutputStream os) throws IOException {
@@ -99,7 +104,7 @@ public class Determinizer {
}
}
private static String writeSorted(JsonObject in) throws IOException {
private static String writeSorted(JsonElement in) throws IOException {
StringWriter writer = new StringWriter();
JsonWriter jw = new JsonWriter(writer);
ORDERED_JSON_WRITER.write(jw, in);

View File

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

43
gradlew.bat vendored
View File

@@ -1,3 +1,19 @@
@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
@@ -13,15 +29,18 @@ 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=
set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init
if "%ERRORLEVEL%" == "0" goto execute
echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init
if exist "%JAVA_EXE%" goto execute
echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ 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 %CMD_LINE_ARGS%
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %*
:end
@rem End local scope for the variables with windows NT shell

161
hacks.gradle Normal file
View File

@@ -0,0 +1,161 @@
/*
* 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}")
// }
// })
// }
//}

View File

@@ -92,9 +92,9 @@
-libraryjars 'tempLibraries/text2speech-1.10.3.jar'
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
-libraryjars 'tempLibraries/launchwrapper-1.11.jar' # TODO why does only 1.11.jar exist?
-libraryjars 'tempLibraries/launchwrapper-1.12.jar'
-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.readAndApply(settings, SettingsUtil.SETTINGS_DEFAULT_NAME);
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();

View File

@@ -88,6 +88,12 @@ public interface IBaritone {
*/
IGetToBlockProcess getGetToBlockProcess();
/**
* @return The {@link IElytraProcess} instance
* @see IElytraProcess
*/
IElytraProcess getElytraProcess();
/**
* @return The {@link IWorldProvider} instance
* @see IWorldProvider

View File

@@ -21,7 +21,9 @@ 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;
@@ -52,15 +54,13 @@ public interface IBaritoneProvider {
List<IBaritone> getAllBaritones();
/**
* 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}.
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}.
*
* @param player The player
* @return The {@link IBaritone} instance.
*/
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
for (IBaritone baritone : getAllBaritones()) {
for (IBaritone baritone : this.getAllBaritones()) {
if (Objects.equals(player, baritone.getPlayerContext().player())) {
return baritone;
}
@@ -68,6 +68,55 @@ 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,11 +29,16 @@ 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;
@@ -69,6 +74,16 @@ 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>
@@ -608,6 +623,13 @@ 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
* <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
*/
public final Setting<Integer> chunkPackerQueueMaxSize = new Setting<>(2000);
/**
* Fill in blocks behind you
*/
@@ -709,6 +731,37 @@ 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.
*/
public final Setting<Boolean> elytraFreeLook = new Setting<>(false);
/**
* Forces the client-sided yaw rotation to an average of the last {@link #smoothLookTicks} of server-sided rotations.
*/
public final Setting<Boolean> smoothLook = new Setting<>(false);
/**
* Same as {@link #smoothLook} but for elytra flying.
*/
public final Setting<Boolean> elytraSmoothLook = new Setting<>(true);
/**
* The number of ticks to average across for {@link #smoothLook};
*/
public final Setting<Integer> smoothLookTicks = new Setting<>(5);
/**
* 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>
@@ -843,6 +896,11 @@ 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.
*/
@@ -1139,6 +1197,7 @@ 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));
/**
@@ -1146,6 +1205,7 @@ 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<String, Boolean>> notifier = new Setting<>(NotificationHelper::notify);
/**
@@ -1153,6 +1213,7 @@ 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);
/**
@@ -1280,6 +1341,115 @@ 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<>(1.2);
/**
* 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> elytraConserveFireworks = new Setting<>(false);
/**
* Renders the raytraces that are performed by the elytra fly calculation.
*/
public final Setting<Boolean> elytraRenderRaytraces = new Setting<>(false);
/**
* Renders the raytraces that are used in the hitbox part of the elytra fly calculation.
* Requires {@link #elytraRenderRaytraces}.
*/
public final Setting<Boolean> elytraRenderHitboxRaytraces = new Setting<>(false);
/**
* Renders the best elytra flight path that was simulated each tick.
*/
public final Setting<Boolean> elytraRenderSimulation = new Setting<>(true);
/**
* 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);
/**
* Whether nether-pathfinder should generate terrain based on {@link #elytraNetherSeed}.
* If false all chunks that haven't been loaded are assumed to be air.
*/
public final Setting<Boolean> elytraPredictTerrain = new Setting<>(true);
/**
* 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);
/**
* The minimum fireworks before landing early for safety
*/
public final Setting<Integer> elytraMinFireworksBeforeLanding = new Setting<>(5);
/**
* Automatically land when elytra is almost out of durability, or almost out of fireworks
*/
public final Setting<Boolean> elytraAllowEmergencyLand = new Setting<>(true);
/**
* 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);
/**
* Should elytra consider nether brick a valid landing block
*/
public final Setting<Boolean> elytraAllowLandOnNetherFortress = new Setting<>(false);
/**
* Has the user read and understood the elytra terms and conditions
*/
public final Setting<Boolean> elytraTermsAccepted = new Setting<>(false);
/**
* A map of lowercase setting field names to their respective setting
*/
@@ -1297,6 +1467,7 @@ public final class Settings {
public T value;
public final T defaultValue;
private String name;
private boolean javaOnly;
@SuppressWarnings("unchecked")
private Setting(T value) {
@@ -1305,6 +1476,7 @@ public final class Settings {
}
this.value = value;
this.defaultValue = value;
this.javaOnly = false;
}
/**
@@ -1341,8 +1513,25 @@ 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() {
@@ -1358,6 +1547,7 @@ 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

@@ -17,6 +17,8 @@
package baritone.api.behavior;
import baritone.api.Settings;
import baritone.api.behavior.look.IAimProcessor;
import baritone.api.utils.Rotation;
/**
@@ -26,14 +28,23 @@ 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 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};
* 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.
*
* @param rotation The target rotations
* @param force Whether or not to "force" the rotations
* @param rotation The target rotations
* @param blockInteract Whether the target rotations are needed for a block interaction
*/
void updateTarget(Rotation rotation, boolean force);
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();
}

View File

@@ -0,0 +1,45 @@
/*
* 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

@@ -0,0 +1,47 @@
/*
* 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

@@ -17,6 +17,8 @@
package baritone.api.cache;
import java.util.function.Consumer;
/**
* @author Brady
* @since 9/24/2018
@@ -29,4 +31,11 @@ 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,11 +23,17 @@ 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());
@@ -40,13 +46,19 @@ 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(ctx.getConsumer().getString())
.filterPrefixNamespaced(arg)
.sortAlphabetically()
.stream();
}

View File

@@ -0,0 +1,43 @@
/*
* 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,20 +18,136 @@
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) {
return ctx.getConsumer().tabCompleteDatatype(BlockById.INSTANCE);
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);
}
}

View File

@@ -19,6 +19,8 @@ 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;
@@ -93,8 +95,13 @@ public enum RelativeFile implements IDatatypePost<File, File> {
.filter(s -> !s.contains(" "));
}
@Deprecated
public static File gameDir() {
File gameDir = HELPER.mc.gameDir.getAbsoluteFile();
return gameDir(Helper.mc);
}
public static File gameDir(Minecraft mc) {
File gameDir = mc.gameDir.getAbsoluteFile();
if (gameDir.getName().equals(".")) {
return gameDir.getParentFile();
}

View File

@@ -19,7 +19,6 @@ 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;
@@ -37,10 +36,6 @@ public class CommandUnhandledException extends RuntimeException implements IComm
@Override
public void handle(ICommand command, List<ICommandArgument> args) {
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();
HELPER.logUnhandledException(this);
}
}

View File

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

View File

@@ -0,0 +1,47 @@
/*
* 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.List;
/**
* @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,31 +57,38 @@ public final class ChunkEvent {
/**
* @return The state of the event
*/
public final EventState getState() {
public EventState getState() {
return this.state;
}
/**
* @return The type of chunk event that occurred;
*/
public final Type getType() {
public Type getType() {
return this.type;
}
/**
* @return The Chunk X position.
*/
public final int getX() {
public int getX() {
return this.x;
}
/**
* @return The Chunk Z position.
*/
public final int getZ() {
public 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 {
/**
@@ -106,6 +113,10 @@ public final class ChunkEvent {
* <p>
* And it's a partial chunk
*/
POPULATE_PARTIAL
POPULATE_PARTIAL;
public final boolean isPopulate() {
return this == POPULATE_FULL || this == POPULATE_PARTIAL;
}
}
}

View File

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

View File

@@ -18,9 +18,18 @@
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,6 +33,9 @@ public interface AbstractGameEventListener extends IGameEventListener {
@Override
default void onTick(TickEvent event) {}
@Override
default void onPostTick(TickEvent event) {}
@Override
default void onPlayerUpdate(PlayerUpdateEvent event) {}
@@ -45,6 +48,9 @@ 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,6 +41,14 @@ 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.
*
@@ -72,6 +80,13 @@ 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,6 +42,16 @@ 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,6 +17,7 @@
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;
@@ -66,6 +67,26 @@ 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(

View File

@@ -67,6 +67,24 @@ 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,6 +17,7 @@
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;
@@ -60,6 +61,26 @@ 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,6 +17,8 @@
package baritone.api.pathing.goals;
import java.util.Objects;
/**
* Invert any goal.
* <p>
@@ -50,6 +52,24 @@ 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,6 +17,7 @@
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;
@@ -86,6 +87,27 @@ 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

@@ -23,6 +23,7 @@ import it.unimi.dsi.fastutil.doubles.DoubleOpenHashSet;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
import java.util.Objects;
/**
* Useful for automated combat (retreating specifically)
@@ -124,6 +125,29 @@ 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,6 +17,7 @@
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;
@@ -69,6 +70,31 @@ 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,6 +17,7 @@
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;
@@ -72,6 +73,26 @@ 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,6 +64,27 @@ 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,6 +58,24 @@ 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,6 +51,7 @@ 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);

View File

@@ -38,6 +38,11 @@ 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

@@ -0,0 +1,50 @@
/*
* 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.process;
import baritone.api.pathing.goals.Goal;
import net.minecraft.util.math.BlockPos;
public interface IElytraProcess extends IBaritoneProcess {
void repackChunks();
/**
* @return Where it is currently flying to, null if not active
*/
BlockPos currentDestination();
void pathTo(BlockPos destination);
void pathTo(Goal destination);
/**
* Resets the state of the process but will maintain the same destination and will try to keep flying
*/
void resetState();
/**
* @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

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

View File

@@ -17,6 +17,7 @@
package baritone.api.schematic;
import baritone.api.schematic.mask.Mask;
import net.minecraft.block.state.IBlockState;
import java.util.List;
@@ -41,4 +42,14 @@ 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

@@ -0,0 +1,49 @@
/*
* 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

@@ -0,0 +1,60 @@
/*
* 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

@@ -0,0 +1,44 @@
/*
* 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
*/
final class PreComputedMask extends AbstractMask implements StaticMask {
private final boolean[][][] mask;
public PreComputedMask(StaticMask mask) {
super(mask.widthX(), mask.heightY(), mask.lengthZ());
this.mask = new boolean[this.heightY()][this.lengthZ()][this.widthX()];
for (int y = 0; y < this.heightY(); y++) {
for (int z = 0; z < this.lengthZ(); z++) {
for (int x = 0; x < this.widthX(); x++) {
this.mask[y][z][x] = mask.partOfMask(x, y, z);
}
}
}
}
@Override
public boolean partOfMask(int x, int y, int z) {
return this.mask[y][z][x];
}
}

View File

@@ -0,0 +1,82 @@
/*
* 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

@@ -0,0 +1,79 @@
/*
* 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

@@ -0,0 +1,56 @@
/*
* 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

@@ -0,0 +1,69 @@
/*
* 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

@@ -0,0 +1,64 @@
/*
* 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

@@ -35,6 +35,15 @@ 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;
@@ -202,6 +211,20 @@ 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() {
@@ -212,4 +235,15 @@ public final class BetterBlockPos extends BlockPos {
SettingsUtil.maybeCensor(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,6 +19,7 @@ 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;
@@ -36,21 +37,24 @@ 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 ImmutableSet<Integer> stateHashes;
private final ImmutableSet<Integer> stackHashes;
private static final Pattern pattern = Pattern.compile("^(.+?)(?::(\\d+))?$");
private final Set<Integer> stateHashes;
private final Set<Integer> stackHashes;
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.blockstates = getStates(block, meta);
this.propertiesDescription = "{}";
this.blockstates = getStates(block, meta, Collections.emptyMap());
this.stateHashes = getStateHashes(blockstates);
this.stackHashes = getStackHashes(blockstates);
}
@@ -60,24 +64,27 @@ 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");
}
MatchResult matchResult = matcher.toMatchResult();
noMeta = matchResult.group(2) == null;
noMeta = matcher.group("meta") == null;
ResourceLocation id = new ResourceLocation(matchResult.group(1));
ResourceLocation id = new ResourceLocation(matcher.group("id"));
if (!Block.REGISTRY.containsKey(id)) {
throw new IllegalArgumentException("Invalid block ID");
}
block = Block.REGISTRY.getObject(id);
meta = noMeta ? 0 : Integer.parseInt(matchResult.group(2));
blockstates = getStates(block, getMeta());
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);
stateHashes = getStateHashes(blockstates);
stackHashes = getStackHashes(blockstates);
}
@@ -243,9 +250,32 @@ public final class BlockOptionalMeta {
return state.getBlock().getMetaFromState(normalize(state));
}
private static Set<IBlockState> getStates(@Nonnull Block block, @Nullable Integer meta) {
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) {
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());
}
@@ -274,6 +304,7 @@ 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;
}
@@ -300,7 +331,11 @@ public final class BlockOptionalMeta {
@Override
public String toString() {
return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
if (noMeta) {
return String.format("BlockOptionalMeta{block=%s,properties=%s}", block, propertiesDescription);
} else {
return String.format("BlockOptionalMeta{block=%s,meta=%s}", block, getMeta());
}
}
public static IBlockState blockStateFromStack(ItemStack stack) {
@@ -315,4 +350,12 @@ public final class BlockOptionalMeta {
return null;
}
public Set<IBlockState> getAllBlockStates() {
return blockstates;
}
public Set<Integer> stackHashes() {
return stackHashes;
}
}

View File

@@ -17,68 +17,70 @@
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.boms = Stream.of(blocks)
this(Stream.of(blocks)
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new);
.toArray(BlockOptionalMeta[]::new));
}
public BlockOptionalMetaLookup(List<Block> blocks) {
this.boms = blocks.stream()
this(blocks.stream()
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new);
.toArray(BlockOptionalMeta[]::new));
}
public BlockOptionalMetaLookup(String... blocks) {
this.boms = Stream.of(blocks)
this(Stream.of(blocks)
.map(BlockOptionalMeta::new)
.toArray(BlockOptionalMeta[]::new);
.toArray(BlockOptionalMeta[]::new));
}
public boolean has(Block block) {
for (BlockOptionalMeta bom : boms) {
if (bom.getBlock() == block) {
return true;
}
}
return false;
return blockSet.contains(block);
}
public boolean has(IBlockState state) {
for (BlockOptionalMeta bom : boms) {
if (bom.matches(state)) {
return true;
}
}
return false;
return blockStateSet.contains(state);
}
public boolean has(ItemStack stack) {
for (BlockOptionalMeta bom : boms) {
if (bom.matches(stack)) {
return true;
}
}
return false;
int hash = ((IItemStack) (Object) stack).getBaritoneHash();
return stackHashes.contains(hash)
|| stackHashes.contains(hash - stack.getItemDamage());
}
public List<BlockOptionalMeta> blocks() {

View File

@@ -15,15 +15,13 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.gradle.util;
package baritone.api.utils;
/**
* 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>
* @author Brady
*/
public enum MappingType {
SEARGE,
NOTCH,
CUSTOM // forgegradle
@FunctionalInterface
public interface BooleanBinaryOperator {
boolean applyAsBoolean(boolean a, boolean b);
}

View File

@@ -0,0 +1,38 @@
/*
* 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;
/**
* @author Brady
*/
public enum BooleanBinaryOperators implements BooleanBinaryOperator {
OR((a, b) -> a || b),
AND((a, b) -> a && b),
XOR((a, b) -> a ^ b);
private final BooleanBinaryOperator op;
BooleanBinaryOperators(BooleanBinaryOperator op) {
this.op = op;
}
@Override
public boolean applyAsBoolean(boolean a, boolean b) {
return this.op.applyAsBoolean(a, b);
}
}

View File

@@ -42,8 +42,10 @@ public interface Helper {
Helper HELPER = new Helper() {};
/**
* Instance of the game
* The main game instance returned by {@link Minecraft#getMinecraft()}.
* Deprecated since {@link IPlayerContext#minecraft()} should be used instead (In the majority of cases).
*/
@Deprecated
Minecraft mc = Minecraft.getMinecraft();
static ITextComponent getPrefix() {
@@ -70,7 +72,7 @@ public interface Helper {
* @param message The message to display in the popup
*/
default void logToast(ITextComponent title, ITextComponent message) {
mc.addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().toaster.value.accept(title, message));
}
/**
@@ -131,7 +133,7 @@ public interface Helper {
* @param error Whether to log as an error
*/
default void logNotificationDirect(String message, boolean error) {
mc.addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().notifier.value.accept(message, error));
}
/**
@@ -168,7 +170,7 @@ public interface Helper {
if (logAsToast) {
logToast(getPrefix(), component);
} else {
mc.addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
Minecraft.getMinecraft().addScheduledTask(() -> BaritoneAPI.getSettings().logger.value.accept(component));
}
}
@@ -228,4 +230,11 @@ 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,6 +19,7 @@ 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;
@@ -33,6 +34,8 @@ import java.util.Optional;
*/
public interface IPlayerContext {
Minecraft minecraft();
EntityPlayerSP player();
IPlayerController playerController();
@@ -72,6 +75,12 @@ 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

@@ -0,0 +1,59 @@
/*
* 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.calcVec3dFromRotation(rotation);
Vec3d direction = RotationUtils.calcLookDirectionFromRotation(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 float yaw;
private final float yaw;
/**
* The pitch angle of this Rotation
*/
private float pitch;
private final float pitch;
public Rotation(float yaw, float pitch) {
this.yaw = yaw;
@@ -110,6 +110,10 @@ public class Rotation {
);
}
public Rotation withPitch(float pitch) {
return new Rotation(this.yaw, pitch);
}
/**
* Is really close to
*

View File

@@ -37,11 +37,13 @@ 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.
@@ -122,26 +124,31 @@ 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) {
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));
return calcLookDirectionFromRotation(rotation);
}
/**
* @param ctx Context for the viewing entity
* @param pos The target block position
* @return The optional rotation
* @see #reachable(EntityPlayerSP, BlockPos, double)
* @see #reachable(IPlayerContext, BlockPos, double)
*/
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos) {
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance());
return reachable(ctx, pos, false);
}
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, boolean wouldSneak) {
return reachable(ctx.player(), pos, ctx.playerController().getBlockReachDistance(), wouldSneak);
return reachable(ctx, pos, ctx.playerController().getBlockReachDistance(), wouldSneak);
}
/**
@@ -151,18 +158,17 @@ 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 entity The viewing entity
* @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> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
return reachable(entity, pos, blockReachDistance, false);
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, boolean wouldSneak) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (baritone.getPlayerContext().isLookingAt(pos)) {
public static Optional<Rotation> reachable(IPlayerContext ctx, BlockPos pos, double blockReachDistance, boolean wouldSneak) {
if (BaritoneAPI.getSettings().remainWithExistingLookDirection.value && ctx.isLookingAt(pos)) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
@@ -173,10 +179,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 = new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F);
Rotation hypothetical = ctx.playerRotations().add(new Rotation(0, 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(entity, hypothetical, blockReachDistance, true);
RayTraceResult result = RayTraceUtils.rayTraceTowards(ctx.player(), 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
}
@@ -184,19 +190,19 @@ public final class RotationUtils {
return Optional.of(hypothetical);
}
}
Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance, wouldSneak);
Optional<Rotation> possibleRotation = reachableCenter(ctx, pos, blockReachDistance, wouldSneak);
//System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
IBlockState state = entity.world.getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
IBlockState state = ctx.world().getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(ctx.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(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak);
possibleRotation = reachableOffset(ctx, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance, wouldSneak);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
@@ -209,12 +215,55 @@ 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 entity The viewing entity
* @param ctx Context for 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));
@@ -231,15 +280,7 @@ public final class RotationUtils {
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 entity The viewing entity
* @param pos The target block position
* @param blockReachDistance The block reach distance of the entity
* @return The optional rotation
*/
@Deprecated
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,6 +20,7 @@ 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;
@@ -44,13 +45,10 @@ 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 {
private static final Path SETTINGS_PATH = getMinecraft().gameDir.toPath().resolve("baritone").resolve("settings.txt");
public static final String SETTINGS_DEFAULT_NAME = "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("//");
@@ -68,12 +66,12 @@ public class SettingsUtil {
}
}
public static void readAndApply(Settings settings) {
public static void readAndApply(Settings settings, String settingsName) {
try {
forEachLine(SETTINGS_PATH, line -> {
forEachLine(settingsByName(settingsName), line -> {
Matcher matcher = SETTING_PATTERN.matcher(line);
if (!matcher.matches()) {
System.out.println("Invalid syntax in setting file: " + line);
Helper.HELPER.logDirect("Invalid syntax in setting file: " + line);
return;
}
@@ -82,29 +80,33 @@ public class SettingsUtil {
try {
parseAndApply(settings, settingName, settingValue);
} catch (Exception ex) {
System.out.println("Unable to parse line " + line);
Helper.HELPER.logDirect("Unable to parse line " + line);
ex.printStackTrace();
}
});
} catch (NoSuchFileException ignored) {
System.out.println("Baritone settings file not found, resetting.");
Helper.HELPER.logDirect("Baritone settings file not found, resetting.");
} catch (Exception ex) {
System.out.println("Exception while reading Baritone settings, some settings may be reset to default values!");
Helper.HELPER.logDirect("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(SETTINGS_PATH)) {
try (BufferedWriter out = Files.newBufferedWriter(settingsByName(SETTINGS_DEFAULT_NAME))) {
for (Settings.Setting setting : modifiedSettings(settings)) {
out.write(settingToString(setting) + "\n");
}
} catch (Exception ex) {
System.out.println("Exception thrown while saving Baritone settings!");
Helper.HELPER.logDirect("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) {
@@ -112,7 +114,7 @@ public class SettingsUtil {
System.out.println("NULL SETTING?" + setting.getName());
continue;
}
if (javaOnlySetting(setting)) {
if (setting.isJavaOnly()) {
continue; // NO
}
if (setting.value == setting.defaultValue) {
@@ -166,7 +168,7 @@ public class SettingsUtil {
}
public static String settingToString(Settings.Setting setting) throws IllegalStateException {
if (javaOnlySetting(setting)) {
if (setting.isJavaOnly()) {
return setting.getName();
}
@@ -174,18 +176,14 @@ public class SettingsUtil {
}
/**
* This should always be the same as whether the setting can be parsed from or serialized to a string
* Deprecated. Use {@link Settings.Setting#isJavaOnly()} instead.
*
* @param setting The Setting
* @return true if the setting can not be set or read by the user
*/
@Deprecated
public static boolean javaOnlySetting(Settings.Setting setting) {
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;
return setting.isJavaOnly();
}
public static void parseAndApply(Settings settings, String settingName, String settingValue) throws IllegalStateException, NumberFormatException {

View File

@@ -17,6 +17,7 @@
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;
@@ -73,6 +74,6 @@ public class BaritoneToast implements IToast {
}
public static void addOrUpdate(ITextComponent title, ITextComponent subtitle) {
addOrUpdate(net.minecraft.client.Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value);
addOrUpdate(Minecraft.getMinecraft().getToastGui(), title, subtitle, baritone.api.BaritoneAPI.getSettings().toastTimer.value);
}
}

View File

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

View File

@@ -35,6 +35,16 @@ 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

@@ -0,0 +1,57 @@
/*
* 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,11 +25,14 @@ 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;
/**
@@ -42,11 +45,14 @@ public abstract class MixinEntityLivingBase extends Entity {
/**
* Event called to override the movement direction when jumping
*/
@Unique
private RotationMoveEvent jumpRotationEvent;
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
@Unique
private RotationMoveEvent elytraRotationEvent;
private MixinEntityLivingBase(World worldIn) {
super(worldIn);
this.jumpRotationEvent = jumpRotationEvent;
}
@Inject(
@@ -54,14 +60,10 @@ public abstract class MixinEntityLivingBase extends Entity {
at = @At("HEAD")
)
private void preMoveRelative(CallbackInfo ci) {
// 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);
}
}
this.getBaritone().ifPresent(baritone -> {
this.jumpRotationEvent = new RotationMoveEvent(RotationMoveEvent.Type.JUMP, this.rotationYaw, this.rotationPitch);
baritone.getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
});
}
@Redirect(
@@ -79,6 +81,38 @@ 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(
@@ -86,17 +120,33 @@ public abstract class MixinEntityLivingBase extends Entity {
target = "net/minecraft/entity/EntityLivingBase.moveRelative(FFFF)V"
)
)
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);
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);
return;
}
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();
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();
this.moveRelative(strafe, up, forward, friction);
this.rotationYaw = originalYaw;
this.rotationYaw = event.getOriginal().getYaw();
this.rotationPitch = event.getOriginal().getPitch();
}
@Unique
private Optional<IBaritone> getBaritone() {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
return Optional.ofNullable(BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this));
} else {
return Optional.empty();
}
}
}

View File

@@ -27,6 +27,8 @@ import baritone.behavior.LookBehavior;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.entity.player.PlayerCapabilities;
import net.minecraft.item.ItemElytra;
import net.minecraft.item.ItemStack;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -61,9 +63,8 @@ public class MixinEntityPlayerSP {
method = "onUpdate",
at = @At(
value = "INVOKE",
target = "net/minecraft/client/entity/EntityPlayerSP.isRiding()Z",
shift = At.Shift.BY,
by = -3
target = "net/minecraft/client/entity/AbstractClientPlayer.onUpdate()V",
shift = At.Shift.AFTER
)
)
private void onPreUpdate(CallbackInfo ci) {
@@ -73,22 +74,6 @@ 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(
@@ -140,4 +125,19 @@ public class MixinEntityPlayerSP {
((LookBehavior) baritone.getLookBehavior()).pig();
}
}
@Redirect(
method = "onLivingUpdate",
at = @At(
value = "INVOKE",
target = "net/minecraft/item/ItemElytra.isUsable(Lnet/minecraft/item/ItemStack;)Z"
)
)
private boolean isElytraUsable(ItemStack stack) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this);
if (baritone != null && baritone.getPathingBehavior().isPathing()) {
return false;
}
return ItemElytra.isUsable(stack);
}
}

View File

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

View File

@@ -17,24 +17,29 @@
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.cache.CachedChunk;
import net.minecraft.client.entity.EntityPlayerSP;
import baritone.api.utils.Pair;
import net.minecraft.block.state.IBlockState;
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
@@ -50,19 +55,18 @@ public class MixinNetHandlerPlayClient {
)
)
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
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()
)
);
}
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
if (baritone == null) {
return;
}
baritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
}
@Inject(
@@ -70,19 +74,18 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN")
)
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
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()
)
);
}
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
if (baritone == null) {
return;
}
baritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
}
@Inject(
@@ -90,25 +93,14 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN")
)
private void postHandleBlockChange(SPacketBlockChange packetIn, CallbackInfo ci) {
if (!Baritone.settings().repackOnAnyBlockChange.value) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
if (baritone == null) {
return;
}
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
)
);
}
}
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)));
}
@Inject(
@@ -116,35 +108,20 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN")
)
private void postHandleMultiBlockChange(SPacketMultiBlockChange packetIn, CallbackInfo ci) {
if (!Baritone.settings().repackOnAnyBlockChange.value) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
if (baritone == null) {
return;
}
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
)
);
}
}
// 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())
));
}
@Inject(
@@ -155,11 +132,10 @@ public class MixinNetHandlerPlayClient {
)
)
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
EntityPlayerSP player = ibaritone.getPlayerContext().player();
if (player != null && player.connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onPlayerDeath();
}
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForConnection((NetHandlerPlayClient) (Object) this);
if (baritone == null) {
return;
}
baritone.getGameEventHandler().onPlayerDeath();
}
}

View File

@@ -16,6 +16,7 @@
"MixinChunkProviderServer",
"MixinChunkRenderContainer",
"MixinChunkRenderWorker",
"MixinEntityFireworkRocket",
"MixinEntityLivingBase",
"MixinEntityPlayerSP",
"MixinEntityRenderer",
@@ -34,4 +35,4 @@
"MixinVboRenderList",
"MixinWorldClient"
]
}
}

View File

@@ -20,8 +20,10 @@ package baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.behavior.IBehavior;
import baritone.api.event.listener.IEventBus;
import baritone.api.utils.Helper;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.IElytraProcess;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
@@ -33,16 +35,19 @@ import baritone.utils.BlockStateInterface;
import baritone.utils.GuiClick;
import baritone.utils.InputOverrideHandler;
import baritone.utils.PathingControlManager;
import baritone.utils.player.PrimaryPlayerContext;
import baritone.utils.player.BaritonePlayerContext;
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
@@ -50,87 +55,103 @@ import java.util.concurrent.TimeUnit;
*/
public class Baritone implements IBaritone {
private static ThreadPoolExecutor threadPool;
private static File dir;
private static final ThreadPoolExecutor threadPool;
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 GameEventHandler gameEventHandler;
private final Minecraft mc;
private final Path directory;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private InventoryBehavior inventoryBehavior;
private WaypointBehavior waypointBehavior;
private InputOverrideHandler inputOverrideHandler;
private final GameEventHandler gameEventHandler;
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 PathingBehavior pathingBehavior;
private final LookBehavior lookBehavior;
private final InventoryBehavior inventoryBehavior;
private final InputOverrideHandler inputOverrideHandler;
private PathingControlManager pathingControlManager;
private SelectionManager selectionManager;
private CommandManager commandManager;
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 final ElytraProcess elytraProcess;
private IPlayerContext playerContext;
private WorldProvider worldProvider;
private final PathingControlManager pathingControlManager;
private final SelectionManager selectionManager;
private final CommandManager commandManager;
private final IPlayerContext playerContext;
private final WorldProvider worldProvider;
public BlockStateInterface bsi;
Baritone() {
Baritone(Minecraft mc) {
this.mc = mc;
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 = PrimaryPlayerContext.INSTANCE;
this.playerContext = new BaritonePlayerContext(this, mc);
{
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
inventoryBehavior = new InventoryBehavior(this);
inputOverrideHandler = new InputOverrideHandler(this);
waypointBehavior = new WaypointBehavior(this);
this.lookBehavior = this.registerBehavior(LookBehavior::new);
this.pathingBehavior = this.registerBehavior(PathingBehavior::new);
this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new);
this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new);
this.registerBehavior(WaypointBehavior::new);
}
this.pathingControlManager = new PathingControlManager(this);
{
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.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.elytraProcess = this.registerProcess(ElytraProcess::create);
this.registerProcess(BackfillProcess::new);
}
this.worldProvider = new WorldProvider();
this.worldProvider = new WorldProvider(this);
this.selectionManager = new SelectionManager(this);
this.commandManager = new CommandManager(this);
}
public void registerBehavior(IBehavior 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;
}
@Override
public PathingControlManager getPathingControlManager() {
return this.pathingControlManager;
}
public void registerBehavior(Behavior behavior) {
this.gameEventHandler.registerEventListener(behavior);
}
@Override
public InputOverrideHandler getInputOverrideHandler() {
return this.inputOverrideHandler;
@@ -170,6 +191,7 @@ public class Baritone implements IBaritone {
return this.lookBehavior;
}
@Override
public ExploreProcess getExploreProcess() {
return this.exploreProcess;
}
@@ -179,10 +201,15 @@ 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;
@@ -208,24 +235,29 @@ public class Baritone implements IBaritone {
return this.commandManager;
}
@Override
public IElytraProcess getElytraProcess() {
return this.elytraProcess;
}
@Override
public void openClick() {
new Thread(() -> {
try {
Thread.sleep(100);
Helper.mc.addScheduledTask(() -> Helper.mc.displayGuiScreen(new GuiClick()));
mc.addScheduledTask(() -> 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,13 +22,15 @@ import baritone.api.IBaritoneProvider;
import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommandSystem;
import baritone.api.schematic.ISchematicSystem;
import baritone.cache.WorldScanner;
import baritone.cache.FasterWorldScanner;
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
@@ -36,30 +38,45 @@ import java.util.List;
*/
public final class BaritoneProvider implements IBaritoneProvider {
private final Baritone primary;
private final List<IBaritone> all;
private final List<IBaritone> allView;
{
this.primary = new Baritone();
this.all = Collections.singletonList(this.primary);
public BaritoneProvider() {
this.all = new CopyOnWriteArrayList<>();
this.allView = Collections.unmodifiableList(this.all);
// Setup chat control, just for the primary instance
new ExampleBaritoneControl(this.primary);
final Baritone primary = (Baritone) this.createBaritone(Minecraft.getMinecraft());
primary.registerBehavior(ExampleBaritoneControl::new);
}
@Override
public IBaritone getPrimaryBaritone() {
return primary;
return this.all.get(0);
}
@Override
public List<IBaritone> getAllBaritones() {
return all;
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);
}
@Override
public IWorldScanner getWorldScanner() {
return WorldScanner.INSTANCE;
return FasterWorldScanner.INSTANCE;
}
@Override

View File

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

View File

@@ -19,6 +19,7 @@ package baritone.behavior;
import baritone.Baritone;
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;
@@ -34,7 +35,10 @@ import java.util.OptionalInt;
import java.util.Random;
import java.util.function.Predicate;
public final class InventoryBehavior extends Behavior {
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 InventoryBehavior(Baritone baritone) {
super(baritone);
@@ -52,20 +56,28 @@ public final class InventoryBehavior extends Behavior {
// 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
swapWithHotBar(firstValidThrowaway(), 8);
requestSwapWithHotBar(firstValidThrowaway(), 8);
}
int pick = bestToolAgainst(Blocks.STONE, ItemPickaxe.class);
if (pick >= 9) {
swapWithHotBar(pick, 0);
requestSwapWithHotBar(pick, 0);
}
if (lastTickRequestedMove != null) {
logDebug("Remembering to move " + lastTickRequestedMove[0] + " " + lastTickRequestedMove[1] + " from a previous tick");
requestSwapWithHotBar(lastTickRequestedMove[0], lastTickRequestedMove[1]);
}
}
public void attemptToPutOnHotbar(int inMainInvy, Predicate<Integer> disallowedHotbar) {
public boolean attemptToPutOnHotbar(int inMainInvy, Predicate<Integer> disallowedHotbar) {
OptionalInt destination = getTempHotbarSlot(disallowedHotbar);
if (destination.isPresent()) {
swapWithHotBar(inMainInvy, destination.getAsInt());
if (!requestSwapWithHotBar(inMainInvy, destination.getAsInt())) {
return false;
}
}
return true;
}
public OptionalInt getTempHotbarSlot(Predicate<Integer> disallowedHotbar) {
@@ -89,8 +101,20 @@ public final class InventoryBehavior extends Behavior {
return OptionalInt.of(candidates.get(new Random().nextInt(candidates.size())));
}
private void swapWithHotBar(int inInventory, int inHotbar) {
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;
}
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
@@ -192,8 +216,8 @@ public final class InventoryBehavior extends Behavior {
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,40 +20,64 @@ package baritone.behavior;
import baritone.Baritone;
import baritone.api.Settings;
import baritone.api.behavior.ILookBehavior;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.RotationMoveEvent;
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.utils.Rotation;
import baritone.behavior.look.ForkableRandom;
import net.minecraft.network.play.client.CPacketPlayer;
import java.util.ArrayDeque;
import java.util.Deque;
import java.util.Optional;
public final class LookBehavior extends Behavior implements ILookBehavior {
/**
* Target's values are as follows:
* <p>
* getFirst() -> yaw
* getSecond() -> pitch
* The current look target, may be {@code null}.
*/
private Rotation target;
private Target target;
/**
* Whether or not rotations are currently being forced
* The rotation known to the server. Returned by {@link #getEffectiveRotation()} for use in {@link IPlayerContext}.
*/
private boolean force;
private Rotation serverRotation;
/**
* The last player yaw angle. Used when free looking
* The last player rotation. Used to restore the player's angle when using free look.
*
* @see Settings#freeLook
*/
private float lastYaw;
private Rotation prevRotation;
private final AimProcessor processor;
private final Deque<Float> smoothYawBuffer;
private final Deque<Float> smoothPitchBuffer;
public LookBehavior(Baritone baritone) {
super(baritone);
this.processor = new AimProcessor(baritone.getPlayerContext());
this.smoothYawBuffer = new ArrayDeque<>();
this.smoothPitchBuffer = new ArrayDeque<>();
}
@Override
public void updateTarget(Rotation target, boolean force) {
this.target = target;
this.force = force || !Baritone.settings().freeLook.value;
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();
}
}
@Override
@@ -61,35 +85,44 @@ 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.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 (silent) {
this.lastYaw = ctx.player().rotationYaw;
ctx.player().rotationYaw = this.target.getYaw();
if (this.target.mode == Target.Mode.NONE) {
// Just return for PRE, we still want to set target to null on POST
return;
}
this.prevRotation = new Rotation(ctx.player().rotationYaw, ctx.player().rotationPitch);
final Rotation actual = this.processor.peekRotation(this.target.rotation);
ctx.player().rotationYaw = actual.getYaw();
ctx.player().rotationPitch = actual.getPitch();
break;
}
case POST: {
if (silent) {
ctx.player().rotationYaw = this.lastYaw;
this.target = null;
// Reset the player's rotations back to their original values
if (this.prevRotation != null) {
this.smoothYawBuffer.addLast(this.target.rotation.getYaw());
while (this.smoothYawBuffer.size() > Baritone.settings().smoothLookTicks.value) {
this.smoothYawBuffer.removeFirst();
}
this.smoothPitchBuffer.addLast(this.target.rotation.getPitch());
while (this.smoothPitchBuffer.size() > Baritone.settings().smoothLookTicks.value) {
this.smoothPitchBuffer.removeFirst();
}
if (this.target.mode == Target.Mode.SERVER) {
ctx.player().rotationYaw = this.prevRotation.getYaw();
ctx.player().rotationPitch = this.prevRotation.getPitch();
} else if (ctx.player().isElytraFlying() ? Baritone.settings().elytraSmoothLook.value : Baritone.settings().smoothLook.value) {
ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getYaw());
if (ctx.player().isElytraFlying()) {
ctx.player().rotationPitch = (float) this.smoothPitchBuffer.stream().mapToDouble(d -> d).average().orElse(this.prevRotation.getPitch());
}
}
this.prevRotation = null;
}
// The target is done being used for this game tick, so it can be invalidated
this.target = null;
break;
}
default:
@@ -97,34 +130,218 @@ 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) {
ctx.player().rotationYaw = this.target.getYaw();
final Rotation actual = this.processor.peekRotation(this.target.rotation);
ctx.player().rotationYaw = actual.getYaw();
}
}
public Optional<Rotation> getEffectiveRotation() {
if (Baritone.settings().freeLook.value) {
return Optional.ofNullable(this.serverRotation);
}
// If freeLook isn't on, just defer to the player's actual rotations
return Optional.empty();
}
@Override
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());
private static final class AimProcessor extends AbstractAimProcessor {
// 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;
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;
if (ctx.player().isElytraFlying()) {
// always need to set angles while flying
return settings.elytraFreeLook.value ? SERVER : CLIENT;
} else if (settings.freeLook.value) {
// 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 (blockInteract) {
return blockFreeLook ? SERVER : CLIENT;
}
return antiCheat ? SERVER : NONE;
}
// all freeLook settings are disabled so set the angles
return CLIENT;
}
}
}
/**
* 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

@@ -33,6 +33,7 @@ import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.PathExecutor;
import baritone.process.ElytraProcess;
import baritone.utils.PathRenderer;
import baritone.utils.PathingCommandContext;
import baritone.utils.pathing.Favoring;
@@ -239,11 +240,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (current != null) {
switch (event.getState()) {
case PRE:
lastAutoJump = mc.gameSettings.autoJump;
mc.gameSettings.autoJump = false;
lastAutoJump = ctx.minecraft().gameSettings.autoJump;
ctx.minecraft().gameSettings.autoJump = false;
break;
case POST:
mc.gameSettings.autoJump = lastAutoJump;
ctx.minecraft().gameSettings.autoJump = lastAutoJump;
break;
default:
break;
@@ -309,7 +310,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
public boolean isSafeToCancel() {
return current == null || safeToCancel;
if (current == null) {
return !baritone.getElytraProcess().isActive() || baritone.getElytraProcess().isSafeToCancel();
}
return safeToCancel;
}
public void requestPause() {
@@ -352,7 +356,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
// just cancel the current path
private void secretInternalSegmentCancel() {
public void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED);
synchronized (pathPlanLock) {
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);

View File

@@ -0,0 +1,85 @@
/*
* 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.look;
import java.util.Arrays;
import java.util.concurrent.atomic.AtomicLong;
import java.util.function.LongSupplier;
/**
* Implementation of Xoroshiro256++
* <p>
* Extended to produce random double-precision floating point numbers, and allow copies to be spawned via {@link #fork},
* which share the same internal state as the source object.
*
* @author Brady
*/
public final class ForkableRandom {
private static final double DOUBLE_UNIT = 0x1.0p-53;
private final long[] s;
public ForkableRandom() {
this(System.nanoTime() ^ System.currentTimeMillis());
}
public ForkableRandom(long seedIn) {
final AtomicLong seed = new AtomicLong(seedIn);
final LongSupplier splitmix64 = () -> {
long z = seed.addAndGet(0x9e3779b97f4a7c15L);
z = (z ^ (z >>> 30)) * 0xbf58476d1ce4e5b9L;
z = (z ^ (z >>> 27)) * 0x94d049bb133111ebL;
return z ^ (z >>> 31);
};
this.s = new long[] {
splitmix64.getAsLong(),
splitmix64.getAsLong(),
splitmix64.getAsLong(),
splitmix64.getAsLong()
};
}
private ForkableRandom(long[] s) {
this.s = s;
}
public double nextDouble() {
return (this.next() >>> 11) * DOUBLE_UNIT;
}
public long next() {
final long result = rotl(this.s[0] + this.s[3], 23) + this.s[0];
final long t = this.s[1] << 17;
this.s[2] ^= this.s[0];
this.s[3] ^= this.s[1];
this.s[1] ^= this.s[2];
this.s[0] ^= this.s[3];
this.s[2] ^= t;
this.s[3] = rotl(this.s[3], 45);
return result;
}
public ForkableRandom fork() {
return new ForkableRandom(Arrays.copyOf(this.s, 4));
}
private static long rotl(long x, int k) {
return (x << k) | (x >>> (64 - k));
}
}

View File

@@ -23,6 +23,7 @@ import baritone.api.IBaritone;
import baritone.api.cache.ICachedWorld;
import baritone.api.cache.IWorldData;
import baritone.api.utils.Helper;
import com.google.common.cache.CacheBuilder;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
import net.minecraft.util.math.BlockPos;
@@ -35,7 +36,6 @@ import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.LinkedBlockingQueue;
/**
@@ -69,7 +69,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
* All chunk positions pending packing. This map will be updated in-place if a new update to the chunk occurs
* while waiting in the queue for the packer thread to get to it.
*/
private final Map<ChunkPos, Chunk> toPackMap = new ConcurrentHashMap<>();
private final Map<ChunkPos, Chunk> toPackMap = CacheBuilder.newBuilder().softValues().<ChunkPos, Chunk>build().asMap();
private final int dimension;
@@ -307,6 +307,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
try {
ChunkPos pos = toPackQueue.take();
Chunk chunk = toPackMap.remove(pos);
if (toPackQueue.size() > Baritone.settings().chunkPackerQueueMaxSize.value) {
continue;
}
CachedChunk cached = ChunkPacker.pack(chunk);
CachedWorld.this.updateCachedChunk(cached);
//System.out.println("Processed chunk at " + chunk.x + "," + chunk.z);

View File

@@ -0,0 +1,276 @@
/*
* 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.cache;
import baritone.api.cache.ICachedWorld;
import baritone.api.cache.IWorldScanner;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.BlockOptionalMetaLookup;
import baritone.api.utils.IPlayerContext;
import baritone.utils.accessor.IBitArray;
import baritone.utils.accessor.IBlockStateContainer;
import io.netty.buffer.Unpooled;
import it.unimi.dsi.fastutil.ints.IntArrayList;
import it.unimi.dsi.fastutil.ints.IntList;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
import net.minecraft.network.PacketBuffer;
import net.minecraft.util.BitArray;
import net.minecraft.util.ObjectIntIdentityMap;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.chunk.*;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import java.util.ArrayList;
import java.util.List;
import java.util.function.BiConsumer;
import java.util.function.IntConsumer;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public enum FasterWorldScanner implements IWorldScanner {
INSTANCE;
@Override
public List<BlockPos> scanChunkRadius(IPlayerContext ctx, BlockOptionalMetaLookup filter, int max, int yLevelThreshold, int maxSearchRadius) {
assert ctx.world() != null;
if (maxSearchRadius < 0) {
throw new IllegalArgumentException("chunkRange must be >= 0");
}
return scanChunksInternal(ctx, filter, getChunkRange(ctx.playerFeet().x >> 4, ctx.playerFeet().z >> 4, maxSearchRadius), max);
}
@Override
public List<BlockPos> scanChunk(IPlayerContext ctx, BlockOptionalMetaLookup filter, ChunkPos pos, int max, int yLevelThreshold) {
Stream<BlockPos> stream = scanChunkInternal(ctx, filter, pos);
if (max >= 0) {
stream = stream.limit(max);
}
return stream.collect(Collectors.toList());
}
@Override
public int repack(IPlayerContext ctx) {
return this.repack(ctx, 40);
}
@Override
public int repack(IPlayerContext ctx, int range) {
IChunkProvider chunkProvider = ctx.world().getChunkProvider();
ICachedWorld cachedWorld = ctx.worldData().getCachedWorld();
BetterBlockPos playerPos = ctx.playerFeet();
int playerChunkX = playerPos.getX() >> 4;
int playerChunkZ = playerPos.getZ() >> 4;
int minX = playerChunkX - range;
int minZ = playerChunkZ - range;
int maxX = playerChunkX + range;
int maxZ = playerChunkZ + range;
int queued = 0;
for (int x = minX; x <= maxX; x++) {
for (int z = minZ; z <= maxZ; z++) {
Chunk chunk = chunkProvider.getLoadedChunk(x, z);
if (chunk != null && !chunk.isEmpty()) {
queued++;
cachedWorld.queueForPacking(chunk);
}
}
}
return queued;
}
// ordered in a way that the closest blocks are generally first
public static List<ChunkPos> getChunkRange(int centerX, int centerZ, int chunkRadius) {
List<ChunkPos> chunks = new ArrayList<>();
// spiral out
chunks.add(new ChunkPos(centerX, centerZ));
for (int i = 1; i < chunkRadius; i++) {
for (int j = 0; j <= i; j++) {
chunks.add(new ChunkPos(centerX - j, centerZ - i));
if (j != 0) {
chunks.add(new ChunkPos(centerX + j, centerZ - i));
chunks.add(new ChunkPos(centerX - j, centerZ + i));
}
chunks.add(new ChunkPos(centerX + j, centerZ + i));
if (j != i) {
chunks.add(new ChunkPos(centerX - i, centerZ - j));
chunks.add(new ChunkPos(centerX + i, centerZ - j));
if (j != 0) {
chunks.add(new ChunkPos(centerX - i, centerZ + j));
chunks.add(new ChunkPos(centerX + i, centerZ + j));
}
}
}
}
return chunks;
}
private List<BlockPos> scanChunksInternal(IPlayerContext ctx, BlockOptionalMetaLookup lookup, List<ChunkPos> chunkPositions, int maxBlocks) {
assert ctx.world() != null;
try {
// p -> scanChunkInternal(ctx, lookup, p)
Stream<BlockPos> posStream = chunkPositions.parallelStream().flatMap(p -> scanChunkInternal(ctx, lookup, p));
if (maxBlocks >= 0) {
// WARNING: this can be expensive if maxBlocks is large...
// see limit's javadoc
posStream = posStream.limit(maxBlocks);
}
return posStream.collect(Collectors.toList());
} catch (Exception e) {
e.printStackTrace();
throw e;
}
}
private Stream<BlockPos> scanChunkInternal(IPlayerContext ctx, BlockOptionalMetaLookup lookup, ChunkPos pos) {
IChunkProvider chunkProvider = ctx.world().getChunkProvider();
// if chunk is not loaded, return empty stream
if (!chunkProvider.isChunkGeneratedAt(pos.x, pos.z)) {
return Stream.empty();
}
long chunkX = (long) pos.x << 4;
long chunkZ = (long) pos.z << 4;
int playerSectionY = ctx.playerFeet().y >> 4;
return collectChunkSections(lookup, chunkProvider.getLoadedChunk(pos.x, pos.z), chunkX, chunkZ, playerSectionY).stream();
}
private List<BlockPos> collectChunkSections(BlockOptionalMetaLookup lookup, Chunk chunk, long chunkX, long chunkZ, int playerSection) {
// iterate over sections relative to player
List<BlockPos> blocks = new ArrayList<>();
ExtendedBlockStorage[] sections = chunk.getBlockStorageArray();
int l = sections.length;
int i = playerSection - 1;
int j = playerSection;
for (; i >= 0 || j < l; ++j, --i) {
if (j < l) {
visitSection(lookup, sections[j], blocks, chunkX, chunkZ);
}
if (i >= 0) {
visitSection(lookup, sections[i], blocks, chunkX, chunkZ);
}
}
return blocks;
}
private void visitSection(BlockOptionalMetaLookup lookup, ExtendedBlockStorage section, List<BlockPos> blocks, long chunkX, long chunkZ) {
if (section == null || section.isEmpty()) {
return;
}
BlockStateContainer sectionContainer = section.getData();
//this won't work if the PaletteStorage is of the type EmptyPaletteStorage
if (((IBlockStateContainer) sectionContainer).getStorage() == null) {
return;
}
boolean[] isInFilter = getIncludedFilterIndices(lookup, ((IBlockStateContainer) sectionContainer).getPalette());
if (isInFilter.length == 0) {
return;
}
BitArray array = ((IBlockStateContainer) section.getData()).getStorage();
long[] longArray = array.getBackingLongArray();
int arraySize = array.size();
int bitsPerEntry = ((IBitArray) array).getBitsPerEntry();
long maxEntryValue = ((IBitArray) array).getMaxEntryValue();
int yOffset = section.getYLocation();
for (int idx = 0, kl = bitsPerEntry - 1; idx < arraySize; idx++, kl += bitsPerEntry) {
final int i = idx * bitsPerEntry;
final int j = i >> 6;
final int l = i & 63;
final int k = kl >> 6;
final long jl = longArray[j] >>> l;
if (j == k) {
if (isInFilter[(int) (jl & maxEntryValue)]) {
//noinspection DuplicateExpressions
blocks.add(new BlockPos(
chunkX + ((idx & 255) & 15),
yOffset + (idx >> 8),
chunkZ + ((idx & 255) >> 4)
));
}
} else {
if (isInFilter[(int) ((jl | longArray[k] << (64 - l)) & maxEntryValue)]) {
//noinspection DuplicateExpressions
blocks.add(new BlockPos(
chunkX + ((idx & 255) & 15),
yOffset + (idx >> 8),
chunkZ + ((idx & 255) >> 4)
));
}
}
}
}
private boolean[] getIncludedFilterIndices(BlockOptionalMetaLookup lookup, IBlockStatePalette palette) {
boolean commonBlockFound = false;
ObjectIntIdentityMap<IBlockState> paletteMap = getPalette(palette);
int size = paletteMap.size();
boolean[] isInFilter = new boolean[size];
for (int i = 0; i < size; i++) {
IBlockState state = paletteMap.getByValue(i);
if (lookup.has(state)) {
isInFilter[i] = true;
commonBlockFound = true;
} else {
isInFilter[i] = false;
}
}
if (!commonBlockFound) {
return new boolean[0];
}
return isInFilter;
}
/**
* cheats to get the actual map of id -> blockstate from the various palette implementations
*/
private static ObjectIntIdentityMap<IBlockState> getPalette(IBlockStatePalette palette) {
if (palette instanceof BlockStatePaletteRegistry) {
return Block.BLOCK_STATE_IDS;
} else {
PacketBuffer buf = new PacketBuffer(Unpooled.buffer());
palette.write(buf);
int size = buf.readVarInt();
ObjectIntIdentityMap<IBlockState> states = new ObjectIntIdentityMap<>();
for (int i = 0; i < size; i++) {
IBlockState state = Block.BLOCK_STATE_IDS.getByValue(buf.readVarInt());
assert state != null;
states.put(state, i);
}
return states;
}
}
}

View File

@@ -19,103 +19,85 @@ package baritone.cache;
import baritone.Baritone;
import baritone.api.cache.IWorldProvider;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import baritone.utils.accessor.IAnvilChunkLoader;
import baritone.utils.accessor.IChunkProviderServer;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.util.Tuple;
import net.minecraft.world.World;
import net.minecraft.world.WorldServer;
import org.apache.commons.lang3.SystemUtils;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Consumer;
import java.util.Optional;
/**
* @author Brady
* @since 8/4/2018
*/
public class WorldProvider implements IWorldProvider, Helper {
public class WorldProvider implements IWorldProvider {
private static final Map<Path, WorldData> worldCache = new HashMap<>(); // this is how the bots have the same cached world
private static final Map<Path, WorldData> worldCache = new HashMap<>();
private final Baritone baritone;
private final IPlayerContext ctx;
private WorldData currentWorld;
private World mcWorld; // this let's us detect a broken load/unload hook
/**
* This lets us detect a broken load/unload hook.
* @see #detectAndHandleBrokenLoading()
*/
private World mcWorld;
public WorldProvider(Baritone baritone) {
this.baritone = baritone;
this.ctx = baritone.getPlayerContext();
}
@Override
public final WorldData getCurrentWorld() {
detectAndHandleBrokenLoading();
this.detectAndHandleBrokenLoading();
return this.currentWorld;
}
/**
* Called when a new world is initialized to discover the
*
* @param dimension The ID of the world's dimension
* @param world The new world
*/
public final void initWorld(int dimension) {
File directory;
File readme;
public final void initWorld(World world) {
this.getSaveDirectories(world).ifPresent(dirs -> {
final Path worldDir = dirs.getFirst();
final Path readmeDir = dirs.getSecond();
IntegratedServer integratedServer = mc.getIntegratedServer();
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
if (mc.isSingleplayer()) {
WorldServer localServerWorld = integratedServer.getWorld(dimension);
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
directory = loader.getChunkSaveLocation();
// Gets the "depth" of this directory relative the the game's run directory, 2 is the location of the world
if (directory.toPath().relativize(mc.gameDir.toPath()).getNameCount() != 2) {
// subdirectory of the main save directory for this world
directory = directory.getParentFile();
}
directory = new File(directory, "baritone");
readme = directory;
} else { // Otherwise, the server must be remote...
String folderName;
if (mc.getCurrentServerData() != null) {
folderName = mc.getCurrentServerData().serverIP;
} else {
//replaymod causes null currentServerData and false singleplayer.
System.out.println("World seems to be a replay. Not loading Baritone cache.");
currentWorld = null;
mcWorld = mc.world;
return;
}
if (SystemUtils.IS_OS_WINDOWS) {
folderName = folderName.replace(":", "_");
}
directory = new File(Baritone.getDir(), folderName);
readme = Baritone.getDir();
}
// lol wtf is this baritone folder in my minecraft save?
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {
// good thing we have a readme
out.write("https://github.com/cabaletta/baritone\n".getBytes());
} catch (IOException ignored) {}
// We will actually store the world data in a subfolder: "DIM<id>"
Path dir = new File(directory, "DIM" + dimension).toPath();
if (!Files.exists(dir)) {
try {
Files.createDirectories(dir);
// lol wtf is this baritone folder in my minecraft save?
// good thing we have a readme
Files.createDirectories(readmeDir);
Files.write(
readmeDir.resolve("readme.txt"),
"https://github.com/cabaletta/baritone\n".getBytes(StandardCharsets.US_ASCII)
);
} catch (IOException ignored) {}
}
System.out.println("Baritone world data dir: " + dir);
synchronized (worldCache) {
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
}
this.mcWorld = mc.world;
// We will actually store the world data in a subfolder: "DIM<id>"
final Path worldDataDir = this.getWorldDataDirectory(worldDir, world);
try {
Files.createDirectories(worldDataDir);
} catch (IOException ignored) {}
System.out.println("Baritone world data dir: " + worldDataDir);
synchronized (worldCache) {
final int dimension = world.provider.getDimensionType().getId();
this.currentWorld = worldCache.computeIfAbsent(worldDataDir, d -> new WorldData(d, dimension));
}
this.mcWorld = ctx.world();
});
}
public final void closeWorld() {
@@ -128,26 +110,75 @@ public class WorldProvider implements IWorldProvider, Helper {
world.onClose();
}
public final void ifWorldLoaded(Consumer<WorldData> currentWorldConsumer) {
detectAndHandleBrokenLoading();
if (this.currentWorld != null) {
currentWorldConsumer.accept(this.currentWorld);
}
private Path getWorldDataDirectory(Path parent, World world) {
return parent.resolve("DIM" + world.provider.getDimensionType().getId());
}
private final void detectAndHandleBrokenLoading() {
if (this.mcWorld != mc.world) {
/**
* @param world The world
* @return An {@link Optional} containing the world's baritone dir and readme dir, or {@link Optional#empty()} if
* the world isn't valid for caching.
*/
private Optional<Tuple<Path, Path>> getSaveDirectories(World world) {
Path worldDir;
Path readmeDir;
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
if (ctx.minecraft().isSingleplayer()) {
final int dimension = world.provider.getDimensionType().getId();
final WorldServer localServerWorld = ctx.minecraft().getIntegratedServer().getWorld(dimension);
final IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
final IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
worldDir = loader.getChunkSaveLocation().toPath();
// Gets the "depth" of this directory relative to the game's run directory, 2 is the location of the world
if (worldDir.relativize(ctx.minecraft().gameDir.toPath()).getNameCount() != 2) {
// subdirectory of the main save directory for this world
worldDir = worldDir.getParent();
}
worldDir = worldDir.resolve("baritone");
readmeDir = worldDir;
} else { // Otherwise, the server must be remote...
String folderName;
final ServerData serverData = ctx.minecraft().getCurrentServerData();
if (serverData != null) {
folderName = serverData.serverIP;
} else {
//replaymod causes null currentServerData and false singleplayer.
System.out.println("World seems to be a replay. Not loading Baritone cache.");
currentWorld = null;
mcWorld = ctx.world();
return Optional.empty();
}
if (SystemUtils.IS_OS_WINDOWS) {
folderName = folderName.replace(":", "_");
}
// TODO: This should probably be in "baritone/servers"
worldDir = baritone.getDirectory().resolve(folderName);
// Just write the readme to the baritone directory instead of each server save in it
readmeDir = baritone.getDirectory();
}
return Optional.of(new Tuple<>(worldDir, readmeDir));
}
/**
* Why does this exist instead of fixing the event? Some mods break the event. Lol.
*/
private void detectAndHandleBrokenLoading() {
if (this.mcWorld != ctx.world()) {
if (this.currentWorld != null) {
System.out.println("mc.world unloaded unnoticed! Unloading Baritone cache now.");
closeWorld();
}
if (mc.world != null) {
if (ctx.world() != null) {
System.out.println("mc.world loaded unnoticed! Loading Baritone cache now.");
initWorld(mc.world.provider.getDimensionType().getId());
initWorld(ctx.world());
}
} else if (currentWorld == null && mc.world != null && (mc.isSingleplayer() || mc.getCurrentServerData() != null)) {
} else if (this.currentWorld == null && ctx.world() != null && (ctx.minecraft().isSingleplayer() || ctx.minecraft().getCurrentServerData() != null)) {
System.out.println("Retrying to load Baritone cache");
initWorld(mc.world.provider.getDimensionType().getId());
initWorld(ctx.world());
}
}
}

View File

@@ -17,8 +17,8 @@
package baritone.command;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.command.argument.ICommandArgument;
import baritone.api.command.exception.CommandNotEnoughArgumentsException;
@@ -30,6 +30,7 @@ import baritone.api.event.events.TabCompleteEvent;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.utils.Helper;
import baritone.api.utils.SettingsUtil;
import baritone.behavior.Behavior;
import baritone.command.argument.ArgConsumer;
import baritone.command.argument.CommandArguments;
import baritone.command.manager.CommandManager;
@@ -49,14 +50,14 @@ import java.util.stream.Stream;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class ExampleBaritoneControl implements Helper, AbstractGameEventListener {
public class ExampleBaritoneControl extends Behavior implements Helper {
private static final Settings settings = BaritoneAPI.getSettings();
private final ICommandManager manager;
public ExampleBaritoneControl(IBaritone baritone) {
public ExampleBaritoneControl(Baritone baritone) {
super(baritone);
this.manager = baritone.getCommandManager();
baritone.getGameEventHandler().registerEventListener(this);
}
@Override
@@ -100,7 +101,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
return false;
} else if (msg.trim().equalsIgnoreCase("orderpizza")) {
try {
((IGuiScreen) mc.currentScreen).openLink(new URI("https://www.dominos.com/en/pages/order/"));
((IGuiScreen) ctx.minecraft().currentScreen).openLink(new URI("https://www.dominos.com/en/pages/order/"));
} catch (NullPointerException | URISyntaxException ignored) {}
return false;
}
@@ -124,7 +125,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
}
} else if (argc.hasExactlyOne()) {
for (Settings.Setting setting : settings.allSettings) {
if (SettingsUtil.javaOnlySetting(setting)) {
if (setting.isJavaOnly()) {
continue;
}
if (setting.getName().equalsIgnoreCase(pair.getFirst())) {
@@ -177,7 +178,7 @@ public class ExampleBaritoneControl implements Helper, AbstractGameEventListener
.stream();
}
Settings.Setting setting = settings.byLowerName.get(argc.getString().toLowerCase(Locale.US));
if (setting != null && !SettingsUtil.javaOnlySetting(setting)) {
if (setting != null && !setting.isJavaOnly()) {
if (setting.getValueClass() == Boolean.class) {
TabCompleteHelper helper = new TabCompleteHelper();
if ((Boolean) setting.value) {

View File

@@ -373,6 +373,8 @@ public class ArgConsumer implements IArgConsumer {
public <T extends IDatatype> Stream<String> tabCompleteDatatype(T datatype) {
try {
return datatype.tabComplete(this.context);
} catch (CommandException ignored) {
// NOP
} catch (Exception e) {
e.printStackTrace();
}

View File

@@ -26,7 +26,6 @@ import baritone.api.command.datatypes.RelativeFile;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.client.Minecraft;
import org.apache.commons.io.FilenameUtils;
import java.io.File;
@@ -36,10 +35,11 @@ import java.util.stream.Stream;
public class BuildCommand extends Command {
private static final File schematicsDir = new File(Minecraft.getMinecraft().gameDir, "schematics");
private final File schematicsDir;
public BuildCommand(IBaritone baritone) {
super(baritone, "build");
this.schematicsDir = new File(baritone.getPlayerContext().minecraft().gameDir, "schematics");
}
@Override

View File

@@ -21,10 +21,7 @@ import baritone.api.IBaritone;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.pathing.goals.GoalBlock;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
import java.util.List;
@@ -39,11 +36,7 @@ public class ComeCommand extends Command {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
args.requireMax(0);
Entity entity = mc.getRenderViewEntity();
if (entity == null) {
throw new CommandInvalidStateException("render view entity is null");
}
baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock(new BlockPos(entity)));
baritone.getCustomGoalProcess().setGoalAndPath(new GoalBlock(ctx.viewerPos()));
logDirect("Coming");
}

View File

@@ -66,7 +66,8 @@ public final class DefaultCommands {
new WaypointsCommand(baritone),
new CommandAlias(baritone, "sethome", "Sets your home waypoint", "waypoints save home"),
new CommandAlias(baritone, "home", "Path to your home waypoint", "waypoints goto home"),
new SelCommand(baritone)
new SelCommand(baritone),
new ElytraCommand(baritone)
));
ExecutionControlCommands prc = new ExecutionControlCommands(baritone);
commands.add(prc.pauseCommand);

View File

@@ -0,0 +1,224 @@
/*
* 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.command.defaults;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidStateException;
import baritone.api.command.helpers.TabCompleteHelper;
import baritone.api.pathing.goals.Goal;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IElytraProcess;
import net.minecraft.client.multiplayer.ServerData;
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.Arrays;
import java.util.List;
import java.util.stream.Stream;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
public class ElytraCommand extends Command {
public ElytraCommand(IBaritone baritone) {
super(baritone, "elytra");
}
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
final ICustomGoalProcess customGoalProcess = baritone.getCustomGoalProcess();
final IElytraProcess elytra = baritone.getElytraProcess();
if (args.hasExactlyOne() && args.peekString().equals("supported")) {
logDirect(elytra.isLoaded() ? "yes" : unsupportedSystemMessage());
return;
}
if (!elytra.isLoaded()) {
throw new CommandInvalidStateException(unsupportedSystemMessage());
}
if (!args.hasAny()) {
if (Baritone.settings().elytraTermsAccepted.value) {
if (detectOn2b2t()) {
warn2b2t();
}
} else {
gatekeep();
}
Goal iGoal = customGoalProcess.mostRecentGoal();
if (iGoal == null) {
throw new CommandInvalidStateException("No goal has been set");
}
if (ctx.player().dimension != -1) {
throw new CommandInvalidStateException("Only works in the nether");
}
try {
elytra.pathTo(iGoal);
} catch (IllegalArgumentException ex) {
throw new CommandInvalidStateException(ex.getMessage());
}
return;
}
final String action = args.getString();
switch (action) {
case "reset": {
elytra.resetState();
logDirect("Reset state but still flying to same goal");
break;
}
case "repack": {
elytra.repackChunks();
logDirect("Queued all loaded chunks for repacking");
break;
}
default: {
throw new CommandInvalidStateException("Invalid action");
}
}
}
private void warn2b2t() {
if (Baritone.settings().elytraPredictTerrain.value) {
long seed = Baritone.settings().elytraNetherSeed.value;
if (seed != NEW_2B2T_SEED && seed != OLD_2B2T_SEED) {
logDirect(new TextComponentString("It looks like you're on 2b2t, but elytraNetherSeed is incorrect.")); // match color
logDirect(suggest2b2tSeeds());
}
}
}
private ITextComponent suggest2b2tSeeds() {
TextComponentString clippy = new TextComponentString("");
clippy.appendText("Within a few hundred blocks of spawn/axis/highways/etc, the terrain is too fragmented to be predictable. Baritone Elytra will still work, just with backtracking. ");
clippy.appendText("However, once you get more than a few thousand blocks out, you should try ");
TextComponentString olderSeed = new TextComponentString("the older seed (click here)");
olderSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + OLD_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + OLD_2B2T_SEED));
clippy.appendSibling(olderSeed);
clippy.appendText(". Once you're further out into newer terrain generation (this includes everything up through 1.12), you should try ");
TextComponentString newerSeed = new TextComponentString("the newer seed (click here)");
newerSeed.getStyle().setUnderlined(true).setBold(true).setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraNetherSeed " + NEW_2B2T_SEED))).setClickEvent(new ClickEvent(ClickEvent.Action.RUN_COMMAND, FORCE_COMMAND_PREFIX + "set elytraNetherSeed " + NEW_2B2T_SEED));
clippy.appendSibling(newerSeed);
clippy.appendText(". Once you get into 1.19 terrain, the terrain becomes unpredictable again, due to custom non-vanilla generation, and you should set #elytraPredictTerrain to false. ");
return clippy;
}
private void gatekeep() {
TextComponentString gatekeep = new TextComponentString("");
gatekeep.appendText("To disable this message, enable the setting elytraTermsAccepted\n");
gatekeep.appendText("Baritone Elytra is an experimental feature. It is only intended for long distance travel in the Nether using fireworks for vanilla boost. It will not work with any other mods (\"hacks\") for non-vanilla boost. ");
TextComponentString gatekeep2 = new TextComponentString("If you want Baritone to attempt to take off from the ground for you, you can enable the elytraAutoJump setting (not advisable on laggy servers!). ");
gatekeep2.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraAutoJump true")));
gatekeep.appendSibling(gatekeep2);
TextComponentString gatekeep3 = new TextComponentString("If you want Baritone to go slower, enable the elytraConserveFireworks setting and/or decrease the elytraFireworkSpeed setting. ");
gatekeep3.getStyle().setHoverEvent(new HoverEvent(HoverEvent.Action.SHOW_TEXT, new TextComponentString(Baritone.settings().prefix.value + "set elytraConserveFireworks true\n" + Baritone.settings().prefix.value + "set elytraFireworkSpeed 0.6\n(the 0.6 number is just an example, tweak to your liking)")));
gatekeep.appendSibling(gatekeep3);
TextComponentString gatekeep4 = new TextComponentString("Baritone Elytra ");
TextComponentString red = new TextComponentString("wants to know the seed");
red.getStyle().setColor(TextFormatting.RED).setUnderlined(true).setBold(true);
gatekeep4.appendSibling(red);
gatekeep4.appendText(" of the world you are in. If it doesn't have the correct seed, it will frequently backtrack. It uses the seed to generate terrain far beyond what you can see, since terrain obstacles in the Nether can be much larger than your render distance. ");
gatekeep.appendSibling(gatekeep4);
gatekeep.appendText("\n");
if (detectOn2b2t()) {
TextComponentString gatekeep5 = new TextComponentString("It looks like you're on 2b2t. ");
gatekeep5.appendSibling(suggest2b2tSeeds());
if (!Baritone.settings().elytraPredictTerrain.value) {
gatekeep5.appendText(Baritone.settings().prefix.value + "elytraPredictTerrain is currently disabled. ");
} else {
if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) {
gatekeep5.appendText("You are using the newer seed. ");
} else if (Baritone.settings().elytraNetherSeed.value == OLD_2B2T_SEED) {
gatekeep5.appendText("You are using the older seed. ");
} else {
gatekeep5.appendText("Defaulting to the newer seed. ");
Baritone.settings().elytraNetherSeed.value = NEW_2B2T_SEED;
}
}
gatekeep.appendSibling(gatekeep5);
} else {
if (Baritone.settings().elytraNetherSeed.value == NEW_2B2T_SEED) {
TextComponentString gatekeep5 = new TextComponentString("Baritone doesn't know the seed of your world. Set it with: " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere\n");
gatekeep5.appendText("For the time being, elytraPredictTerrain is defaulting to false since the seed is unknown.");
gatekeep.appendSibling(gatekeep5);
Baritone.settings().elytraPredictTerrain.value = false;
} else {
if (Baritone.settings().elytraPredictTerrain.value) {
TextComponentString gatekeep5 = new TextComponentString("Baritone Elytra is predicting terrain assuming that " + Baritone.settings().elytraNetherSeed.value + " is the correct seed. Change that with " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere, or disable it with " + Baritone.settings().prefix.value + "set elytraPredictTerrain false");
gatekeep.appendSibling(gatekeep5);
} else {
TextComponentString gatekeep5 = new TextComponentString("Baritone Elytra is not predicting terrain. If you don't know the seed, this is the correct thing to do. If you do know the seed, input it with " + Baritone.settings().prefix.value + "set elytraNetherSeed seedgoeshere, and then enable it with " + Baritone.settings().prefix.value + "set elytraPredictTerrain true");
gatekeep.appendSibling(gatekeep5);
}
}
}
logDirect(gatekeep);
}
private boolean detectOn2b2t() {
ServerData data = ctx.minecraft().getCurrentServerData();
return data != null && data.serverIP.toLowerCase().contains("2b2t.org");
}
private static final long OLD_2B2T_SEED = -4100785268875389365L;
private static final long NEW_2B2T_SEED = 146008555100680L;
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
TabCompleteHelper helper = new TabCompleteHelper();
if (args.hasExactlyOne()) {
helper.append("reset", "repack", "supported");
}
return helper.filterPrefix(args.getString()).stream();
}
@Override
public String getShortDesc() {
return "elytra time";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"The elytra command tells baritone to, in the nether, automatically fly to the current goal.",
"",
"Usage:",
"> elytra - fly to the current goal",
"> elytra reset - Resets the state of the process, but will try to keep flying to the same goal.",
"> elytra repack - Queues all of the chunks in render distance to be given to the native library.",
"> elytra supported - Tells you if baritone ships a native library that is compatible with your PC."
);
}
private static String unsupportedSystemMessage() {
final String osArch = System.getProperty("os.arch");
final String osName = System.getProperty("os.name");
return String.format(
"Legacy architectures are not supported. Your CPU is %s and your operating system is %s. " +
"Supported architectures are 64 bit x86, and 64 bit ARM. Supported operating systems are Windows, " +
"Linux, and Mac",
osArch, osName
);
}
}

View File

@@ -41,7 +41,7 @@ public class ExploreFilterCommand extends Command {
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
args.requireMax(2);
File file = args.getDatatypePost(RelativeFile.INSTANCE, mc.gameDir.getAbsoluteFile().getParentFile());
File file = args.getDatatypePost(RelativeFile.INSTANCE, ctx.minecraft().gameDir.getAbsoluteFile().getParentFile());
boolean invert = false;
if (args.hasAny()) {
if (args.getString().equalsIgnoreCase("invert")) {
@@ -65,7 +65,7 @@ public class ExploreFilterCommand extends Command {
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
if (args.hasExactlyOne()) {
return RelativeFile.tabComplete(args, RelativeFile.gameDir());
return RelativeFile.tabComplete(args, RelativeFile.gameDir(ctx.minecraft()));
}
return Stream.empty();
}

View File

@@ -51,7 +51,7 @@ public class GoalCommand extends Command {
}
} else {
args.requireMax(3);
BetterBlockPos origin = baritone.getPlayerContext().playerFeet();
BetterBlockPos origin = ctx.playerFeet();
Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin);
goalProcess.setGoal(goal);
logDirect(String.format("Goal: %s", goal.toString()));

View File

@@ -20,7 +20,6 @@ package baritone.command.defaults;
import baritone.api.IBaritone;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.datatypes.BlockById;
import baritone.api.command.datatypes.ForBlockOptionalMeta;
import baritone.api.command.datatypes.RelativeCoordinate;
import baritone.api.command.datatypes.RelativeGoal;
@@ -46,7 +45,7 @@ public class GotoCommand extends Command {
// is no need to handle the case of empty arguments.
if (args.peekDatatypeOrNull(RelativeCoordinate.INSTANCE) != null) {
args.requireMax(3);
BetterBlockPos origin = baritone.getPlayerContext().playerFeet();
BetterBlockPos origin = ctx.playerFeet();
Goal goal = args.getDatatypePost(RelativeGoal.INSTANCE, origin);
logDirect(String.format("Going to: %s", goal.toString()));
baritone.getCustomGoalProcess().setGoalAndPath(goal);
@@ -61,7 +60,8 @@ public class GotoCommand extends Command {
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
// since it's either a goal or a block, I don't think we can tab complete properly?
// so just tab complete for the block variant
return args.tabCompleteDatatype(BlockById.INSTANCE);
args.requireMax(1);
return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE);
}
@Override

View File

@@ -17,10 +17,10 @@
package baritone.command.defaults;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.datatypes.BlockById;
import baritone.api.command.datatypes.ForBlockOptionalMeta;
import baritone.api.command.exception.CommandException;
import baritone.api.utils.BlockOptionalMeta;
@@ -45,14 +45,18 @@ public class MineCommand extends Command {
while (args.hasAny()) {
boms.add(args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE));
}
WorldScanner.INSTANCE.repack(ctx);
BaritoneAPI.getProvider().getWorldScanner().repack(ctx);
logDirect(String.format("Mining %s", boms.toString()));
baritone.getMineProcess().mine(quantity, boms.toArray(new BlockOptionalMeta[0]));
}
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) {
return args.tabCompleteDatatype(BlockById.INSTANCE);
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
args.getAsOrDefault(Integer.class, 0);
while (args.has(2)) {
args.getDatatypeFor(ForBlockOptionalMeta.INSTANCE);
}
return args.tabCompleteDatatype(ForBlockOptionalMeta.INSTANCE);
}
@Override

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