Compare commits

...

270 Commits

Author SHA1 Message Date
Leijurv 060741bfdc fixes 2018-11-24 19:17:30 -08:00
Leijurv 2a21a1ca18 simplify 2018-11-24 12:53:09 -08:00
Leijurv 8ece179912 recalculate on allocation size change 2018-11-24 11:32:23 -08:00
Leijurv c79f40a5f1 tenor comms integration, and priority allocation caching 2018-11-24 11:01:23 -08:00
Leijurv 3b7e1adf24 add default lol 2018-11-23 19:24:14 -08:00
Leijurv 01bec5d8f9 computation requests on the tenor side 2018-11-23 19:06:35 -08:00
Leijurv 82c64d4d06 Merge branch 'comms' into tenor 2018-11-23 16:35:35 -08:00
Leijurv 11e44acf65 helper to handle pending msgs 2018-11-23 16:35:03 -08:00
Leijurv c73751ef98 Merge branch 'comms' into tenor 2018-11-23 16:10:06 -08:00
Leijurv 16fec4a1a0 buffered connection creation helper 2018-11-23 16:09:59 -08:00
Leijurv 81c95a2d43 fix tenor build after comms refactor 2018-11-23 13:36:06 -08:00
Leijurv 07970f803f Merge branch 'calc-request' into tenor 2018-11-23 13:35:03 -08:00
Leijurv 5ae4f23886 Merge branch 'comms' into calc-request 2018-11-23 13:34:48 -08:00
Leijurv f222980a1a move comms to cabaletta.comms 2018-11-23 13:32:18 -08:00
Leijurv 7f1fb2a8fe Merge branch 'calc-request' into tenor 2018-11-23 13:17:42 -08:00
Leijurv c57f65f832 complete new segmented calculation system 2018-11-23 13:17:03 -08:00
Leijurv 85a6ec022e Merge branch 'comms' into calc-request 2018-11-23 13:13:35 -08:00
Leijurv c1032da828 Merge branch 'master' into comms 2018-11-23 13:12:38 -08:00
Leijurv 9c5274dde4 runnable conversion 2018-11-23 13:12:18 -08:00
Leijurv 002c678b4a Merge branch 'master' into segment-calculation 2018-11-23 13:09:57 -08:00
Leijurv 806c2a4af1 tenor dependency on comms 2018-11-23 13:08:38 -08:00
Leijurv 038533c33f explain documentation more 2018-11-23 15:06:09 -06:00
Leijurv 50d4b5b4ed unneeded 2018-11-23 15:06:09 -06:00
Leijurv 7632d667c9 add a secondary failure cutoff 2018-11-23 15:06:09 -06:00
Leijurv c5ecb9bb9b Merge branch 'calc-request' into tenor 2018-11-23 12:57:08 -08:00
Leijurv e0d894d296 computation request and response 2018-11-23 12:09:35 -08:00
Leijurv 27c818f873 Merge branch 'comms' into calc-request 2018-11-23 11:49:49 -08:00
Leijurv fdd758bc90 too much log spam 2018-11-23 11:48:01 -08:00
Leijurv 3a2620192b too much log spam 2018-11-23 11:46:47 -08:00
Leijurv c423d5f575 report path start position 2018-11-23 11:35:13 -08:00
Leijurv 5aa78cd478 crucial performance optimization 2018-11-23 11:22:49 -08:00
Leijurv 84cd4b1acb unused 2018-11-23 10:58:23 -08:00
Leijurv b705279153 consistency 2018-11-23 10:55:02 -08:00
Leijurv d854750ee8 improve accuracy of GoalGetToBlock heuristic 2018-11-23 10:52:56 -08:00
Leijurv 81a9b71429 Merge branch 'segment-calculation' into comms 2018-11-23 10:36:56 -08:00
Leijurv 4502adda28 segmented path calculator 2018-11-23 10:36:06 -08:00
Leijurv a98c5d7d99 my house 2018-11-23 10:25:02 -08:00
Leijurv c81a00268a Merge branch 'master' into segment-calculation 2018-11-23 10:21:45 -08:00
Leijurv dd47e20070 remove unneeded 2018-11-23 10:20:48 -08:00
Leijurv 81ecc209d3 synchronize partial reads and writes to a socket 2018-11-23 10:09:13 -08:00
Leijurv f05613147e Merge branch 'master' into failure-cutoff 2018-11-23 09:59:23 -08:00
Leijurv 6ed8d617cd improve path checks, and add a overlap splice option 2018-11-23 09:31:25 -08:00
Leijurv b228f4c6fb remove extraneous checks in bsi 2018-11-23 09:03:51 -08:00
Leijurv 70f8d1d4ae fix bsi creation on wrong thread, cache chunks, fixes #210 2018-11-23 09:00:52 -08:00
Leijurv 0d7131413a prevent double jumping 2018-11-23 07:55:59 -08:00
Leijurv b5a4e65fbf unable to start a parkour jump from stairs 2018-11-23 07:47:28 -08:00
Leijurv 7c51106d27 unneeded 2018-11-22 10:08:55 -08:00
Leijurv 1e9786d5b9 add a secondary failure cutoff 2018-11-22 09:39:54 -08:00
Leijurv 4b8c85f8a6 whoops 2018-11-22 08:57:27 -08:00
Leijurv aed8dae175 hehe 2018-11-21 18:11:58 -08:00
Leijurv 8db26af36c tweak sneak range for ncp compatibility 2018-11-21 11:02:12 -08:00
Leijurv cfa874982c fix a bunch of stuff in pillar, fixes #266 2018-11-21 11:00:46 -08:00
Leijurv 2a674cb869 don't sprint straight into danger 2018-11-20 18:58:47 -08:00
Leijurv fb971301a4 fix getting permanently stuck on sideways fence gates in our way 2018-11-20 16:32:55 -08:00
Leijurv 3bb16de67e greatly increase mining visual scan range 2018-11-20 16:32:44 -08:00
Leijurv 033da7e737 fix coefficient 2018-11-20 13:22:33 -08:00
Leijurv 14650f93c5 walk into lava less 2018-11-20 08:19:27 -08:00
Leijurv e5184efdaa fix cached path loop 2018-11-20 08:00:52 -08:00
Leijurv d95a72f2cc correct wording 2018-11-19 17:14:54 -08:00
Leijurv 0dc67593bb lots more status 2018-11-18 21:56:46 -08:00
Leijurv 2e180e81ed Merge branch 'comms' of github.com:cabaletta/baritone into comms 2018-11-18 21:42:04 -08:00
Leijurv 0b11057449 Merge branch 'master' into comms 2018-11-18 21:41:50 -08:00
Leijurv 16e3fd9305 IPathingControlManager 2018-11-18 21:41:42 -08:00
Brady 186652a8d8 Protocol lol 2018-11-18 19:52:11 -06:00
Leijurv 18d8cfb6de Merge branch 'master' into comms 2018-11-18 17:39:26 -08:00
Leijurv 4fb6c71174 lol 2018-11-18 17:32:16 -08:00
Leijurv f99befd307 oh thats important 2018-11-18 12:04:37 -08:00
Leijurv 9ad35dbf28 remove the useless stuff 2018-11-18 11:35:54 -08:00
Leijurv dfb49179c5 not a handler lol 2018-11-18 11:27:53 -08:00
Brady 3c913a7b85 Fix jar export 2018-11-18 13:27:25 -06:00
Leijurv f01cf669e8 wtf 2018-11-18 11:06:40 -08:00
Leijurv 2d87033f49 f 2018-11-18 11:06:11 -08:00
Leijurv f014e42aa4 initial comms 2018-11-18 11:01:46 -08:00
Leijurv 12bbd57a24 standalone build shouldn't keep ExampleBaritoneControl 2018-11-17 16:09:15 -08:00
Brady 46de72e28c Comms Sourceset 2018-11-17 18:07:16 -06:00
Brady 689dc74330 Whoops 2018-11-17 11:41:16 -06:00
Brady 6caae889b7 Fix AStarPathFinder Optional usage that's icky 2018-11-17 11:26:46 -06:00
Brady ce0e8b4cd1 Clean up some bad Optional practices 2018-11-17 11:18:55 -06:00
Leijurv 737c632227 path creation no longer throws this 2018-11-16 16:28:20 -08:00
Leijurv 04e87c9810 cleaner 2018-11-15 16:03:20 -08:00
Leijurv 57c0613843 rename 2018-11-14 16:39:04 -08:00
Leijurv f5d0143b09 im dumb 2018-11-14 14:37:41 -08:00
Brady 237f1846d3 Remove Baritone casts 2018-11-14 16:30:20 -06:00
Leijurv f6dee1ecb7 add todo 2018-11-14 14:29:33 -08:00
Leijurv f808fc9802 general cleanup 2018-11-14 14:27:30 -08:00
Leijurv 8385bc35ed wow thats a rare bug 2018-11-14 14:26:35 -08:00
Leijurv 80d6d7fd58 simplify 2018-11-14 14:22:14 -08:00
Leijurv b56cdcda52 remove that toxic cloud 2018-11-14 14:19:24 -08:00
Leijurv ea81cd76ca sigh 2018-11-14 14:00:56 -08:00
Leijurv c3a3670785 unused imports 2018-11-14 13:57:37 -08:00
Leijurv e4045e1343 and another 2018-11-14 13:48:45 -08:00
Leijurv 5a52cea415 epic 2018-11-14 13:48:09 -08:00
Leijurv 933b295c40 context objectMouseOver 2018-11-14 13:46:16 -08:00
Leijurv ce6ec00a89 get rid of the remaining references to mc.world 2018-11-14 13:24:44 -08:00
Leijurv b53f3925a4 forgot to add these files lol 2018-11-13 22:28:12 -08:00
Leijurv e93fd596ff customized TickEvent Type based on player context status 2018-11-13 22:17:18 -08:00
Leijurv 57b60c734b fixes to BlockBreakHelper 2018-11-13 22:15:01 -08:00
Leijurv c74ccaafbf remove Baritone.INSTANCE 2018-11-13 21:34:11 -08:00
Leijurv f6891feb64 removed all references to Baritone.INSTANCE 2018-11-13 21:33:14 -08:00
Leijurv 2675852dbe canc 2018-11-13 20:11:51 -08:00
Brady 0302c6f14b Fix really really bad error mega critical 2018-11-13 21:57:22 -06:00
Leijurv a0dd43244c immense iq 2018-11-13 19:54:24 -08:00
Brady 3ccb0c74c6 Remove timestamps from since annotations 2018-11-13 21:53:27 -06:00
Brady f9270a7ed0 my house 2018-11-13 21:47:40 -06:00
Brady d79d56c2f9 Expose all possible Baritone instances 2018-11-13 21:45:26 -06:00
Leijurv a8f09a7fe9 Merge pull request #259 from cabaletta/currentlyticking-solution
currentlyTicking Solution
2018-11-13 15:11:38 -08:00
Brady 94bf8d4bbd More review things 2018-11-13 16:53:13 -06:00
Brady 5e2f40a322 Fix some things mentioned by @Leijurv 2018-11-13 16:33:45 -06:00
Brady 17161fd576 Resolve merge conflicts 2018-11-13 15:29:02 -06:00
Brady d3db551cc9 Awesome 2018-11-13 15:14:29 -06:00
Leijurv 72058c792a fix toxic clouds in legit mine 2018-11-13 12:20:27 -08:00
Brady ef5e3ab06e pwnage 2018-11-13 13:39:11 -06:00
Brady 71e7f0a04c Fix GetToBlockProcess rescan 2018-11-13 11:59:02 -06:00
Brady bae34e5b80 Initial meme
Still need to fix MovementHelper LUL
2018-11-13 11:50:29 -06:00
Leijurv 1ab3e61984 reformatted 2018-11-12 21:01:40 -08:00
Leijurv e81b6d4d96 fought 2018-11-12 16:39:58 -08:00
Leijurv 87a44e4093 Merge branch 'master' into tenor 2018-11-12 16:16:03 -08:00
Brady d082d25253 Tenor Sourceset 2018-11-12 18:09:57 -06:00
Leijurv 83f14b10bb whoa codacy suggested something actually helpful 2018-11-12 15:45:35 -08:00
Leijurv 7fecd1a5dd tweak 2018-11-12 14:43:39 -08:00
Leijurv 0ce4107d56 "fix" it 2018-11-11 18:23:18 -08:00
Leijurv 66769365d0 much better 2018-11-11 17:59:13 -08:00
Leijurv e3cb164723 fix blockstateinterface 2018-11-11 17:36:54 -08:00
Brady 903b1b16a4 static 2018-11-11 17:45:01 -06:00
Brady e81d0a0b1b Small brain 2018-11-11 17:12:18 -06:00
Brady 51243f0981 Some comments 2018-11-11 16:22:00 -06:00
Brady fad5a6deac lol 2018-11-11 15:46:07 -06:00
Leijurv 355443e440 forgot one 2018-11-11 12:48:53 -08:00
Leijurv 45e4239b26 context specific blockstateinterface lookups. also toxic 2018-11-11 12:35:22 -08:00
Brady a83074e773 Map Input to state in InputOverrideHandler 2018-11-11 14:20:38 -06:00
Leijurv f854d886d1 fix water bucket being placed one tick too early 2018-11-10 11:26:52 -08:00
Leijurv 73d4e9bbb9 another day another static world reference gone 2018-11-10 09:37:23 -08:00
Leijurv 232644feb0 these are cool and should default on 2018-11-10 09:25:44 -08:00
Brady 1c80950a70 Add note to MixinBlockPos
I looked at this Mixin for a second and thought wtf why did I make this and then remembered why, so it's probably important to let anybody else that looks at it know why.
2018-11-09 22:32:40 -06:00
Leijurv 0bd46e88a5 branch compatibility message 2018-11-09 20:22:24 -08:00
Leijurv b054e9dbe8 toxic cloud to get around two references to mc.player.dimension 2018-11-09 19:25:10 -08:00
Leijurv 3ddf6b2335 player and player controller toxic cloud 2018-11-09 19:12:36 -08:00
Leijurv 1a1686b7c3 fix yet more player references 2018-11-09 18:55:53 -08:00
Leijurv dd08b2c825 no more references to player() from pathing thread 2018-11-09 17:21:02 -08:00
Leijurv a2a60e9847 misc cleanup 2018-11-09 16:55:31 -08:00
Leijurv 13505a052f wait a tick until objectMouseOver matches, fixes #254 2018-11-09 15:59:08 -08:00
Leijurv f2dcdda9b3 revamp follow and fix some bugs in mine 2018-11-09 14:49:25 -08:00
Leijurv 1cf6768e27 misc 2018-11-09 12:59:46 -08:00
Leijurv dc6389c46f comment 2018-11-08 14:58:18 -08:00
Leijurv 7dc89b0190 single runaway goal object, allows splicing better 2018-11-07 17:27:57 -08:00
Leijurv 5b395ce3da should be in the synchronized block 2018-11-07 17:23:36 -08:00
Leijurv 40da7b3734 don't fail silently in the future 2018-11-07 17:18:43 -08:00
Leijurv 842e50adb9 path cleanup 2018-11-07 17:16:34 -08:00
Leijurv 96da078219 cutoff path up until movement failure, don't throw exception and fail entire path 2018-11-07 14:37:23 -08:00
Leijurv 4a1951b027 many fixes 2018-11-07 14:09:23 -08:00
Leijurv 83348e6b3c rearrange readme 2018-11-06 20:12:02 -08:00
Leijurv a1778f401f tweak a bit 2018-11-06 11:20:39 -08:00
Leijurv 9c93d3a474 splice next into current if no backtrack, fixes #122, fixes #249 2018-11-06 11:18:13 -08:00
Leijurv cbc8a6d45b Merge branch 'processes' 2018-11-06 08:43:57 -08:00
Leijurv 382c7e7888 reformat, optimize imports 2018-11-06 08:22:19 -08:00
Leijurv ae200a56b0 CaPiTaLiZe 2018-11-06 08:19:26 -08:00
Brady c50af5acfd A couple minor cleanups 2018-11-06 08:02:08 -06:00
Leijurv 527691a2ec fix blockbreakhelper toxic cloud in movement 2018-11-05 20:37:54 -08:00
Leijurv a182c22d36 this can be moved i think 2018-11-05 20:05:47 -08:00
Leijurv aac0d623fa why not just... 2018-11-05 20:02:27 -08:00
Leijurv 604ef2bb64 misc cleanup 2018-11-05 20:01:46 -08:00
Leijurv 6ca7f47bf9 +0.5y not helpful 2018-11-05 19:31:05 -08:00
Leijurv a1b71219cb make sure to pick up dropped items while mining, fixes #170 2018-11-05 18:31:59 -08:00
Leijurv d59c7cb7a8 temporarily disable cached region ram pruning 2018-11-05 17:30:45 -08:00
Leijurv d121ca182f spammy 2018-11-05 17:26:52 -08:00
Leijurv 2aee91be10 fix it up a bit 2018-11-05 16:46:24 -08:00
Brady 99da815f49 Massive brain 2018-11-05 18:40:25 -06:00
Brady ebd3ce42d0 whoops 2018-11-05 18:28:29 -06:00
Brady fdee1b9453 More javadocs 2018-11-05 18:11:16 -06:00
Brady 472e89239c IBaritoneProcess javadoc update 2018-11-05 18:07:47 -06:00
Leijurv 5692e79e02 more docs 2018-11-05 15:25:19 -08:00
Leijurv 52246e41c8 appease codacy 2018-11-05 15:16:23 -08:00
Leijurv 2da3222115 fix 2018-11-05 14:55:13 -08:00
Leijurv 4d0bfce712 make InputOverrideHandler a Behavior 2018-11-05 14:47:40 -08:00
Leijurv cb153e039b not used and not publicly exposed 2018-11-05 14:43:57 -08:00
Leijurv 8aa5a6756a add to api 2018-11-05 14:41:17 -08:00
Leijurv 23286dd8b8 disallow null PathingCommandType 2018-11-05 14:38:32 -08:00
Leijurv 30408384c6 fix 2018-11-05 14:37:05 -08:00
Leijurv e11e3dfd86 explain 2018-11-05 14:22:30 -08:00
Leijurv 2c39cd06ed cleanup 2018-11-05 14:19:50 -08:00
Brady 75a224cef1 Partially revert README update 2018-11-05 16:06:23 -06:00
Brady 0373f1875f Meme 2018-11-05 16:05:45 -06:00
Leijurv fffd016008 Merge branch 'master' into processes 2018-11-05 13:51:41 -08:00
Leijurv f286c400a3 when parkouring from soul sand, the maximum gap should be 1, fixes #247 2018-11-05 13:47:06 -08:00
Brady c0e0f8dc2a Fix last commit lol 2018-11-05 13:53:26 -06:00
Brady ffb044ffc6 Replace RotationMoveEvent Inject with Redirect 2018-11-05 13:47:55 -06:00
Brady 1c4f029bf4 Update README.md 2018-11-05 12:47:17 -06:00
Leijurv 6812d2ba7d simplify readme 2018-11-04 22:22:11 -08:00
Leijurv c0b5d60715 fix 2018-11-04 22:17:49 -08:00
0x22 c814874cb6 Updated mappings to stable_39 2018-11-04 20:21:24 -06:00
Leijurv cd3aef47a5 that already does that 2018-11-04 10:30:46 -08:00
Leijurv 338fdb509a it works 2018-11-04 10:29:22 -08:00
Leijurv 660efe5e16 pathing processes wip 2018-11-03 22:12:51 -07:00
Leijurv 58a2965fea Merge branch 'impact4.4-compat' 2018-11-03 20:25:19 -07:00
Leijurv c614d7ec6a fix stupid minebehavior bug 2018-11-03 20:25:09 -07:00
Leijurv e017238aca unneeded 2018-11-03 19:41:40 -07:00
Leijurv c37a5ba956 revamp readme 2018-11-02 16:23:57 -07:00
Leijurv da5969c2fd shouldnt have taken this long to figure that out 2018-11-01 20:58:48 -07:00
Leijurv 990107a1fa simplify 2018-11-01 20:27:34 -07:00
Leijurv 42eb86b624 useless check? 2018-11-01 15:41:53 -07:00
Leijurv b65a199e54 move all checks from BlockStateInterface to MovementHelper 2018-11-01 15:36:32 -07:00
Leijurv 88e3bcdf63 what 2018-11-01 15:32:58 -07:00
Leijurv 0fbfa32e6b fix exception in pathfinder 2018-11-01 15:30:33 -07:00
Leijurv 20405716bc fix impact 4.4 compatibility and add help message 2018-11-01 14:07:08 -07:00
Leijurv 8da7406e8f green 2018-10-31 20:37:18 -07:00
Leijurv 890dbec852 bunch of stuff 2018-10-31 20:04:32 -07:00
Leijurv 24bb0c541c split up singular and quantized single parent priority allocators 2018-10-31 13:30:37 -07:00
Leijurv e7a09c34ea cleanup and combine single parent priority allocation 2018-10-31 13:19:48 -07:00
Leijurv 97fd3df8f7 minecraft version badge 2018-10-30 19:06:42 -07:00
Brady 9642950b54 oppa 2018-10-30 20:30:44 -05:00
Brady f76736a378 Minecraft imports should only be in minecraft task implementations 2018-10-30 20:05:35 -05:00
Leijurv 91c6baead1 dont allocate parent tasks with empty priority 2018-10-30 17:42:58 -07:00
Leijurv e81b01a8f3 fix priority allocation method 2018-10-30 17:18:08 -07:00
Brady f2a45b9eeb Streams are nice 2018-10-30 18:21:09 -05:00
Leijurv 5e2ccdac08 i love generics 2018-10-30 15:44:52 -07:00
Leijurv 473f872d2f you are no longer being poisoned by a toxic cloud 2018-10-30 15:31:02 -07:00
Brady 3d03f15749 Fix bad interface naming 2018-10-30 17:30:03 -05:00
Leijurv 15e91c7c7c quite cool that this can now be done 2018-10-30 15:28:04 -07:00
Leijurv 5089c62ada generics LOL 2018-10-30 15:23:14 -07:00
Leijurv 7c69a188f6 pog 2018-10-30 15:07:16 -07:00
Leijurv ef6b36b2cc wew lad 2018-10-30 15:05:17 -07:00
Brady f2f806669c Generify pt 1 2018-10-30 15:51:19 -05:00
Leijurv c887b27df9 in too deep 2018-10-30 11:51:49 -07:00
Leijurv e1bb8fd570 here we go LOL 2018-10-29 23:15:08 -07:00
Leijurv b9b33b5351 move calculation context construction to main thread 2018-10-29 18:58:59 -07:00
Brady 19ecb1bbb3 Merge LocationTrackingBehavior into MemoryBehavior
Fixes #242
2018-10-29 16:43:03 -05:00
Leijurv f6043f4ac6 changed wording 2018-10-28 16:44:56 -07:00
Brady ed1941abdb Fix desynchronized allowFlying state 2018-10-28 18:38:23 -05:00
Leijurv 24d24728dc intellij be like 2018-10-28 16:05:08 -07:00
Leijurv 77db4cd19f codacy 2018-10-28 15:24:52 -07:00
Leijurv adbb03e5cb unused lol 2018-10-28 15:24:23 -07:00
Leijurv f0226f1ea7 brady doesn't know how to do imports 2018-10-28 15:23:34 -07:00
Leijurv be5df2677b finally add shulkers lol 2018-10-28 13:55:03 -07:00
Brady 3d4a856bb2 Remove unnecessary casts 2018-10-27 23:21:30 -05:00
Leijurv 1b1233d26a only one singleton 2018-10-27 18:45:17 -07:00
Leijurv c4b0e0a810 codady submission complete 2018-10-27 16:18:03 -07:00
Leijurv 1dee8ef355 completely submitting to codacy 2018-10-27 14:41:25 -07:00
Leijurv 8cee173f92 appease codacy some more 2018-10-27 14:16:34 -07:00
Brady 19e0e6d962 Feed codacy 2018-10-27 14:38:10 -05:00
Leijurv ef8fd70475 add some more badges for no reason lol 2018-10-27 09:25:53 -07:00
Leijurv 6df05f4b7f add link to my vid 2018-10-27 08:37:30 -07:00
Brady 4e1491a0cc Rename xrayFor to searchWorld 2018-10-26 13:30:16 -05:00
leijurv 55091154c4 start on legitMine 2018-10-25 21:22:00 -07:00
leijurv a0b1cb2993 preliminary refactoring 2018-10-25 20:09:06 -07:00
Leijurv 7617081637 no longer needed 2018-10-24 23:22:19 -07:00
Leijurv 96e7f37799 add link to adovin's video 2018-10-23 20:41:35 -07:00
Leijurv a0bf22de86 Merge pull request #233 from ave4224/toolkit
Toolkit fixes
2018-10-22 21:43:42 -07:00
ave4224 9a1aecc002 tool set, fixes #227 2018-10-23 00:41:59 -04:00
Brady ad941fcbb2 Clarify anti nudge 2018-10-22 18:02:18 -05:00
Leijurv e5ca30dc26 forgot that one 2018-10-22 14:04:19 -07:00
Leijurv a23eadf5cf Merge pull request #235 from 0-x-2-2/patch-1
Fixed serious issue.
2018-10-22 12:46:17 -07:00
Leijurv 82417f4f85 comment to explain weird thing 2018-10-22 12:42:08 -07:00
0x22 af788133c2 Fixed serious issue.
Determinizer description was incorrect.
2018-10-22 15:42:05 -04:00
Leijurv a6dc156a79 bump version to match build gradle 2018-10-21 14:24:23 -07:00
Leijurv 25bebdc172 leftClickCounter shadow appears to be unneeded 2018-10-20 20:33:49 -07:00
Leijurv b55d96169f update some documentation 2018-10-19 21:15:37 -07:00
Leijurv 1a809fa7a3 dispatch path events from main thread instead of calculation thread 2018-10-18 15:04:40 -07:00
Leijurv 313a5fddbe add release badge 2018-10-18 14:36:14 -07:00
Leijurv 732d806820 allow cutting onto next path one movement earlier 2018-10-17 12:16:03 -07:00
Leijurv 11ed8a2f21 rearrange fields and constructors 2018-10-16 20:05:18 -07:00
Leijurv 3aa8f51015 print shasums on build 2018-10-16 17:00:37 -07:00
Leijurv 85b038dada v1.0.0-hotfix-2 2018-10-16 16:03:51 -07:00
Leijurv dd25527a62 pillar fixes for ncp 2018-10-16 14:21:27 -07:00
Leijurv ac372bc6fc v1.0.0-hotfix-1 2018-10-16 11:32:44 -07:00
Leijurv 63ce4fe0bd don't crash on empty region 2018-10-16 11:32:27 -07:00
Leijurv 398169f68e special case for damn daniel 2018-10-16 11:13:35 -07:00
Leijurv 46a24af373 cancel chat event 2018-10-16 11:13:08 -07:00
Leijurv 0cd9bb658f keep ExampleBaritoneControl 2018-10-16 11:04:49 -07:00
Leijurv b0678fd259 better control 2018-10-16 10:47:44 -07:00
Leijurv 9cb4a1779e fix placement rotation during parkour 2018-10-15 20:37:10 -07:00
188 changed files with 7597 additions and 2641 deletions
+4 -4
View File
@@ -15,10 +15,10 @@ RUN apt install -qq --force-yes mesa-utils libgl1-mesa-glx libxcursor1 libxrandr
COPY . /code
# this .deb is specially patched to support lwjgl
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i /code/scripts/xvfb_1.16.4-1_amd64.deb
WORKDIR /code
# this .deb is specially patched to support lwjgl
# source: https://github.com/tectonicus/tectonicus/issues/60#issuecomment-154239173
RUN dpkg -i scripts/xvfb_1.16.4-1_amd64.deb
RUN ./gradlew build
+4 -6
View File
@@ -3,6 +3,8 @@ Impact 4.4 has Baritone included.
These instructions apply to Impact 4.3 (and potentially other hacked clients).
To run Baritone on Vanilla, just follow the instructions in the README (it's `./gradlew runClient`).
## An Introduction
There are some basic steps to getting Baritone setup with Impact.
@@ -12,7 +14,7 @@ There are some basic steps to getting Baritone setup with Impact.
- How to use Baritone
## Acquiring a build of Baritone
There are 3 methods of acquiring a build of Baritone (While it is still in development)
There are two methods of acquiring a build of Baritone
### Official Release (Not always up to date)
https://github.com/cabaletta/baritone/releases
@@ -33,10 +35,6 @@ command line
- Mac/Linux: ``./gradlew build``
- The build should be exported into ``/build/libs/baritone-X.Y.Z.jar``
### Cutting Edge Release
If you want to trust @Plutie#9079, you can download an automatically generated build of the latest commit
from his Jenkins server, found <a href="https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/">here</a>.
## Placing Baritone in the libraries directory
``/libraries`` is a neat directory in your <a href="https://minecraft.gamepedia.com/.minecraft">Minecraft Installation Directory</a>
that contains all of the dependencies that are required from the game and some mods. This is where we will be
@@ -83,7 +81,7 @@ The final step is "registering" the Baritone library with Impact, so that it loa
"name": "cabaletta:baritone:X.Y.Z"
},
{
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.1",
"name": "com.github.ImpactDevelopment:SimpleTweaker:1.2",
"url": "https://impactdevelopment.github.io/maven/"
},
```
+36
View File
@@ -0,0 +1,36 @@
# Baritone Comms Protocol
## Data Types
| Name | Descriptor | Java |
|------------|-----------------------------------------------------------|-----------------------------|
| coordinate | Big endian 8-byte floating point number | [readDouble], [writeDouble] |
| string | unsigned short (length) followed by UTF-8 character bytes | [readUTF], [writeUTF] |
## Inbound
Allows the server to execute a chat command on behalf of the client's player
### Chat
| Name | Type |
|---------|--------|
| Message | string |
## Outbound
Update the player position with the server
### Status
| Name | Type |
|------|------------|
| X | coordinate |
| Y | coordinate |
| Z | coordinate |
<!-- External links -->
[readUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readUTF()
[writeUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeUTF(java.lang.String)
[readDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readDouble()
[writeDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeDouble(double)
+22 -19
View File
@@ -1,15 +1,19 @@
# Baritone
[![Build Status](https://travis-ci.com/cabaletta/baritone.svg?branch=master)](https://travis-ci.com/cabaletta/baritone)
[![Release](https://img.shields.io/github/release/cabaletta/baritone.svg)](https://github.com/cabaletta/baritone/releases)
[![License](https://img.shields.io/github/license/cabaletta/baritone.svg)](LICENSE)
[![Codacy Badge](https://api.codacy.com/project/badge/Grade/a73d037823b64a5faf597a18d71e3400)](https://www.codacy.com/app/leijurv/baritone?utm_source=github.com&amp;utm_medium=referral&amp;utm_content=cabaletta/baritone&amp;utm_campaign=Badge_Grade)
[![HitCount](http://hits.dwyl.com/cabaletta/baritone.svg)](http://hits.dwyl.com/cabaletta/baritone)
[![contributions welcome](https://img.shields.io/badge/contributions-welcome-brightgreen.svg?style=flat)](https://github.com/cabaletta/baritone/issues)
[![Minecraft](https://img.shields.io/badge/MC-1.12.2-green.svg)](https://minecraft.gamepedia.com/1.12.2)
<!-- Unofficial Jenkins: [![Build Status](https://plutiejenkins.leijurv.com/job/baritone/badge/icon)](https://plutiejenkins.leijurv.com/job/baritone/lastSuccessfulBuild/) -->
A Minecraft pathfinder bot.
A Minecraft pathfinder bot. This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4. There's a [showcase video](https://www.youtube.com/watch?v=yI8hgW_m6dQ) made by @Adovin#3153 on Baritone's integration into Impact. [Here's](https://www.youtube.com/watch?v=StquF69-_wI) a video I made showing off what it can do.
This project is an updated version of [MineBot](https://github.com/leijurv/MineBot/),
the original version of the bot for Minecraft 1.8, rebuilt for 1.12.2. Baritone focuses on reliability and particularly performance (it's over [29x faster](https://github.com/cabaletta/baritone/pull/180#issuecomment-423822928) than MineBot at calculating paths).
Baritone is the pathfinding system used in [Impact](https://impactdevelopment.github.io/) since 4.4.
Here are some links to help to get started:
- [Features](FEATURES.md)
@@ -20,29 +24,29 @@ There's also some useful information down below
# Setup
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle task `setupDecompWorkspace`
- Run the Gradle task `genIntellijRuns`
- Refresh the Gradle project (or just restart IntelliJ)
- Select the "Minecraft Client" launch config and run
## Command Line
On Mac OSX and Linux, use `./gradlew` instead of `gradlew`.
Running Baritone:
```
$ gradlew run
$ gradlew runClient
```
Setting up for IntelliJ:
Building Baritone:
```
$ gradlew setupDecompWorkspace
$ gradlew --refresh-dependencies
$ gradlew genIntellijRuns
$ gradlew build
```
For example, to replace out Impact 4.4's Baritone build with a customized one, switch to the `impact4.4-compat` branch, build Baritone as above then copy `dist/baritone-api-$VERSION$.jar` into `minecraft/libraries/cabaletta/baritone-api/1.0.0/baritone-api-1.0.0.jar`, replacing the jar that was previously there. You also need to edit `minecraft/versions/1.12.2-Impact_4.4/1.12.2-Impact_4.4.json`, find the line `"name": "cabaletta:baritone-api:1.0.0"`, remove the comma from the end, and entirely remove the line that's immediately after (starts with `"url"`).
## IntelliJ's Gradle UI
- Open the project in IntelliJ as a Gradle project
- Run the Gradle tasks `setupDecompWorkspace` then `genIntellijRuns`
- Refresh the Gradle project (or, to be safe, just restart IntelliJ)
- Select the "Minecraft Client" launch config
- In `Edit Configurations...` you may need to select `baritone_launch` for `Use classpath of module:`.
# Chat control
[Defined Here](src/main/java/baritone/utils/ExampleBaritoneControl.java)
@@ -54,13 +58,12 @@ Quick start example: `thisway 1000` or `goal 70` to set the goal, `path` to actu
BaritoneAPI.getSettings().allowSprint.value = true;
BaritoneAPI.getSettings().pathTimeoutMS.value = 2000L;
BaritoneAPI.getPathingBehavior().setGoal(new GoalXZ(10000, 20000));
BaritoneAPI.getPathingBehavior().path();
BaritoneAPI.getProvider().getPrimaryBaritone().getCustomGoalProcess().setGoalAndPath(new GoalXZ(10000, 20000));
```
# FAQ
## Can I use Baritone as a library in my hacked client?
## Can I use Baritone as a library in my custom utility client?
Sure! (As long as usage is in compliance with the LGPL 3 License)
+13 -3
View File
@@ -16,7 +16,7 @@
*/
group 'baritone'
version '1.0.0'
version '1.0.0-hotfix-2'
buildscript {
repositories {
@@ -51,14 +51,24 @@ compileJava {
}
sourceSets {
comms {}
main {
compileClasspath += comms.compileClasspath + comms.output
}
launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
tenor {
compileClasspath += comms.compileClasspath + comms.output
}
main {
compileClasspath += tenor.compileClasspath + tenor.output
}
}
minecraft {
version = '1.12.2'
mappings = 'snapshot_20180731'
mappings = 'stable_39'
tweakClass = 'baritone.launch.BaritoneTweaker'
runDir = 'run'
@@ -99,7 +109,7 @@ mixin {
}
jar {
from sourceSets.launch.output, sourceSets.api.output
from sourceSets.comms.output, sourceSets.launch.output, sourceSets.api.output
preserveFileTimestamps = false
reproducibleFileOrder = true
}
@@ -34,9 +34,9 @@ import java.util.List;
*/
class BaritoneGradleTask extends DefaultTask {
static final JsonParser PARSER = new JsonParser();
protected static final JsonParser PARSER = new JsonParser();
static final String
protected static final String
PROGUARD_ZIP = "proguard.zip",
PROGUARD_JAR = "proguard.jar",
PROGUARD_CONFIG_TEMPLATE = "scripts/proguard.pro",
@@ -54,10 +54,10 @@ class BaritoneGradleTask extends DefaultTask {
ARTIFACT_API = "%s-api-%s.jar",
ARTIFACT_STANDALONE = "%s-standalone-%s.jar";
String artifactName, artifactVersion;
Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
protected String artifactName, artifactVersion;
protected Path artifactPath, artifactUnoptimizedPath, artifactApiPath, artifactStandalonePath, proguardOut;
void verifyArtifacts() throws Exception {
protected void verifyArtifacts() throws IllegalStateException {
this.artifactName = getProject().getName();
this.artifactVersion = getProject().getVersion().toString();
@@ -69,34 +69,34 @@ class BaritoneGradleTask extends DefaultTask {
this.proguardOut = this.getTemporaryFile(PROGUARD_EXPORT_PATH);
if (!Files.exists(this.artifactPath)) {
throw new Exception("Artifact not found! Run build first!");
throw new IllegalStateException("Artifact not found! Run build first!");
}
}
void write(InputStream stream, Path file) throws Exception {
protected void write(InputStream stream, Path file) throws Exception {
if (Files.exists(file)) {
Files.delete(file);
}
Files.copy(stream, file);
}
String formatVersion(String string) {
protected String formatVersion(String string) {
return String.format(string, this.artifactName, this.artifactVersion);
}
Path getRelativeFile(String file) {
protected Path getRelativeFile(String file) {
return Paths.get(new File(file).getAbsolutePath());
}
Path getTemporaryFile(String file) {
protected Path getTemporaryFile(String file) {
return Paths.get(new File(getTemporaryDir(), file).getAbsolutePath());
}
Path getBuildFile(String file) {
protected Path getBuildFile(String file) {
return getRelativeFile("build/libs/" + file);
}
JsonElement readJson(List<String> lines) {
protected JsonElement readJson(List<String> lines) {
return PARSER.parse(String.join("\n", lines));
}
}
@@ -62,6 +62,8 @@ public class CreateDistTask extends BaritoneGradleTask {
.map(path -> sha1(path) + " " + path.getFileName().toString())
.collect(Collectors.toList());
shasum.forEach(System.out::println);
// Write the checksums to a file
Files.write(getRelativeFile("dist/checksums.txt"), shasum);
}
@@ -74,7 +76,7 @@ public class CreateDistTask extends BaritoneGradleTask {
return DatatypeConverter.printHexBinary(SHA1_DIGEST.digest(Files.readAllBytes(path))).toLowerCase();
} catch (Exception e) {
// haha no thanks
throw new RuntimeException(e);
throw new IllegalStateException(e);
}
}
}
@@ -241,7 +241,7 @@ public class ProguardTask extends BaritoneGradleTask {
// Halt the current thread until the process is complete, if the exit code isn't 0, throw an exception
int exitCode = p.waitFor();
if (exitCode != 0) {
throw new Exception("Proguard exited with code " + exitCode);
throw new IllegalStateException("Proguard exited with code " + exitCode);
}
}
@@ -32,7 +32,7 @@ import java.util.jar.JarOutputStream;
import java.util.stream.Collectors;
/**
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 0.
* Make a .jar file deterministic by sorting all entries by name, and setting all the last modified times to 42069.
* This makes the build 100% reproducible since the timestamp when you built it no longer affects the final file.
*
* @author leijurv
+5
View File
@@ -13,9 +13,14 @@
-repackageclasses 'baritone'
-keep class baritone.api.** { *; } # this is the keep api
# service provider needs these class names
-keep class baritone.BaritoneProvider
-keep class baritone.api.IBaritoneProvider
# hack
-keep class baritone.utils.ExampleBaritoneControl { *; } # have to include this string to remove this keep in the standalone build: # this is the keep api
# setting names are reflected from field names, so keep field names
-keepclassmembers class baritone.api.Settings {
public <fields>;
+5 -37
View File
@@ -17,10 +17,6 @@
package baritone.api;
import baritone.api.behavior.*;
import baritone.api.cache.IWorldProvider;
import baritone.api.cache.IWorldScanner;
import baritone.api.event.listener.IGameEventListener;
import baritone.api.utils.SettingsUtil;
import java.util.Iterator;
@@ -36,51 +32,23 @@ import java.util.ServiceLoader;
*/
public final class BaritoneAPI {
private static final IBaritoneProvider baritone;
private static final IBaritoneProvider provider;
private static final Settings settings;
static {
ServiceLoader<IBaritoneProvider> baritoneLoader = ServiceLoader.load(IBaritoneProvider.class);
Iterator<IBaritoneProvider> instances = baritoneLoader.iterator();
baritone = instances.next();
provider = instances.next();
settings = new Settings();
SettingsUtil.readAndApply(settings);
}
public static IFollowBehavior getFollowBehavior() {
return baritone.getFollowBehavior();
}
public static ILookBehavior getLookBehavior() {
return baritone.getLookBehavior();
}
public static IMemoryBehavior getMemoryBehavior() {
return baritone.getMemoryBehavior();
}
public static IMineBehavior getMineBehavior() {
return baritone.getMineBehavior();
}
public static IPathingBehavior getPathingBehavior() {
return baritone.getPathingBehavior();
public static IBaritoneProvider getProvider() {
return BaritoneAPI.provider;
}
public static Settings getSettings() {
return settings;
}
public static IWorldProvider getWorldProvider() {
return baritone.getWorldProvider();
}
public static IWorldScanner getWorldScanner() {
return baritone.getWorldScanner();
}
public static void registerEventListener(IGameEventListener listener) {
baritone.registerEventListener(listener);
return BaritoneAPI.settings;
}
}
+86
View File
@@ -0,0 +1,86 @@
/*
* 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;
import baritone.api.behavior.ILookBehavior;
import baritone.api.behavior.IMemoryBehavior;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IWorldProvider;
import baritone.api.event.listener.IEventBus;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IFollowProcess;
import baritone.api.process.IGetToBlockProcess;
import baritone.api.process.IMineProcess;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.IPlayerContext;
/**
* @author Brady
* @since 9/29/2018
*/
public interface IBaritone {
/**
* @return The {@link IFollowProcess} instance
* @see IFollowProcess
*/
IFollowProcess getFollowProcess();
/**
* @return The {@link ILookBehavior} instance
* @see ILookBehavior
*/
ILookBehavior getLookBehavior();
/**
* @return The {@link IMemoryBehavior} instance
* @see IMemoryBehavior
*/
IMemoryBehavior getMemoryBehavior();
/**
* @return The {@link IMineProcess} instance
* @see IMineProcess
*/
IMineProcess getMineProcess();
IPathingControlManager getPathingControlManager();
/**
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior
*/
IPathingBehavior getPathingBehavior();
/**
* @return The {@link IWorldProvider} instance
* @see IWorldProvider
*/
IWorldProvider getWorldProvider();
IInputOverrideHandler getInputOverrideHandler();
ICustomGoalProcess getCustomGoalProcess();
IGetToBlockProcess getGetToBlockProcess();
IPlayerContext getPlayerContext();
IEventBus getGameEventHandler();
}
@@ -17,70 +17,55 @@
package baritone.api;
import baritone.api.behavior.*;
import baritone.api.cache.IWorldProvider;
import baritone.api.cache.IWorldScanner;
import baritone.api.event.listener.IGameEventListener;
import net.minecraft.client.entity.EntityPlayerSP;
import java.util.List;
/**
* @author Brady
* @since 9/29/2018
* @author Leijurv
*/
public interface IBaritoneProvider {
/**
* @see IFollowBehavior
* Returns the primary {@link IBaritone} instance. This instance is persistent, and
* is represented by the local player that is created by the game itself, not a "bot"
* player through Baritone.
*
* @return The {@link IFollowBehavior} instance
* @return The primary {@link IBaritone} instance.
*/
IFollowBehavior getFollowBehavior();
IBaritone getPrimaryBaritone();
/**
* @see ILookBehavior
* Returns all of the active {@link IBaritone} instances. This includes the local one
* returned by {@link #getPrimaryBaritone()}.
*
* @return The {@link ILookBehavior} instance
* @return All active {@link IBaritone} instances.
* @see #getBaritoneForPlayer(EntityPlayerSP)
*/
ILookBehavior getLookBehavior();
List<IBaritone> getAllBaritones();
/**
* @see IMemoryBehavior
* Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be
* replaced with {@code #getBaritoneForUser(IBaritoneUser)} when {@code bot-system} is merged.
*
* @return The {@link IMemoryBehavior} instance
* @param player The player
* @return The {@link IBaritone} instance.
*/
IMemoryBehavior getMemoryBehavior();
default IBaritone getBaritoneForPlayer(EntityPlayerSP player) {
for (IBaritone baritone : getAllBaritones()) {
if (player.equals(baritone.getPlayerContext().player())) {
return baritone;
}
}
throw new IllegalStateException("No baritone for player " + player);
}
/**
* @see IMineBehavior
* Returns the {@link IWorldScanner} instance. This is not a type returned by
* {@link IBaritone} implementation, because it is not linked with {@link IBaritone}.
*
* @return The {@link IMineBehavior} instance
*/
IMineBehavior getMineBehavior();
/**
* @see IPathingBehavior
*
* @return The {@link IPathingBehavior} instance
*/
IPathingBehavior getPathingBehavior();
/**
* @see IWorldProvider
*
* @return The {@link IWorldProvider} instance
*/
IWorldProvider getWorldProvider();
/**
* @see IWorldScanner
*
* @return The {@link IWorldScanner} instance
* @return The {@link IWorldScanner} instance.
*/
IWorldScanner getWorldScanner();
/**
* Registers a {@link IGameEventListener} with Baritone's "event bus".
*
* @param listener The listener
*/
void registerEventListener(IGameEventListener listener);
}
+56 -8
View File
@@ -247,14 +247,28 @@ public class Settings {
public Setting<Integer> movementTimeoutTicks = new Setting<>(100);
/**
* Pathing can never take longer than this
* Pathing ends after this amount of time, but only if a path has been found
* <p>
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
*/
public Setting<Long> pathTimeoutMS = new Setting<>(2000L);
public Setting<Long> primaryTimeoutMS = new Setting<>(500L);
/**
* Planning ahead while executing a segment can never take longer than this
* Pathing can never take longer than this, even if that means failing to find any path at all
*/
public Setting<Long> planAheadTimeoutMS = new Setting<>(4000L);
public Setting<Long> failureTimeoutMS = new Setting<>(2000L);
/**
* Planning ahead while executing a segment ends after this amount of time, but only if a path has been found
* <p>
* If no valid path (length above the minimum) has been found, pathing continues up until the failure timeout
*/
public Setting<Long> planAheadPrimaryTimeoutMS = new Setting<>(4000L);
/**
* Planning ahead while executing a segment can never take longer than this, even if that means failing to find any path at all
*/
public Setting<Long> planAheadFailureTimeoutMS = new Setting<>(5000L);
/**
* For debugging, consider nodes much much slower
@@ -276,6 +290,13 @@ public class Settings {
*/
public Setting<Boolean> chunkCaching = new Setting<>(true);
/**
* On save, delete from RAM any cached regions that are more than 1024 blocks away from the player
* <p>
* Temporarily disabled, see issue #248
*/
public Setting<Boolean> pruneRegionsFromRAM = new Setting<>(false);
/**
* Print all the debug messages to chat
*/
@@ -305,17 +326,17 @@ public class Settings {
/**
* Ignore depth when rendering the goal
*/
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(false);
public Setting<Boolean> renderGoalIgnoreDepth = new Setting<>(true);
/**
* Ignore depth when rendering the selection boxes (to break, to place, to walk into)
*/
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(false);
public Setting<Boolean> renderSelectionBoxesIgnoreDepth = new Setting<>(true);
/**
* Ignore depth when rendering the path
*/
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(false);
public Setting<Boolean> renderPathIgnoreDepth = new Setting<>(true);
/**
* Line width of the path when rendered, in pixels
@@ -370,12 +391,27 @@ public class Settings {
*/
public Setting<Boolean> walkWhileBreaking = new Setting<>(true);
/**
* If we are more than 500 movements into the current path, discard the oldest segments, as they are no longer useful
*/
public Setting<Integer> maxPathHistoryLength = new Setting<>(300);
/**
* If the current path is too long, cut off this many movements from the beginning.
*/
public Setting<Integer> pathHistoryCutoffAmount = new Setting<>(50);
/**
* Rescan for the goal once every 5 ticks.
* Set to 0 to disable.
*/
public Setting<Integer> mineGoalUpdateInterval = new Setting<>(5);
/**
* While mining, should it also consider dropped items of the correct type as a pathing destination (as well as ore blocks)?
*/
public Setting<Boolean> mineScanDroppedItems = new Setting<>(true);
/**
* Cancel the current path if the goal has changed, and the path originally ended in the goal but doesn't anymore.
* <p>
@@ -389,13 +425,25 @@ public class Settings {
* <p>
* Also on cosmic prisons this should be set to true since you don't actually mine the ore it just gets replaced with stone.
*/
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(false);
public Setting<Boolean> cancelOnGoalInvalidation = new Setting<>(true);
/**
* The "axis" command (aka GoalAxis) will go to a axis, or diagonal axis, at this Y level.
*/
public Setting<Integer> axisHeight = new Setting<>(120);
/**
* Allow MineBehavior to use X-Ray to see where the ores are. Turn this option off to force it to mine "legit"
* where it will only mine an ore once it can actually see it, so it won't do or know anything that a normal player
* couldn't. If you don't want it to look like you're X-Raying, turn this off
*/
public Setting<Boolean> legitMine = new Setting<>(false);
/**
* What Y level to go to for legit strip mining
*/
public Setting<Integer> legitMineYLevel = new Setting<>(11);
/**
* When mining block of a certain type, try to mine two at once instead of one.
* If the block above is also a goal block, set GoalBlock instead of GoalTwoBlocks
@@ -18,10 +18,9 @@
package baritone.api.behavior;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.utils.interfaces.Toggleable;
/**
* @author Brady
* @since 9/23/2018
*/
public interface IBehavior extends AbstractGameEventListener, Toggleable {}
public interface IBehavior extends AbstractGameEventListener {}
@@ -33,7 +33,7 @@ public interface ILookBehavior extends IBehavior {
* otherwise, it should be {@code false};
*
* @param rotation The target rotations
* @param force Whether or not to "force" the rotations
* @param force Whether or not to "force" the rotations
*/
void updateTarget(Rotation rotation, boolean force);
}
@@ -39,35 +39,25 @@ public interface IPathingBehavior extends IBehavior {
*/
Optional<Double> ticksRemainingInSegment();
/**
* Sets the pathing goal.
*
* @param goal The pathing goal
*/
void setGoal(Goal goal);
/**
* @return The current pathing goal
*/
Goal getGoal();
/**
* Begins pathing. Calculation will start in a new thread, and once completed,
* movement will commence. Returns whether or not the operation was successful.
*
* @return Whether or not the operation was successful
*/
boolean path();
/**
* @return Whether or not a path is currently being executed.
*/
boolean isPathing();
/**
* Cancels the pathing behavior or the current path calculation.
* Cancels the pathing behavior or the current path calculation, and all processes that could be controlling path.
* <p>
* Basically, "MAKE IT STOP".
*
* @return Whether or not the pathing behavior was canceled. All processes are guaranteed to be canceled, but the
* PathingBehavior might be in the middle of an uncancelable action like a parkour jump
*/
void cancel();
boolean cancelEverything();
/**
* Returns the current path, from the current path executor, if there is one.
@@ -81,7 +71,7 @@ public interface IPathingBehavior extends IBehavior {
/**
* @return The current path finder being executed
*/
Optional<IPathFinder> getPathFinder();
Optional<? extends IPathFinder> getInProgress();
/**
* @return The current path executor
+1 -1
View File
@@ -22,7 +22,7 @@ import net.minecraft.util.math.BlockPos;
/**
* @author Brady
* @since 8/4/2018 2:01 AM
* @since 8/4/2018
*/
public interface IBlockTypeAccess {
+1 -2
View File
@@ -29,11 +29,10 @@ public interface ICachedRegion extends IBlockTypeAccess {
* however, the block coordinates should in on a scale from 0 to 511 (inclusive)
* because region sizes are 512x512 blocks.
*
* @see ICachedWorld#isCached(int, int)
*
* @param blockX The block X coordinate
* @param blockZ The block Z coordinate
* @return Whether or not the specified XZ location is cached
* @see ICachedWorld#isCached(int, int)
*/
boolean isCached(int blockX, int blockZ);
+5 -3
View File
@@ -61,12 +61,14 @@ public interface ICachedWorld {
* information that is returned by this method may not be up to date, because
* older cached chunks can contain data that is much more likely to have changed.
*
* @param block The special block to search for
* @param maximum The maximum number of position results to receive
* @param block The special block to search for
* @param maximum The maximum number of position results to receive
* @param centerX The x block coordinate center of the search
* @param centerZ The z block coordinate center of the search
* @param maxRegionDistanceSq The maximum region distance, squared
* @return The locations found that match the special block
*/
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq);
LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq);
/**
* Reloads all of the cached regions in this world from disk. Anything that is not saved
+2 -4
View File
@@ -50,19 +50,17 @@ public interface IWaypointCollection {
/**
* Gets all of the waypoints that have the specified tag
*
* @see IWaypointCollection#getAllWaypoints()
*
* @param tag The tag
* @return All of the waypoints with the specified tag
* @see IWaypointCollection#getAllWaypoints()
*/
Set<IWaypoint> getByTag(IWaypoint.Tag tag);
/**
* Gets all of the waypoints in this collection, regardless of the tag.
*
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
*
* @return All of the waypoints in this collection
* @see IWaypointCollection#getByTag(IWaypoint.Tag)
*/
Set<IWaypoint> getAllWaypoints();
}
+4 -1
View File
@@ -17,6 +17,7 @@
package baritone.api.cache;
import baritone.api.utils.IPlayerContext;
import net.minecraft.block.Block;
import net.minecraft.util.math.BlockPos;
@@ -31,6 +32,8 @@ public interface IWorldScanner {
/**
* Scans the world, up to the specified max chunk radius, for the specified blocks.
*
* @param ctx The {@link IPlayerContext} containing player and world info that the
* scan is based upon
* @param blocks The blocks to scan for
* @param max The maximum number of blocks to scan before cutoff
* @param yLevelThreshold If a block is found within this Y level, the current result will be
@@ -38,5 +41,5 @@ public interface IWorldScanner {
* @param maxSearchRadius The maximum chunk search radius
* @return The matching block positions
*/
List<BlockPos> scanChunkRadius(List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
List<BlockPos> scanChunkRadius(IPlayerContext ctx, List<Block> blocks, int max, int yLevelThreshold, int maxSearchRadius);
}
@@ -22,7 +22,7 @@ import net.minecraft.client.entity.EntityPlayerSP;
/**
* @author Brady
* @since 8/1/2018 6:39 PM
* @since 8/1/2018
*/
public final class ChatEvent extends ManagedPlayerEvent.Cancellable {
@@ -21,7 +21,7 @@ import baritone.api.event.events.type.EventState;
/**
* @author Brady
* @since 8/2/2018 12:32 AM
* @since 8/2/2018
*/
public final class ChunkEvent {
@@ -94,7 +94,16 @@ public final class ChunkEvent {
/**
* When the chunk is being populated with blocks, tile entities, etc.
* <p>
* And it's a full chunk
*/
POPULATE
POPULATE_FULL,
/**
* When the chunk is being populated with blocks, tile entities, etc.
* <p>
* And it's a partial chunk
*/
POPULATE_PARTIAL
}
}
@@ -23,7 +23,7 @@ import net.minecraft.network.Packet;
/**
* @author Brady
* @since 8/6/2018 9:31 PM
* @since 8/6/2018
*/
public final class PacketEvent {
@@ -19,7 +19,7 @@ package baritone.api.event.events;
/**
* @author Brady
* @since 8/5/2018 12:28 AM
* @since 8/5/2018
*/
public final class RenderEvent {
@@ -17,7 +17,6 @@
package baritone.api.event.events;
import baritone.api.event.events.type.EventState;
import baritone.api.event.events.type.ManagedPlayerEvent;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
@@ -35,21 +34,30 @@ public final class RotationMoveEvent extends ManagedPlayerEvent {
private final Type type;
/**
* The state of the event
* The yaw rotation
*/
private final EventState state;
private float yaw;
public RotationMoveEvent(EntityPlayerSP player, EventState state, Type type) {
public RotationMoveEvent(EntityPlayerSP player, Type type, float yaw) {
super(player);
this.state = state;
this.type = type;
this.yaw = yaw;
}
/**
* @return The state of the event
* Set the yaw movement rotation
*
* @param yaw Yaw rotation
*/
public final EventState getState() {
return this.state;
public final void setYaw(float yaw) {
this.yaw = yaw;
}
/**
* @return The yaw rotation
*/
public final float getYaw() {
return this.yaw;
}
/**
@@ -22,7 +22,7 @@ import net.minecraft.client.multiplayer.WorldClient;
/**
* @author Brady
* @since 8/4/2018 3:13 AM
* @since 8/4/2018
*/
public final class WorldEvent {
@@ -19,7 +19,7 @@ package baritone.api.event.events.type;
/**
* @author Brady
* @since 8/1/2018 6:41 PM
* @since 8/1/2018
*/
public class Cancellable implements ICancellable {
@@ -19,19 +19,17 @@ package baritone.api.event.events.type;
/**
* @author Brady
* @since 8/2/2018 12:34 AM
* @since 8/2/2018
*/
public enum EventState {
/**
* Indicates that whatever movement the event is being
* dispatched as a result of is about to occur.
* Before the dispatching of what the event is targetting
*/
PRE,
/**
* Indicates that whatever movement the event is being
* dispatched as a result of has already occurred.
* After the dispatching of what the event is targetting
*/
POST
}
@@ -26,7 +26,7 @@ import baritone.api.event.events.*;
*
* @author Brady
* @see IGameEventListener
* @since 8/1/2018 6:29 PM
* @since 8/1/2018
*/
public interface AbstractGameEventListener extends IGameEventListener {
@@ -0,0 +1,36 @@
/*
* 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.listener;
/**
* A type of {@link IGameEventListener} that can have additional listeners
* registered so that they receive the events that are dispatched to this
* listener.
*
* @author Brady
* @since 11/14/2018
*/
public interface IEventBus extends IGameEventListener {
/**
* Registers the specified {@link IGameEventListener} to this event bus
*
* @param listener The listener
*/
void registerEventListener(IGameEventListener listener);
}
@@ -33,7 +33,7 @@ import net.minecraft.util.text.ITextComponent;
/**
* @author Brady
* @since 7/31/2018 11:05 PM
* @since 7/31/2018
*/
public interface IGameEventListener {
@@ -21,7 +21,9 @@ import baritone.api.Settings;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.movement.IMovement;
import baritone.api.utils.BetterBlockPos;
import net.minecraft.world.World;
import java.util.HashSet;
import java.util.List;
/**
@@ -51,7 +53,9 @@ public interface IPath {
* This path is actually going to be executed in the world. Do whatever additional processing is required.
* (as opposed to Path objects that are just constructed every frame for rendering)
*/
default void postProcess() {}
default IPath postProcess() {
throw new UnsupportedOperationException();
}
/**
* Returns the number of positions in this path. Equivalent to {@code positions().size()}.
@@ -100,7 +104,7 @@ public interface IPath {
* Returns the estimated number of ticks to complete the path from the given node index.
*
* @param pathPosition The index of the node we're calculating from
* @return The estimated number of ticks remaining frm the given position
* @return The estimated number of ticks remaining from the given position
*/
default double ticksRemainingFrom(int pathPosition) {
double sum = 0;
@@ -111,26 +115,68 @@ public interface IPath {
return sum;
}
/**
* Returns the estimated amount of time needed to complete this path from start to finish
*
* @return The estimated amount of time, in ticks
*/
default double totalTicks() {
return ticksRemainingFrom(0);
}
/**
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
* implementation just returns this path, without the intended functionality.
*
* @return The result of this cut-off operation
*/
default IPath cutoffAtLoadedChunks() {
return this;
default IPath cutoffAtLoadedChunks(World world) {
throw new UnsupportedOperationException();
}
/**
* Cuts off this path using the min length and cutoff factor settings, and returns the resulting path.
* Default implementation just returns this path, without the intended functionality.
*
* @return The result of this cut-off operation
* @see Settings#pathCutoffMinimumLength
* @see Settings#pathCutoffFactor
*
* @return The result of this cut-off operation
*/
default IPath staticCutoff(Goal destination) {
return this;
throw new UnsupportedOperationException();
}
/**
* Performs a series of checks to ensure that the assembly of the path went as expected.
*/
default void sanityCheck() {
List<BetterBlockPos> path = positions();
List<IMovement> movements = movements();
if (!getSrc().equals(path.get(0))) {
throw new IllegalStateException("Start node does not equal first path element");
}
if (!getDest().equals(path.get(path.size() - 1))) {
throw new IllegalStateException("End node does not equal last path element");
}
if (path.size() != movements.size() + 1) {
throw new IllegalStateException("Size of path array is unexpected");
}
HashSet<BetterBlockPos> seenSoFar = new HashSet<>();
for (int i = 0; i < path.size() - 1; i++) {
BetterBlockPos src = path.get(i);
BetterBlockPos dest = path.get(i + 1);
IMovement movement = movements.get(i);
if (!src.equals(movement.getSrc())) {
throw new IllegalStateException("Path source is not equal to the movement source");
}
if (!dest.equals(movement.getDest())) {
throw new IllegalStateException("Path destination is not equal to the movement destination");
}
if (seenSoFar.contains(src)) {
throw new IllegalStateException("Path doubles back on itself, making a loop");
}
seenSoFar.add(src);
}
}
}
@@ -18,6 +18,7 @@
package baritone.api.pathing.calc;
import baritone.api.pathing.goals.Goal;
import baritone.api.utils.PathCalculationResult;
import java.util.Optional;
@@ -35,7 +36,7 @@ public interface IPathFinder {
*
* @return The final path
*/
Optional<IPath> calculate(long timeout);
PathCalculationResult calculate(long primaryTimeout, long failureTimeout);
/**
* Intended to be called concurrently with calculatePath from a different thread to tell if it's finished yet
@@ -0,0 +1,31 @@
/*
* 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.pathing.calc;
import baritone.api.process.IBaritoneProcess;
import baritone.api.process.PathingCommand;
import java.util.Optional;
public interface IPathingControlManager {
void registerProcess(IBaritoneProcess process);
Optional<IBaritoneProcess> mostRecentInControl();
Optional<PathingCommand> mostRecentCommand();
}
@@ -17,10 +17,7 @@
package baritone.api.pathing.goals;
import net.minecraft.util.math.BlockPos;
import java.util.Arrays;
import java.util.Collection;
/**
* A composite of many goals, any one of which satisfies the composite.
@@ -40,14 +37,6 @@ public class GoalComposite implements Goal {
this.goals = goals;
}
public GoalComposite(BlockPos... blocks) {
this(Arrays.asList(blocks));
}
public GoalComposite(Collection<BlockPos> blocks) {
this(blocks.stream().map(GoalBlock::new).toArray(Goal[]::new));
}
@Override
public boolean isInGoal(int x, int y, int z) {
for (Goal goal : goals) {
@@ -48,10 +48,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
int xDiff = x - this.x;
int yDiff = y - this.y;
int zDiff = z - this.z;
if (yDiff < 0) {
yDiff++;
}
return Math.abs(xDiff) + Math.abs(yDiff) + Math.abs(zDiff) <= 1;
return Math.abs(xDiff) + Math.abs(yDiff < 0 ? yDiff + 1 : yDiff) + Math.abs(zDiff) <= 1;
}
@Override
@@ -59,7 +56,7 @@ public class GoalGetToBlock implements Goal, IGoalRenderPos {
int xDiff = x - this.x;
int yDiff = y - this.y;
int zDiff = z - this.z;
return GoalBlock.calculate(xDiff, yDiff, zDiff);
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
}
@Override
@@ -32,16 +32,26 @@ public class GoalRunAway implements Goal {
private final double distanceSq;
private final Integer maintainY;
public GoalRunAway(double distance, BlockPos... from) {
this(distance, null, from);
}
public GoalRunAway(double distance, Integer maintainY, BlockPos... from) {
if (from.length == 0) {
throw new IllegalArgumentException();
}
this.from = from;
this.distanceSq = distance * distance;
this.maintainY = maintainY;
}
@Override
public boolean isInGoal(int x, int y, int z) {
if (maintainY != null && maintainY != y) {
return false;
}
for (BlockPos p : from) {
int diffX = x - p.getX();
int diffZ = z - p.getZ();
@@ -62,11 +72,19 @@ public class GoalRunAway implements Goal {
min = h;
}
}
return -min;
min = -min;
if (maintainY != null) {
min = min * 0.6 + GoalYLevel.calculate(maintainY, y) * 1.5;
}
return min;
}
@Override
public String toString() {
return "GoalRunAwayFrom" + Arrays.asList(from);
if (maintainY != null) {
return "GoalRunAwayFromMaintainY y=" + maintainY + ", " + Arrays.asList(from);
} else {
return "GoalRunAwayFrom" + Arrays.asList(from);
}
}
}
@@ -63,10 +63,7 @@ public class GoalTwoBlocks implements Goal, IGoalRenderPos {
int xDiff = x - this.x;
int yDiff = y - this.y;
int zDiff = z - this.z;
if (yDiff < 0) {
yDiff++;
}
return GoalBlock.calculate(xDiff, yDiff, zDiff);
return GoalBlock.calculate(xDiff, yDiff < 0 ? yDiff + 1 : yDiff, zDiff);
}
@Override
@@ -0,0 +1,99 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
import baritone.api.IBaritone;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.PathEvent;
/**
* A process that can control the PathingBehavior.
* <p>
* Differences between a baritone process and a behavior:
* Only one baritone process can be active at a time
* PathingBehavior can only be controlled by a process
* <p>
* That's it actually
*
* @author leijurv
*/
public interface IBaritoneProcess {
/**
* Would this process like to be in control?
*
* @return Whether or not this process would like to be in contorl.
*/
boolean isActive();
/**
* Called when this process is in control of pathing; Returns what Baritone should do.
*
* @param calcFailed {@code true} if this specific process was in control last tick,
* and there was a {@link PathEvent#CALC_FAILED} event last tick
* @param isSafeToCancel {@code true} if a {@link PathingCommandType#REQUEST_PAUSE} would happen this tick, and
* {@link IPathingBehavior} wouldn't actually tick. {@code false} if the PathExecutor reported
* pausing would be unsafe at the end of the last tick. Effectively "could request cancel or
* pause and have it happen right away"
* @return What the {@link IPathingBehavior} should do
*/
PathingCommand onTick(boolean calcFailed, boolean isSafeToCancel);
/**
* Returns whether or not this process should be treated as "temporary".
* <p>
* If a process is temporary, it doesn't call {@link #onLostControl} on the processes that aren't execute because of it.
* <p>
* For example, {@code CombatPauserProcess} and {@code PauseForAutoEatProcess} should return {@code true} always,
* and should return {@link #isActive} {@code true} only if there's something in range this tick, or if the player would like
* to start eating this tick. {@code PauseForAutoEatProcess} should only actually right click once onTick is called with
* {@code isSafeToCancel} true though.
*
* @return Whethor or not if this control is temporary
*/
boolean isTemporary();
/**
* Called if {@link #isActive} returned {@code true}, but another non-temporary
* process has control. Effectively the same as cancel. You want control but you
* don't get it.
*/
void onLostControl();
/**
* Used to determine which Process gains control if multiple are reporting {@link #isActive()}. The one
* that returns the highest value will be given control.
*
* @return A double representing the priority
*/
double priority();
/**
* Returns which bot this process is associated with. (5000000iq forward thinking)
*
* @return The Bot associated with this process
*/
IBaritone associatedWith();
/**
* Returns a user-friendly name for this process. Suitable for a HUD.
*
* @return A display name that's suitable for a HUD
*/
String displayName();
}
@@ -15,40 +15,36 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils.interfaces;
package baritone.api.process;
/**
* @author Brady
* @since 8/20/2018
*/
public interface Toggleable {
import baritone.api.pathing.goals.Goal;
public interface ICustomGoalProcess extends IBaritoneProcess {
/**
* Toggles the enabled state of this {@link Toggleable}.
* Sets the pathing goal
*
* @return The new state.
* @param goal The new goal
*/
boolean toggle();
void setGoal(Goal goal);
/**
* Sets the enabled state of this {@link Toggleable}.
* Starts path calculation and execution.
*/
void path();
/**
* @return The current goal
*/
Goal getGoal();
/**
* Sets the goal and begins the path execution.
*
* @return The new state.
* @param goal The new goal
*/
boolean setEnabled(boolean enabled);
/**
* @return Whether or not this {@link Toggleable} object is enabled
*/
boolean isEnabled();
/**
* Called when the state changes from disabled to enabled
*/
default void onEnable() {}
/**
* Called when the state changes from enabled to disabled
*/
default void onDisable() {}
default void setGoalAndPath(Goal goal) {
this.setGoal(goal);
this.path();
}
}
@@ -15,30 +15,37 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.behavior;
package baritone.api.process;
import net.minecraft.entity.Entity;
import java.util.List;
import java.util.function.Predicate;
/**
* @author Brady
* @since 9/23/2018
*/
public interface IFollowBehavior extends IBehavior {
public interface IFollowProcess extends IBaritoneProcess {
/**
* Set the follow target to the specified entity;
* Set the follow target to any entities matching this predicate
*
* @param entity The entity to follow
* @param filter the predicate
*/
void follow(Entity entity);
void follow(Predicate<Entity> filter);
/**
* @return The entity that is currently being followed
* @return The entities that are currently being followed. null if not currently following, empty if nothing matches the predicate
*/
Entity following();
List<Entity> following();
Predicate<Entity> currentFilter();
/**
* Cancels the follow behavior, this will clear the current follow target.
*/
void cancel();
default void cancel() {
onLostControl();
}
}
@@ -0,0 +1,28 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
import net.minecraft.block.Block;
/**
* but it rescans the world every once in a while so it doesn't get fooled by its cache
*/
public interface IGetToBlockProcess extends IBaritoneProcess {
void getToBlock(Block block);
}
@@ -15,7 +15,7 @@
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.behavior;
package baritone.api.process;
import net.minecraft.block.Block;
@@ -23,7 +23,7 @@ import net.minecraft.block.Block;
* @author Brady
* @since 9/23/2018
*/
public interface IMineBehavior extends IBehavior {
public interface IMineProcess extends IBaritoneProcess {
/**
* Begin to search for and mine the specified blocks until
@@ -31,9 +31,9 @@ public interface IMineBehavior extends IBehavior {
* are mined. This is based on the first target block to mine.
*
* @param quantity The number of items to get from blocks mined
* @param blocks The blocks to mine
* @param blocks The blocks to mine
*/
void mine(int quantity, String... blocks);
void mineByName(int quantity, String... blocks);
/**
* Begin to search for and mine the specified blocks until
@@ -41,7 +41,7 @@ public interface IMineBehavior extends IBehavior {
* are mined. This is based on the first target block to mine.
*
* @param quantity The number of items to get from blocks mined
* @param blocks The blocks to mine
* @param blocks The blocks to mine
*/
void mine(int quantity, Block... blocks);
@@ -50,8 +50,8 @@ public interface IMineBehavior extends IBehavior {
*
* @param blocks The blocks to mine
*/
default void mine(String... blocks) {
this.mine(0, blocks);
default void mineByName(String... blocks) {
mineByName(0, blocks);
}
/**
@@ -60,11 +60,13 @@ public interface IMineBehavior extends IBehavior {
* @param blocks The blocks to mine
*/
default void mine(Block... blocks) {
this.mine(0, blocks);
mine(0, blocks);
}
/**
* Cancels the current mining task
*/
void cancel();
default void cancel() {
onLostControl();
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
import baritone.api.pathing.goals.Goal;
import java.util.Objects;
/**
* @author leijurv
*/
public class PathingCommand {
/**
* The target goal, may be {@code null}.
*/
public final Goal goal;
/**
* The command type.
*
* @see PathingCommandType
*/
public final PathingCommandType commandType;
/**
* Create a new {@link PathingCommand}.
*
* @param goal The target goal, may be {@code null}.
* @param commandType The command type, cannot be {@code null}.
* @throws NullPointerException if {@code commandType} is {@code null}.
* @see Goal
* @see PathingCommandType
*/
public PathingCommand(Goal goal, PathingCommandType commandType) {
Objects.requireNonNull(commandType);
this.goal = goal;
this.commandType = commandType;
}
}
@@ -0,0 +1,55 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.process;
import baritone.api.Settings;
public enum PathingCommandType {
/**
* Set the goal and path.
* <p>
* If you use this alongside a {@code null} goal, it will continue along its current path and current goal.
*/
SET_GOAL_AND_PATH,
/**
* Has no effect on the current goal or path, just requests a pause
*/
REQUEST_PAUSE,
/**
* Set the goal (regardless of {@code null}), and request a cancel of the current path (when safe)
*/
CANCEL_AND_SET_GOAL,
/**
* Set the goal and path.
* <p>
* If {@link Settings#cancelOnGoalInvalidation} is {@code true}, revalidate the
* current goal, and cancel if it's no longer valid, or if the new goal is {@code null}.
*/
REVALIDATE_GOAL_AND_PATH,
/**
* Set the goal and path.
* <p>
* Cancel the current path if the goals are not equal
*/
FORCE_REVALIDATE_GOAL_AND_PATH
}
@@ -0,0 +1,39 @@
/*
* 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 baritone.api.behavior.IBehavior;
import baritone.api.utils.input.Input;
import net.minecraft.client.settings.KeyBinding;
/**
* @author Brady
* @since 11/12/2018
*/
public interface IInputOverrideHandler extends IBehavior {
default boolean isInputForcedDown(KeyBinding key) {
return isInputForcedDown(Input.getInputForBind(key));
}
boolean isInputForcedDown(Input input);
void setInputForceState(Input input, boolean forced);
void clearAllKeys();
}
@@ -0,0 +1,92 @@
/*
* 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 baritone.api.cache.IWorldData;
import net.minecraft.block.BlockSlab;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
import java.util.Optional;
/**
* @author Brady
* @since 11/12/2018
*/
public interface IPlayerContext {
EntityPlayerSP player();
PlayerControllerMP playerController();
World world();
IWorldData worldData();
RayTraceResult objectMouseOver();
default BetterBlockPos playerFeet() {
// TODO find a better way to deal with soul sand!!!!!
BetterBlockPos feet = new BetterBlockPos(player().posX, player().posY + 0.1251, player().posZ);
if (world().getBlockState(feet).getBlock() instanceof BlockSlab) {
return feet.up();
}
return feet;
}
default Vec3d playerFeetAsVec() {
return new Vec3d(player().posX, player().posY, player().posZ);
}
default Vec3d playerHead() {
return new Vec3d(player().posX, player().posY + player().getEyeHeight(), player().posZ);
}
default Rotation playerRotations() {
return new Rotation(player().rotationYaw, player().rotationPitch);
}
/**
* Returns the block that the crosshair is currently placed over. Updated once per tick.
*
* @return The position of the highlighted block
*/
default Optional<BlockPos> getSelectedBlock() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(objectMouseOver().getBlockPos());
}
return Optional.empty();
}
/**
* Returns the entity that the crosshair is currently placed over. Updated once per tick.
*
* @return The entity
*/
default Optional<Entity> getSelectedEntity() {
if (objectMouseOver() != null && objectMouseOver().typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(objectMouseOver().entityHit);
}
return Optional.empty();
}
}
@@ -0,0 +1,56 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.utils;
import baritone.api.pathing.calc.IPath;
import java.util.Optional;
public class PathCalculationResult {
private final IPath path;
private final Type type;
public PathCalculationResult(Type type) {
this(type, null);
}
public PathCalculationResult(Type type, IPath path) {
this.path = path;
this.type = type;
if (type == null) {
throw new IllegalArgumentException("come on");
}
}
public final Optional<IPath> getPath() {
return Optional.ofNullable(this.path);
}
public final Type getType() {
return this.type;
}
public enum Type {
SUCCESS_TO_GOAL,
SUCCESS_SEGMENT,
FAILURE,
CANCELLATION,
EXCEPTION,
}
}
@@ -17,14 +17,10 @@
package baritone.api.utils;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.RayTraceResult;
import net.minecraft.util.math.Vec3d;
import java.util.Optional;
/**
* @author Brady
* @since 8/25/2018
@@ -33,41 +29,6 @@ public final class RayTraceUtils {
private RayTraceUtils() {}
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
/**
* Simulates a "vanilla" raytrace. A RayTraceResult returned by this method
* will be that of the next render pass given that the local player's yaw and
* pitch match the specified yaw and pitch values. This is particularly useful
* when you would like to simulate a "legit" raytrace with certainty that the only
* thing to achieve the desired outcome (whether it is hitting and entity or placing
* a block) can be done just by modifying user input.
*
* @param yaw The yaw to raytrace with
* @param pitch The pitch to raytrace with
* @return The calculated raytrace result
*/
public static RayTraceResult simulateRayTrace(float yaw, float pitch) {
RayTraceResult oldTrace = mc.objectMouseOver;
float oldYaw = mc.player.rotationYaw;
float oldPitch = mc.player.rotationPitch;
mc.player.rotationYaw = yaw;
mc.player.rotationPitch = pitch;
mc.entityRenderer.getMouseOver(1.0F);
RayTraceResult result = mc.objectMouseOver;
mc.objectMouseOver = oldTrace;
mc.player.rotationYaw = oldYaw;
mc.player.rotationPitch = oldPitch;
return result;
}
/**
* Performs a block raytrace with the specified rotations. This should only be used when
* any entity collisions can be ignored, because this method will not recognize if an
@@ -76,39 +37,14 @@ public final class RayTraceUtils {
* @param rotation The rotation to raytrace towards
* @return The calculated raytrace result
*/
public static RayTraceResult rayTraceTowards(Rotation rotation) {
double blockReachDistance = mc.playerController.getBlockReachDistance();
Vec3d start = mc.player.getPositionEyes(1.0F);
public static RayTraceResult rayTraceTowards(Entity entity, Rotation rotation, double blockReachDistance) {
Vec3d start = entity.getPositionEyes(1.0F);
Vec3d direction = RotationUtils.calcVec3dFromRotation(rotation);
Vec3d end = start.add(
direction.x * blockReachDistance,
direction.y * blockReachDistance,
direction.z * blockReachDistance
);
return mc.world.rayTraceBlocks(start, end, false, false, true);
}
/**
* Returns the block that the crosshair is currently placed over. Updated once per render tick.
*
* @return The position of the highlighted block
*/
public static Optional<BlockPos> getSelectedBlock() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.BLOCK) {
return Optional.of(mc.objectMouseOver.getBlockPos());
}
return Optional.empty();
}
/**
* Returns the entity that the crosshair is currently placed over. Updated once per render tick.
*
* @return The entity
*/
public static Optional<Entity> getSelectedEntity() {
if (mc.objectMouseOver != null && mc.objectMouseOver.typeOfHit == RayTraceResult.Type.ENTITY) {
return Optional.of(mc.objectMouseOver.entityHit);
}
return Optional.empty();
return entity.world.rayTraceBlocks(start, end, false, false, true);
}
}
+31 -4
View File
@@ -86,7 +86,7 @@ public class Rotation {
public Rotation clamp() {
return new Rotation(
this.yaw,
RotationUtils.clampPitch(this.pitch)
clampPitch(this.pitch)
);
}
@@ -95,7 +95,7 @@ public class Rotation {
*/
public Rotation normalize() {
return new Rotation(
RotationUtils.normalizeYaw(this.yaw),
normalizeYaw(this.yaw),
this.pitch
);
}
@@ -105,8 +105,35 @@ public class Rotation {
*/
public Rotation normalizeAndClamp() {
return new Rotation(
RotationUtils.normalizeYaw(this.yaw),
RotationUtils.clampPitch(this.pitch)
normalizeYaw(this.yaw),
clampPitch(this.pitch)
);
}
/**
* Clamps the specified pitch value between -90 and 90.
*
* @param pitch The input pitch
* @return The clamped pitch
*/
public static float clampPitch(float pitch) {
return Math.max(-90, Math.min(90, pitch));
}
/**
* Normalizes the specified yaw value between -180 and 180.
*
* @param yaw The input yaw
* @return The normalized yaw
*/
public static float normalizeYaw(float yaw) {
float newYaw = yaw % 360F;
if (newYaw < -180F) {
newYaw += 360F;
}
if (newYaw >= 180F) {
newYaw -= 360F;
}
return newYaw;
}
}
@@ -17,9 +17,11 @@
package baritone.api.utils;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.*;
@@ -31,13 +33,6 @@ import java.util.Optional;
*/
public final class RotationUtils {
private RotationUtils() {}
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
/**
* Constant that a degree value is multiplied by to get the equivalent radian value
*/
@@ -60,32 +55,7 @@ public final class RotationUtils {
new Vec3d(1, 0.5, 0.5) // East
};
/**
* Clamps the specified pitch value between -90 and 90.
*
* @param pitch The input pitch
* @return The clamped pitch
*/
public static float clampPitch(float pitch) {
return Math.max(-90, Math.min(90, pitch));
}
/**
* Normalizes the specified yaw value between -180 and 180.
*
* @param yaw The input yaw
* @return The normalized yaw
*/
public static float normalizeYaw(float yaw) {
float newYaw = yaw % 360F;
if (newYaw < -180F) {
newYaw += 360F;
}
if (newYaw >= 180F) {
newYaw -= 360F;
}
return newYaw;
}
private RotationUtils() {}
/**
* Calculates the rotation from BlockPos<sub>dest</sub> to BlockPos<sub>orig</sub>
@@ -168,8 +138,9 @@ public final class RotationUtils {
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachable(Entity entity, BlockPos pos) {
if (pos.equals(RayTraceUtils.getSelectedBlock().orElse(null))) {
public static Optional<Rotation> reachable(EntityPlayerSP entity, BlockPos pos, double blockReachDistance) {
IBaritone baritone = BaritoneAPI.getProvider().getBaritoneForPlayer(entity);
if (pos.equals(baritone.getPlayerContext().getSelectedBlock().orElse(null))) {
/*
* why add 0.0001?
* to indicate that we actually have a desired pitch
@@ -177,22 +148,24 @@ public final class RotationUtils {
* is by setting the desired pitch to the current pitch
* setting the desired pitch to the current pitch + 0.0001 means that we do have a desired pitch, it's
* just what it currently is
*
* or if you're a normal person literally all this does it ensure that we don't nudge the pitch to a normal level
*/
return Optional.of(new Rotation(entity.rotationYaw, entity.rotationPitch + 0.0001F));
}
Optional<Rotation> possibleRotation = reachableCenter(entity, pos);
Optional<Rotation> possibleRotation = reachableCenter(entity, pos, blockReachDistance);
//System.out.println("center: " + possibleRotation);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
IBlockState state = mc.world.getBlockState(pos);
IBlockState state = entity.world.getBlockState(pos);
AxisAlignedBB aabb = state.getBoundingBox(entity.world, pos);
for (Vec3d sideOffset : BLOCK_SIDE_MULTIPLIERS) {
double xDiff = aabb.minX * sideOffset.x + aabb.maxX * (1 - sideOffset.x);
double yDiff = aabb.minY * sideOffset.y + aabb.maxY * (1 - sideOffset.y);
double zDiff = aabb.minZ * sideOffset.z + aabb.maxZ * (1 - sideOffset.z);
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff));
possibleRotation = reachableOffset(entity, pos, new Vec3d(pos).add(xDiff, yDiff, zDiff), blockReachDistance);
if (possibleRotation.isPresent()) {
return possibleRotation;
}
@@ -210,18 +183,16 @@ public final class RotationUtils {
* @param offsetPos The position of the block with the offset applied.
* @return The optional rotation
*/
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos) {
public static Optional<Rotation> reachableOffset(Entity entity, BlockPos pos, Vec3d offsetPos, double blockReachDistance) {
Rotation rotation = calcRotationFromVec3d(entity.getPositionEyes(1.0F), offsetPos);
RayTraceResult result = RayTraceUtils.rayTraceTowards(rotation);
RayTraceResult result = RayTraceUtils.rayTraceTowards(entity, rotation, blockReachDistance);
//System.out.println(result);
if (result != null && result.typeOfHit == RayTraceResult.Type.BLOCK) {
if (result.getBlockPos().equals(pos)) {
return Optional.of(rotation);
}
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire) {
if (result.getBlockPos().equals(pos.down())) {
return Optional.of(rotation);
}
if (entity.world.getBlockState(pos).getBlock() instanceof BlockFire && result.getBlockPos().equals(pos.down())) {
return Optional.of(rotation);
}
}
return Optional.empty();
@@ -235,7 +206,7 @@ public final class RotationUtils {
* @param pos The target block position
* @return The optional rotation
*/
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos) {
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(pos));
public static Optional<Rotation> reachableCenter(Entity entity, BlockPos pos, double blockReachDistance) {
return reachableOffset(entity, pos, VecUtils.calculateBlockCenter(entity.world, pos), blockReachDistance);
}
}
+14 -24
View File
@@ -19,11 +19,11 @@ package baritone.api.utils;
import net.minecraft.block.BlockFire;
import net.minecraft.block.state.IBlockState;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.AxisAlignedBB;
import net.minecraft.util.math.BlockPos;
import net.minecraft.util.math.Vec3d;
import net.minecraft.world.World;
/**
* @author Brady
@@ -33,22 +33,16 @@ public final class VecUtils {
private VecUtils() {}
/**
* The {@link Minecraft} instance
*/
private static final Minecraft mc = Minecraft.getMinecraft();
/**
* Calculates the center of the block at the specified position's bounding box
*
* @see #getBlockPosCenter(BlockPos)
*
* @param pos The block position
* @return The center of the block's bounding box
* @see #getBlockPosCenter(BlockPos)
*/
public static Vec3d calculateBlockCenter(BlockPos pos) {
IBlockState b = mc.world.getBlockState(pos);
AxisAlignedBB bbox = b.getBoundingBox(mc.world, pos);
public static Vec3d calculateBlockCenter(World world, BlockPos pos) {
IBlockState b = world.getBlockState(pos);
AxisAlignedBB bbox = b.getBoundingBox(world, pos);
double xDiff = (bbox.minX + bbox.maxX) / 2;
double yDiff = (bbox.minY + bbox.maxY) / 2;
double zDiff = (bbox.minZ + bbox.maxZ) / 2;
@@ -68,10 +62,9 @@ public final class VecUtils {
* <p>
* TODO: We may want to consider replacing many usages of this method with #calculateBlockCenter(BlockPos)
*
* @see #calculateBlockCenter(BlockPos)
*
* @param pos The block position
* @return The assumed center of the position
* @see #calculateBlockCenter(World, BlockPos)
*/
public static Vec3d getBlockPosCenter(BlockPos pos) {
return new Vec3d(pos.getX() + 0.5, pos.getY() + 0.5, pos.getZ() + 0.5);
@@ -80,13 +73,12 @@ public final class VecUtils {
/**
* Gets the distance from the specified position to the assumed center of the specified block position.
*
* @see #getBlockPosCenter(BlockPos)
*
* @param pos The block position
* @param x The x pos
* @param y The y pos
* @param z The z pos
* @param x The x pos
* @param y The y pos
* @param z The z pos
* @return The distance from the assumed block center to the position
* @see #getBlockPosCenter(BlockPos)
*/
public static double distanceToCenter(BlockPos pos, double x, double y, double z) {
Vec3d center = getBlockPosCenter(pos);
@@ -100,11 +92,10 @@ public final class VecUtils {
* Gets the distance from the specified entity's position to the assumed
* center of the specified block position.
*
* @see #getBlockPosCenter(BlockPos)
*
* @param entity The entity
* @param pos The block position
* @param pos The block position
* @return The distance from the entity to the block's assumed center
* @see #getBlockPosCenter(BlockPos)
*/
public static double entityDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, entity.posY, entity.posZ);
@@ -114,11 +105,10 @@ public final class VecUtils {
* Gets the distance from the specified entity's position to the assumed
* center of the specified block position, ignoring the Y axis.
*
* @see #getBlockPosCenter(BlockPos)
*
* @param entity The entity
* @param pos The block position
* @param pos The block position
* @return The horizontal distance from the entity to the block's assumed center
* @see #getBlockPosCenter(BlockPos)
*/
public static double entityFlatDistanceToCenter(Entity entity, BlockPos pos) {
return distanceToCenter(pos, entity.posX, pos.getY() + 0.5, entity.posZ);
@@ -0,0 +1,119 @@
/*
* 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.input;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.function.Function;
/**
* An {@link Enum} representing the inputs that control the player's
* behavior. This includes moving, interacting with blocks, jumping,
* sneaking, and sprinting.
*/
public enum Input {
/**
* The move forward input
*/
MOVE_FORWARD(s -> s.keyBindForward),
/**
* The move back input
*/
MOVE_BACK(s -> s.keyBindBack),
/**
* The move left input
*/
MOVE_LEFT(s -> s.keyBindLeft),
/**
* The move right input
*/
MOVE_RIGHT(s -> s.keyBindRight),
/**
* The attack input
*/
CLICK_LEFT(s -> s.keyBindAttack),
/**
* The use item input
*/
CLICK_RIGHT(s -> s.keyBindUseItem),
/**
* The jump input
*/
JUMP(s -> s.keyBindJump),
/**
* The sneak input
*/
SNEAK(s -> s.keyBindSneak),
/**
* The sprint input
*/
SPRINT(s -> s.keyBindSprint);
/**
* Map of {@link KeyBinding} to {@link Input}. Values should be queried through {@link #getInputForBind(KeyBinding)}
*/
private static final Map<KeyBinding, Input> bindToInputMap = new HashMap<>();
/**
* The actual game {@link KeyBinding} being forced.
*/
private final KeyBinding keyBinding;
Input(Function<GameSettings, KeyBinding> keyBindingMapper) {
/*
Here, a Function is used because referring to a static field in this enum for the game instance,
as it was before, wouldn't be possible in an Enum constructor unless the static field was in an
interface that this class implemented. (Helper acted as this interface) I didn't feel like making
an interface with a game instance field just to not have to do this.
*/
this.keyBinding = keyBindingMapper.apply(Minecraft.getMinecraft().gameSettings);
}
/**
* @return The actual game {@link KeyBinding} being forced.
*/
public final KeyBinding getKeyBinding() {
return this.keyBinding;
}
/**
* Finds the {@link Input} constant that is associated with the specified {@link KeyBinding}.
*
* @param binding The {@link KeyBinding} to find the associated {@link Input} for
* @return The {@link Input} associated with the specified {@link KeyBinding}
*/
public static Input getInputForBind(KeyBinding binding) {
return bindToInputMap.computeIfAbsent(binding, b -> Arrays.stream(values()).filter(input -> input.keyBinding == b).findFirst().orElse(null));
}
}
@@ -0,0 +1,98 @@
/*
* 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 cabaletta.comms;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Do you not like having a blocking "receiveMessage" thingy?
* <p>
* Do you prefer just being able to get a list of all messages received since the last tick?
* <p>
* If so, this class is for you!
*
* @author leijurv
*/
public class BufferedConnection implements IConnection {
private final IConnection wrapped;
private final LinkedBlockingQueue<iMessage> queue;
private volatile transient IOException thrownOnRead;
public BufferedConnection(IConnection wrapped) {
this(wrapped, Integer.MAX_VALUE); // LinkedBlockingQueue accepts this as "no limit"
}
public BufferedConnection(IConnection wrapped, int maxInternalQueueSize) {
this.wrapped = wrapped;
this.queue = new LinkedBlockingQueue<>();
this.thrownOnRead = null;
new Thread(() -> {
try {
while (thrownOnRead == null) {
queue.put(wrapped.receiveMessage());
}
} catch (IOException e) {
thrownOnRead = e;
} catch (InterruptedException e) {
thrownOnRead = new IOException("Interrupted while enqueueing", e);
}
}).start();
}
@Override
public void sendMessage(iMessage message) throws IOException {
wrapped.sendMessage(message);
}
@Override
public iMessage receiveMessage() {
throw new UnsupportedOperationException("BufferedConnection can only be read from non-blockingly");
}
@Override
public void close() {
wrapped.close();
thrownOnRead = new EOFException("Closed");
}
public List<iMessage> receiveMessagesNonBlocking() throws IOException {
ArrayList<iMessage> msgs = new ArrayList<>();
queue.drainTo(msgs); // preserves order -- first message received will be first in this arraylist
if (msgs.isEmpty() && thrownOnRead != null) {
IOException up = new IOException("BufferedConnection wrapped", thrownOnRead);
throw up;
}
return msgs;
}
public void handleAllPendingMessages(IMessageListener listener) throws IOException {
receiveMessagesNonBlocking().forEach(msg -> msg.handle(listener));
}
public static BufferedConnection makeBuffered(IConnection conn) {
if (conn instanceof BufferedConnection) {
return (BufferedConnection) conn;
} else {
return new BufferedConnection(conn);
}
}
}
@@ -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 cabaletta.comms;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public enum ConstructingDeserializer implements MessageDeserializer {
INSTANCE;
private final List<Class<? extends iMessage>> MSGS;
ConstructingDeserializer() {
MSGS = new ArrayList<>();
// imagine doing something in reflect but it's actually concise and you don't need to catch 42069 different exceptions. huh.
for (Method m : IMessageListener.class.getDeclaredMethods()) {
if (m.getName().equals("handle")) {
MSGS.add((Class<? extends iMessage>) m.getParameterTypes()[0]);
}
}
}
@Override
public synchronized iMessage deserialize(DataInputStream in) throws IOException {
int type = ((int) in.readByte()) & 0xff;
try {
return MSGS.get(type).getConstructor(DataInputStream.class).newInstance(in);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException ex) {
throw new IOException("Unknown message type " + type, ex);
}
}
public byte getHeader(Class<? extends iMessage> klass) {
return (byte) MSGS.indexOf(klass);
}
}
@@ -0,0 +1,28 @@
/*
* 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 cabaletta.comms;
import java.io.IOException;
public interface IConnection {
void sendMessage(iMessage message) throws IOException;
iMessage receiveMessage() throws IOException;
void close();
}
@@ -0,0 +1,46 @@
/*
* 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 cabaletta.comms;
import cabaletta.comms.downward.MessageChat;
import cabaletta.comms.downward.MessageComputationRequest;
import cabaletta.comms.upward.MessageComputationResponse;
import cabaletta.comms.upward.MessageStatus;
public interface IMessageListener {
default void handle(MessageStatus message) {
unhandled(message);
}
default void handle(MessageChat message) {
unhandled(message);
}
default void handle(MessageComputationRequest message) {
unhandled(message);
}
default void handle(MessageComputationResponse message) {
unhandled(message);
}
default void unhandled(iMessage msg) {
// can override this to throw UnsupportedOperationException, if you want to make sure you're handling everything
// default is to silently ignore messages without handlers
}
}
@@ -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 cabaletta.comms;
import java.io.DataInputStream;
import java.io.IOException;
public interface MessageDeserializer {
iMessage deserialize(DataInputStream in) throws IOException;
}
+99
View File
@@ -0,0 +1,99 @@
/*
* 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 cabaletta.comms;
import java.io.EOFException;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Do you want a socket to localhost without actually making a gross real socket to localhost?
*/
public class Pipe<T extends iMessage> {
private final LinkedBlockingQueue<Optional<iMessage>> AtoB;
private final LinkedBlockingQueue<Optional<iMessage>> BtoA;
private final PipedConnection A;
private final PipedConnection B;
private volatile boolean closed;
public Pipe() {
this.AtoB = new LinkedBlockingQueue<>();
this.BtoA = new LinkedBlockingQueue<>();
this.A = new PipedConnection(BtoA, AtoB);
this.B = new PipedConnection(AtoB, BtoA);
}
public PipedConnection getA() {
return A;
}
public PipedConnection getB() {
return B;
}
public class PipedConnection implements IConnection {
private final LinkedBlockingQueue<Optional<iMessage>> in;
private final LinkedBlockingQueue<Optional<iMessage>> out;
private PipedConnection(LinkedBlockingQueue<Optional<iMessage>> in, LinkedBlockingQueue<Optional<iMessage>> out) {
this.in = in;
this.out = out;
}
@Override
public void sendMessage(iMessage message) throws IOException {
if (closed) {
throw new EOFException("Closed");
}
try {
out.put(Optional.of(message));
} catch (InterruptedException e) {
// this can never happen since the LinkedBlockingQueues are not constructed with a maximum capacity, see above
}
}
@Override
public iMessage receiveMessage() throws IOException {
if (closed) {
throw new EOFException("Closed");
}
try {
Optional<iMessage> t = in.take();
if (!t.isPresent()) {
throw new EOFException("Closed");
}
return t.get();
} catch (InterruptedException e) {
// again, cannot happen
// but we have to throw something
throw new IllegalStateException(e);
}
}
@Override
public void close() {
closed = true;
try {
AtoB.put(Optional.empty()); // unstick threads
BtoA.put(Optional.empty());
} catch (InterruptedException e) {
}
}
}
}
@@ -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 cabaletta.comms;
import java.io.*;
public class SerializedConnection implements IConnection {
private final DataInputStream in;
private final DataOutputStream out;
private final MessageDeserializer deserializer;
public SerializedConnection(InputStream in, OutputStream out) {
this(ConstructingDeserializer.INSTANCE, in, out);
}
public SerializedConnection(MessageDeserializer d, InputStream in, OutputStream out) {
this.in = new DataInputStream(in);
this.out = new DataOutputStream(out);
this.deserializer = d;
}
@Override
public synchronized void sendMessage(iMessage message) throws IOException {
message.writeHeader(out);
message.write(out);
}
@Override
public iMessage receiveMessage() throws IOException {
return deserializer.deserialize(in);
}
@Override
public void close() {
try {
in.close();
} catch (IOException e) {
}
try {
out.close();
} catch (IOException e) {
}
}
}
@@ -0,0 +1,27 @@
/*
* 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 cabaletta.comms;
import java.io.IOException;
import java.net.Socket;
public class SocketConnection extends SerializedConnection {
public SocketConnection(Socket s) throws IOException {
super(s.getInputStream(), s.getOutputStream());
}
}
@@ -0,0 +1,48 @@
/*
* 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 cabaletta.comms.downward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageChat implements iMessage {
public final String msg;
public MessageChat(DataInputStream in) throws IOException {
this.msg = in.readUTF();
}
public MessageChat(String msg) {
this.msg = msg;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeUTF(msg);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}
@@ -0,0 +1,62 @@
/*
* 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 cabaletta.comms.downward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageComputationRequest implements iMessage {
public final long computationID;
public final int startX;
public final int startY;
public final int startZ;
public final String goal; // TODO find a better way to do this lol
public MessageComputationRequest(DataInputStream in) throws IOException {
this.computationID = in.readLong();
this.startX = in.readInt();
this.startY = in.readInt();
this.startZ = in.readInt();
this.goal = in.readUTF();
}
public MessageComputationRequest(long computationID, int startX, int startY, int startZ, String goal) {
this.computationID = computationID;
this.startX = startX;
this.startY = startY;
this.startZ = startZ;
this.goal = goal;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeLong(computationID);
out.writeInt(startX);
out.writeInt(startY);
out.writeUTF(goal);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}
@@ -0,0 +1,44 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* hell yeah
* <p>
* <p>
* dumb android users cant read this file
* <p>
*
* @author leijurv
*/
public interface iMessage {
void write(DataOutputStream out) throws IOException;
default void writeHeader(DataOutputStream out) throws IOException {
out.writeByte(getHeader());
}
default byte getHeader() {
return ConstructingDeserializer.INSTANCE.getHeader(getClass());
}
void handle(IMessageListener listener);
}
@@ -0,0 +1,72 @@
/*
* 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 cabaletta.comms.upward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageComputationResponse implements iMessage {
public final long computationID;
public final int pathLength;
public final double pathCost;
public final boolean endsInGoal;
public final int endX;
public final int endY;
public final int endZ;
public MessageComputationResponse(DataInputStream in) throws IOException {
this.computationID = in.readLong();
this.pathLength = in.readInt();
this.pathCost = in.readDouble();
this.endsInGoal = in.readBoolean();
this.endX = in.readInt();
this.endY = in.readInt();
this.endZ = in.readInt();
}
public MessageComputationResponse(long computationID, int pathLength, double pathCost, boolean endsInGoal, int endX, int endY, int endZ) {
this.computationID = computationID;
this.pathLength = pathLength;
this.pathCost = pathCost;
this.endsInGoal = endsInGoal;
this.endX = endX;
this.endY = endY;
this.endZ = endZ;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeLong(computationID);
out.writeInt(pathLength);
out.writeDouble(pathCost);
out.writeBoolean(endsInGoal);
out.writeInt(endX);
out.writeInt(endY);
out.writeInt(endZ);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}
@@ -0,0 +1,124 @@
/*
* 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 cabaletta.comms.upward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageStatus implements iMessage {
public final double x;
public final double y;
public final double z;
public final float yaw;
public final float pitch;
public final boolean onGround;
public final float health;
public final float saturation;
public final int foodLevel;
public final int pathStartX;
public final int pathStartY;
public final int pathStartZ;
public final boolean hasCurrentSegment;
public final boolean hasNextSegment;
public final boolean calcInProgress;
public final double ticksRemainingInCurrent;
public final boolean calcFailedLastTick;
public final boolean safeToCancel;
public final String currentGoal;
public final String currentProcess;
public MessageStatus(DataInputStream in) throws IOException {
this.x = in.readDouble();
this.y = in.readDouble();
this.z = in.readDouble();
this.yaw = in.readFloat();
this.pitch = in.readFloat();
this.onGround = in.readBoolean();
this.health = in.readFloat();
this.saturation = in.readFloat();
this.foodLevel = in.readInt();
this.pathStartX = in.readInt();
this.pathStartY = in.readInt();
this.pathStartZ = in.readInt();
this.hasCurrentSegment = in.readBoolean();
this.hasNextSegment = in.readBoolean();
this.calcInProgress = in.readBoolean();
this.ticksRemainingInCurrent = in.readDouble();
this.calcFailedLastTick = in.readBoolean();
this.safeToCancel = in.readBoolean();
this.currentGoal = in.readUTF();
this.currentProcess = in.readUTF();
}
public MessageStatus(double x, double y, double z, float yaw, float pitch, boolean onGround, float health, float saturation, int foodLevel, int pathStartX, int pathStartY, int pathStartZ, boolean hasCurrentSegment, boolean hasNextSegment, boolean calcInProgress, double ticksRemainingInCurrent, boolean calcFailedLastTick, boolean safeToCancel, String currentGoal, String currentProcess) {
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
this.onGround = onGround;
this.health = health;
this.saturation = saturation;
this.foodLevel = foodLevel;
this.pathStartX = pathStartX;
this.pathStartY = pathStartY;
this.pathStartZ = pathStartZ;
this.hasCurrentSegment = hasCurrentSegment;
this.hasNextSegment = hasNextSegment;
this.calcInProgress = calcInProgress;
this.ticksRemainingInCurrent = ticksRemainingInCurrent;
this.calcFailedLastTick = calcFailedLastTick;
this.safeToCancel = safeToCancel;
this.currentGoal = currentGoal;
this.currentProcess = currentProcess;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeDouble(x);
out.writeDouble(y);
out.writeDouble(z);
out.writeFloat(yaw);
out.writeFloat(pitch);
out.writeBoolean(onGround);
out.writeFloat(health);
out.writeFloat(saturation);
out.writeInt(foodLevel);
out.writeInt(pathStartX);
out.writeInt(pathStartY);
out.writeInt(pathStartZ);
out.writeBoolean(hasCurrentSegment);
out.writeBoolean(hasNextSegment);
out.writeBoolean(calcInProgress);
out.writeDouble(ticksRemainingInCurrent);
out.writeBoolean(calcFailedLastTick);
out.writeBoolean(safeToCancel);
out.writeUTF(currentGoal);
out.writeUTF(currentProcess);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}
@@ -29,7 +29,7 @@ import java.util.List;
/**
* @author Brady
* @since 7/31/2018 9:59 PM
* @since 7/31/2018
*/
public class BaritoneTweaker extends SimpleTweaker {
@@ -32,7 +32,9 @@ import java.io.File;
@Mixin(AnvilChunkLoader.class)
public class MixinAnvilChunkLoader implements IAnvilChunkLoader {
@Shadow @Final private File chunkSaveLocation;
@Shadow
@Final
private File chunkSaveLocation;
@Override
public File getChunkSaveLocation() {
@@ -35,6 +35,12 @@ public class MixinBlockPos extends Vec3i {
super(xIn, yIn, zIn);
}
/**
* The purpose of this was to ensure a friendly name for when we print raw
* block positions to chat in the context of an obfuscated environment.
*
* @return a string representation of the object.
*/
@Override
@Nonnull
public String toString() {
@@ -0,0 +1,39 @@
/*
* 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.IChunkProviderClient;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.world.chunk.Chunk;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
@Mixin(ChunkProviderClient.class)
public class MixinChunkProviderClient implements IChunkProviderClient {
@Shadow
@Final
private Long2ObjectMap<Chunk> loadedChunks;
@Override
public Long2ObjectMap<Chunk> loadedChunks() {
return this.loadedChunks;
}
}
@@ -31,7 +31,9 @@ import org.spongepowered.asm.mixin.Shadow;
@Mixin(ChunkProviderServer.class)
public class MixinChunkProviderServer implements IChunkProviderServer {
@Shadow @Final private IChunkLoader chunkLoader;
@Shadow
@Final
private IChunkLoader chunkLoader;
@Override
public IChunkLoader getChunkLoader() {
@@ -17,16 +17,19 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.RotationMoveEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
/**
* @author Brady
* @since 8/21/2018
@@ -34,23 +37,38 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@Mixin(Entity.class)
public class MixinEntity {
@Shadow
public float rotationYaw;
/**
* Event called to override the movement direction when walking
*/
private RotationMoveEvent motionUpdateRotationEvent;
@Inject(
method = "moveRelative",
at = @At("HEAD")
)
private void preMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
Entity _this = (Entity) (Object) this;
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.MOTION_UPDATE));
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
this.motionUpdateRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.MOTION_UPDATE, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.motionUpdateRotationEvent);
}
}
@Inject(
@Redirect(
method = "moveRelative",
at = @At("RETURN")
at = @At(
value = "FIELD",
opcode = GETFIELD,
target = "net/minecraft/entity/Entity.rotationYaw:F"
)
)
private void postMoveRelative(float strafe, float up, float forward, float friction, CallbackInfo ci) {
Entity _this = (Entity) (Object) this;
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.MOTION_UPDATE));
private float overrideYaw(Entity self) {
if (self instanceof EntityPlayerSP) {
return this.motionUpdateRotationEvent.getYaw();
}
return self.rotationYaw;
}
}
@@ -17,40 +17,61 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.event.events.RotationMoveEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.Entity;
import net.minecraft.entity.EntityLivingBase;
import net.minecraft.world.World;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import static org.spongepowered.asm.lib.Opcodes.GETFIELD;
/**
* @author Brady
* @since 9/10/2018
*/
@Mixin(EntityLivingBase.class)
public class MixinEntityLivingBase {
public abstract class MixinEntityLivingBase extends Entity {
/**
* Event called to override the movement direction when jumping
*/
private RotationMoveEvent jumpRotationEvent;
public MixinEntityLivingBase(World worldIn, RotationMoveEvent jumpRotationEvent) {
super(worldIn);
this.jumpRotationEvent = jumpRotationEvent;
}
@Inject(
method = "jump",
at = @At("HEAD")
)
private void preJump(CallbackInfo ci) {
EntityLivingBase _this = (EntityLivingBase) (Object) this;
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.PRE, RotationMoveEvent.Type.JUMP));
private void preMoveRelative(CallbackInfo ci) {
// noinspection ConstantConditions
if (EntityPlayerSP.class.isInstance(this)) {
this.jumpRotationEvent = new RotationMoveEvent((EntityPlayerSP) (Object) this, RotationMoveEvent.Type.JUMP, this.rotationYaw);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerRotationMove(this.jumpRotationEvent);
}
}
@Inject(
@Redirect(
method = "jump",
at = @At("RETURN")
at = @At(
value = "FIELD",
opcode = GETFIELD,
target = "net/minecraft/entity/EntityLivingBase.rotationYaw:F"
)
)
private void postJump(CallbackInfo ci) {
EntityLivingBase _this = (EntityLivingBase) (Object) this;
if (EntityPlayerSP.class.isInstance(_this))
Baritone.INSTANCE.getGameEventHandler().onPlayerRotationMove(new RotationMoveEvent((EntityPlayerSP) _this, EventState.POST, RotationMoveEvent.Type.JUMP));
private float overrideYaw(EntityLivingBase self) {
if (self instanceof EntityPlayerSP) {
return this.jumpRotationEvent.getYaw();
}
return self.rotationYaw;
}
}
@@ -17,19 +17,22 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.entity.player.PlayerCapabilities;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* @author Brady
* @since 8/1/2018 5:06 PM
* @since 8/1/2018
*/
@Mixin(EntityPlayerSP.class)
public class MixinEntityPlayerSP {
@@ -41,7 +44,7 @@ public class MixinEntityPlayerSP {
)
private void sendChatMessage(String msg, CallbackInfo ci) {
ChatEvent event = new ChatEvent((EntityPlayerSP) (Object) this, msg);
Baritone.INSTANCE.getGameEventHandler().onSendChatMessage(event);
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onSendChatMessage(event);
if (event.isCancelled()) {
ci.cancel();
}
@@ -57,7 +60,7 @@ public class MixinEntityPlayerSP {
)
)
private void onPreUpdate(CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.PRE));
}
@Inject(
@@ -70,6 +73,18 @@ public class MixinEntityPlayerSP {
)
)
private void onPostUpdate(CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getGameEventHandler().onPlayerUpdate(new PlayerUpdateEvent((EntityPlayerSP) (Object) this, EventState.POST));
}
@Redirect(
method = "onLivingUpdate",
at = @At(
value = "FIELD",
target = "net/minecraft/entity/player/PlayerCapabilities.allowFlying:Z"
)
)
private boolean isAllowFlying(PlayerCapabilities capabilities) {
IPathingBehavior pathingBehavior = BaritoneAPI.getProvider().getBaritoneForPlayer((EntityPlayerSP) (Object) this).getPathingBehavior();
return !pathingBehavior.isPathing() && capabilities.allowFlying;
}
}
@@ -17,7 +17,8 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.RenderEvent;
import net.minecraft.client.renderer.EntityRenderer;
import org.spongepowered.asm.mixin.Mixin;
@@ -33,10 +34,12 @@ public class MixinEntityRenderer {
at = @At(
value = "INVOKE_STRING",
target = "Lnet/minecraft/profiler/Profiler;endStartSection(Ljava/lang/String;)V",
args = { "ldc=hand" }
args = {"ldc=hand"}
)
)
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
}
}
}
@@ -17,7 +17,7 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import net.minecraft.client.settings.KeyBinding;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.injection.At;
@@ -26,7 +26,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfoReturnable;
/**
* @author Brady
* @since 7/31/2018 11:44 PM
* @since 7/31/2018
*/
@Mixin(KeyBinding.class)
public class MixinKeyBinding {
@@ -37,7 +37,8 @@ public class MixinKeyBinding {
cancellable = true
)
private void isKeyDown(CallbackInfoReturnable<Boolean> cir) {
if (Baritone.INSTANCE.getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
// only the primary baritone forces keys
if (BaritoneAPI.getProvider().getPrimaryBaritone().getInputOverrideHandler().isInputForcedDown((KeyBinding) (Object) this)) {
cir.setReturnValue(true);
}
}
@@ -18,13 +18,13 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.WorldEvent;
import baritone.api.event.events.type.EventState;
import baritone.behavior.PathingBehavior;
import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen;
@@ -44,13 +44,11 @@ import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
/**
* @author Brady
* @since 7/31/2018 10:51 PM
* @since 7/31/2018
*/
@Mixin(Minecraft.class)
public class MixinMinecraft {
@Shadow
private int leftClickCounter;
@Shadow
public EntityPlayerSP player;
@Shadow
@@ -61,8 +59,7 @@ public class MixinMinecraft {
at = @At("RETURN")
)
private void postInit(CallbackInfo ci) {
Baritone.INSTANCE.init();
ExampleBaritoneControl.INSTANCE.initAndRegister();
((Baritone) BaritoneAPI.getProvider().getPrimaryBaritone()).init();
}
@Inject(
@@ -88,13 +85,15 @@ public class MixinMinecraft {
)
)
private void runTick(CallbackInfo ci) {
Minecraft mc = (Minecraft) (Object) this;
Baritone.INSTANCE.getGameEventHandler().onTick(new TickEvent(
EventState.PRE,
(mc.player != null && mc.world != null)
? TickEvent.Type.IN
: TickEvent.Type.OUT
));
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
TickEvent.Type type = ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().world() != null
? TickEvent.Type.IN
: TickEvent.Type.OUT;
ibaritone.getGameEventHandler().onTick(new TickEvent(EventState.PRE, type));
}
}
@Inject(
@@ -102,7 +101,8 @@ public class MixinMinecraft {
at = @At("HEAD")
)
private void runTickKeyboard(CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onProcessKeyBinds();
// keyboard input is only the primary baritone
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onProcessKeyBinds();
}
@Inject(
@@ -115,7 +115,9 @@ public class MixinMinecraft {
return;
}
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
// mc.world changing is only the primary baritone
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onWorldEvent(
new WorldEvent(
world,
EventState.PRE
@@ -130,7 +132,8 @@ public class MixinMinecraft {
private void postLoadWorld(WorldClient world, String loadingMessage, CallbackInfo ci) {
// still fire event for both null, as that means we've just finished exiting a world
Baritone.INSTANCE.getGameEventHandler().onWorldEvent(
// mc.world changing is only the primary baritone
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onWorldEvent(
new WorldEvent(
world,
EventState.POST
@@ -147,7 +150,8 @@ public class MixinMinecraft {
)
)
private boolean isAllowUserInput(GuiScreen screen) {
return (PathingBehavior.INSTANCE.getCurrent() != null && PathingBehavior.INSTANCE.isEnabled() && player != null) || screen.allowUserInput;
// allow user input is only the primary baritone
return (BaritoneAPI.getProvider().getPrimaryBaritone().getPathingBehavior().getCurrent() != null && player != null) || screen.allowUserInput;
}
@Inject(
@@ -159,7 +163,8 @@ public class MixinMinecraft {
locals = LocalCapture.CAPTURE_FAILHARD
)
private void onBlockBreak(CallbackInfo ci, BlockPos pos) {
Baritone.INSTANCE.getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.BREAK));
// clickMouse is only for the main player
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(pos, BlockInteractEvent.Type.BREAK));
}
@Inject(
@@ -171,6 +176,7 @@ public class MixinMinecraft {
locals = LocalCapture.CAPTURE_FAILHARD
)
private void onBlockUse(CallbackInfo ci, EnumHand var1[], int var2, int var3, EnumHand enumhand, ItemStack itemstack, BlockPos blockpos, int i, EnumActionResult enumactionresult) {
Baritone.INSTANCE.getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
// rightClickMouse is only for the main player
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
}
}
@@ -17,7 +17,8 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.ChunkEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.network.NetHandlerPlayClient;
@@ -30,7 +31,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* @author Brady
* @since 8/3/2018 12:54 AM
* @since 8/3/2018
*/
@Mixin(NetHandlerPlayClient.class)
public class MixinNetHandlerPlayClient {
@@ -43,14 +44,18 @@ public class MixinNetHandlerPlayClient {
)
)
private void preRead(SPacketChunkData packetIn, CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
ChunkEvent.Type.POPULATE,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
}
}
}
@Inject(
@@ -58,14 +63,18 @@ public class MixinNetHandlerPlayClient {
at = @At("RETURN")
)
private void postHandleChunkData(SPacketChunkData packetIn, CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
ChunkEvent.Type.POPULATE,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
packetIn.isFullChunk() ? ChunkEvent.Type.POPULATE_FULL : ChunkEvent.Type.POPULATE_PARTIAL,
packetIn.getChunkX(),
packetIn.getChunkZ()
)
);
}
}
}
@Inject(
@@ -76,6 +85,10 @@ public class MixinNetHandlerPlayClient {
)
)
private void onPlayerDeath(SPacketCombatEvent packetIn, CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onPlayerDeath();
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player().connection == (NetHandlerPlayClient) (Object) this) {
ibaritone.getGameEventHandler().onPlayerDeath();
}
}
}
}
@@ -17,7 +17,8 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.type.EventState;
import io.netty.channel.Channel;
@@ -36,7 +37,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* @author Brady
* @since 8/6/2018 9:30 PM
* @since 8/6/2018
*/
@Mixin(NetworkManager.class)
public class MixinNetworkManager {
@@ -53,8 +54,14 @@ public class MixinNetworkManager {
at = @At("HEAD")
)
private void preDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, inPacket));
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
return;
}
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
ibaritone.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, inPacket));
}
}
}
@@ -63,8 +70,14 @@ public class MixinNetworkManager {
at = @At("RETURN")
)
private void postDispatchPacket(Packet<?> inPacket, final GenericFutureListener<? extends Future<? super Void>>[] futureListeners, CallbackInfo ci) {
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, inPacket));
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
return;
}
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
ibaritone.getGameEventHandler().onSendPacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, inPacket));
}
}
}
@@ -76,8 +89,14 @@ public class MixinNetworkManager {
)
)
private void preProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
if (this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));}
if (this.direction != EnumPacketDirection.CLIENTBOUND) {
return;
}
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
ibaritone.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.PRE, packet));
}
}
}
@Inject(
@@ -85,8 +104,13 @@ public class MixinNetworkManager {
at = @At("RETURN")
)
private void postProcessPacket(ChannelHandlerContext context, Packet<?> packet, CallbackInfo ci) {
if (this.channel.isOpen() && this.direction == EnumPacketDirection.CLIENTBOUND) {
Baritone.INSTANCE.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, packet));
if (!this.channel.isOpen() || this.direction != EnumPacketDirection.CLIENTBOUND) {
return;
}
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().player() != null && ibaritone.getPlayerContext().player().connection.getNetworkManager() == (NetworkManager) (Object) this) {
ibaritone.getGameEventHandler().onReceivePacket(new PacketEvent((NetworkManager) (Object) this, EventState.POST, packet));
}
}
}
}
@@ -17,7 +17,8 @@
package baritone.launch.mixins;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.ChunkEvent;
import baritone.api.event.events.type.EventState;
import net.minecraft.client.multiplayer.WorldClient;
@@ -28,7 +29,7 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
/**
* @author Brady
* @since 8/2/2018 12:41 AM
* @since 8/2/2018
*/
@Mixin(WorldClient.class)
public class MixinWorldClient {
@@ -38,14 +39,19 @@ public class MixinWorldClient {
at = @At("HEAD")
)
private void preDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
chunkX,
chunkZ
)
);
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.PRE,
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
chunkX,
chunkZ
)
);
}
}
}
@Inject(
@@ -53,13 +59,17 @@ public class MixinWorldClient {
at = @At("RETURN")
)
private void postDoPreChunk(int chunkX, int chunkZ, boolean loadChunk, CallbackInfo ci) {
Baritone.INSTANCE.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
chunkX,
chunkZ
)
);
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
if (ibaritone.getPlayerContext().world() == (WorldClient) (Object) this) {
ibaritone.getGameEventHandler().onChunkEvent(
new ChunkEvent(
EventState.POST,
loadChunk ? ChunkEvent.Type.LOAD : ChunkEvent.Type.UNLOAD,
chunkX,
chunkZ
)
);
}
}
}
}
@@ -10,6 +10,7 @@
"client": [
"MixinAnvilChunkLoader",
"MixinBlockPos",
"MixinChunkProviderClient",
"MixinChunkProviderServer",
"MixinEntity",
"MixinEntityLivingBase",
+137 -69
View File
@@ -18,12 +18,22 @@
package baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.IGameEventListener;
import baritone.api.event.listener.IEventBus;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.event.GameEventHandler;
import baritone.process.CustomGoalProcess;
import baritone.process.FollowProcess;
import baritone.process.GetToBlockProcess;
import baritone.process.MineProcess;
import baritone.utils.BaritoneAutoTest;
import baritone.utils.ExampleBaritoneControl;
import baritone.utils.InputOverrideHandler;
import baritone.utils.PathingControlManager;
import baritone.utils.player.PrimaryPlayerContext;
import net.minecraft.client.Minecraft;
import java.io.File;
@@ -38,14 +48,23 @@ import java.util.concurrent.TimeUnit;
/**
* @author Brady
* @since 7/31/2018 10:50 PM
* @since 7/31/2018
*/
public enum Baritone {
public class Baritone implements IBaritone {
/**
* Singleton instance of this class
*/
INSTANCE;
private static ThreadPoolExecutor threadPool;
private static File dir;
static {
threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
if (!Files.exists(dir.toPath())) {
try {
Files.createDirectories(dir.toPath());
} catch (IOException ignored) {}
}
}
/**
* Whether or not {@link Baritone#init()} has been called yet
@@ -53,97 +72,146 @@ public enum Baritone {
private boolean initialized;
private GameEventHandler gameEventHandler;
private InputOverrideHandler inputOverrideHandler;
private Settings settings;
private List<Behavior> behaviors;
private File dir;
private ThreadPoolExecutor threadPool;
/**
* Whether or not Baritone is active
*/
private boolean active;
private List<Behavior> behaviors;
private ControllerBehavior controllerBehavior;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
private InputOverrideHandler inputOverrideHandler;
private FollowProcess followProcess;
private MineProcess mineProcess;
private GetToBlockProcess getToBlockProcess;
private CustomGoalProcess customGoalProcess;
private PathingControlManager pathingControlManager;
private IPlayerContext playerContext;
private WorldProvider worldProvider;
Baritone() {
this.gameEventHandler = new GameEventHandler();
this.gameEventHandler = new GameEventHandler(this);
}
public synchronized void init() {
if (initialized) {
return;
}
this.threadPool = new ThreadPoolExecutor(4, Integer.MAX_VALUE, 60L, TimeUnit.SECONDS, new SynchronousQueue<>());
this.inputOverrideHandler = new InputOverrideHandler();
// Acquire the "singleton" instance of the settings directly from the API
// We might want to change this...
this.settings = BaritoneAPI.getSettings();
// Define this before behaviors try and get it, or else it will be null and the builds will fail!
this.playerContext = PrimaryPlayerContext.INSTANCE;
this.behaviors = new ArrayList<>();
{
registerBehavior(PathingBehavior.INSTANCE);
registerBehavior(LookBehavior.INSTANCE);
registerBehavior(MemoryBehavior.INSTANCE);
registerBehavior(LocationTrackingBehavior.INSTANCE);
registerBehavior(FollowBehavior.INSTANCE);
registerBehavior(MineBehavior.INSTANCE);
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
controllerBehavior = new ControllerBehavior(this);
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
memoryBehavior = new MemoryBehavior(this);
inputOverrideHandler = new InputOverrideHandler(this);
new ExampleBaritoneControl(this);
}
this.pathingControlManager = new PathingControlManager(this);
{
followProcess = new FollowProcess(this);
mineProcess = new MineProcess(this);
customGoalProcess = new CustomGoalProcess(this); // very high iq
getToBlockProcess = new GetToBlockProcess(this);
}
this.worldProvider = new WorldProvider();
if (BaritoneAutoTest.ENABLE_AUTO_TEST) {
registerEventListener(BaritoneAutoTest.INSTANCE);
}
this.dir = new File(Minecraft.getMinecraft().gameDir, "baritone");
if (!Files.exists(dir.toPath())) {
try {
Files.createDirectories(dir.toPath());
} catch (IOException ignored) {}
this.gameEventHandler.registerEventListener(BaritoneAutoTest.INSTANCE);
}
this.active = true;
this.initialized = true;
}
public boolean isInitialized() {
return this.initialized;
}
public IGameEventListener getGameEventHandler() {
return this.gameEventHandler;
}
public InputOverrideHandler getInputOverrideHandler() {
return this.inputOverrideHandler;
}
public List<Behavior> getBehaviors() {
return this.behaviors;
}
public Executor getExecutor() {
public void registerBehavior(Behavior behavior) {
this.behaviors.add(behavior);
this.gameEventHandler.registerEventListener(behavior);
}
@Override
public PathingControlManager getPathingControlManager() {
return this.pathingControlManager;
}
@Override
public InputOverrideHandler getInputOverrideHandler() {
return this.inputOverrideHandler;
}
public ControllerBehavior getControllerBehavior() {
return this.controllerBehavior;
}
@Override
public CustomGoalProcess getCustomGoalProcess() { // Iffy
return this.customGoalProcess;
}
@Override
public GetToBlockProcess getGetToBlockProcess() { // Iffy
return this.getToBlockProcess;
}
@Override
public PathingBehavior getPathingBehavior() {
return this.pathingBehavior;
}
@Override
public MemoryBehavior getMemoryBehavior() {
return this.memoryBehavior;
}
@Override
public IPlayerContext getPlayerContext() {
return this.playerContext;
}
@Override
public FollowProcess getFollowProcess() {
return this.followProcess;
}
@Override
public WorldProvider getWorldProvider() {
return this.worldProvider;
}
@Override
public IEventBus getGameEventHandler() {
return this.gameEventHandler;
}
@Override
public LookBehavior getLookBehavior() {
return this.lookBehavior;
}
@Override
public MineProcess getMineProcess() {
return this.mineProcess;
}
public static Executor getExecutor() {
return threadPool;
}
public void registerBehavior(Behavior behavior) {
this.behaviors.add(behavior);
this.registerEventListener(behavior);
}
public void registerEventListener(IGameEventListener listener) {
this.gameEventHandler.registerEventListener(listener);
}
public boolean isActive() {
return this.active;
}
public Settings getSettings() {
return this.settings;
}
public static Settings settings() {
return Baritone.INSTANCE.settings; // yolo
return BaritoneAPI.getSettings();
}
public File getDir() {
return this.dir;
public static File getDir() {
return dir;
}
}
+11 -34
View File
@@ -17,58 +17,35 @@
package baritone;
import baritone.api.IBaritone;
import baritone.api.IBaritoneProvider;
import baritone.api.behavior.*;
import baritone.api.cache.IWorldProvider;
import baritone.api.cache.IWorldScanner;
import baritone.api.event.listener.IGameEventListener;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import java.util.Collections;
import java.util.List;
/**
* @author Brady
* @since 9/29/2018
*/
public final class BaritoneProvider implements IBaritoneProvider {
private final Baritone primary = new Baritone();
@Override
public IFollowBehavior getFollowBehavior() {
return FollowBehavior.INSTANCE;
public IBaritone getPrimaryBaritone() {
return primary;
}
@Override
public ILookBehavior getLookBehavior() {
return LookBehavior.INSTANCE;
}
@Override
public IMemoryBehavior getMemoryBehavior() {
return MemoryBehavior.INSTANCE;
}
@Override
public IMineBehavior getMineBehavior() {
return MineBehavior.INSTANCE;
}
@Override
public IPathingBehavior getPathingBehavior() {
return PathingBehavior.INSTANCE;
}
@Override
public IWorldProvider getWorldProvider() {
return WorldProvider.INSTANCE;
public List<IBaritone> getAllBaritones() {
// TODO return a CopyOnWriteArrayList
return Collections.singletonList(primary);
}
@Override
public IWorldScanner getWorldScanner() {
return WorldScanner.INSTANCE;
}
@Override
public void registerEventListener(IGameEventListener listener) {
Baritone.INSTANCE.registerEventListener(listener);
}
}
+10 -40
View File
@@ -17,54 +17,24 @@
package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IBehavior;
import baritone.api.utils.IPlayerContext;
/**
* A type of game event listener that can be toggled.
* A type of game event listener that is given {@link Baritone} instance context.
*
* @author Brady
* @since 8/1/2018 6:29 PM
* @since 8/1/2018
*/
public class Behavior implements IBehavior {
/**
* Whether or not this behavior is enabled
*/
private boolean enabled = true;
public final Baritone baritone;
public final IPlayerContext ctx;
/**
* Toggles the enabled state of this {@link Behavior}.
*
* @return The new state.
*/
@Override
public final boolean toggle() {
return this.setEnabled(!this.isEnabled());
}
/**
* Sets the enabled state of this {@link Behavior}.
*
* @return The new state.
*/
@Override
public final boolean setEnabled(boolean enabled) {
if (enabled == this.enabled) {
return this.enabled;
}
if (this.enabled = enabled) {
this.onEnable();
} else {
this.onDisable();
}
return this.enabled;
}
/**
* @return Whether or not this {@link Behavior} is active.
*/
@Override
public final boolean isEnabled() {
return this.enabled;
protected Behavior(Baritone baritone) {
this.baritone = baritone;
this.ctx = baritone.getPlayerContext();
baritone.registerBehavior(this);
}
}
@@ -0,0 +1,163 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.Baritone;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalYLevel;
import baritone.api.process.IBaritoneProcess;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.CalculationContext;
import baritone.utils.Helper;
import baritone.utils.pathing.SegmentedCalculator;
import cabaletta.comms.BufferedConnection;
import cabaletta.comms.IConnection;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.downward.MessageChat;
import cabaletta.comms.downward.MessageComputationRequest;
import cabaletta.comms.iMessage;
import cabaletta.comms.upward.MessageComputationResponse;
import cabaletta.comms.upward.MessageStatus;
import net.minecraft.util.math.BlockPos;
import java.io.IOException;
import java.util.Objects;
public class ControllerBehavior extends Behavior implements IMessageListener {
public ControllerBehavior(Baritone baritone) {
super(baritone);
}
private BufferedConnection conn;
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
return;
}
trySend(buildStatus());
readAndHandle();
}
public MessageStatus buildStatus() {
// TODO report inventory and echest contents
// TODO figure out who should remember echest contents when it isn't open, baritone or tenor?
BlockPos pathStart = baritone.getPathingBehavior().pathStart();
return new MessageStatus(
ctx.player().posX,
ctx.player().posY,
ctx.player().posZ,
ctx.player().rotationYaw,
ctx.player().rotationPitch,
ctx.player().onGround,
ctx.player().getHealth(),
ctx.player().getFoodStats().getSaturationLevel(),
ctx.player().getFoodStats().getFoodLevel(),
pathStart.getX(),
pathStart.getY(),
pathStart.getZ(),
baritone.getPathingBehavior().getCurrent() != null,
baritone.getPathingBehavior().getNext() != null,
baritone.getPathingBehavior().getInProgress().isPresent(),
baritone.getPathingBehavior().ticksRemainingInSegment().orElse(0D),
baritone.getPathingBehavior().calcFailedLastTick(),
baritone.getPathingBehavior().isSafeToCancel(),
baritone.getPathingBehavior().getGoal() + "",
baritone.getPathingControlManager().mostRecentInControl().map(IBaritoneProcess::displayName).orElse("")
);
}
private void readAndHandle() {
if (conn == null) {
return;
}
try {
conn.handleAllPendingMessages(this);
} catch (IOException e) {
e.printStackTrace();
disconnect();
}
}
public boolean trySend(iMessage msg) {
if (conn == null) {
return false;
}
try {
conn.sendMessage(msg);
return true;
} catch (IOException e) {
e.printStackTrace();
disconnect();
return false;
}
}
public void connectTo(IConnection conn) {
disconnect();
this.conn = BufferedConnection.makeBuffered(conn);
}
public void disconnect() {
if (conn != null) {
conn.close();
}
conn = null;
}
@Override
public void handle(MessageChat msg) { // big brain
ChatEvent event = new ChatEvent(ctx.player(), msg.msg);
baritone.getGameEventHandler().onSendChatMessage(event);
}
@Override
public void handle(MessageComputationRequest msg) {
BetterBlockPos start = new BetterBlockPos(msg.startX, msg.startY, msg.startZ);
// TODO this may require scanning the world for blocks of a certain type, idk how to manage that
Goal goal = new GoalYLevel(Integer.parseInt(msg.goal)); // im already winston
SegmentedCalculator.calculateSegmentsThreaded(start, goal, new CalculationContext(baritone), path -> {
if (!Objects.equals(path.getGoal(), goal)) {
throw new IllegalStateException(); // sanity check
}
try {
BetterBlockPos dest = path.getDest();
conn.sendMessage(new MessageComputationResponse(msg.computationID, path.length(), path.totalTicks(), path.getGoal().isInGoal(dest), dest.x, dest.y, dest.z));
} catch (IOException e) {
// nothing we can do about this, we just completed a computation but our tenor connection was closed in the meantime
// just discard the path we made for them =((
e.printStackTrace(); // and complain =)
}
}, () -> {
try {
conn.sendMessage(new MessageComputationResponse(msg.computationID, 0, 0, false, 0, 0, 0));
} catch (IOException e) {
// same deal
e.printStackTrace();
}
});
}
@Override
public void unhandled(iMessage msg) {
Helper.HELPER.logDebug("Unhandled message received by ControllerBehavior " + msg);
}
}
@@ -1,79 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IFollowBehavior;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.GoalNear;
import baritone.api.pathing.goals.GoalXZ;
import baritone.utils.Helper;
import net.minecraft.entity.Entity;
import net.minecraft.util.math.BlockPos;
/**
* Follow an entity
*
* @author leijurv
*/
public final class FollowBehavior extends Behavior implements IFollowBehavior, Helper {
public static final FollowBehavior INSTANCE = new FollowBehavior();
private Entity following;
private FollowBehavior() {}
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
following = null;
return;
}
if (following == null) {
return;
}
// lol this is trashy but it works
BlockPos pos;
if (Baritone.settings().followOffsetDistance.get() == 0) {
pos = following.getPosition();
} else {
GoalXZ g = GoalXZ.fromDirection(following.getPositionVector(), Baritone.settings().followOffsetDirection.get(), Baritone.settings().followOffsetDistance.get());
pos = new BlockPos(g.getX(), following.posY, g.getZ());
}
PathingBehavior.INSTANCE.setGoal(new GoalNear(pos, Baritone.settings().followRadius.get()));
PathingBehavior.INSTANCE.revalidateGoal();
PathingBehavior.INSTANCE.path();
}
@Override
public void follow(Entity entity) {
this.following = entity;
}
@Override
public Entity following() {
return this.following;
}
@Override
public void cancel() {
PathingBehavior.INSTANCE.cancel();
follow(null);
}
}
@@ -1,53 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.api.event.events.BlockInteractEvent;
import baritone.cache.Waypoint;
import baritone.cache.WorldProvider;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.BlockBed;
/**
* A collection of event methods that are used to interact with Baritone's
* waypoint system. This class probably needs a better name.
*
* @see Waypoint
*
* @author Brady
* @since 8/22/2018
*/
public final class LocationTrackingBehavior extends Behavior implements Helper {
public static final LocationTrackingBehavior INSTANCE = new LocationTrackingBehavior();
private LocationTrackingBehavior() {}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(event.getPos()) instanceof BlockBed) {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
}
}
@Override
public void onPlayerDeath() {
WorldProvider.INSTANCE.getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, playerFeet()));
}
}
@@ -23,11 +23,8 @@ import baritone.api.behavior.ILookBehavior;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.RotationMoveEvent;
import baritone.api.utils.Rotation;
import baritone.utils.Helper;
public final class LookBehavior extends Behavior implements ILookBehavior, Helper {
public static final LookBehavior INSTANCE = new LookBehavior();
public final class LookBehavior extends Behavior implements ILookBehavior {
/**
* Target's values are as follows:
@@ -49,7 +46,9 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
*/
private float lastYaw;
private LookBehavior() {}
public LookBehavior(Baritone baritone) {
super(baritone);
}
@Override
public void updateTarget(Rotation target, boolean force) {
@@ -64,28 +63,29 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
}
// Whether or not we're going to silently set our angles
boolean silent = Baritone.settings().antiCheatCompatibility.get();
boolean silent = Baritone.settings().antiCheatCompatibility.get() && !this.force;
switch (event.getState()) {
case PRE: {
if (this.force) {
player().rotationYaw = this.target.getYaw();
float oldPitch = player().rotationPitch;
ctx.player().rotationYaw = this.target.getYaw();
float oldPitch = ctx.player().rotationPitch;
float desiredPitch = this.target.getPitch();
player().rotationPitch = desiredPitch;
ctx.player().rotationPitch = desiredPitch;
if (desiredPitch == oldPitch) {
nudgeToLevel();
}
this.target = null;
} else if (silent) {
this.lastYaw = player().rotationYaw;
player().rotationYaw = this.target.getYaw();
}
if (silent) {
this.lastYaw = ctx.player().rotationYaw;
ctx.player().rotationYaw = this.target.getYaw();
}
break;
}
case POST: {
if (!this.force && silent) {
player().rotationYaw = this.lastYaw;
if (silent) {
ctx.player().rotationYaw = this.lastYaw;
this.target = null;
}
break;
@@ -98,31 +98,25 @@ public final class LookBehavior extends Behavior implements ILookBehavior, Helpe
@Override
public void onPlayerRotationMove(RotationMoveEvent event) {
if (this.target != null && !this.force) {
switch (event.getState()) {
case PRE:
this.lastYaw = player().rotationYaw;
player().rotationYaw = this.target.getYaw();
break;
case POST:
player().rotationYaw = this.lastYaw;
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
// Also the type has to be MOTION_UPDATE because that is called after JUMP
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
this.target = null;
}
break;
default:
break;
event.setYaw(this.target.getYaw());
// If we have antiCheatCompatibility on, we're going to use the target value later in onPlayerUpdate()
// Also the type has to be MOTION_UPDATE because that is called after JUMP
if (!Baritone.settings().antiCheatCompatibility.get() && event.getType() == RotationMoveEvent.Type.MOTION_UPDATE) {
this.target = null;
}
}
}
/**
* Nudges the player's pitch to a regular level. (Between {@code -20} and {@code 10}, increments are by {@code 1})
*/
private void nudgeToLevel() {
if (player().rotationPitch < -20) {
player().rotationPitch++;
} else if (player().rotationPitch > 10) {
player().rotationPitch--;
if (ctx.player().rotationPitch < -20) {
ctx.player().rotationPitch++;
} else if (ctx.player().rotationPitch > 10) {
ctx.player().rotationPitch--;
}
}
}
@@ -17,14 +17,17 @@
package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IMemoryBehavior;
import baritone.api.behavior.memory.IRememberedInventory;
import baritone.api.cache.IWorldData;
import baritone.api.event.events.BlockInteractEvent;
import baritone.api.event.events.PacketEvent;
import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.type.EventState;
import baritone.cache.WorldProvider;
import baritone.utils.Helper;
import baritone.cache.Waypoint;
import baritone.utils.BlockStateInterface;
import net.minecraft.block.BlockBed;
import net.minecraft.item.ItemStack;
import net.minecraft.network.Packet;
import net.minecraft.network.play.client.CPacketCloseWindow;
@@ -39,15 +42,15 @@ import java.util.*;
/**
* @author Brady
* @since 8/6/2018 9:47 PM
* @since 8/6/2018
*/
public final class MemoryBehavior extends Behavior implements IMemoryBehavior, Helper {
public static MemoryBehavior INSTANCE = new MemoryBehavior();
public final class MemoryBehavior extends Behavior implements IMemoryBehavior {
private final Map<IWorldData, WorldDataContainer> worldDataContainers = new HashMap<>();
private MemoryBehavior() {}
public MemoryBehavior(Baritone baritone) {
super(baritone);
}
@Override
public synchronized void onPlayerUpdate(PlayerUpdateEvent event) {
@@ -64,7 +67,7 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
if (p instanceof CPacketPlayerTryUseItemOnBlock) {
CPacketPlayerTryUseItemOnBlock packet = event.cast();
TileEntity tileEntity = world().getTileEntity(packet.getPos());
TileEntity tileEntity = ctx.world().getTileEntity(packet.getPos());
// Ensure the TileEntity is a container of some sort
if (tileEntity instanceof TileEntityLockable) {
@@ -114,19 +117,31 @@ public final class MemoryBehavior extends Behavior implements IMemoryBehavior, H
}
}
@Override
public void onBlockInteract(BlockInteractEvent event) {
if (event.getType() == BlockInteractEvent.Type.USE && BlockStateInterface.getBlock(ctx, event.getPos()) instanceof BlockBed) {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("bed", Waypoint.Tag.BED, event.getPos()));
}
}
@Override
public void onPlayerDeath() {
baritone.getWorldProvider().getCurrentWorld().getWaypoints().addWaypoint(new Waypoint("death", Waypoint.Tag.DEATH, ctx.playerFeet()));
}
private Optional<RememberedInventory> getInventoryFromWindow(int windowId) {
return this.getCurrentContainer().rememberedInventories.values().stream().filter(i -> i.windowId == windowId).findFirst();
}
private void updateInventory() {
getInventoryFromWindow(player().openContainer.windowId).ifPresent(inventory -> {
getInventoryFromWindow(ctx.player().openContainer.windowId).ifPresent(inventory -> {
inventory.items.clear();
inventory.items.addAll(player().openContainer.getInventory().subList(0, inventory.size));
inventory.items.addAll(ctx.player().openContainer.getInventory().subList(0, inventory.size));
});
}
private WorldDataContainer getCurrentContainer() {
return this.worldDataContainers.computeIfAbsent(WorldProvider.INSTANCE.getCurrentWorld(), data -> new WorldDataContainer());
return this.worldDataContainers.computeIfAbsent(baritone.getWorldProvider().getCurrentWorld(), data -> new WorldDataContainer());
}
@Override
@@ -1,200 +0,0 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.Baritone;
import baritone.api.behavior.IMineBehavior;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalBlock;
import baritone.api.pathing.goals.GoalComposite;
import baritone.api.pathing.goals.GoalTwoBlocks;
import baritone.cache.CachedChunk;
import baritone.cache.ChunkPacker;
import baritone.cache.WorldProvider;
import baritone.cache.WorldScanner;
import baritone.utils.BlockStateInterface;
import baritone.utils.Helper;
import net.minecraft.block.Block;
import net.minecraft.init.Blocks;
import net.minecraft.item.Item;
import net.minecraft.item.ItemStack;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.*;
import java.util.stream.Collectors;
/**
* Mine blocks of a certain type
*
* @author leijurv
*/
public final class MineBehavior extends Behavior implements IMineBehavior, Helper {
public static final MineBehavior INSTANCE = new MineBehavior();
private List<Block> mining;
private List<BlockPos> locationsCache;
private int quantity;
private MineBehavior() {}
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
cancel();
return;
}
if (mining == null) {
return;
}
if (quantity > 0) {
Item item = mining.get(0).getItemDropped(mining.get(0).getDefaultState(), new Random(), 0);
int curr = player().inventory.mainInventory.stream().filter(stack -> item.equals(stack.getItem())).mapToInt(ItemStack::getCount).sum();
System.out.println("Currently have " + curr + " " + item);
if (curr >= quantity) {
logDirect("Have " + curr + " " + item.getItemStackDisplayName(new ItemStack(item, 1)));
cancel();
return;
}
}
int mineGoalUpdateInterval = Baritone.settings().mineGoalUpdateInterval.get();
if (mineGoalUpdateInterval != 0) {
if (event.getCount() % mineGoalUpdateInterval == 0) {
Baritone.INSTANCE.getExecutor().execute(this::rescan);
}
}
updateGoal();
PathingBehavior.INSTANCE.revalidateGoal();
}
private void updateGoal() {
if (mining == null) {
return;
}
List<BlockPos> locs = locationsCache;
if (!locs.isEmpty()) {
locs = prune(new ArrayList<>(locs), mining, 64);
PathingBehavior.INSTANCE.setGoal(coalesce(locs));
PathingBehavior.INSTANCE.path();
locationsCache = locs;
}
}
private void rescan() {
if (mining == null) {
return;
}
List<BlockPos> locs = scanFor(mining, 64);
if (locs.isEmpty()) {
logDebug("No locations for " + mining + " known, cancelling");
mine(0, (String[]) null);
return;
}
locationsCache = locs;
}
public Goal coalesce(BlockPos loc, List<BlockPos> locs) {
if (!Baritone.settings().forceInternalMining.get()) {
return new GoalTwoBlocks(loc);
}
boolean upwardGoal = locs.contains(loc.up()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
boolean downwardGoal = locs.contains(loc.down()) || (Baritone.settings().internalMiningAirException.get() && BlockStateInterface.getBlock(loc.up()) == Blocks.AIR);
if (upwardGoal) {
if (downwardGoal) {
return new GoalTwoBlocks(loc);
} else {
return new GoalBlock(loc);
}
} else {
if (downwardGoal) {
return new GoalBlock(loc.down());
} else {
return new GoalTwoBlocks(loc);
}
}
}
public GoalComposite coalesce(List<BlockPos> locs) {
return new GoalComposite(locs.stream().map(loc -> coalesce(loc, locs)).toArray(Goal[]::new));
}
public List<BlockPos> scanFor(List<Block> mining, int max) {
List<BlockPos> locs = new ArrayList<>();
List<Block> uninteresting = new ArrayList<>();
//long b = System.currentTimeMillis();
for (Block m : mining) {
if (CachedChunk.BLOCKS_TO_KEEP_TRACK_OF.contains(m)) {
locs.addAll(WorldProvider.INSTANCE.getCurrentWorld().getCachedWorld().getLocationsOf(ChunkPacker.blockToString(m), 1, 1));
} else {
uninteresting.add(m);
}
}
//System.out.println("Scan of cached chunks took " + (System.currentTimeMillis() - b) + "ms");
if (locs.isEmpty()) {
uninteresting = mining;
}
if (!uninteresting.isEmpty()) {
//long before = System.currentTimeMillis();
locs.addAll(WorldScanner.INSTANCE.scanChunkRadius(uninteresting, max, 10, 26));
//System.out.println("Scan of loaded chunks took " + (System.currentTimeMillis() - before) + "ms");
}
return prune(locs, mining, max);
}
public List<BlockPos> prune(List<BlockPos> locs, List<Block> mining, int max) {
BlockPos playerFeet = MineBehavior.INSTANCE.playerFeet();
locs.sort(Comparator.comparingDouble(playerFeet::distanceSq));
// remove any that are within loaded chunks that aren't actually what we want
locs.removeAll(locs.stream()
.filter(pos -> !(MineBehavior.INSTANCE.world().getChunk(pos) instanceof EmptyChunk))
.filter(pos -> !mining.contains(BlockStateInterface.get(pos).getBlock()))
.collect(Collectors.toList()));
if (locs.size() > max) {
return locs.subList(0, max);
}
return locs;
}
@Override
public void mine(int quantity, String... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.stream(blocks).map(ChunkPacker::stringToBlock).collect(Collectors.toList());
this.quantity = quantity;
this.locationsCache = new ArrayList<>();
rescan();
updateGoal();
}
@Override
public void mine(int quantity, Block... blocks) {
this.mining = blocks == null || blocks.length == 0 ? null : Arrays.asList(blocks);
this.quantity = quantity;
this.locationsCache = new ArrayList<>();
rescan();
updateGoal();
}
@Override
public void cancel() {
mine(0, (String[]) null);
PathingBehavior.INSTANCE.cancel();
}
}
@@ -24,68 +24,102 @@ import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.RenderEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.calc.IPath;
import baritone.api.pathing.calc.IPathFinder;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalXZ;
import baritone.api.utils.BetterBlockPos;
import baritone.api.utils.PathCalculationResult;
import baritone.api.utils.interfaces.IGoalRenderPos;
import baritone.pathing.calc.AStarPathFinder;
import baritone.pathing.calc.AbstractNodeCostSearch;
import baritone.pathing.calc.CutoffPath;
import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.MovementHelper;
import baritone.pathing.path.CutoffPath;
import baritone.pathing.path.PathExecutor;
import baritone.utils.BlockBreakHelper;
import baritone.utils.Helper;
import baritone.utils.PathRenderer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.EmptyChunk;
import java.util.*;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.stream.Collectors;
public final class PathingBehavior extends Behavior implements IPathingBehavior, Helper {
public static final PathingBehavior INSTANCE = new PathingBehavior();
private PathExecutor current;
private PathExecutor next;
private Goal goal;
private volatile boolean isPathCalcInProgress;
private boolean safeToCancel;
private boolean pauseRequestedLastTick;
private boolean cancelRequested;
private boolean calcFailedLastTick;
private volatile AbstractNodeCostSearch inProgress;
private final Object pathCalcLock = new Object();
private final Object pathPlanLock = new Object();
private boolean lastAutoJump;
private PathingBehavior() {}
private final LinkedBlockingQueue<PathEvent> toDispatch = new LinkedBlockingQueue<>();
private void dispatchPathEvent(PathEvent event) {
Baritone.INSTANCE.getExecutor().execute(() -> Baritone.INSTANCE.getGameEventHandler().onPathEvent(event));
public PathingBehavior(Baritone baritone) {
super(baritone);
}
private void queuePathEvent(PathEvent event) {
toDispatch.add(event);
}
private void dispatchEvents() {
ArrayList<PathEvent> curr = new ArrayList<>();
toDispatch.drainTo(curr);
calcFailedLastTick = curr.contains(PathEvent.CALC_FAILED);
for (PathEvent event : curr) {
baritone.getGameEventHandler().onPathEvent(event);
}
}
@Override
public void onTick(TickEvent event) {
dispatchEvents();
if (event.getType() == TickEvent.Type.OUT) {
this.cancel();
secretInternalSegmentCancel();
baritone.getPathingControlManager().cancelEverything();
return;
}
mc.playerController.setPlayerCapabilities(mc.player);
baritone.getPathingControlManager().preTick();
tickPath();
dispatchEvents();
}
private void tickPath() {
if (pauseRequestedLastTick && safeToCancel) {
pauseRequestedLastTick = false;
baritone.getInputOverrideHandler().clearAllKeys();
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
return;
}
if (cancelRequested) {
cancelRequested = false;
baritone.getInputOverrideHandler().clearAllKeys();
}
if (current == null) {
return;
}
boolean safe = current.onTick(event);
safeToCancel = current.onTick();
synchronized (pathPlanLock) {
if (current.failed() || current.finished()) {
current = null;
if (goal == null || goal.isInGoal(playerFeet())) {
if (goal == null || goal.isInGoal(ctx.playerFeet())) {
logDebug("All done. At " + goal);
dispatchPathEvent(PathEvent.AT_GOAL);
queuePathEvent(PathEvent.AT_GOAL);
next = null;
return;
}
if (next != null && !next.getPath().positions().contains(playerFeet())) {
if (next != null && !next.getPath().positions().contains(ctx.playerFeet())) {
// if the current path failed, we may not actually be on the next one, so make sure
logDebug("Discarding next path as it does not contain current position");
// for example if we had a nicely planned ahead path that starts where current ends
@@ -93,46 +127,45 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
// but if we fail in the middle of current
// we're nowhere close to our planned ahead path
// so need to discard it sadly.
dispatchPathEvent(PathEvent.DISCARD_NEXT);
queuePathEvent(PathEvent.DISCARD_NEXT);
next = null;
}
if (next != null) {
logDebug("Continuing on to planned next path");
dispatchPathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
queuePathEvent(PathEvent.CONTINUING_ONTO_PLANNED_NEXT);
current = next;
next = null;
current.onTick(event);
current.onTick();
return;
}
// at this point, current just ended, but we aren't in the goal and have no plan for the future
synchronized (pathCalcLock) {
if (isPathCalcInProgress) {
dispatchPathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
if (inProgress != null) {
queuePathEvent(PathEvent.PATH_FINISHED_NEXT_STILL_CALCULATING);
// if we aren't calculating right now
return;
}
dispatchPathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true, Optional.empty());
queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true);
}
return;
}
// at this point, we know current is in progress
if (safe) {
// a movement just ended
if (next != null) {
if (next.snipsnapifpossible()) {
// jump directly onto the next path
logDebug("Splicing into planned next path early...");
dispatchPathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
current = next;
next = null;
current.onTick(event);
return;
}
}
if (safeToCancel && next != null && next.snipsnapifpossible()) {
// a movement just ended; jump directly onto the next path
logDebug("Splicing into planned next path early...");
queuePathEvent(PathEvent.SPLICING_ONTO_NEXT_EARLY);
current = next;
next = null;
current.onTick();
return;
}
current = current.trySplice(next);
if (next != null && current.getPath().getDest().equals(next.getPath().getDest())) {
next = null;
}
synchronized (pathCalcLock) {
if (isPathCalcInProgress) {
if (inProgress != null) {
// if we aren't calculating right now
return;
}
@@ -147,8 +180,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
if (ticksRemainingInSegment().get() < Baritone.settings().planningTickLookAhead.get()) {
// and this path has 5 seconds or less left
logDebug("Path almost over. Planning ahead...");
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
findPathInNewThread(current.getPath().getDest(), false, Optional.of(current.getPath()));
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_STARTED);
findPathInNewThread(current.getPath().getDest(), false);
}
}
}
@@ -179,11 +212,15 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return Optional.of(current.getPath().ticksRemainingFrom(current.getPosition()));
}
@Override
public void setGoal(Goal goal) {
public void secretInternalSetGoal(Goal goal) {
this.goal = goal;
}
public boolean secretInternalSetGoalAndPath(Goal goal) {
secretInternalSetGoal(goal);
return secretInternalPath();
}
@Override
public Goal getGoal() {
return goal;
@@ -200,8 +237,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
@Override
public Optional<IPathFinder> getPathFinder() {
return Optional.ofNullable(AbstractNodeCostSearch.currentlyRunning());
public Optional<AbstractNodeCostSearch> getInProgress() {
return Optional.ofNullable(inProgress);
}
@Override
@@ -209,18 +246,61 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return this.current != null;
}
public boolean isSafeToCancel() {
return current == null || safeToCancel;
}
public void requestPause() {
pauseRequestedLastTick = true;
}
public boolean cancelSegmentIfSafe() {
if (isSafeToCancel()) {
secretInternalSegmentCancel();
return true;
}
return false;
}
@Override
public void cancel() {
dispatchPathEvent(PathEvent.CANCELED);
public boolean cancelEverything() {
boolean doIt = isSafeToCancel();
if (doIt) {
secretInternalSegmentCancel();
}
baritone.getPathingControlManager().cancelEverything();
return doIt;
}
public boolean calcFailedLastTick() { // NOT exposed on public api
return calcFailedLastTick;
}
public void softCancelIfSafe() {
if (!isSafeToCancel()) {
return;
}
current = null;
next = null;
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
AbstractNodeCostSearch.getCurrentlyRunning().ifPresent(AbstractNodeCostSearch::cancel);
BlockBreakHelper.stopBreakingBlock();
cancelRequested = true;
getInProgress().ifPresent(AbstractNodeCostSearch::cancel); // only cancel ours
// do everything BUT clear keys
}
// just cancel the current path
public void secretInternalSegmentCancel() {
queuePathEvent(PathEvent.CANCELED);
current = null;
next = null;
baritone.getInputOverrideHandler().clearAllKeys();
getInProgress().ifPresent(AbstractNodeCostSearch::cancel);
baritone.getInputOverrideHandler().getBlockBreakHelper().stopBreakingBlock();
}
public void forceCancel() { // NOT exposed on public api
isPathCalcInProgress = false;
cancelEverything();
secretInternalSegmentCancel();
inProgress = null;
}
/**
@@ -228,12 +308,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
*
* @return true if this call started path calculation, false if it was already calculating or executing a path
*/
@Override
public boolean path() {
public boolean secretInternalPath() {
if (goal == null) {
return false;
}
if (goal.isInGoal(playerFeet())) {
if (goal.isInGoal(ctx.playerFeet())) {
return false;
}
synchronized (pathPlanLock) {
@@ -241,11 +320,11 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
return false;
}
synchronized (pathCalcLock) {
if (isPathCalcInProgress) {
if (inProgress != null) {
return false;
}
dispatchPathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true, Optional.empty());
queuePathEvent(PathEvent.CALC_STARTED);
findPathInNewThread(pathStart(), true);
return true;
}
}
@@ -256,12 +335,12 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
*
* @return The starting {@link BlockPos} for a new path
*/
public BlockPos pathStart() {
BetterBlockPos feet = playerFeet();
if (!MovementHelper.canWalkOn(feet.down())) {
if (player().onGround) {
double playerX = player().posX;
double playerZ = player().posZ;
public BlockPos pathStart() { // TODO move to a helper or util class
BetterBlockPos feet = ctx.playerFeet();
if (!MovementHelper.canWalkOn(ctx, feet.down())) {
if (ctx.player().onGround) {
double playerX = ctx.player().posX;
double playerZ = ctx.player().posZ;
ArrayList<BetterBlockPos> closest = new ArrayList<>();
for (int dx = -1; dx <= 1; dx++) {
for (int dz = -1; dz <= 1; dz++) {
@@ -277,9 +356,9 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
// can't possibly be sneaking off of this one, we're too far away
continue;
}
if (MovementHelper.canWalkOn(possibleSupport.down()) && MovementHelper.canWalkThrough(possibleSupport) && MovementHelper.canWalkThrough(possibleSupport.up())) {
if (MovementHelper.canWalkOn(ctx, possibleSupport.down()) && MovementHelper.canWalkThrough(ctx, possibleSupport) && MovementHelper.canWalkThrough(ctx, possibleSupport.up())) {
// this is plausible
logDebug("Faking path start assuming player is standing off the edge of a block");
//logDebug("Faking path start assuming player is standing off the edge of a block");
return possibleSupport;
}
}
@@ -287,8 +366,8 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
} else {
// !onGround
// we're in the middle of a jump
if (MovementHelper.canWalkOn(feet.down().down())) {
logDebug("Faking path start assuming player is midair and falling");
if (MovementHelper.canWalkOn(ctx, feet.down().down())) {
//logDebug("Faking path start assuming player is midair and falling");
return feet.down();
}
}
@@ -302,22 +381,46 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
* @param start
* @param talkAboutIt
*/
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt, final Optional<IPath> previous) {
synchronized (pathCalcLock) {
if (isPathCalcInProgress) {
throw new IllegalStateException("Already doing it");
}
isPathCalcInProgress = true;
private void findPathInNewThread(final BlockPos start, final boolean talkAboutIt) {
// this must be called with synchronization on pathCalcLock!
// actually, we can check this, muahaha
if (!Thread.holdsLock(pathCalcLock)) {
throw new IllegalStateException("Must be called with synchronization on pathCalcLock");
// why do it this way? it's already indented so much that putting the whole thing in a synchronized(pathCalcLock) was just too much lol
}
Baritone.INSTANCE.getExecutor().execute(() -> {
if (inProgress != null) {
throw new IllegalStateException("Already doing it"); // should have been checked by caller
}
Goal goal = this.goal;
if (goal == null) {
logDebug("no goal"); // TODO should this be an exception too? definitely should be checked by caller
return;
}
long primaryTimeout;
long failureTimeout;
if (current == null) {
primaryTimeout = Baritone.settings().primaryTimeoutMS.get();
failureTimeout = Baritone.settings().failureTimeoutMS.get();
} else {
primaryTimeout = Baritone.settings().planAheadPrimaryTimeoutMS.get();
failureTimeout = Baritone.settings().planAheadFailureTimeoutMS.get();
}
CalculationContext context = new CalculationContext(baritone); // not safe to create on the other thread, it looks up a lot of stuff in minecraft
AbstractNodeCostSearch pathfinder = createPathfinder(start, goal, current == null ? null : current.getPath(), context);
if (!Objects.equals(pathfinder.getGoal(), goal)) {
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
}
inProgress = pathfinder;
Baritone.getExecutor().execute(() -> {
if (talkAboutIt) {
logDebug("Starting to search for path from " + start + " to " + goal);
}
Optional<IPath> path = findPath(start, previous);
PathCalculationResult calcResult = pathfinder.calculate(primaryTimeout, failureTimeout);
Optional<IPath> path = calcResult.getPath();
if (Baritone.settings().cutoffAtLoadBoundary.get()) {
path = path.map(p -> {
IPath result = p.cutoffAtLoadedChunks();
IPath result = p.cutoffAtLoadedChunks(context.world());
if (result instanceof CutoffPath) {
logDebug("Cutting off path at edge of loaded chunks");
@@ -338,114 +441,62 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
return result;
}).map(PathExecutor::new);
}).map(p -> new PathExecutor(this, p));
synchronized (pathPlanLock) {
if (current == null) {
if (executor.isPresent()) {
dispatchPathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
queuePathEvent(PathEvent.CALC_FINISHED_NOW_EXECUTING);
current = executor.get();
} else {
dispatchPathEvent(PathEvent.CALC_FAILED);
if (calcResult.getType() != PathCalculationResult.Type.CANCELLATION && calcResult.getType() != PathCalculationResult.Type.EXCEPTION) {
// don't dispatch CALC_FAILED on cancellation
queuePathEvent(PathEvent.CALC_FAILED);
}
}
} else {
if (next == null) {
if (executor.isPresent()) {
dispatchPathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
queuePathEvent(PathEvent.NEXT_SEGMENT_CALC_FINISHED);
next = executor.get();
} else {
dispatchPathEvent(PathEvent.NEXT_CALC_FAILED);
queuePathEvent(PathEvent.NEXT_CALC_FAILED);
}
} else {
throw new IllegalStateException("I have no idea what to do with this path");
}
}
}
if (talkAboutIt && current != null && current.getPath() != null) {
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
} else {
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
if (talkAboutIt && current != null && current.getPath() != null) {
if (goal == null || goal.isInGoal(current.getPath().getDest())) {
logDebug("Finished finding a path from " + start + " to " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
} else {
logDebug("Found path segment from " + start + " towards " + goal + ". " + current.getPath().getNumNodesConsidered() + " nodes considered");
}
}
synchronized (pathCalcLock) {
inProgress = null;
}
}
synchronized (pathCalcLock) {
isPathCalcInProgress = false;
}
});
}
/**
* Actually do the pathing
*
* @param start
* @return
*/
private Optional<IPath> findPath(BlockPos start, Optional<IPath> previous) {
Goal goal = this.goal;
if (goal == null) {
logDebug("no goal");
return Optional.empty();
}
if (Baritone.settings().simplifyUnloadedYCoord.get()) {
BlockPos pos = null;
if (goal instanceof IGoalRenderPos) {
pos = ((IGoalRenderPos) goal).getGoalPos();
}
if (pos != null && world().getChunk(pos) instanceof EmptyChunk) {
logDebug("Simplifying " + goal.getClass() + " to GoalXZ due to distance");
goal = new GoalXZ(pos.getX(), pos.getZ());
public static AbstractNodeCostSearch createPathfinder(BlockPos start, Goal goal, IPath previous, CalculationContext context) {
Goal transformed = goal;
if (Baritone.settings().simplifyUnloadedYCoord.get() && goal instanceof IGoalRenderPos) {
BlockPos pos = ((IGoalRenderPos) goal).getGoalPos();
if (context.world().getChunk(pos) instanceof EmptyChunk) {
transformed = new GoalXZ(pos.getX(), pos.getZ());
}
}
long timeout;
if (current == null) {
timeout = Baritone.settings().pathTimeoutMS.<Long>get();
} else {
timeout = Baritone.settings().planAheadTimeoutMS.<Long>get();
}
Optional<HashSet<Long>> favoredPositions;
if (Baritone.settings().backtrackCostFavoringCoefficient.get() == 1D) {
favoredPositions = Optional.empty();
} else {
favoredPositions = previous.map(IPath::positions).map(Collection::stream).map(x -> x.map(BetterBlockPos::longHash)).map(x -> x.collect(Collectors.toList())).map(HashSet::new); // <-- okay this is EPIC
}
try {
IPathFinder pf = new AStarPathFinder(start.getX(), start.getY(), start.getZ(), goal, favoredPositions);
return pf.calculate(timeout);
} catch (Exception e) {
logDebug("Pathing exception: " + e);
e.printStackTrace();
return Optional.empty();
}
}
public void revalidateGoal() {
if (!Baritone.settings().cancelOnGoalInvalidation.get()) {
return;
}
synchronized (pathPlanLock) {
if (current == null || goal == null) {
return;
}
Goal intended = current.getPath().getGoal();
BlockPos end = current.getPath().getDest();
if (intended.isInGoal(end) && !goal.isInGoal(end)) {
// this path used to end in the goal
// but the goal has changed, so there's no reason to continue...
cancel();
}
HashSet<Long> favoredPositions = null;
if (Baritone.settings().backtrackCostFavoringCoefficient.get() != 1D && previous != null) {
favoredPositions = previous.positions().stream().map(BetterBlockPos::longHash).collect(Collectors.toCollection(HashSet::new));
}
return new AStarPathFinder(start.getX(), start.getY(), start.getZ(), transformed, favoredPositions, context);
}
@Override
public void onRenderPass(RenderEvent event) {
PathRenderer.render(event, this);
}
@Override
public void onDisable() {
Baritone.INSTANCE.getInputOverrideHandler().clearAllKeys();
}
}
+60 -41
View File
@@ -17,8 +17,6 @@
package baritone.cache;
import baritone.api.cache.IBlockTypeAccess;
import baritone.utils.Helper;
import baritone.utils.pathing.PathingBlockType;
import net.minecraft.block.Block;
import net.minecraft.block.state.IBlockState;
@@ -29,44 +27,66 @@ import java.util.*;
/**
* @author Brady
* @since 8/3/2018 1:04 AM
* @since 8/3/2018
*/
public final class CachedChunk implements IBlockTypeAccess, Helper {
public final class CachedChunk {
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(new HashSet<Block>() {{
add(Blocks.DIAMOND_ORE);
add(Blocks.DIAMOND_BLOCK);
//add(Blocks.COAL_ORE);
add(Blocks.COAL_BLOCK);
//add(Blocks.IRON_ORE);
add(Blocks.IRON_BLOCK);
//add(Blocks.GOLD_ORE);
add(Blocks.GOLD_BLOCK);
add(Blocks.EMERALD_ORE);
add(Blocks.EMERALD_BLOCK);
public static final Set<Block> BLOCKS_TO_KEEP_TRACK_OF;
add(Blocks.ENDER_CHEST);
add(Blocks.FURNACE);
add(Blocks.CHEST);
add(Blocks.END_PORTAL);
add(Blocks.END_PORTAL_FRAME);
add(Blocks.MOB_SPAWNER);
// TODO add all shulker colors
add(Blocks.PORTAL);
add(Blocks.HOPPER);
add(Blocks.BEACON);
add(Blocks.BREWING_STAND);
add(Blocks.SKULL);
add(Blocks.ENCHANTING_TABLE);
add(Blocks.ANVIL);
add(Blocks.LIT_FURNACE);
add(Blocks.BED);
add(Blocks.DRAGON_EGG);
add(Blocks.JUKEBOX);
add(Blocks.END_GATEWAY);
add(Blocks.WEB);
add(Blocks.NETHER_WART);
}});
static {
HashSet<Block> temp = new HashSet<>();
temp.add(Blocks.DIAMOND_ORE);
temp.add(Blocks.DIAMOND_BLOCK);
//temp.add(Blocks.COAL_ORE);
temp.add(Blocks.COAL_BLOCK);
//temp.add(Blocks.IRON_ORE);
temp.add(Blocks.IRON_BLOCK);
//temp.add(Blocks.GOLD_ORE);
temp.add(Blocks.GOLD_BLOCK);
temp.add(Blocks.EMERALD_ORE);
temp.add(Blocks.EMERALD_BLOCK);
temp.add(Blocks.ENDER_CHEST);
temp.add(Blocks.FURNACE);
temp.add(Blocks.CHEST);
temp.add(Blocks.TRAPPED_CHEST);
temp.add(Blocks.END_PORTAL);
temp.add(Blocks.END_PORTAL_FRAME);
temp.add(Blocks.MOB_SPAWNER);
temp.add(Blocks.BARRIER);
temp.add(Blocks.OBSERVER);
temp.add(Blocks.WHITE_SHULKER_BOX);
temp.add(Blocks.ORANGE_SHULKER_BOX);
temp.add(Blocks.MAGENTA_SHULKER_BOX);
temp.add(Blocks.LIGHT_BLUE_SHULKER_BOX);
temp.add(Blocks.YELLOW_SHULKER_BOX);
temp.add(Blocks.LIME_SHULKER_BOX);
temp.add(Blocks.PINK_SHULKER_BOX);
temp.add(Blocks.GRAY_SHULKER_BOX);
temp.add(Blocks.SILVER_SHULKER_BOX);
temp.add(Blocks.CYAN_SHULKER_BOX);
temp.add(Blocks.PURPLE_SHULKER_BOX);
temp.add(Blocks.BLUE_SHULKER_BOX);
temp.add(Blocks.BROWN_SHULKER_BOX);
temp.add(Blocks.GREEN_SHULKER_BOX);
temp.add(Blocks.RED_SHULKER_BOX);
temp.add(Blocks.BLACK_SHULKER_BOX);
temp.add(Blocks.PORTAL);
temp.add(Blocks.HOPPER);
temp.add(Blocks.BEACON);
temp.add(Blocks.BREWING_STAND);
temp.add(Blocks.SKULL);
temp.add(Blocks.ENCHANTING_TABLE);
temp.add(Blocks.ANVIL);
temp.add(Blocks.LIT_FURNACE);
temp.add(Blocks.BED);
temp.add(Blocks.DRAGON_EGG);
temp.add(Blocks.JUKEBOX);
temp.add(Blocks.END_GATEWAY);
temp.add(Blocks.WEB);
temp.add(Blocks.NETHER_WART);
BLOCKS_TO_KEEP_TRACK_OF = Collections.unmodifiableSet(temp);
}
/**
* The size of the chunk data in bits. Equal to 16 KiB.
@@ -121,8 +141,7 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
calculateHeightMap();
}
@Override
public final IBlockState getBlock(int x, int y, int z) {
public final IBlockState getBlock(int x, int y, int z, int dimension) {
int internalPos = z << 4 | x;
if (heightMap[internalPos] == y) {
// we have this exact block, it's a surface block
@@ -133,10 +152,10 @@ public final class CachedChunk implements IBlockTypeAccess, Helper {
return overview[internalPos];
}
PathingBlockType type = getType(x, y, z);
if (type == PathingBlockType.SOLID && y == 127 && mc.player.dimension == -1) {
if (type == PathingBlockType.SOLID && y == 127 && dimension == -1) {
return Blocks.BEDROCK.getDefaultState();
}
return ChunkPacker.pathingTypeToBlock(type);
return ChunkPacker.pathingTypeToBlock(type, dimension);
}
private PathingBlockType getType(int x, int y, int z) {
+6 -3
View File
@@ -32,7 +32,7 @@ import java.util.zip.GZIPOutputStream;
/**
* @author Brady
* @since 8/3/2018 9:35 PM
* @since 8/3/2018
*/
public final class CachedRegion implements ICachedRegion {
@@ -59,22 +59,25 @@ public final class CachedRegion implements ICachedRegion {
*/
private final int z;
private final int dimension;
/**
* Has this region been modified since its most recent load or save
*/
private boolean hasUnsavedChanges;
CachedRegion(int x, int z) {
CachedRegion(int x, int z, int dimension) {
this.x = x;
this.z = z;
this.hasUnsavedChanges = false;
this.dimension = dimension;
}
@Override
public final IBlockState getBlock(int x, int y, int z) {
CachedChunk chunk = chunks[x >> 4][z >> 4];
if (chunk != null) {
return chunk.getBlock(x & 15, y, z & 15);
return chunk.getBlock(x & 15, y, z & 15, dimension);
}
return null;
}
+30 -13
View File
@@ -18,7 +18,10 @@
package baritone.cache;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.cache.ICachedWorld;
import baritone.api.cache.IWorldData;
import baritone.utils.Helper;
import it.unimi.dsi.fastutil.longs.Long2ObjectMap;
import it.unimi.dsi.fastutil.longs.Long2ObjectOpenHashMap;
@@ -35,7 +38,7 @@ import java.util.concurrent.LinkedBlockingQueue;
/**
* @author Brady
* @since 8/4/2018 12:02 AM
* @since 8/4/2018
*/
public final class CachedWorld implements ICachedWorld, Helper {
@@ -56,7 +59,9 @@ public final class CachedWorld implements ICachedWorld, Helper {
private final LinkedBlockingQueue<Chunk> toPack = new LinkedBlockingQueue<>();
CachedWorld(Path directory) {
private final int dimension;
CachedWorld(Path directory, int dimension) {
if (!Files.exists(directory)) {
try {
Files.createDirectories(directory);
@@ -64,11 +69,12 @@ public final class CachedWorld implements ICachedWorld, Helper {
}
}
this.directory = directory.toString();
this.dimension = dimension;
System.out.println("Cached world directory: " + directory);
// Insert an invalid region element
cachedRegions.put(0, null);
Baritone.INSTANCE.getExecutor().execute(new PackerThread());
Baritone.INSTANCE.getExecutor().execute(() -> {
Baritone.getExecutor().execute(new PackerThread());
Baritone.getExecutor().execute(() -> {
try {
Thread.sleep(30000);
while (true) {
@@ -103,10 +109,10 @@ public final class CachedWorld implements ICachedWorld, Helper {
}
@Override
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int maxRegionDistanceSq) {
public final LinkedList<BlockPos> getLocationsOf(String block, int maximum, int centerX, int centerZ, int maxRegionDistanceSq) {
LinkedList<BlockPos> res = new LinkedList<>();
int playerRegionX = playerFeet().getX() >> 9;
int playerRegionZ = playerFeet().getZ() >> 9;
int centerRegionX = centerX >> 9;
int centerRegionZ = centerZ >> 9;
int searchRadius = 0;
while (searchRadius <= maxRegionDistanceSq) {
@@ -116,8 +122,8 @@ public final class CachedWorld implements ICachedWorld, Helper {
if (distance != searchRadius) {
continue;
}
int regionX = xoff + playerRegionX;
int regionZ = zoff + playerRegionZ;
int regionX = xoff + centerRegionX;
int regionZ = zoff + centerRegionZ;
CachedRegion region = getOrCreateRegion(regionX, regionZ);
if (region != null) {
// TODO: 100% verify if this or addAll is faster.
@@ -165,8 +171,14 @@ public final class CachedWorld implements ICachedWorld, Helper {
* Delete regions that are too far from the player
*/
private synchronized void prune() {
if (!Baritone.settings().pruneRegionsFromRAM.get()) {
return;
}
BlockPos pruneCenter = guessPosition();
for (CachedRegion region : allRegions()) {
if (region == null) {
continue;
}
int distX = (region.getX() * 512 + 256) - pruneCenter.getX();
int distZ = (region.getZ() * 512 + 256) - pruneCenter.getZ();
double dist = Math.sqrt(distX * distX + distZ * distZ);
@@ -181,12 +193,17 @@ public final class CachedWorld implements ICachedWorld, Helper {
* If we are still in this world and dimension, return player feet, otherwise return most recently modified chunk
*/
private BlockPos guessPosition() {
WorldData data = WorldProvider.INSTANCE.getCurrentWorld();
if (data != null && data.getCachedWorld() == this) {
return playerFeet();
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
IWorldData data = ibaritone.getWorldProvider().getCurrentWorld();
if (data != null && data.getCachedWorld() == this) {
return ibaritone.getPlayerContext().playerFeet();
}
}
CachedChunk mostRecentlyModified = null;
for (CachedRegion region : allRegions()) {
if (region == null) {
continue;
}
CachedChunk ch = region.mostRecentlyModified();
if (ch == null) {
continue;
@@ -232,7 +249,7 @@ public final class CachedWorld implements ICachedWorld, Helper {
*/
private synchronized CachedRegion getOrCreateRegion(int regionX, int regionZ) {
return cachedRegions.computeIfAbsent(getRegionID(regionX, regionZ), id -> {
CachedRegion newRegion = new CachedRegion(regionX, regionZ);
CachedRegion newRegion = new CachedRegion(regionX, regionZ, dimension);
newRegion.load(this.directory);
return newRegion;
});
+7 -7
View File
@@ -18,7 +18,6 @@
package baritone.cache;
import baritone.pathing.movement.MovementHelper;
import baritone.utils.Helper;
import baritone.utils.pathing.PathingBlockType;
import net.minecraft.block.Block;
import net.minecraft.block.BlockDoublePlant;
@@ -36,9 +35,9 @@ import java.util.*;
/**
* @author Brady
* @since 8/3/2018 1:09 AM
* @since 8/3/2018
*/
public final class ChunkPacker implements Helper {
public final class ChunkPacker {
private ChunkPacker() {}
@@ -93,7 +92,8 @@ public final class ChunkPacker implements Helper {
for (int z = 0; z < 16; z++) {
// @formatter:off
https://www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
https:
//www.ibm.com/developerworks/library/j-perry-writing-good-java-code/index.html
// @formatter:on
for (int x = 0; x < 16; x++) {
for (int y = 255; y >= 0; y--) {
@@ -125,7 +125,7 @@ public final class ChunkPacker implements Helper {
private static PathingBlockType getPathingBlockType(IBlockState state) {
Block block = state.getBlock();
if (block.equals(Blocks.WATER)) {
if (block == Blocks.WATER && !MovementHelper.isFlowing(state)) {
// only water source blocks are plausibly usable, flowing water should be avoid
return PathingBlockType.WATER;
}
@@ -144,7 +144,7 @@ public final class ChunkPacker implements Helper {
return PathingBlockType.SOLID;
}
public static IBlockState pathingTypeToBlock(PathingBlockType type) {
public static IBlockState pathingTypeToBlock(PathingBlockType type, int dimension) {
switch (type) {
case AIR:
return Blocks.AIR.getDefaultState();
@@ -154,7 +154,7 @@ public final class ChunkPacker implements Helper {
return Blocks.LAVA.getDefaultState();
case SOLID:
// Dimension solid types
switch (mc.player.dimension) {
switch (dimension) {
case -1:
return Blocks.NETHERRACK.getDefaultState();
case 0:
+3 -3
View File
@@ -42,9 +42,9 @@ public class Waypoint implements IWaypoint {
* Constructor called when a Waypoint is read from disk, adds the creationTimestamp
* as a parameter so that it is reserved after a waypoint is wrote to the disk.
*
* @param name The waypoint name
* @param tag The waypoint tag
* @param location The waypoint location
* @param name The waypoint name
* @param tag The waypoint tag
* @param location The waypoint location
* @param creationTimestamp When the waypoint was created
*/
Waypoint(String name, Tag tag, BlockPos location, long creationTimestamp) {
+5 -3
View File
@@ -35,15 +35,17 @@ public class WorldData implements IWorldData {
private final Waypoints waypoints;
//public final MapData map;
public final Path directory;
public final int dimension;
WorldData(Path directory) {
WorldData(Path directory, int dimension) {
this.directory = directory;
this.cache = new CachedWorld(directory.resolve("cache"));
this.cache = new CachedWorld(directory.resolve("cache"), dimension);
this.waypoints = new Waypoints(directory.resolve("waypoints"));
this.dimension = dimension;
}
public void onClose() {
Baritone.INSTANCE.getExecutor().execute(() -> {
Baritone.getExecutor().execute(() -> {
System.out.println("Started saving the world in a new thread");
cache.save();
});
+21 -17
View File
@@ -22,7 +22,6 @@ import baritone.api.cache.IWorldProvider;
import baritone.utils.Helper;
import baritone.utils.accessor.IAnvilChunkLoader;
import baritone.utils.accessor.IChunkProviderServer;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.server.integrated.IntegratedServer;
import net.minecraft.world.WorldServer;
@@ -37,13 +36,11 @@ import java.util.function.Consumer;
/**
* @author Brady
* @since 8/4/2018 11:06 AM
* @since 8/4/2018
*/
public enum WorldProvider implements IWorldProvider, Helper {
public class WorldProvider implements IWorldProvider, Helper {
INSTANCE;
private final Map<Path, WorldData> worldCache = new HashMap<>();
private static final Map<Path, WorldData> worldCache = new HashMap<>(); // this is how the bots have the same cached world
private WorldData currentWorld;
@@ -52,13 +49,20 @@ public enum WorldProvider implements IWorldProvider, Helper {
return this.currentWorld;
}
public final void initWorld(WorldClient world) {
int dimensionID = world.provider.getDimensionType().getId();
/**
* Called when a new world is initialized to discover the
*
* @param dimension The ID of the world's dimension
*/
public final void initWorld(int dimension) {
File directory;
File readme;
IntegratedServer integratedServer = mc.getIntegratedServer();
// If there is an integrated server running (Aka Singleplayer) then do magic to find the world save file
if (integratedServer != null) {
WorldServer localServerWorld = integratedServer.getWorld(dimensionID);
WorldServer localServerWorld = integratedServer.getWorld(dimension);
IChunkProviderServer provider = (IChunkProviderServer) localServerWorld.getChunkProvider();
IAnvilChunkLoader loader = (IAnvilChunkLoader) provider.getChunkLoader();
directory = loader.getChunkSaveLocation();
@@ -71,27 +75,27 @@ public enum WorldProvider implements IWorldProvider, Helper {
directory = new File(directory, "baritone");
readme = directory;
} else {
//remote
directory = new File(Baritone.INSTANCE.getDir(), mc.getCurrentServerData().serverIP);
readme = Baritone.INSTANCE.getDir();
} else { // Otherwise, the server must be remote...
directory = new File(Baritone.getDir(), mc.getCurrentServerData().serverIP);
readme = Baritone.getDir();
}
// lol wtf is this baritone folder in my minecraft save?
try (FileOutputStream out = new FileOutputStream(new File(readme, "readme.txt"))) {
// good thing we have a readme
out.write("https://github.com/cabaletta/baritone\n".getBytes());
} catch (IOException ignored) {}
directory = new File(directory, "DIM" + dimensionID);
Path dir = directory.toPath();
// We will actually store the world data in a subfolder: "DIM<id>"
Path dir = new File(directory, "DIM" + dimension).toPath();
if (!Files.exists(dir)) {
try {
Files.createDirectories(dir);
} catch (IOException ignored) {}
}
System.out.println("Baritone world data dir: " + dir);
this.currentWorld = this.worldCache.computeIfAbsent(dir, WorldData::new);
this.currentWorld = worldCache.computeIfAbsent(dir, d -> new WorldData(d, dimension));
}
public final void closeWorld() {

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