Compare commits

...

213 Commits

Author SHA1 Message Date
Brady
3873aae710 surely this is ok 2023-07-16 19:14:44 -05:00
Brady
19b66903d0 move cull code 2023-07-16 18:58:13 -05:00
Brady
839ddaf85e hack fix babij trolle 2023-07-16 18:55:14 -05:00
Brady
b4780ca17e based 2023-07-16 18:54:58 -05: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
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
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
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
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
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
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
Brady
0aff31b768 Perfect elytra simulation 2023-06-21 18:59:44 -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
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
Babbaj
e57a84ded4 use legacy raytrace with ignore liquid to get out of lava 2023-06-19 17:58:06 -04: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
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
rfresh2
8dc32ae03c firework inv management + pause/resume 2023-06-18 13:34:55 -07:00
Brady
68901695ca Add experimental takeoff feature 2023-06-18 13:23:41 -05: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
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
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
8df6778641 sort of integrated nether pathfinder 2023-06-15 00:32:26 -07: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
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
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
Leijurv
c48c2aa45c allow even more desperate motion 2023-06-11 13:57:21 -07:00
Leijurv
a602863426 better elytra 2023-06-11 12:49:31 -07:00
Leijurv
705a5a0712 elytra prototype mvp 2023-06-11 00:33:35 -07:00
61 changed files with 3670 additions and 484 deletions

2
.gitignore vendored
View File

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

View File

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

View File

@@ -20,6 +20,6 @@ repositories {
} }
dependencies { dependencies {
compile group: 'com.google.code.gson', name: 'gson', version: '2.8.5' implementation group: 'com.google.code.gson', name: 'gson', version: '2.8.5'
compile group: 'commons-io', name: 'commons-io', version: '2.6' 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 { class BaritoneGradleTask extends DefaultTask {
protected static final String protected static final String
PROGUARD_ZIP = "proguard.zip", PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar", PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro", PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
PROGUARD_CONFIG_DEST = "template.pro", PROGUARD_CONFIG_DEST = "template.pro",
PROGUARD_API_CONFIG = "api.pro", PROGUARD_API_CONFIG = "api.pro",
PROGUARD_STANDALONE_CONFIG = "standalone.pro", PROGUARD_STANDALONE_CONFIG = "standalone.pro",
PROGUARD_EXPORT_PATH = "proguard_out.jar", PROGUARD_EXPORT_PATH = "proguard_out.jar",
TEMP_LIBRARY_DIR = "tempLibraries/", TEMP_LIBRARY_DIR = "tempLibraries/",
ARTIFACT_STANDARD = "%s-%s.jar", ARTIFACT_STANDARD = "%s-%s.jar",
ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar", ARTIFACT_UNOPTIMIZED = "%s-unoptimized-%s.jar",
ARTIFACT_API = "%s-api-%s.jar", ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar", ARTIFACT_STANDALONE = "%s-standalone-%s.jar",
ARTIFACT_FORGE_API = "%s-api-forge-%s.jar", ARTIFACT_FORGE_API = "%s-api-forge-%s.jar",
ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar"; ARTIFACT_FORGE_STANDALONE = "%s-standalone-forge-%s.jar";
protected String artifactName, artifactVersion; protected String artifactName, artifactVersion;
@@ -56,17 +56,17 @@ class BaritoneGradleTask extends DefaultTask {
this.artifactName = getProject().getName(); this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString(); this.artifactVersion = getProject().getVersion().toString();
this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD)); this.artifactPath = this.getBuildFile(formatVersion(ARTIFACT_STANDARD));
this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED)); this.artifactUnoptimizedPath = this.getBuildFile(formatVersion(ARTIFACT_UNOPTIMIZED));
this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API)); this.artifactApiPath = this.getBuildFile(formatVersion(ARTIFACT_API));
this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE)); this.artifactStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_STANDALONE));
this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API)); this.artifactForgeApiPath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_API));
this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE)); this.artifactForgeStandalonePath = this.getBuildFile(formatVersion(ARTIFACT_FORGE_STANDALONE));
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH); this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
if (!Files.exists(this.artifactPath)) { if (!Files.exists(this.artifactPath)) {
throw new IllegalStateException("Artifact not found! Run build first!"); throw new IllegalStateException("Artifact not found! Run build first! " + this.artifactPath);
} }
} }
@@ -82,7 +82,7 @@ class BaritoneGradleTask extends DefaultTask {
} }
protected Path getRelativeFile(String file) { 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) { protected Path getTemporaryFile(String file) {

View File

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

View File

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

View File

@@ -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 distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-6.9.4-all.zip
zipStoreBase=GRADLE_USER_HOME zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-4.9-all.zip

55
gradlew vendored
View File

@@ -1,5 +1,21 @@
#!/usr/bin/env sh #!/usr/bin/env sh
#
# Copyright 2015 the original author or authors.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# https://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
############################################################################## ##############################################################################
## ##
## Gradle start up script for UN*X ## Gradle start up script for UN*X
@@ -28,7 +44,7 @@ APP_NAME="Gradle"
APP_BASE_NAME=`basename "$0"` APP_BASE_NAME=`basename "$0"`
# Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. # Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
DEFAULT_JVM_OPTS="" DEFAULT_JVM_OPTS='"-Xmx64m" "-Xms64m"'
# Use the maximum available, or set MAX_FD != -1 to use that value. # Use the maximum available, or set MAX_FD != -1 to use that value.
MAX_FD="maximum" MAX_FD="maximum"
@@ -56,7 +72,7 @@ case "`uname`" in
Darwin* ) Darwin* )
darwin=true darwin=true
;; ;;
MINGW* ) MSYS* | MINGW* )
msys=true msys=true
;; ;;
NONSTOP* ) NONSTOP* )
@@ -66,6 +82,7 @@ esac
CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar CLASSPATH=$APP_HOME/gradle/wrapper/gradle-wrapper.jar
# Determine the Java command to use to start the JVM. # Determine the Java command to use to start the JVM.
if [ -n "$JAVA_HOME" ] ; then if [ -n "$JAVA_HOME" ] ; then
if [ -x "$JAVA_HOME/jre/sh/java" ] ; then if [ -x "$JAVA_HOME/jre/sh/java" ] ; then
@@ -109,10 +126,11 @@ if $darwin; then
GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\"" GRADLE_OPTS="$GRADLE_OPTS \"-Xdock:name=$APP_NAME\" \"-Xdock:icon=$APP_HOME/media/gradle.icns\""
fi fi
# For Cygwin, switch paths to Windows format before running java # For Cygwin or MSYS, switch paths to Windows format before running java
if $cygwin ; then if [ "$cygwin" = "true" -o "$msys" = "true" ] ; then
APP_HOME=`cygpath --path --mixed "$APP_HOME"` APP_HOME=`cygpath --path --mixed "$APP_HOME"`
CLASSPATH=`cygpath --path --mixed "$CLASSPATH"` CLASSPATH=`cygpath --path --mixed "$CLASSPATH"`
JAVACMD=`cygpath --unix "$JAVACMD"` JAVACMD=`cygpath --unix "$JAVACMD"`
# We build the pattern for arguments to be converted via cygpath # We build the pattern for arguments to be converted via cygpath
@@ -138,19 +156,19 @@ if $cygwin ; then
else else
eval `echo args$i`="\"$arg\"" eval `echo args$i`="\"$arg\""
fi fi
i=$((i+1)) i=`expr $i + 1`
done done
case $i in case $i in
(0) set -- ;; 0) set -- ;;
(1) set -- "$args0" ;; 1) set -- "$args0" ;;
(2) set -- "$args0" "$args1" ;; 2) set -- "$args0" "$args1" ;;
(3) set -- "$args0" "$args1" "$args2" ;; 3) set -- "$args0" "$args1" "$args2" ;;
(4) set -- "$args0" "$args1" "$args2" "$args3" ;; 4) set -- "$args0" "$args1" "$args2" "$args3" ;;
(5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;; 5) set -- "$args0" "$args1" "$args2" "$args3" "$args4" ;;
(6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;; 6) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" ;;
(7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;; 7) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" ;;
(8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;; 8) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" ;;
(9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;; 9) set -- "$args0" "$args1" "$args2" "$args3" "$args4" "$args5" "$args6" "$args7" "$args8" ;;
esac esac
fi fi
@@ -159,14 +177,9 @@ save () {
for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done for i do printf %s\\n "$i" | sed "s/'/'\\\\''/g;1s/^/'/;\$s/\$/' \\\\/" ; done
echo " " echo " "
} }
APP_ARGS=$(save "$@") APP_ARGS=`save "$@"`
# Collect all arguments for the java command, following the shell quoting and substitution rules # Collect all arguments for the java command, following the shell quoting and substitution rules
eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS" eval set -- $DEFAULT_JVM_OPTS $JAVA_OPTS $GRADLE_OPTS "\"-Dorg.gradle.appname=$APP_BASE_NAME\"" -classpath "\"$CLASSPATH\"" org.gradle.wrapper.GradleWrapperMain "$APP_ARGS"
# by default we should be in the correct project dir, but when run from Finder on Mac, the cwd is wrong
if [ "$(uname)" = "Darwin" ] && [ "$HOME" = "$PWD" ]; then
cd "$(dirname "$0")"
fi
exec "$JAVACMD" "$@" exec "$JAVACMD" "$@"

43
gradlew.bat vendored
View File

@@ -1,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 @if "%DEBUG%" == "" @echo off
@rem ########################################################################## @rem ##########################################################################
@rem @rem
@@ -13,15 +29,18 @@ if "%DIRNAME%" == "" set DIRNAME=.
set APP_BASE_NAME=%~n0 set APP_BASE_NAME=%~n0
set APP_HOME=%DIRNAME% set APP_HOME=%DIRNAME%
@rem Resolve any "." and ".." in APP_HOME to make it shorter.
for %%i in ("%APP_HOME%") do set APP_HOME=%%~fi
@rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script. @rem Add default JVM options here. You can also use JAVA_OPTS and GRADLE_OPTS to pass JVM options to this script.
set DEFAULT_JVM_OPTS= set DEFAULT_JVM_OPTS="-Xmx64m" "-Xms64m"
@rem Find java.exe @rem Find java.exe
if defined JAVA_HOME goto findJavaFromJavaHome if defined JAVA_HOME goto findJavaFromJavaHome
set JAVA_EXE=java.exe set JAVA_EXE=java.exe
%JAVA_EXE% -version >NUL 2>&1 %JAVA_EXE% -version >NUL 2>&1
if "%ERRORLEVEL%" == "0" goto init if "%ERRORLEVEL%" == "0" goto execute
echo. echo.
echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH. echo ERROR: JAVA_HOME is not set and no 'java' command could be found in your PATH.
@@ -35,7 +54,7 @@ goto fail
set JAVA_HOME=%JAVA_HOME:"=% set JAVA_HOME=%JAVA_HOME:"=%
set JAVA_EXE=%JAVA_HOME%/bin/java.exe set JAVA_EXE=%JAVA_HOME%/bin/java.exe
if exist "%JAVA_EXE%" goto init if exist "%JAVA_EXE%" goto execute
echo. echo.
echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME% echo ERROR: JAVA_HOME is set to an invalid directory: %JAVA_HOME%
@@ -45,28 +64,14 @@ echo location of your Java installation.
goto fail goto fail
:init
@rem Get command-line arguments, handling Windows variants
if not "%OS%" == "Windows_NT" goto win9xME_args
:win9xME_args
@rem Slurp the command line arguments.
set CMD_LINE_ARGS=
set _SKIP=2
:win9xME_args_slurp
if "x%~1" == "x" goto execute
set CMD_LINE_ARGS=%*
:execute :execute
@rem Setup the command line @rem Setup the command line
set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar set CLASSPATH=%APP_HOME%\gradle\wrapper\gradle-wrapper.jar
@rem Execute Gradle @rem Execute Gradle
"%JAVA_EXE%" %DEFAULT_JVM_OPTS% %JAVA_OPTS% %GRADLE_OPTS% "-Dorg.gradle.appname=%APP_BASE_NAME%" -classpath "%CLASSPATH%" org.gradle.wrapper.GradleWrapperMain %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 :end
@rem End local scope for the variables with windows NT shell @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/text2speech-1.10.3.jar'
-libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar' -libraryjars 'tempLibraries/mixin-0.7.11-SNAPSHOT.jar'
-libraryjars 'tempLibraries/launchwrapper-1.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' # Keep - Applications. Keep all application classes, along with their 'main'

View File

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

View File

@@ -23,6 +23,7 @@ import baritone.api.command.ICommandSystem;
import baritone.api.schematic.ISchematicSystem; import baritone.api.schematic.ISchematicSystem;
import net.minecraft.client.Minecraft; import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP; import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.network.NetHandlerPlayClient;
import java.util.List; import java.util.List;
import java.util.Objects; import java.util.Objects;
@@ -82,6 +83,22 @@ public interface IBaritoneProvider {
return null; 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 * Creates and registers a new {@link IBaritone} instance using the specified {@link Minecraft}. The existing
* instance is returned if already registered. * instance is returned if already registered.

View File

@@ -38,6 +38,7 @@ import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type; import java.lang.reflect.Type;
import java.util.List; import java.util.List;
import java.util.*; import java.util.*;
import java.util.concurrent.TimeUnit;
import java.util.function.BiConsumer; import java.util.function.BiConsumer;
import java.util.function.Consumer; import java.util.function.Consumer;
@@ -735,6 +736,17 @@ public final class Settings {
*/ */
public final Setting<Boolean> blockFreeLook = new Setting<>(false); public final Setting<Boolean> blockFreeLook = new Setting<>(false);
/**
* Automatically elytra fly without having to force the client-sided rotations. Requires {@link #freeLook}.
*/
public final Setting<Boolean> elytraFreeLook = new Setting<>(false);
/**
* Forces the client-sided rotations to an average of the last 10 ticks of server-sided rotations.
* Requires {@link #freeLook}.
*/
public final Setting<Boolean> smoothLook = new Setting<>(false);
/** /**
* When true, the player will remain with its existing look direction as often as possible. * 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. * Although, in some cases this can get it stuck, hence this setting to disable that behavior.
@@ -1320,6 +1332,89 @@ public final class Settings {
*/ */
public final Setting<Boolean> notificationOnMineFail = new Setting<>(true); public final Setting<Boolean> notificationOnMineFail = new Setting<>(true);
/**
* The number of ticks of elytra movement to simulate while firework boost is not active. Higher values are
* computationally more expensive.
*/
public final Setting<Integer> elytraSimulationTicks = new Setting<>(20);
/**
* The maximum allowed deviation in pitch from a direct line-of-sight to the flight target. Higher values are
* computationally more expensive.
*/
public final Setting<Integer> elytraPitchRange = new Setting<>(25);
/**
* The minimum speed that the player can drop to (in blocks/tick) before a firework is automatically deployed.
*/
public final Setting<Double> elytraFireworkSpeed = new Setting<>(0.6);
/**
* The delay after the player's position is set-back by the server that a firework may be automatically deployed.
* Value is in ticks.
*/
public final Setting<Integer> elytraFireworkSetbackUseDelay = new Setting<>(15);
/**
* The minimum padding value that is added to the player's hitbox when considering which point to fly to on the
* path. High values can result in points not being considered which are otherwise safe to fly to. Low values can
* result in flight paths which are extremely tight, and there's the possibility of crashing due to getting too low
* to the ground.
*/
public final Setting<Double> elytraMinimumAvoidance = new Setting<>(0.2);
/**
* If enabled, avoids using fireworks when descending along the flight path.
*/
public final Setting<Boolean> conserveFireworks = new Setting<>(true);
/**
* Renders the raytraces that are performed by the elytra fly calculation.
*/
public final Setting<Boolean> renderRaytraces = new Setting<>(false);
/**
* Renders the raytraces that are used in the hitbox part of the elytra fly calculation.
* Requires {@link #renderRaytraces}.
*/
public final Setting<Boolean> renderHitboxRaytraces = new Setting<>(false);
/**
* Renders the best elytra flight path that was simulated each tick.
*/
public final Setting<Boolean> renderElytraSimulation = new Setting<>(false);
/**
* Automatically path to and jump off of ledges to initiate elytra flight when grounded.
*/
public final Setting<Boolean> elytraAutoJump = new Setting<>(false);
/**
* The seed used to generate chunks for long distance elytra path-finding in the nether.
* Defaults to 2b2t's nether seed.
*/
public final Setting<Long> elytraNetherSeed = new Setting<>(146008555100680L);
/**
* Automatically swap the current elytra with a new one when the durability gets too low
*/
public final Setting<Boolean> elytraAutoSwap = new Setting<>(true);
/**
* The minimum durability an elytra can have before being swapped
*/
public final Setting<Integer> elytraMinimumDurability = new Setting<>(5);
/**
* Time between culling far away chunks from the nether pathfinder chunk cache
*/
public final Setting<Long> elytraTimeBetweenCacheCullSecs = new Setting<>(TimeUnit.MINUTES.toSeconds(3));
/**
* Maximum distance chunks can be before being culled from the nether pathfinder chunk cache
*/
public final Setting<Integer> elytraCacheCullDistance = new Setting<>(5000);
/** /**
* A map of lowercase setting field names to their respective setting * A map of lowercase setting field names to their respective setting
*/ */

View File

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

View File

@@ -0,0 +1,54 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.behavior;
import net.minecraft.util.math.BlockPos;
import java.util.concurrent.CompletableFuture;
public interface IElytraBehavior extends IBehavior {
/**
* Marks the nether pathfinder context to be reset when it is safe to do so. Because this operation is not
* immediate, a {@link CompletableFuture} is returned that will complete after the context has been reset.
*
* @return A {@link CompletableFuture} that is completed when the context is reset
*/
CompletableFuture<Void> resetContext();
void repackChunks();
void pathTo(BlockPos destination);
void cancel();
/**
* Returns {@code true} if the current {@link IElytraBehavior} is actively pathing.
*/
boolean isActive();
/**
* @return {@code true} if the native library loaded and elytra is actually usable
*/
boolean isLoaded();
/*
* FOR INTERNAL USE ONLY. MAY BE REMOVED AT ANY TIME.
*/
boolean isSafeToCancel();
}

View File

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

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.event.events;
import baritone.api.utils.Pair;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import java.util.Collections;
import java.util.List;
import java.util.Set;
/**
* @author Brady
*/
public final class BlockChangeEvent {
private final ChunkPos chunk;
private final List<Pair<BlockPos, IBlockState>> blocks;
public BlockChangeEvent(ChunkPos pos, List<Pair<BlockPos, IBlockState>> blocks) {
this.chunk = pos;
this.blocks = blocks;
}
public ChunkPos getChunkPos() {
return this.chunk;
}
public List<Pair<BlockPos, IBlockState>> getBlocks() {
return this.blocks;
}
}

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -35,6 +35,15 @@ import javax.annotation.Nonnull;
*/ */
public final class BetterBlockPos extends BlockPos { public final class BetterBlockPos extends BlockPos {
private static final int NUM_X_BITS = 26;
private static final int NUM_Z_BITS = NUM_X_BITS;
private static final int NUM_Y_BITS = 64 - NUM_X_BITS - NUM_Z_BITS;
private static final int Y_SHIFT = NUM_Z_BITS;
private static final int X_SHIFT = Y_SHIFT + NUM_Y_BITS;
private static final long X_MASK = (1L << NUM_X_BITS) - 1L;
private static final long Y_MASK = (1L << NUM_Y_BITS) - 1L;
private static final long Z_MASK = (1L << NUM_Z_BITS) - 1L;
public static final BetterBlockPos ORIGIN = new BetterBlockPos(0, 0, 0); public static final BetterBlockPos ORIGIN = new BetterBlockPos(0, 0, 0);
public final int x; public final int x;
@@ -202,6 +211,20 @@ public final class BetterBlockPos extends BlockPos {
return amt == 0 ? this : new BetterBlockPos(x - amt, y, z); return amt == 0 ? this : new BetterBlockPos(x - amt, y, z);
} }
public double distanceSq(final BetterBlockPos to) {
double dx = (double) this.x - to.x;
double dy = (double) this.y - to.y;
double dz = (double) this.z - to.z;
return dx * dx + dy * dy + dz * dz;
}
public double distanceTo(final BetterBlockPos to) {
double dx = (double) this.x - to.x;
double dy = (double) this.y - to.y;
double dz = (double) this.z - to.z;
return Math.sqrt(dx * dx + dy * dy + dz * dz);
}
@Override @Override
@Nonnull @Nonnull
public String toString() { public String toString() {
@@ -212,4 +235,15 @@ public final class BetterBlockPos extends BlockPos {
SettingsUtil.maybeCensor(z) 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

@@ -230,4 +230,11 @@ public interface Helper {
default void logDirect(String message) { default void logDirect(String message) {
logDirect(message, BaritoneAPI.getSettings().logAsToast.value); logDirect(message, BaritoneAPI.getSettings().logAsToast.value);
} }
default void logUnhandledException(final Throwable exception) {
HELPER.logDirect("An unhandled exception occurred. " +
"The error is in your game's log, please report this at https://github.com/cabaletta/baritone/issues",
TextFormatting.RED);
exception.printStackTrace();
}
} }

View File

@@ -75,6 +75,10 @@ public interface IPlayerContext {
return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ); return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ);
} }
default Vec3d playerMotion() {
return new Vec3d(player().motionX, player().motionY, player().motionZ);
}
BetterBlockPos viewerPos(); BetterBlockPos viewerPos();
default Rotation playerRotations() { default Rotation playerRotations() {

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 { } else {
start = entity.getPositionEyes(1.0F); // do whatever is correct start = entity.getPositionEyes(1.0F); // do whatever is correct
} }
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation); Vec3d direction = RotationUtils.calcLookDirectionFromRotation(rotation);
Vec3d end = start.add( Vec3d end = start.add(
direction.x * blockReachDistance, direction.x * blockReachDistance,
direction.y * blockReachDistance, direction.y * blockReachDistance,

View File

@@ -37,11 +37,13 @@ public final class RotationUtils {
* Constant that a degree value is multiplied by to get the equivalent radian value * Constant that a degree value is multiplied by to get the equivalent radian value
*/ */
public static final double DEG_TO_RAD = Math.PI / 180.0; public static final double DEG_TO_RAD = Math.PI / 180.0;
public static final float DEG_TO_RAD_F = (float) DEG_TO_RAD;
/** /**
* Constant that a radian value is multiplied by to get the equivalent degree value * Constant that a radian value is multiplied by to get the equivalent degree value
*/ */
public static final double RAD_TO_DEG = 180.0 / Math.PI; public static final double RAD_TO_DEG = 180.0 / Math.PI;
public static final float RAD_TO_DEG_F = (float) RAD_TO_DEG;
/** /**
* Offsets from the root block position to the center of each side. * Offsets from the root block position to the center of each side.
@@ -122,12 +124,17 @@ public final class RotationUtils {
* @param rotation The input rotation * @param rotation The input rotation
* @return Look vector for the rotation * @return Look vector for the rotation
*/ */
public static Vec3d calcLookDirectionFromRotation(Rotation rotation) {
float flatZ = MathHelper.cos((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
float flatX = MathHelper.sin((-rotation.getYaw() * DEG_TO_RAD_F) - (float) Math.PI);
float pitchBase = -MathHelper.cos(-rotation.getPitch() * DEG_TO_RAD_F);
float pitchHeight = MathHelper.sin(-rotation.getPitch() * DEG_TO_RAD_F);
return new Vec3d(flatX * pitchBase, pitchHeight, flatZ * pitchBase);
}
@Deprecated
public static Vec3d calcVec3dFromRotation(Rotation rotation) { public static Vec3d calcVec3dFromRotation(Rotation rotation) {
float f = MathHelper.cos(-rotation.getYaw() * (float) DEG_TO_RAD - (float) Math.PI); return calcLookDirectionFromRotation(rotation);
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));
} }
/** /**

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

@@ -51,7 +51,7 @@ public abstract class MixinEntityLivingBase extends Entity {
@Unique @Unique
private RotationMoveEvent elytraRotationEvent; private RotationMoveEvent elytraRotationEvent;
public MixinEntityLivingBase(World worldIn) { private MixinEntityLivingBase(World worldIn) {
super(worldIn); super(worldIn);
} }
@@ -123,7 +123,8 @@ public abstract class MixinEntityLivingBase extends Entity {
private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) { private void onMoveRelative(EntityLivingBase self, float strafe, float up, float forward, float friction) {
Optional<IBaritone> baritone = this.getBaritone(); Optional<IBaritone> baritone = this.getBaritone();
if (!baritone.isPresent()) { if (!baritone.isPresent()) {
moveRelative(strafe, up, forward, friction); // If a shadow is used here it breaks on Forge
this.moveRelative(strafe, up, forward, friction);
return; return;
} }

View File

@@ -35,9 +35,11 @@ import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.lib.Opcodes; import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.mixin.Mixin; import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow; import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.Unique;
import org.spongepowered.asm.mixin.injection.At; import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject; import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect; import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.Slice;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo; import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture; import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
@@ -52,9 +54,13 @@ public class MixinMinecraft {
@Shadow @Shadow
public EntityPlayerSP player; public EntityPlayerSP player;
@Shadow @Shadow
public WorldClient world; public WorldClient world;
@Unique
private BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider;
@Inject( @Inject(
method = "init", method = "init",
at = @At("RETURN") at = @At("RETURN")
@@ -69,24 +75,47 @@ public class MixinMinecraft {
value = "FIELD", value = "FIELD",
opcode = Opcodes.GETFIELD, opcode = Opcodes.GETFIELD,
target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;", target = "net/minecraft/client/Minecraft.currentScreen:Lnet/minecraft/client/gui/GuiScreen;",
ordinal = 5, ordinal = 0,
shift = At.Shift.BY, shift = At.Shift.BEFORE
by = -3 ),
slice = @Slice(
from = @At(
value = "FIELD",
opcode = Opcodes.PUTFIELD,
target = "net/minecraft/client/Minecraft.leftClickCounter:I"
)
) )
) )
private void runTick(CallbackInfo ci) { private void runTick(CallbackInfo ci) {
final BiFunction<EventState, TickEvent.Type, TickEvent> tickProvider = TickEvent.createNextProvider(); this.tickProvider = TickEvent.createNextProvider();
for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) { for (IBaritone baritone : BaritoneAPI.getProvider().getAllBaritones()) {
TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null TickEvent.Type type = baritone.getPlayerContext().player() != null && baritone.getPlayerContext().world() != null
? TickEvent.Type.IN ? TickEvent.Type.IN
: TickEvent.Type.OUT; : TickEvent.Type.OUT;
baritone.getGameEventHandler().onTick(this.tickProvider.apply(EventState.PRE, type));
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( @Inject(
method = "runTick", method = "runTick",
at = @At( at = @At(
@@ -98,6 +127,8 @@ public class MixinMinecraft {
private void postUpdateEntities(CallbackInfo ci) { private void postUpdateEntities(CallbackInfo ci) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.player); IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(this.player);
if (baritone != null) { 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)); baritone.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent(EventState.POST));
} }
} }

View File

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

View File

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

View File

@@ -21,6 +21,7 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone; import baritone.api.IBaritone;
import baritone.api.Settings; import baritone.api.Settings;
import baritone.api.behavior.IBehavior; import baritone.api.behavior.IBehavior;
import baritone.api.behavior.IElytraBehavior;
import baritone.api.event.listener.IEventBus; import baritone.api.event.listener.IEventBus;
import baritone.api.process.IBaritoneProcess; import baritone.api.process.IBaritoneProcess;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
@@ -40,6 +41,8 @@ import net.minecraft.client.Minecraft;
import java.io.IOException; import java.io.IOException;
import java.nio.file.Files; import java.nio.file.Files;
import java.nio.file.Path; import java.nio.file.Path;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.SynchronousQueue; import java.util.concurrent.SynchronousQueue;
import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.ThreadPoolExecutor;
@@ -63,7 +66,9 @@ public class Baritone implements IBaritone {
private final GameEventHandler gameEventHandler; private final GameEventHandler gameEventHandler;
private final List<IBehavior> behaviors;
private final PathingBehavior pathingBehavior; private final PathingBehavior pathingBehavior;
private final IElytraBehavior elytraBehavior;
private final LookBehavior lookBehavior; private final LookBehavior lookBehavior;
private final InventoryBehavior inventoryBehavior; private final InventoryBehavior inventoryBehavior;
private final InputOverrideHandler inputOverrideHandler; private final InputOverrideHandler inputOverrideHandler;
@@ -88,6 +93,7 @@ public class Baritone implements IBaritone {
Baritone(Minecraft mc) { Baritone(Minecraft mc) {
this.mc = mc; this.mc = mc;
this.behaviors = new ArrayList<>();
this.gameEventHandler = new GameEventHandler(this); this.gameEventHandler = new GameEventHandler(this);
this.directory = mc.gameDir.toPath().resolve("baritone"); this.directory = mc.gameDir.toPath().resolve("baritone");
@@ -102,6 +108,7 @@ public class Baritone implements IBaritone {
{ {
this.lookBehavior = this.registerBehavior(LookBehavior::new); this.lookBehavior = this.registerBehavior(LookBehavior::new);
this.elytraBehavior = this.registerBehavior(ElytraBehavior::create);
this.pathingBehavior = this.registerBehavior(PathingBehavior::new); this.pathingBehavior = this.registerBehavior(PathingBehavior::new);
this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new); this.inventoryBehavior = this.registerBehavior(InventoryBehavior::new);
this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new); this.inputOverrideHandler = this.registerBehavior(InputOverrideHandler::new);
@@ -124,9 +131,12 @@ public class Baritone implements IBaritone {
this.worldProvider = new WorldProvider(this); this.worldProvider = new WorldProvider(this);
this.selectionManager = new SelectionManager(this); this.selectionManager = new SelectionManager(this);
this.commandManager = new CommandManager(this); this.commandManager = new CommandManager(this);
this.behaviors.forEach(IBehavior::onLoad);
} }
public void registerBehavior(IBehavior behavior) { public void registerBehavior(IBehavior behavior) {
this.behaviors.add(behavior);
this.gameEventHandler.registerEventListener(behavior); this.gameEventHandler.registerEventListener(behavior);
} }
@@ -230,6 +240,11 @@ public class Baritone implements IBaritone {
return this.commandManager; return this.commandManager;
} }
@Override
public IElytraBehavior getElytraBehavior() {
return this.elytraBehavior;
}
@Override @Override
public void openClick() { public void openClick() {
new Thread(() -> { new Thread(() -> {

File diff suppressed because it is too large Load Diff

View File

@@ -26,6 +26,7 @@ import baritone.api.event.events.*;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
import baritone.api.utils.Rotation; import baritone.api.utils.Rotation;
import baritone.behavior.look.ForkableRandom; import baritone.behavior.look.ForkableRandom;
import com.google.common.collect.EvictingQueue;
import net.minecraft.network.play.client.CPacketPlayer; import net.minecraft.network.play.client.CPacketPlayer;
import java.util.Optional; import java.util.Optional;
@@ -51,14 +52,17 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
private final AimProcessor processor; private final AimProcessor processor;
private final EvictingQueue<Float> smoothYawBuffer;
public LookBehavior(Baritone baritone) { public LookBehavior(Baritone baritone) {
super(baritone); super(baritone);
this.processor = new AimProcessor(baritone.getPlayerContext()); this.processor = new AimProcessor(baritone.getPlayerContext());
this.smoothYawBuffer = EvictingQueue.create(10);
} }
@Override @Override
public void updateTarget(Rotation rotation, boolean blockInteract) { public void updateTarget(Rotation rotation, boolean blockInteract) {
this.target = new Target(rotation, blockInteract); this.target = new Target(rotation, Target.Mode.resolve(ctx, blockInteract));
} }
@Override @Override
@@ -96,8 +100,15 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
case POST: { case POST: {
// Reset the player's rotations back to their original values // Reset the player's rotations back to their original values
if (this.prevRotation != null) { if (this.prevRotation != null) {
ctx.player().rotationYaw = this.prevRotation.getYaw(); if (Baritone.settings().smoothLook.value) {
ctx.player().rotationPitch = this.prevRotation.getPitch(); this.smoothYawBuffer.add(this.target.rotation.getYaw());
ctx.player().rotationYaw = (float) this.smoothYawBuffer.stream()
.mapToDouble(d -> d).average().orElseGet(this.prevRotation::getYaw);
ctx.player().rotationPitch = this.prevRotation.getPitch();
} else {
ctx.player().rotationYaw = this.prevRotation.getYaw();
ctx.player().rotationPitch = this.prevRotation.getPitch();
}
this.prevRotation = null; this.prevRotation = null;
} }
// The target is done being used for this game tick, so it can be invalidated // The target is done being used for this game tick, so it can be invalidated
@@ -279,9 +290,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
public final Rotation rotation; public final Rotation rotation;
public final Mode mode; public final Mode mode;
public Target(Rotation rotation, boolean blockInteract) { public Target(Rotation rotation, Mode mode) {
this.rotation = rotation; this.rotation = rotation;
this.mode = Mode.resolve(blockInteract); this.mode = mode;
} }
enum Mode { enum Mode {
@@ -300,7 +311,7 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
*/ */
NONE; NONE;
static Mode resolve(boolean blockInteract) { static Mode resolve(IPlayerContext ctx, boolean blockInteract) {
final Settings settings = Baritone.settings(); final Settings settings = Baritone.settings();
final boolean antiCheat = settings.antiCheatCompatibility.value; final boolean antiCheat = settings.antiCheatCompatibility.value;
final boolean blockFreeLook = settings.blockFreeLook.value; final boolean blockFreeLook = settings.blockFreeLook.value;
@@ -309,6 +320,10 @@ public final class LookBehavior extends Behavior implements ILookBehavior {
if (!freeLook) return CLIENT; if (!freeLook) return CLIENT;
if (!blockFreeLook && blockInteract) return CLIENT; if (!blockFreeLook && blockInteract) return CLIENT;
if (ctx.player().isElytraFlying()) {
return settings.elytraFreeLook.value ? SERVER : CLIENT;
}
// Regardless of if antiCheatCompatibility is enabled, if a blockInteract is requested then the player // 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 // 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. // whatever the player is mousing over visually. Let's just settle for setting it silently.

View File

@@ -309,7 +309,10 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} }
public boolean isSafeToCancel() { public boolean isSafeToCancel() {
return current == null || safeToCancel; if (current == null) {
return !baritone.getElytraBehavior().isActive() || baritone.getElytraBehavior().isSafeToCancel();
}
return safeToCancel;
} }
public void requestPause() { public void requestPause() {
@@ -352,7 +355,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} }
// just cancel the current path // just cancel the current path
private void secretInternalSegmentCancel() { public void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED); queuePathEvent(PathEvent.CANCELED);
synchronized (pathPlanLock) { synchronized (pathPlanLock) {
getInProgress().ifPresent(AbstractNodeCostSearch::cancel); getInProgress().ifPresent(AbstractNodeCostSearch::cancel);

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.behavior.elytra;
import dev.babbaj.pathfinder.NetherPathfinder;
import dev.babbaj.pathfinder.Octree;
/**
* @author Brady
*/
public final class BlockStateOctreeInterface {
private final NetherPathfinderContext context;
private final long contextPtr;
volatile long chunkPtr;
// Guarantee that the first lookup will fetch the context by setting MAX_VALUE
private int prevChunkX = Integer.MAX_VALUE;
private int prevChunkZ = Integer.MAX_VALUE;
public BlockStateOctreeInterface(final NetherPathfinderContext context) {
this.context = context;
this.contextPtr = context.context;
}
public boolean get0(final int x, final int y, final int z) {
if ((y | (128 - y)) < 0) {
return false;
}
final int chunkX = x >> 4;
final int chunkZ = z >> 4;
long pointer = this.chunkPtr;
if (pointer == 0 | ((chunkX ^ this.prevChunkX) | (chunkZ ^ this.prevChunkZ)) != 0) {
this.prevChunkX = chunkX;
this.prevChunkZ = chunkZ;
synchronized (this.context.cacheLock) {
this.chunkPtr = pointer = NetherPathfinder.getOrCreateChunk(this.contextPtr, chunkX, chunkZ);
}
}
return Octree.getBlock(pointer, x & 0xF, y & 0x7F, z & 0xF);
}
}

View File

@@ -0,0 +1,65 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior.elytra;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.util.math.Vec3d;
import java.util.AbstractList;
import java.util.Collections;
import java.util.List;
/**
* @author Brady
*/
public final class NetherPath extends AbstractList<BetterBlockPos> {
private static final NetherPath EMPTY_PATH = new NetherPath(Collections.emptyList());
private final List<BetterBlockPos> backing;
NetherPath(List<BetterBlockPos> backing) {
this.backing = backing;
}
@Override
public BetterBlockPos get(int index) {
return this.backing.get(index);
}
@Override
public int size() {
return this.backing.size();
}
/**
* @return The last position in the path, or {@code null} if empty
*/
public BetterBlockPos getLast() {
return this.isEmpty() ? null : this.backing.get(this.backing.size() - 1);
}
public Vec3d getVec(int index) {
final BetterBlockPos pos = this.get(index);
return new Vec3d(pos.x, pos.y, pos.z);
}
public static NetherPath emptyPath() {
return EMPTY_PATH;
}
}

View File

@@ -0,0 +1,456 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior.elytra;
import baritone.Baritone;
import baritone.api.event.events.BlockChangeEvent;
import baritone.utils.accessor.IBitArray;
import baritone.utils.accessor.IBlockStateContainer;
import dev.babbaj.pathfinder.NetherPathfinder;
import dev.babbaj.pathfinder.Octree;
import dev.babbaj.pathfinder.PathSegment;
import net.minecraft.block.state.IBlockState;
import net.minecraft.init.Blocks;
import net.minecraft.util.BitArray;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.chunk.BlockStateContainer;
import net.minecraft.world.chunk.Chunk;
import net.minecraft.world.chunk.storage.ExtendedBlockStorage;
import javax.annotation.Nonnull;
import java.lang.ref.SoftReference;
import java.util.*;
import java.util.concurrent.*;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;
import java.util.stream.Stream;
/**
* @author Brady
*/
public final class NetherPathfinderContext {
private static final IBlockState AIR_BLOCK_STATE = Blocks.AIR.getDefaultState();
public final Object cacheLock = new Object();
// Visible for access in BlockStateOctreeInterface
final long context;
private final long seed;
private final ExecutorService executor;
public NetherPathfinderContext(long seed) {
this.context = NetherPathfinder.newContext(seed);
this.seed = seed;
this.executor = new ThreadPoolExecutor(1, 1, 0L, TimeUnit.MILLISECONDS, new WorkQueue());
}
public void queueCacheCulling(int chunkX, int chunkZ, int maxDistanceBlocks, BlockStateOctreeInterface boi) {
this.executor.execute(() -> {
synchronized (this.cacheLock) {
boi.chunkPtr = 0L;
NetherPathfinder.cullFarChunks(this.context, chunkX, chunkZ, maxDistanceBlocks);
}
});
}
public void queueForPacking(final Chunk chunkIn) {
final SoftReference<Chunk> ref = new SoftReference<>(chunkIn);
this.executor.execute(() -> {
// TODO: Prioritize packing recent chunks and/or ones that the path goes through,
// and prune the oldest chunks per chunkPackerQueueMaxSize
final Chunk chunk = ref.get();
if (chunk != null) {
long ptr = NetherPathfinder.getOrCreateChunk(this.context, chunk.x, chunk.z);
writeChunkData(chunk, ptr);
}
});
}
public void queueBlockUpdate(BlockChangeEvent event) {
this.executor.execute(() -> {
ChunkPos chunkPos = event.getChunkPos();
long ptr = NetherPathfinder.getChunkPointer(this.context, chunkPos.x, chunkPos.z);
if (ptr == 0) return; // this shouldn't ever happen
event.getBlocks().forEach(pair -> {
BlockPos pos = pair.first();
if (pos.getY() >= 128) return;
boolean isSolid = pair.second() != AIR_BLOCK_STATE;
Octree.setBlock(ptr, pos.getX() & 15, pos.getY(), pos.getZ() & 15, isSolid);
});
});
}
public CompletableFuture<PathSegment> pathFindAsync(final BlockPos src, final BlockPos dst) {
return CompletableFuture.supplyAsync(() -> {
final PathSegment segment = NetherPathfinder.pathFind(
this.context,
src.getX(), src.getY(), src.getZ(),
dst.getX(), dst.getY(), dst.getZ(),
true,
10000
);
if (segment == null) {
throw new PathCalculationException("Path calculation failed");
}
return segment;
}, this.executor);
}
/**
* Performs a raytrace from the given start position to the given end position, returning {@code true} if there is
* visibility between the two points.
*
* @param startX The start X coordinate
* @param startY The start Y coordinate
* @param startZ The start Z coordinate
* @param endX The end X coordinate
* @param endY The end Y coordinate
* @param endZ The end Z coordinate
* @return {@code true} if there is visibility between the points
*/
public boolean raytrace(final double startX, final double startY, final double startZ,
final double endX, final double endY, final double endZ) {
return NetherPathfinder.isVisible(this.context, true, startX, startY, startZ, endX, endY, endZ);
}
/**
* Performs a raytrace from the given start position to the given end position, returning {@code true} if there is
* visibility between the two points.
*
* @param start The starting point
* @param end The ending point
* @return {@code true} if there is visibility between the points
*/
public boolean raytrace(final Vec3d start, final Vec3d end) {
return NetherPathfinder.isVisible(this.context, true, start.x, start.y, start.z, end.x, end.y, end.z);
}
public boolean raytrace(final int count, final double[] src, final double[] dst, final int visibility) {
switch (visibility) {
case Visibility.ALL:
return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, false) == -1;
case Visibility.NONE:
return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) == -1;
case Visibility.ANY:
return NetherPathfinder.isVisibleMulti(this.context, true, count, src, dst, true) != -1;
default:
throw new IllegalArgumentException("lol");
}
}
public void raytrace(final int count, final double[] src, final double[] dst, final boolean[] hitsOut, final double[] hitPosOut) {
NetherPathfinder.raytrace(this.context, true, count, src, dst, hitsOut, hitPosOut);
}
public void cancel() {
NetherPathfinder.cancel(this.context);
}
public void destroy() {
this.cancel();
// Ignore anything that was queued up, just shutdown the executor
this.executor.shutdownNow();
try {
while (!this.executor.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS)) {}
} catch (InterruptedException e) {
e.printStackTrace();
}
NetherPathfinder.freeContext(this.context);
}
public long getSeed() {
return this.seed;
}
private static void writeChunkData(Chunk chunk, long ptr) {
try {
ExtendedBlockStorage[] chunkInternalStorageArray = chunk.getBlockStorageArray();
for (int y0 = 0; y0 < 8; y0++) {
final ExtendedBlockStorage extendedblockstorage = chunkInternalStorageArray[y0];
if (extendedblockstorage == null) {
continue;
}
final BlockStateContainer bsc = extendedblockstorage.getData();
final int airId = ((IBlockStateContainer) bsc).getPalette().idFor(AIR_BLOCK_STATE);
// pasted from FasterWorldScanner
final BitArray array = ((IBlockStateContainer) bsc).getStorage();
if (array == null) continue;
final long[] longArray = array.getBackingLongArray();
final int arraySize = array.size();
final int bitsPerEntry = ((IBitArray) array).getBitsPerEntry();
final long maxEntryValue = ((IBitArray) array).getMaxEntryValue();
final int yReal = y0 << 4;
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;
final int id;
if (j == k) {
id = (int) (jl & maxEntryValue);
} else {
id = (int) ((jl | longArray[k] << (64 - l)) & maxEntryValue);
}
int x = (idx & 15);
int y = yReal + (idx >> 8);
int z = ((idx >> 4) & 15);
Octree.setBlock(ptr, x, y, z, id != airId);
}
}
Octree.setIsFromJava(ptr);
} catch (Exception e) {
e.printStackTrace();
throw new RuntimeException(e);
}
}
private static final class WorkQueue extends TrollBlockingQueue<Runnable> {
private final LinkedList<Runnable> path;
private final LinkedList<Runnable> chunk;
private final ReentrantLock takeLock = new ReentrantLock();
private final ReentrantLock putLock = new ReentrantLock();
private final Condition notEmpty = takeLock.newCondition();
public WorkQueue() {
this.path = new LinkedList<>();
this.chunk = new LinkedList<>();
}
private void signalNotEmpty() {
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
try {
this.notEmpty.signal();
} finally {
takeLock.unlock();
}
}
@Override
public boolean offer(@Nonnull Runnable runnable) {
final ReentrantLock putLock = this.putLock;
putLock.lock();
try {
if (runnable instanceof ForkJoinTask) {
this.path.offer(runnable);
} else {
// Put new chunks at the head of the queue
this.chunk.offerFirst(runnable);
// Purge oldest chunks
while (this.chunk.size() > Baritone.settings().chunkPackerQueueMaxSize.value) {
this.chunk.removeLast();
}
}
} finally {
putLock.unlock();
}
signalNotEmpty();
return true;
}
@Override
public Runnable take() throws InterruptedException {
Runnable x;
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
while (size() == 0) {
notEmpty.await();
}
x = dequeue();
if (!isEmpty()) {
notEmpty.signal();
}
} finally {
takeLock.unlock();
}
return x;
}
@Override
public Runnable poll(long timeout, TimeUnit unit) throws InterruptedException {
Runnable x;
long nanos = unit.toNanos(timeout);
final ReentrantLock takeLock = this.takeLock;
takeLock.lockInterruptibly();
try {
while (isEmpty()) {
if (nanos <= 0)
return null;
nanos = notEmpty.awaitNanos(nanos);
}
x = dequeue();
if (!isEmpty())
notEmpty.signal();
} finally {
takeLock.unlock();
}
return x;
}
@Override
public boolean remove(Object o) {
takeLock.lock();
putLock.lock();
try {
return this.path.remove(o) || this.chunk.remove(o);
} finally {
takeLock.unlock();
putLock.unlock();
}
}
@Override
public int drainTo(Collection<? super Runnable> c) {
final ReentrantLock takeLock = this.takeLock;
takeLock.lock();
int n = size();
try {
if (!this.path.isEmpty()) {
c.add(this.path.remove());
}
if (!this.chunk.isEmpty()) {
c.add(this.chunk.remove());
}
} finally {
takeLock.unlock();
}
return n;
}
@Override
public int size() {
takeLock.lock();
putLock.lock();
try {
return this.path.size() + this.chunk.size();
} finally {
takeLock.unlock();
putLock.unlock();
}
}
@Override
public boolean isEmpty() {
return this.size() == 0;
}
@SuppressWarnings("unchecked")
@Override
public synchronized @Nonnull <T> T[] toArray(@Nonnull T[] a) {
takeLock.lock();
putLock.lock();
try {
return (T[]) Stream.concat(this.path.stream(), this.chunk.stream()).toArray(Runnable[]::new);
} finally {
takeLock.unlock();
putLock.unlock();
}
}
private Runnable dequeue() {
return !this.path.isEmpty() ? this.path.remove() : this.chunk.remove();
}
}
@SuppressWarnings("NullableProblems")
private static class TrollBlockingQueue<T> extends AbstractQueue<T> implements BlockingQueue<T> {
@Override
public Iterator<T> iterator() {
throw new UnsupportedOperationException();
}
@Override
public int size() {
throw new UnsupportedOperationException();
}
@Override
public void put(T t) {
throw new UnsupportedOperationException();
}
@Override
public boolean offer(T t, long timeout, TimeUnit unit) {
throw new UnsupportedOperationException();
}
@Override
public T take() throws InterruptedException {
throw new UnsupportedOperationException();
}
@Override
public T poll(long timeout, TimeUnit unit) throws InterruptedException {
throw new UnsupportedOperationException();
}
@Override
public int remainingCapacity() {
throw new UnsupportedOperationException();
}
@Override
public int drainTo(Collection<? super T> c) {
throw new UnsupportedOperationException();
}
@Override
public int drainTo(Collection<? super T> c, int maxElements) {
throw new UnsupportedOperationException();
}
@Override
public boolean offer(T t) {
throw new UnsupportedOperationException();
}
@Override
public T poll() {
throw new UnsupportedOperationException();
}
@Override
public T peek() {
throw new UnsupportedOperationException();
}
}
public static final class Visibility {
public static final int ALL = 0;
public static final int NONE = 1;
public static final int ANY = 2;
private Visibility() {}
}
public static boolean isSupported() {
return NetherPathfinder.isThisSystemSupported();
}
}

View File

@@ -0,0 +1,70 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior.elytra;
import baritone.Baritone;
import baritone.api.behavior.IElytraBehavior;
import baritone.behavior.Behavior;
import net.minecraft.util.math.BlockPos;
import java.util.concurrent.CompletableFuture;
/**
* @author Brady
*/
public final class NullElytraBehavior extends Behavior implements IElytraBehavior {
public NullElytraBehavior(Baritone baritone) {
super(baritone);
}
@Override
public CompletableFuture<Void> resetContext() {
throw new UnsupportedOperationException("Called resetContext() on NullElytraBehavior");
}
@Override
public void repackChunks() {
throw new UnsupportedOperationException("Called repackChunks() on NullElytraBehavior");
}
@Override
public void pathTo(BlockPos destination) {
throw new UnsupportedOperationException("Called pathTo() on NullElytraBehavior");
}
@Override
public void cancel() {
throw new UnsupportedOperationException("Called cancel() on NullElytraBehavior");
}
@Override
public boolean isActive() {
return false;
}
@Override
public boolean isLoaded() {
return false;
}
@Override
public boolean isSafeToCancel() {
return true;
}
}

View File

@@ -15,15 +15,14 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>. * along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/ */
package baritone.gradle.util; package baritone.behavior.elytra;
/** /**
* All credits go to AsmLibGradle and its contributors. * @author Brady
*
* @see <a href="https://github.com/pozzed/AsmLibGradle/blob/8f917dbc3939eab7a3d9daf54d9d285fdf34f4b2/src/main/java/net/futureclient/asmlib/forgegradle/MappingType.java">Original Source</a>
*/ */
public enum MappingType { public final class PathCalculationException extends RuntimeException {
SEARGE,
NOTCH, public PathCalculationException(final String message) {
CUSTOM // forgegradle super(message);
}
} }

View File

@@ -0,0 +1,83 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior.elytra;
import baritone.api.utils.BetterBlockPos;
import dev.babbaj.pathfinder.PathSegment;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.Stream;
/**
* @author Brady
*/
public final class UnpackedSegment {
private final Stream<BetterBlockPos> path;
private final boolean finished;
public UnpackedSegment(Stream<BetterBlockPos> path, boolean finished) {
this.path = path;
this.finished = finished;
}
public UnpackedSegment append(Stream<BetterBlockPos> other, boolean otherFinished) {
// The new segment is only finished if the one getting added on is
return new UnpackedSegment(Stream.concat(this.path, other), otherFinished);
}
public UnpackedSegment prepend(Stream<BetterBlockPos> other) {
return new UnpackedSegment(Stream.concat(other, this.path), this.finished);
}
public NetherPath collect() {
final List<BetterBlockPos> path = this.path.collect(Collectors.toList());
// Remove backtracks
final Map<BetterBlockPos, Integer> positionFirstSeen = new HashMap<>();
for (int i = 0; i < path.size(); i++) {
BetterBlockPos pos = path.get(i);
if (positionFirstSeen.containsKey(pos)) {
int j = positionFirstSeen.get(pos);
while (i > j) {
path.remove(i);
i--;
}
} else {
positionFirstSeen.put(pos, i);
}
}
return new NetherPath(path);
}
public boolean isFinished() {
return this.finished;
}
public static UnpackedSegment from(final PathSegment segment) {
return new UnpackedSegment(
Arrays.stream(segment.packed).mapToObj(BetterBlockPos::deserializeFromLong),
segment.finished
);
}
}

View File

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

View File

@@ -0,0 +1,117 @@
/*
* 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.api.IBaritone;
import baritone.api.behavior.IElytraBehavior;
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.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.process.ICustomGoalProcess;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
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 IElytraBehavior elytra = baritone.getElytraBehavior();
if (!elytra.isLoaded()) {
final String osArch = System.getProperty("os.arch");
final String osName = System.getProperty("os.name");
throw new CommandInvalidStateException(String.format(
"legacy architectures are not supported. your CPU is %s and your operating system is %s. " +
"supported architectures are x86_64 or arm64, supported operating systems are windows, " +
"linux, and mac",
osArch, osName
));
}
if (!args.hasAny()) {
Goal iGoal = customGoalProcess.mostRecentGoal();
if (iGoal == null) {
throw new CommandInvalidStateException("No goal has been set");
}
final int x, y, z;
if (iGoal instanceof GoalXZ) {
GoalXZ goal = (GoalXZ) iGoal;
x = goal.getX();
y = 64;
z = goal.getZ();
} else if (iGoal instanceof GoalBlock) {
GoalBlock goal = (GoalBlock) iGoal;
x = goal.x;
y = goal.y;
z = goal.z;
} else {
throw new CommandInvalidStateException("The goal must be a GoalXZ or GoalBlock");
}
if (y <= 0 || y >= 128) {
throw new CommandInvalidStateException("The y of the goal is not between 0 and 128");
}
elytra.pathTo(new BlockPos(x, y, z));
return;
}
final String action = args.getString();
switch (action) {
case "reset": {
elytra.resetContext().whenComplete((result, ex) -> {
logDirect("Context reset, repacking chunks");
elytra.repackChunks();
});
break;
}
case "repack": {
elytra.repackChunks();
logDirect("Queued all loaded chunks for repacking");
break;
}
default: {
throw new CommandInvalidStateException("Invalid action");
}
}
}
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) throws CommandException {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "elytra time";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList();
}
}

View File

@@ -180,6 +180,7 @@ public class ExecutionControlCommands {
paused[0] = false; paused[0] = false;
} }
baritone.getPathingBehavior().cancelEverything(); baritone.getPathingBehavior().cancelEverything();
baritone.getElytraBehavior().cancel();
logDirect("ok canceled"); logDirect("ok canceled");
} }

View File

@@ -39,6 +39,7 @@ public class ForceCancelCommand extends Command {
IPathingBehavior pathingBehavior = baritone.getPathingBehavior(); IPathingBehavior pathingBehavior = baritone.getPathingBehavior();
pathingBehavior.cancelEverything(); pathingBehavior.cancelEverything();
pathingBehavior.forceCancel(); pathingBehavior.forceCancel();
baritone.getElytraBehavior().cancel();
logDirect("ok force canceled"); logDirect("ok force canceled");
} }

View File

@@ -23,8 +23,12 @@ import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.IEventBus; import baritone.api.event.listener.IEventBus;
import baritone.api.event.listener.IGameEventListener; import baritone.api.event.listener.IGameEventListener;
import baritone.api.utils.Helper; import baritone.api.utils.Helper;
import baritone.api.utils.Pair;
import baritone.cache.CachedChunk;
import baritone.cache.WorldProvider; import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface; import baritone.utils.BlockStateInterface;
import net.minecraft.block.state.IBlockState;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.World; import net.minecraft.world.World;
import net.minecraft.world.chunk.Chunk; import net.minecraft.world.chunk.Chunk;
@@ -59,6 +63,11 @@ public final class GameEventHandler implements IEventBus, Helper {
listeners.forEach(l -> l.onTick(event)); listeners.forEach(l -> l.onTick(event));
} }
@Override
public void onPostTick(TickEvent event) {
listeners.forEach(l -> l.onPostTick(event));
}
@Override @Override
public final void onPlayerUpdate(PlayerUpdateEvent event) { public final void onPlayerUpdate(PlayerUpdateEvent event) {
listeners.forEach(l -> l.onPlayerUpdate(event)); listeners.forEach(l -> l.onPlayerUpdate(event));
@@ -75,13 +84,10 @@ public final class GameEventHandler implements IEventBus, Helper {
} }
@Override @Override
public final void onChunkEvent(ChunkEvent event) { public void onChunkEvent(ChunkEvent event) {
EventState state = event.getState(); EventState state = event.getState();
ChunkEvent.Type type = event.getType(); ChunkEvent.Type type = event.getType();
boolean isPostPopulate = state == EventState.POST
&& (type == ChunkEvent.Type.POPULATE_FULL || type == ChunkEvent.Type.POPULATE_PARTIAL);
World world = baritone.getPlayerContext().world(); World world = baritone.getPlayerContext().world();
// Whenever the server sends us to another dimension, chunks are unloaded // Whenever the server sends us to another dimension, chunks are unloaded
@@ -91,7 +97,7 @@ public final class GameEventHandler implements IEventBus, Helper {
&& type == ChunkEvent.Type.UNLOAD && type == ChunkEvent.Type.UNLOAD
&& world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ()); && world.getChunkProvider().isChunkGeneratedAt(event.getX(), event.getZ());
if (isPostPopulate || isPreUnload) { if (event.isPostPopulate() || isPreUnload) {
baritone.getWorldProvider().ifWorldLoaded(worldData -> { baritone.getWorldProvider().ifWorldLoaded(worldData -> {
Chunk chunk = world.getChunk(event.getX(), event.getZ()); Chunk chunk = world.getChunk(event.getX(), event.getZ());
worldData.getCachedWorld().queueForPacking(chunk); worldData.getCachedWorld().queueForPacking(chunk);
@@ -102,6 +108,25 @@ public final class GameEventHandler implements IEventBus, Helper {
listeners.forEach(l -> l.onChunkEvent(event)); listeners.forEach(l -> l.onChunkEvent(event));
} }
@Override
public void onBlockChange(BlockChangeEvent event) {
if (Baritone.settings().repackOnAnyBlockChange.value) {
final boolean keepingTrackOf = event.getBlocks().stream()
.map(Pair::second).map(IBlockState::getBlock)
.anyMatch(CachedChunk.BLOCKS_TO_KEEP_TRACK_OF::contains);
if (keepingTrackOf) {
baritone.getWorldProvider().ifWorldLoaded(worldData -> {
final World world = baritone.getPlayerContext().world();
ChunkPos pos = event.getChunkPos();
worldData.getCachedWorld().queueForPacking(world.getChunk(pos.x, pos.z));
});
}
}
listeners.forEach(l -> l.onBlockChange(event));
}
@Override @Override
public final void onRenderPass(RenderEvent event) { public final void onRenderPass(RenderEvent event) {
listeners.forEach(l -> l.onRenderPass(event)); listeners.forEach(l -> l.onRenderPass(event));

View File

@@ -66,11 +66,13 @@ public class CalculationContext {
public final boolean allowJumpAt256; public final boolean allowJumpAt256;
public final boolean allowParkourAscend; public final boolean allowParkourAscend;
public final boolean assumeWalkOnWater; public final boolean assumeWalkOnWater;
public boolean allowFallIntoLava;
public final int frostWalker; public final int frostWalker;
public final boolean allowDiagonalDescend; public final boolean allowDiagonalDescend;
public final boolean allowDiagonalAscend; public final boolean allowDiagonalAscend;
public final boolean allowDownward; public final boolean allowDownward;
public final int maxFallHeightNoWater; public int minFallHeight;
public int maxFallHeightNoWater;
public final int maxFallHeightBucket; public final int maxFallHeightBucket;
public final double waterWalkSpeed; public final double waterWalkSpeed;
public final double breakBlockAdditionalCost; public final double breakBlockAdditionalCost;
@@ -105,10 +107,12 @@ public class CalculationContext {
this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value; this.allowJumpAt256 = Baritone.settings().allowJumpAt256.value;
this.allowParkourAscend = Baritone.settings().allowParkourAscend.value; this.allowParkourAscend = Baritone.settings().allowParkourAscend.value;
this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value; this.assumeWalkOnWater = Baritone.settings().assumeWalkOnWater.value;
this.allowFallIntoLava = false; // Super secret internal setting for ElytraBehavior
this.frostWalker = EnchantmentHelper.getMaxEnchantmentLevel(Enchantments.FROST_WALKER, baritone.getPlayerContext().player()); this.frostWalker = EnchantmentHelper.getMaxEnchantmentLevel(Enchantments.FROST_WALKER, baritone.getPlayerContext().player());
this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value; this.allowDiagonalDescend = Baritone.settings().allowDiagonalDescend.value;
this.allowDiagonalAscend = Baritone.settings().allowDiagonalAscend.value; this.allowDiagonalAscend = Baritone.settings().allowDiagonalAscend.value;
this.allowDownward = Baritone.settings().allowDownward.value; this.allowDownward = Baritone.settings().allowDownward.value;
this.minFallHeight = 3; // Minimum fall height used by MovementFall
this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value; this.maxFallHeightNoWater = Baritone.settings().maxFallHeightNoWater.value;
this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value; this.maxFallHeightBucket = Baritone.settings().maxFallHeightBucket.value;
int depth = EnchantmentHelper.getDepthStriderModifier(player); int depth = EnchantmentHelper.getDepthStriderModifier(player);

View File

@@ -154,10 +154,11 @@ public class MovementDescend extends Movement {
// this check prevents it from getting the block at y=-1 and crashing // this check prevents it from getting the block at y=-1 and crashing
return false; return false;
} }
boolean reachedMinimum = fallHeight >= context.minFallHeight;
IBlockState ontoBlock = context.get(destX, newY, destZ); IBlockState ontoBlock = context.get(destX, newY, destZ);
int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY int unprotectedFallHeight = fallHeight - (y - effectiveStartHeight); // equal to fallHeight - y + effectiveFallHeight, which is equal to -newY + effectiveFallHeight, which is equal to effectiveFallHeight - newY
double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar; double tentativeCost = WALK_OFF_BLOCK_COST + FALL_N_BLOCKS_COST[unprotectedFallHeight] + frontBreak + costSoFar;
if (MovementHelper.isWater(ontoBlock.getBlock())) { if (reachedMinimum && MovementHelper.isWater(ontoBlock.getBlock())) {
if (!MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) { if (!MovementHelper.canWalkThrough(context, destX, newY, destZ, ontoBlock)) {
return false; return false;
} }
@@ -178,6 +179,14 @@ public class MovementDescend extends Movement {
res.cost = tentativeCost;// TODO incorporate water swim up cost? res.cost = tentativeCost;// TODO incorporate water swim up cost?
return false; return false;
} }
if (reachedMinimum && context.allowFallIntoLava && MovementHelper.isLava(ontoBlock.getBlock())) {
// found a fall into lava
res.x = destX;
res.y = newY;
res.z = destZ;
res.cost = tentativeCost;
return false;
}
if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) { if (unprotectedFallHeight <= 11 && (ontoBlock.getBlock() == Blocks.VINE || ontoBlock.getBlock() == Blocks.LADDER)) {
// if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know // if fall height is greater than or equal to 11, we don't actually grab on to vines or ladders. the more you know
// this effectively "resets" our falling speed // this effectively "resets" our falling speed
@@ -195,7 +204,7 @@ public class MovementDescend extends Movement {
if (MovementHelper.isBottomSlab(ontoBlock)) { if (MovementHelper.isBottomSlab(ontoBlock)) {
return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect return false; // falling onto a half slab is really glitchy, and can cause more fall damage than we'd expect
} }
if (unprotectedFallHeight <= context.maxFallHeightNoWater + 1) { if (reachedMinimum && unprotectedFallHeight <= context.maxFallHeightNoWater + 1) {
// fallHeight = 4 means onto.up() is 3 blocks down, which is the max // fallHeight = 4 means onto.up() is 3 blocks down, which is the max
res.x = destX; res.x = destX;
res.y = newY + 1; res.y = newY + 1;
@@ -203,7 +212,7 @@ public class MovementDescend extends Movement {
res.cost = tentativeCost; res.cost = tentativeCost;
return false; return false;
} }
if (context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) { if (reachedMinimum && context.hasWaterBucket && unprotectedFallHeight <= context.maxFallHeightBucket + 1) {
res.x = destX; res.x = destX;
res.y = newY + 1;// this is the block we're falling onto, so dest is +1 res.y = newY + 1;// this is the block we're falling onto, so dest is +1
res.z = destZ; res.z = destZ;

View File

@@ -36,6 +36,11 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
*/ */
private Goal goal; private Goal goal;
/**
* The most recent goal. Not invalidated upon {@link #onLostControl()}
*/
private Goal mostRecentGoal;
/** /**
* The current process state. * The current process state.
* *
@@ -50,6 +55,7 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
@Override @Override
public void setGoal(Goal goal) { public void setGoal(Goal goal) {
this.goal = goal; this.goal = goal;
this.mostRecentGoal = goal;
if (this.state == State.NONE) { if (this.state == State.NONE) {
this.state = State.GOAL_SET; this.state = State.GOAL_SET;
} }
@@ -68,6 +74,11 @@ public final class CustomGoalProcess extends BaritoneProcessHelper implements IC
return this.goal; return this.goal;
} }
@Override
public Goal mostRecentGoal() {
return this.mostRecentGoal;
}
@Override @Override
public boolean isActive() { public boolean isActive() {
return this.state != State.NONE; return this.state != State.NONE;

View File

@@ -0,0 +1,37 @@
/*
* 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.utils;
/**
* @author Brady
*/
public final class BaritoneMath {
private static final double FLOOR_DOUBLE_D = 1_073_741_824.0;
private static final int FLOOR_DOUBLE_I = 1_073_741_824;
private BaritoneMath() {}
public static int fastFloor(final double v) {
return (int) (v + FLOOR_DOUBLE_D) - FLOOR_DOUBLE_I;
}
public static int fastCeil(final double v) {
return FLOOR_DOUBLE_I - (int) (FLOOR_DOUBLE_D - v);
}
}

View File

@@ -27,6 +27,7 @@ import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureManager; import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.vertex.DefaultVertexFormats; import net.minecraft.client.renderer.vertex.DefaultVertexFormats;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.Vec3d;
import java.awt.*; import java.awt.*;
@@ -120,4 +121,16 @@ public interface IRenderer {
emitAABB(aabb); emitAABB(aabb);
tessellator.draw(); tessellator.draw();
} }
static void emitLine(Vec3d start, Vec3d end) {
emitLine(start.x, start.y, start.z, end.x, end.y, end.z);
}
static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) {
double vpX = renderManager.viewerPosX;
double vpY = renderManager.viewerPosY;
double vpZ = renderManager.viewerPosZ;
buffer.pos(x1 - vpX, y1 - vpY, z1 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
buffer.pos(x2 - vpX, y2 - vpY, z2 - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
}
} }

View File

@@ -107,7 +107,7 @@ public final class InputOverrideHandler extends Behavior implements IInputOverri
} }
private boolean inControl() { private boolean inControl() {
for (Input input : new Input[]{Input.MOVE_FORWARD, Input.MOVE_BACK, Input.MOVE_LEFT, Input.MOVE_RIGHT, Input.SNEAK}) { for (Input input : new Input[]{Input.MOVE_FORWARD, Input.MOVE_BACK, Input.MOVE_LEFT, Input.MOVE_RIGHT, Input.SNEAK, Input.JUMP}) {
if (isInputForcedDown(input)) { if (isInputForcedDown(input)) {
return true; return true;
} }

View File

@@ -19,7 +19,6 @@ package baritone.utils;
import baritone.api.BaritoneAPI; import baritone.api.BaritoneAPI;
import baritone.api.event.events.RenderEvent; import baritone.api.event.events.RenderEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.goals.*; import baritone.api.pathing.goals.*;
import baritone.api.utils.BetterBlockPos; import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.IPlayerContext; import baritone.api.utils.IPlayerContext;
@@ -34,6 +33,7 @@ import net.minecraft.init.Blocks;
import net.minecraft.util.math.AxisAlignedBB; import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos; import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.MathHelper; import net.minecraft.util.math.MathHelper;
import net.minecraft.util.math.Vec3d;
import java.awt.*; import java.awt.*;
import java.util.Arrays; import java.util.Arrays;
@@ -92,33 +92,36 @@ public final class PathRenderer implements IRenderer {
// Render the current path, if there is one // Render the current path, if there is one
if (current != null && current.getPath() != null) { if (current != null && current.getPath() != null) {
int renderBegin = Math.max(current.getPosition() - 3, 0); int renderBegin = Math.max(current.getPosition() - 3, 0);
drawPath(current.getPath(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20); drawPath(current.getPath().positions(), renderBegin, settings.colorCurrentPath.value, settings.fadePath.value, 10, 20);
} }
if (next != null && next.getPath() != null) { if (next != null && next.getPath() != null) {
drawPath(next.getPath(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20); drawPath(next.getPath().positions(), 0, settings.colorNextPath.value, settings.fadePath.value, 10, 20);
} }
// If there is a path calculation currently running, render the path calculation process // If there is a path calculation currently running, render the path calculation process
behavior.getInProgress().ifPresent(currentlyRunning -> { behavior.getInProgress().ifPresent(currentlyRunning -> {
currentlyRunning.bestPathSoFar().ifPresent(p -> { currentlyRunning.bestPathSoFar().ifPresent(p -> {
drawPath(p, 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20); drawPath(p.positions(), 0, settings.colorBestPathSoFar.value, settings.fadePath.value, 10, 20);
}); });
currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> { currentlyRunning.pathToMostRecentNodeConsidered().ifPresent(mr -> {
drawPath(mr, 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20); drawPath(mr.positions(), 0, settings.colorMostRecentConsidered.value, settings.fadePath.value, 10, 20);
drawManySelectionBoxes(ctx.player(), Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value); drawManySelectionBoxes(ctx.player(), Collections.singletonList(mr.getDest()), settings.colorMostRecentConsidered.value);
}); });
}); });
} }
private static void drawPath(IPath path, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) { public static void drawPath(List<BetterBlockPos> positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0) {
drawPath(positions, startIndex, color, fadeOut, fadeStart0, fadeEnd0, 0.5D);
}
public static void drawPath(List<BetterBlockPos> positions, int startIndex, Color color, boolean fadeOut, int fadeStart0, int fadeEnd0, double offset) {
IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value); IRenderer.startLines(color, settings.pathRenderLineWidthPixels.value, settings.renderPathIgnoreDepth.value);
int fadeStart = fadeStart0 + startIndex; int fadeStart = fadeStart0 + startIndex;
int fadeEnd = fadeEnd0 + startIndex; int fadeEnd = fadeEnd0 + startIndex;
List<BetterBlockPos> positions = path.positions();
for (int i = startIndex, next; i < positions.size() - 1; i = next) { for (int i = startIndex, next; i < positions.size() - 1; i = next) {
BetterBlockPos start = positions.get(i); BetterBlockPos start = positions.get(i);
BetterBlockPos end = positions.get(next = i + 1); BetterBlockPos end = positions.get(next = i + 1);
@@ -127,12 +130,12 @@ public final class PathRenderer implements IRenderer {
int dirY = end.y - start.y; int dirY = end.y - start.y;
int dirZ = end.z - start.z; int dirZ = end.z - start.z;
while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) && /*while (next + 1 < positions.size() && (!fadeOut || next + 1 < fadeStart) &&
(dirX == positions.get(next + 1).x - end.x && (dirX == positions.get(next + 1).x - end.x &&
dirY == positions.get(next + 1).y - end.y && dirY == positions.get(next + 1).y - end.y &&
dirZ == positions.get(next + 1).z - end.z)) { dirZ == positions.get(next + 1).z - end.z)) {
end = positions.get(++next); end = positions.get(++next);
} }*/
if (fadeOut) { if (fadeOut) {
float alpha; float alpha;
@@ -149,30 +152,31 @@ public final class PathRenderer implements IRenderer {
IRenderer.glColor(color, alpha); IRenderer.glColor(color, alpha);
} }
emitLine(start.x, start.y, start.z, end.x, end.y, end.z); emitPathLine(start.x, start.y, start.z, end.x, end.y, end.z, offset);
} }
IRenderer.endLines(settings.renderPathIgnoreDepth.value); IRenderer.endLines(settings.renderPathIgnoreDepth.value);
} }
private static void emitLine(double x1, double y1, double z1, double x2, double y2, double z2) { private static void emitPathLine(double x1, double y1, double z1, double x2, double y2, double z2, double offset) {
final double extraOffset = offset + 0.03D;
double vpX = renderManager.viewerPosX; double vpX = renderManager.viewerPosX;
double vpY = renderManager.viewerPosY; double vpY = renderManager.viewerPosY;
double vpZ = renderManager.viewerPosZ; double vpZ = renderManager.viewerPosZ;
boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value; boolean renderPathAsFrickinThingy = !settings.renderPathAsLine.value;
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x1 + offset - vpX, y1 + offset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x2 + offset - vpX, y2 + offset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
if (renderPathAsFrickinThingy) { if (renderPathAsFrickinThingy) {
buffer.pos(x2 + 0.5D - vpX, y2 + 0.5D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x2 + offset - vpX, y2 + offset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x2 + offset - vpX, y2 + extraOffset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
buffer.pos(x2 + 0.5D - vpX, y2 + 0.53D - vpY, z2 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x2 + offset - vpX, y2 + extraOffset - vpY, z2 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x1 + offset - vpX, y1 + extraOffset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
buffer.pos(x1 + 0.5D - vpX, y1 + 0.53D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x1 + offset - vpX, y1 + extraOffset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
buffer.pos(x1 + 0.5D - vpX, y1 + 0.5D - vpY, z1 + 0.5D - vpZ).color(color[0], color[1], color[2], color[3]).endVertex(); buffer.pos(x1 + offset - vpX, y1 + offset - vpY, z1 + offset - vpZ).color(color[0], color[1], color[2], color[3]).endVertex();
} }
} }
@@ -198,7 +202,7 @@ public final class PathRenderer implements IRenderer {
IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value); IRenderer.endLines(settings.renderSelectionBoxesIgnoreDepth.value);
} }
private static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) { public static void drawGoal(Entity player, Goal goal, float partialTicks, Color color) {
drawGoal(player, goal, partialTicks, color, true); drawGoal(player, goal, partialTicks, color, true);
} }

View File

@@ -99,6 +99,8 @@ public class PathingControlManager implements IPathingControlManager {
// get rid of the in progress stuff from the last process // get rid of the in progress stuff from the last process
} }
switch (command.commandType) { switch (command.commandType) {
case SET_GOAL_AND_PAUSE:
p.secretInternalSetGoalAndPath(command);
case REQUEST_PAUSE: case REQUEST_PAUSE:
p.requestPause(); p.requestPause();
break; break;
@@ -119,7 +121,7 @@ public class PathingControlManager implements IPathingControlManager {
case SET_GOAL_AND_PATH: case SET_GOAL_AND_PATH:
// now this i can do // now this i can do
if (command.goal != null) { if (command.goal != null) {
baritone.getPathingBehavior().secretInternalSetGoalAndPath(command); p.secretInternalSetGoalAndPath(command);
} }
break; break;
default: default:

View File

@@ -0,0 +1,25 @@
/*
* 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.utils.accessor;
import net.minecraft.entity.EntityLivingBase;
public interface IEntityFireworkRocket {
EntityLivingBase getBoostedEntity();
}