Compare commits

...

152 Commits

Author SHA1 Message Date
Brady
2e8327cd8a Wrong command... 2023-08-11 21:54:56 -05:00
Brady
ac72ad717b bot execute and bot say 2023-06-28 00:09:53 -05:00
Brady
a3df7ebd4c Always render nametag 2023-06-27 23:47:24 -05:00
Brady
d24cd263bf Fix rendering bot player in gui 2023-06-27 23:37:47 -05:00
Brady
5878c255e2 Manage bot inventories with gui 2023-06-27 23:29:15 -05:00
Brady
ab54114bee I think it works again 2023-06-26 21:04:19 -05:00
Brady
4441f644c3 Revert more changes not relevant to PR 2023-06-26 20:33:00 -05:00
Brady
4899b4a3d0 De-bloat 2023-06-26 20:30:37 -05:00
Brady
2670f4a1f9 Merge branch 'master' into bot-system 2023-06-26 20:04:42 -05:00
Brady
5edada6111 Reorganize code 2023-06-13 11:45:58 -05:00
Brady
efa4dc1d04 Use inner class implementation for getAllBaritones
`this.new` 😻
2023-06-13 11:36:24 -05:00
Brady
b25d1a44a2 Fix NPE on bot respawn 2023-06-13 11:34:23 -05:00
Brady
c8de6c027a Rename spec package to impl 2023-06-13 10:59:08 -05:00
Brady
08c8a772a8 Merge branch 'master' into bot-system
# Conflicts:
#	src/api/java/baritone/api/Settings.java
#	src/launch/java/baritone/launch/mixins/MixinNetHandlerPlayClient.java
#	src/main/java/baritone/Baritone.java
#	src/main/java/baritone/BaritoneProvider.java
2023-06-13 00:52:06 -05:00
Brady
9e225949ea Don't dispatch RenderEvent if bot isn't in same dimension 2020-03-13 16:17:54 -05:00
Brady
5b1340e362 Fix bot removal 2020-03-13 08:38:46 -05:00
Brady
dee737689d Initialization consistency 2020-03-12 17:01:10 -05:00
Brady
f0fd30080e Better 2020-03-12 16:54:26 -05:00
Brady
5e316d094d Fix runtime error and change getEntity to getPlayer 2020-03-12 16:50:34 -05:00
Brady
191add6ce5 Better bot tick handling 2020-03-12 16:42:36 -05:00
Brady
9951d37e3b Additional Entity handing for Bot Worlds
+ Some minor cleanups that make the PR more favorable
2020-03-12 08:55:22 -05:00
Brady
29f700d1c9 Naming consistency 2020-03-09 21:27:52 -05:00
Brady
22ed50a739 Chunk management 2020-03-09 20:34:14 -05:00
Brady
b9069a68dc Run on main thread 2020-03-08 17:33:22 -05:00
Brady
881ce738d9 Respect game state changes 2020-03-08 17:32:52 -05:00
Brady
35e4460fb1 Fix NPE 2020-03-08 16:40:26 -05:00
Brady
d25e9a6047 More NetHandlerPlayClient utilization 2020-03-08 03:10:44 -05:00
Brady
05af906a3c Remove MemoryBehavior changes 2020-03-08 01:48:37 -06:00
Brady
aa95cbe0e4 Update goals and remove unnecessary override 2020-03-08 01:44:50 -06:00
Brady
9f20ce9e18 Add some clarification 2020-03-08 01:40:08 -06:00
Brady
e6b409c0da Merge branch 'master' into bot-system 2020-03-08 01:36:25 -06:00
Brady
ec427e6b74 Insane cleanups 2020-03-08 01:32:52 -06:00
Brady
3ddd1c38f5 Add disconnect command for bots, fix sound crash 2020-03-07 20:08:29 -06:00
Brady
60c0fff016 Fix bot entity removal 2020-03-07 14:30:21 -06:00
Brady
180d55b9c5 Fix some entity list scuff 2020-03-06 20:06:36 -06:00
Brady
a6ea5c8df1 Utilize sendSettingsToServer 2020-03-06 16:25:34 -06:00
Brady
7940eca11e Reduce potential outbound packet loss 2020-03-05 23:50:31 -06:00
Brady
cffe907c76 Centralize disconnect handling 2020-03-05 23:48:42 -06:00
Brady
51840df97d Fix Bot GameSettings overriding KeyBindings 2020-03-05 23:24:37 -06:00
Brady
4762d3f28f Separate GameSettings for bots 2020-03-05 16:52:58 -06:00
Brady
255e70fd7e Separate cache for bots 2020-03-04 15:41:34 -06:00
Brady
8f4e3fbc0e Might as well populate the server name 2020-03-04 11:35:11 -06:00
Brady
b038cedfc5 LAN support in production 2020-03-04 11:12:07 -06:00
Brady
b34ad03bcc final final final (2) 2020-03-04 00:14:16 -06:00
Brady
554fe87789 final final final 2020-03-04 00:12:51 -06:00
Brady
175a44f4ac Fix LAN world support 2020-03-04 00:12:22 -06:00
Brady
0bafcef2a1 Block placing for bots 2020-03-03 23:26:19 -06:00
Brady
f83262be23 Test compatible: Commands are forwarded to bots 2020-03-03 21:58:03 -06:00
Brady
15c0dc3fa5 Fix bad thread check 2020-03-03 16:01:14 -06:00
Brady
6844bc0922 Allocation time 2020-03-03 14:47:50 -06:00
Brady
d82fd04f5f reorder lol 2020-03-02 17:12:27 -06:00
Brady
9130734a9f Remove PROTOCOL.md 2020-03-02 13:50:46 -06:00
Brady
d4d2e1ea50 Merge branch 'master' into bot-system 2020-03-02 13:46:43 -06:00
Brady
9a33c5cd9f Merge branch 'master' into bot-system 2020-01-01 19:23:01 -06:00
Brady
9f5f275a17 Merge branch 'master' into bot-system 2019-10-07 09:42:35 -05:00
Brady
ac4895823e Remove comms 2019-10-04 15:52:08 -05:00
Brady
62cea04080 Fix compiler errors 2019-10-04 15:51:44 -05:00
Brady
d772a97a0b Fix 2019-10-04 10:22:06 -05:00
Brady
7af0ed6ea1 Merge conflicts 2019-10-04 10:19:35 -05:00
Brady
fe3f3a66ce Format bot code 2019-01-22 13:30:11 -06:00
Brady
9c5f82c814 Merge branch 'master' into bot-system 2019-01-18 13:52:22 -06:00
Brady
7c66762f48 Bot system API exposure 2019-01-17 14:43:44 -06:00
Leijurv
830c8190de Merge branch 'comms' into bot-system 2019-01-17 12:18:27 -08:00
Leijurv
47b258d7a4 Merge branch 'master' into comms 2019-01-17 12:16:45 -08:00
Brady
df80858c49 Remove duplicate MovementInput implementation, Fixes #312 2019-01-16 13:55:24 -06:00
Brady
5dec544802 Minor fix LOL 2019-01-15 14:59:56 -06:00
Brady
494c056613 Resolve merge conflicts 2019-01-15 14:53:05 -06:00
Brady
c0e947f016 Clean up canBreak 2018-12-24 12:23:57 -06:00
Brady
c6ce5ea160 Nobody cares about creative mode 2018-12-24 12:19:09 -06:00
Brady
7b2930d5e5 Bot Breaking that is moderately cursed
DMCA gang
2018-12-24 12:11:28 -06:00
Brady
44ca284717 Merge branch 'master' into bot-system 2018-12-18 19:36:10 -06:00
Leijurv
380a645a6c only report items that are actually in the echest 2018-12-17 19:51:24 -08:00
Leijurv
0249bd5dd7 a few more packets, and consistent indexing 2018-12-17 15:15:20 -08:00
Leijurv
8cd8a95763 little fix 2018-12-16 20:14:07 -08:00
Brady
029a2b7f3e Fix NullPointerException 2018-12-15 12:27:19 -06:00
Leijurv
767d0c8ec1 better reporting 2018-12-14 21:57:20 -08:00
Brady
8febed2e42 Remove dependency for PlayerControllerMP implementation 2018-12-14 17:24:07 -06:00
Leijurv
37b1604e5d Merge branch 'master' into comms 2018-12-14 09:38:40 -08:00
Leijurv
82d15570f3 fix rare exception 2018-12-02 16:05:21 -08:00
Leijurv
2c2c420b3a Merge branch 'comms' into bot-system 2018-12-02 13:35:40 -08:00
Leijurv
1422b0a149 Merge branch 'master' into bot-system 2018-12-02 13:35:23 -08:00
Leijurv
6b6dd916b4 Merge branch 'calc-request' into comms 2018-11-23 19:09:01 -08:00
Leijurv
11e44acf65 helper to handle pending msgs 2018-11-23 16:35:03 -08:00
Leijurv
16fec4a1a0 buffered connection creation helper 2018-11-23 16:09:59 -08:00
Leijurv
bbded21afb Merge branch 'master' into bot-system 2018-11-23 14:12:02 -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
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
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
81a9b71429 Merge branch 'segment-calculation' into comms 2018-11-23 10:36:56 -08:00
Leijurv
81ecc209d3 synchronize partial reads and writes to a socket 2018-11-23 10:09:13 -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
Brady
186652a8d8 Protocol lol 2018-11-18 19:52:11 -06:00
Leijurv
168c151901 Merge branch 'comms' into bot-system 2018-11-18 17:39:35 -08:00
Leijurv
18d8cfb6de Merge branch 'master' into comms 2018-11-18 17:39:26 -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
Brady
46de72e28c Comms Sourceset 2018-11-17 18:07:16 -06:00
Brady
3d5cf9772e Less cancer 2018-11-14 20:55:37 -06:00
Leijurv
7cb38352ac bots 2018-11-14 17:17:52 -08:00
Leijurv
42c78337c7 Merge branch 'master' into bot-system 2018-11-14 16:41:52 -08:00
Brady
0f81212f17 Compile fix 2018-11-13 21:41:52 -06:00
Brady
ad0041c2c5 Merge branch 'master' into bot-system 2018-11-13 17:14:29 -06:00
Brady
19e7585cd2 Merge branch 'master' into bot-system 2018-11-11 16:23:47 -06:00
Brady
3aeb29ab22 Merge branch 'master' into bot-system 2018-11-11 13:36:22 -06:00
Brady
8dfe5dfd32 Fix jce.jar not being included as library jar in proguard config 2018-11-09 22:43:00 -06:00
Brady
90236962c4 nice 2018-11-09 22:17:00 -06:00
Brady
2e9e8c1ea1 Actually entirely epic, we're okay 2018-11-09 22:00:11 -06:00
Brady
4bf659e14e Fix ConcurrentModificationException 2018-11-09 21:10:49 -06:00
Brady
ceca258867 MORE handlers
also removed scoreboard handlers because lol
2018-11-09 20:50:43 -06:00
Leijurv
abda4b3a31 begone 2018-11-09 13:28:49 -08:00
Brady
98664540e2 Merge branch 'master' into bot-system 2018-11-09 14:42:23 -06:00
Brady
484dac66b7 JUMP 2018-11-09 13:58:55 -06:00
Brady
40282cd140 Automatic Disconnect 2018-11-07 16:53:32 -06:00
Brady
41c74cb08c More handlers 2018-11-07 12:23:28 -06:00
Brady
7c92817801 Offline bot testing 2018-11-07 12:01:26 -06:00
Brady
1d56585c67 Fix success connection result 2018-11-06 16:22:24 -06:00
Brady
a4ac9c6f8d Bot Connecting 2018-11-06 15:25:25 -06:00
Brady
42d15a7b93 Merge branch 'master' into bot-system 2018-11-06 14:10:11 -06:00
Brady
335c97bae6 Merge branch 'master' into bot-system 2018-11-05 16:06:53 -06:00
Brady
8a8afddce3 Fix bad stack overflow error 2018-10-30 13:57:50 -05:00
Brady
c3f6ee87b3 Feed codacy 2018-10-29 23:27:54 -05:00
Brady
f45fb3cd8c Add reminder lol 2018-10-29 23:20:11 -05:00
Brady
71c7ed54e5 Reverse increment/decrement 2018-10-29 23:10:46 -05:00
Brady
4f978be2a2 Begin MovementInput implementation 2018-10-29 23:04:26 -05:00
Brady
133d956b3a Create login handler 2018-10-29 22:43:36 -05:00
Brady
095e452632 Merge branch 'master' into bot-system 2018-10-29 22:08:29 -05:00
Brady
047d7f06b8 More handlers 2018-10-26 11:38:52 -05:00
Brady
09a119c4ca More handlers 2018-10-24 20:51:01 -05:00
Brady
746e1f6652 handleTimeUpdate 2018-10-24 19:04:49 -05:00
Brady
1d22cf63f0 Lol 2018-10-23 23:08:43 -05:00
Brady
d4b3e71694 handleCombatEvent 2018-10-23 23:07:58 -05:00
Brady
a08b406af9 handleCooldown 2018-10-23 23:04:13 -05:00
Brady
1afd367e53 handleResourcePack 2018-10-23 23:00:58 -05:00
Brady
59e920b7b1 Meme 3 2018-10-23 09:58:36 -05:00
Brady
79d230d924 another thought 2018-10-23 00:49:38 -05:00
Brady
29cf79fe17 We don't need the connection handler from the user 2018-10-23 00:46:31 -05:00
Brady
8e75817e29 Meme 2 2018-10-23 00:29:30 -05:00
Brady
c6bd3f4f00 Meme 2018-10-23 00:05:48 -05:00
41 changed files with 2508 additions and 6 deletions

View File

@@ -42,6 +42,7 @@ import java.lang.reflect.Field;
import java.net.URL;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.*;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
@@ -216,6 +217,7 @@ public class ProguardTask extends BaritoneGradleTask {
Process p = new ProcessBuilder(this.getJavaBinPathForProguard(), "-verbose").start();
String out = IOUtils.toString(p.getInputStream(), "UTF-8").split("\n")[0].split("Opened ")[1].replace("]", "");
template.add(2, "-libraryjars '" + out + "'");
template.add(3, "-libraryjars '" + Paths.get(out).resolveSibling("jce.jar") + "'");
// API config doesn't require any changes from the changes that we made to the template
Files.write(getTemporaryFile(PROGUARD_API_CONFIG), template);

View File

@@ -17,6 +17,7 @@
package baritone.api;
import baritone.api.bot.IUserManager;
import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommand;
import baritone.api.command.ICommandSystem;
@@ -108,6 +109,11 @@ public interface IBaritoneProvider {
*/
IWorldScanner getWorldScanner();
/**
* @return The {@link IUserManager} instance.
*/
IUserManager getUserManager();
/**
* Returns the {@link ICommandSystem} instance. This is not bound to a specific {@link IBaritone}
* instance because {@link ICommandSystem} itself controls global behavior for {@link ICommand}s.

View File

@@ -1289,6 +1289,13 @@ public final class Settings {
*/
public final Setting<Boolean> desktopNotifications = new Setting<>(false);
/**
* Having this setting enabled keeps vanilla collision working. If disabled, bots will ignore
* collision boxes and be able to walk inside each other without issues. This should only be
* disabled when multiple bots are are needed to simultaneously use narrow tunnels.
*/
public final Setting<Boolean> botCollision = new Setting<>(true);
/**
* Desktop notification on path complete
*/

View File

@@ -0,0 +1,68 @@
/*
* 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.bot;
import baritone.api.IBaritone;
import baritone.api.utils.IPlayerContext;
import com.mojang.authlib.GameProfile;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.Session;
/**
* @author Brady
* @since 10/23/2018
*/
public interface IBaritoneUser {
/**
* @return The Baritone instance
*/
IBaritone getBaritone();
/**
* Returns the player context. Equivalent to {@code getBaritone().getPlayerContext()}.
*
* @return The player context
*/
IPlayerContext getPlayerContext();
/**
* @return The network manager that is responsible for the current connection.
*/
NetworkManager getNetworkManager();
/**
* Returns the user login session. Should never be {@code null}, as this should be set when the
* user is constructed.
*
* @return This users's login session
*/
Session getSession();
/**
* Returns the game profile for the account represented by this user.
*
* @return This users's profile.
*/
GameProfile getProfile();
/**
* @return The manager that spawned this {@link IBaritoneUser}.
*/
IUserManager getManager();
}

View File

@@ -0,0 +1,97 @@
/*
* 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.bot;
import baritone.api.bot.connect.ConnectionStatus;
import baritone.api.bot.connect.IConnectionResult;
import baritone.api.event.events.TickEvent;
import com.mojang.authlib.GameProfile;
import net.minecraft.util.Session;
import net.minecraft.util.text.ITextComponent;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
/**
* @author Brady
* @since 1/17/2019
*/
public interface IUserManager {
/**
* Connects a new user with the specified {@link Session} to the current server. Returns
* a {@link IConnectionResult} describing the result of the attempted connection as well
* as a {@link IBaritoneUser} instance if it was {@link ConnectionStatus#SUCCESS}.
*
* @param session The user session
* @return The result of the attempted connection
*/
IConnectionResult connect(Session session);
/**
* Disconnects the specified {@link IBaritoneUser} from its current server. All valid users
* are automatically disconnected when the current game state becomes {@link TickEvent.Type#OUT}.
* A reason may be specified, but is more widely used in server-initiated disconnects.
*
* @param user The user to disconnect
* @param reason The reason for the disconnect, may be {@code null}
*/
void disconnect(IBaritoneUser user, ITextComponent reason);
/**
* Finds the {@link IBaritoneUser} associated with the specified {@link GameProfile}
*
* @param profile The game profile of the user
* @return The user, {@link Optional#empty()} if no match or {@code profile} is {@code null}
*/
default Optional<IBaritoneUser> getUserByProfile(GameProfile profile) {
return profile == null
? Optional.empty()
: this.getUsers().stream().filter(user -> user.getProfile().equals(profile)).findFirst();
}
/**
* Finds the {@link IBaritoneUser} associated with the specified {@link UUID}
*
* @param uuid The uuid of the user
* @return The user, {@link Optional#empty()} if no match or {@code uuid} is {@code null}
*/
default Optional<IBaritoneUser> getUserByUUID(UUID uuid) {
return uuid == null
? Optional.empty()
: this.getUsers().stream().filter(user -> user.getProfile().getId().equals(uuid)).findFirst();
}
/**
* Finds the {@link IBaritoneUser} associated with the specified username
*
* @param username The username of the user
* @return The user, {@link Optional#empty()} if no match or {@code uuid} is {@code null}
*/
default Optional<IBaritoneUser> getUserByName(String username) {
return username == null || username.isEmpty()
? Optional.empty()
: this.getUsers().stream().filter(user -> user.getProfile().getName().equalsIgnoreCase(username)).findFirst();
}
/**
* @return All of the users held by this manager
*/
List<IBaritoneUser> getUsers();
}

View File

@@ -0,0 +1,50 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.bot.connect;
/**
* @author Brady
* @since 11/6/2018
*/
public enum ConnectionStatus {
/**
* The local player is not connected to a server, therefore, there is no target server to connect to.
*/
NO_CURRENT_CONNECTION,
/**
* The IP of the targetted address to connect to could not be resolved.
*/
CANT_RESOLVE_HOST,
/**
* The port for the detected LAN server could not be resolved.
*/
CANT_RESOLVE_LAN,
/**
* The connection initialization failed.
*/
CONNECTION_FAILED,
/**
* The connection was a success
*/
SUCCESS
}

View File

@@ -0,0 +1,44 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.api.bot.connect;
import baritone.api.bot.IBaritoneUser;
import java.util.Optional;
/**
* @author Brady
* @since 1/17/2019
*/
public interface IConnectionResult {
/**
* @return The actual status of the connection attempt.
* @see ConnectionStatus
*/
ConnectionStatus getStatus();
/**
* Returns the user that was created in this connection this result reflects, if
* {@link #getStatus()} is {@link ConnectionStatus#SUCCESS}, otherwise it will
* return {@link Optional#empty()}.
*
* @return The user created in the connection
*/
Optional<IBaritoneUser> getUser();
}

View File

@@ -46,6 +46,8 @@ public interface IPlayerController {
ItemStack windowClick(int windowId, int slotId, int mouseButton, ClickType type, EntityPlayer player);
void setGameType(GameType type);
GameType getGameType();
EnumActionResult processRightClickBlock(EntityPlayerSP player, World world, BlockPos pos, EnumFacing direction, Vec3d vec, EnumHand hand);

View File

@@ -21,6 +21,7 @@ import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.event.events.RenderEvent;
import net.minecraft.client.renderer.EntityRenderer;
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;
@@ -38,7 +39,13 @@ public class MixinEntityRenderer {
)
)
private void renderWorldPass(int pass, float partialTicks, long finishTimeNano, CallbackInfo ci) {
int renderViewDimension = BaritoneAPI.getProvider().getPrimaryBaritone().getPlayerContext().world().provider.getDimensionType().getId();
for (IBaritone ibaritone : BaritoneAPI.getProvider().getAllBaritones()) {
World world = ibaritone.getPlayerContext().world();
if (world == null || world.provider.getDimensionType().getId() != renderViewDimension) {
continue;
}
ibaritone.getGameEventHandler().onRenderPass(new RenderEvent(partialTicks));
}
}

View File

@@ -0,0 +1,43 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.launch.mixins;
import baritone.utils.accessor.IGameSettings;
import net.minecraft.client.Minecraft;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.entity.player.EnumPlayerModelParts;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import java.util.Set;
/**
* @author Brady
* @since 3/6/2020
*/
@Mixin(GameSettings.class)
public abstract class MixinGameSettings implements IGameSettings {
@Accessor
@Override
public abstract void setSetModelParts(Set<EnumPlayerModelParts> setModelParts);
@Accessor
@Override
public abstract void setMc(Minecraft mc);
}

View File

@@ -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.launch.mixins;
import baritone.utils.accessor.IIntegratedServer;
import net.minecraft.client.multiplayer.ThreadLanServerPing;
import net.minecraft.server.integrated.IntegratedServer;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
/**
* @author Brady
* @since 3/4/2020
*/
@Mixin(IntegratedServer.class)
public abstract class MixinIntegratedServer implements IIntegratedServer {
@Accessor
@Override
public abstract ThreadLanServerPing getLanServerPing();
}

View File

@@ -24,6 +24,7 @@ import baritone.api.event.events.PlayerUpdateEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.WorldEvent;
import baritone.api.event.events.type.EventState;
import baritone.utils.accessor.IMinecraft;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.gui.GuiScreen;
@@ -33,7 +34,9 @@ import net.minecraft.util.EnumActionResult;
import net.minecraft.util.EnumHand;
import net.minecraft.util.math.BlockPos;
import org.spongepowered.asm.lib.Opcodes;
import org.spongepowered.asm.mixin.Final;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.Mutable;
import org.spongepowered.asm.mixin.Shadow;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
@@ -41,6 +44,7 @@ import org.spongepowered.asm.mixin.injection.Redirect;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
import org.spongepowered.asm.mixin.injection.callback.LocalCapture;
import java.io.File;
import java.util.function.BiFunction;
/**
@@ -48,13 +52,19 @@ import java.util.function.BiFunction;
* @since 7/31/2018
*/
@Mixin(Minecraft.class)
public class MixinMinecraft {
public class MixinMinecraft implements IMinecraft {
@Shadow
public EntityPlayerSP player;
@Shadow
public WorldClient world;
@Shadow
@Final
@Mutable
public File gameDir;
@Inject(
method = "init",
at = @At("RETURN")
@@ -176,4 +186,9 @@ public class MixinMinecraft {
// rightClickMouse is only for the main player
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().onBlockInteract(new BlockInteractEvent(blockpos, BlockInteractEvent.Type.USE));
}
@Override
public void setGameDir(File gameDir) {
this.gameDir = gameDir;
}
}

View File

@@ -23,7 +23,9 @@ import baritone.api.IBaritone;
import baritone.api.event.events.ChunkEvent;
import baritone.api.event.events.type.EventState;
import baritone.cache.CachedChunk;
import baritone.utils.accessor.INetHandlerPlayClient;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.network.play.server.SPacketBlockChange;
import net.minecraft.network.play.server.SPacketChunkData;
@@ -31,6 +33,7 @@ import net.minecraft.network.play.server.SPacketCombatEvent;
import net.minecraft.network.play.server.SPacketMultiBlockChange;
import net.minecraft.util.math.ChunkPos;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
import org.spongepowered.asm.mixin.injection.At;
import org.spongepowered.asm.mixin.injection.Inject;
import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
@@ -40,7 +43,11 @@ import org.spongepowered.asm.mixin.injection.callback.CallbackInfo;
* @since 8/3/2018
*/
@Mixin(NetHandlerPlayClient.class)
public class MixinNetHandlerPlayClient {
public abstract class MixinNetHandlerPlayClient implements INetHandlerPlayClient {
@Accessor
@Override
public abstract void setWorld(WorldClient world);
@Inject(
method = "handleChunkData",

View File

@@ -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.IThreadLanServerPing;
import net.minecraft.client.multiplayer.ThreadLanServerPing;
import org.spongepowered.asm.mixin.Mixin;
import org.spongepowered.asm.mixin.gen.Accessor;
/**
* @author Brady
* @since 3/4/2020
*/
@Mixin(ThreadLanServerPing.class)
public abstract class MixinThreadLanServerPing implements IThreadLanServerPing {
@Accessor
@Override
public abstract String getMotd();
@Accessor
@Override
public abstract String getAddress();
}

View File

@@ -19,7 +19,9 @@
"MixinEntityLivingBase",
"MixinEntityPlayerSP",
"MixinEntityRenderer",
"MixinGameSettings",
"MixinGuiScreen",
"MixinIntegratedServer",
"MixinItemStack",
"MixinItemTool",
"MixinMinecraft",
@@ -31,6 +33,7 @@
"MixinRenderList",
"MixinStateImplementation",
"MixinTabCompleter",
"MixinThreadLanServerPing",
"MixinVboRenderList",
"MixinWorldClient"
]

View File

@@ -26,6 +26,7 @@ import baritone.api.process.IBaritoneProcess;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.command.ExampleBaritoneControl;
import baritone.command.manager.CommandManager;
import baritone.event.GameEventHandler;
import baritone.process.*;
@@ -36,6 +37,7 @@ import baritone.utils.InputOverrideHandler;
import baritone.utils.PathingControlManager;
import baritone.utils.player.BaritonePlayerContext;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.GuiScreen;
import java.io.IOException;
import java.nio.file.Files;
@@ -232,10 +234,14 @@ public class Baritone implements IBaritone {
@Override
public void openClick() {
this.showScreen(new GuiClick());
}
public void showScreen(GuiScreen screen) {
new Thread(() -> {
try {
Thread.sleep(100);
mc.addScheduledTask(() -> mc.displayGuiScreen(new GuiClick()));
mc.addScheduledTask(() -> mc.displayGuiScreen(screen));
} catch (Exception ignored) {}
}).start();
}

View File

@@ -19,9 +19,11 @@ package baritone;
import baritone.api.IBaritone;
import baritone.api.IBaritoneProvider;
import baritone.api.bot.IUserManager;
import baritone.api.cache.IWorldScanner;
import baritone.api.command.ICommandSystem;
import baritone.api.schematic.ISchematicSystem;
import baritone.bot.UserManager;
import baritone.cache.FasterWorldScanner;
import baritone.command.CommandSystem;
import baritone.command.ExampleBaritoneControl;
@@ -79,6 +81,11 @@ public final class BaritoneProvider implements IBaritoneProvider {
return FasterWorldScanner.INSTANCE;
}
@Override
public IUserManager getUserManager() {
return UserManager.INSTANCE;
}
@Override
public ICommandSystem getCommandSystem() {
return CommandSystem.INSTANCE;

View File

@@ -0,0 +1,107 @@
/*
* 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.bot;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.IBaritone;
import baritone.api.bot.IBaritoneUser;
import baritone.api.event.events.WorldEvent;
import baritone.api.event.events.type.EventState;
import baritone.api.utils.IPlayerContext;
import baritone.bot.impl.BotMinecraft;
import baritone.bot.impl.BotWorld;
import baritone.bot.impl.BotPlayer;
import baritone.command.ExampleBaritoneControl;
import com.mojang.authlib.GameProfile;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.Session;
/**
* Implementation of {@link IBaritoneUser}
*
* @author Brady
* @since 11/6/2018
*/
public final class BaritoneUser implements IBaritoneUser {
private final BotMinecraft mc;
private final UserManager manager;
private final NetworkManager networkManager;
private final Session session;
private final Baritone baritone;
private GameProfile profile;
BaritoneUser(UserManager manager, NetworkManager networkManager, Session session, ServerData serverData) {
this.mc = BotMinecraft.allocate(this);
this.mc.setServerData(serverData);
this.manager = manager;
this.networkManager = networkManager;
this.session = session;
this.profile = session.getProfile();
this.baritone = (Baritone) BaritoneAPI.getProvider().createBaritone(this.mc);
this.baritone.registerBehavior(ExampleBaritoneControl::new);
}
public void onLoginSuccess(GameProfile profile) {
this.profile = profile;
}
public void onWorldLoad(BotWorld world, BotPlayer player, PlayerControllerMP playerController) {
this.baritone.getGameEventHandler().onWorldEvent(new WorldEvent(world, EventState.PRE));
this.mc.player = player;
this.mc.world = world;
this.mc.playerController = playerController;
this.baritone.getGameEventHandler().onWorldEvent(new WorldEvent(world, EventState.POST));
}
@Override
public IBaritone getBaritone() {
return this.baritone;
}
@Override
public IPlayerContext getPlayerContext() {
return this.baritone.getPlayerContext();
}
@Override
public NetworkManager getNetworkManager() {
return this.networkManager;
}
@Override
public Session getSession() {
return this.session;
}
@Override
public GameProfile getProfile() {
return this.profile;
}
@Override
public UserManager getManager() {
return this.manager;
}
}

View File

@@ -0,0 +1,66 @@
/*
* 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.bot;
import baritone.bot.impl.BotWorld;
import it.unimi.dsi.fastutil.ints.Int2ObjectArrayMap;
import it.unimi.dsi.fastutil.ints.Int2ObjectMap;
import net.minecraft.world.GameType;
import net.minecraft.world.WorldSettings;
import net.minecraft.world.WorldType;
/**
* @author Brady
* @since 11/7/2018
*/
public final class BotWorldProvider {
/**
* Generic world settings for a typical survival world.
*/
private static final WorldSettings GENERIC_WORLD_SETTINGS = new WorldSettings(0L, GameType.SURVIVAL, true, false, WorldType.DEFAULT);
/**
* All of the dimensions mapped to their respective worlds.
*/
private final Int2ObjectMap<BotWorld> worlds = new Int2ObjectArrayMap<>();
/**
* Gets or creates the {@link BotWorld} for the specified dimension
*
* @param dimension The dimension id
* @return The world
*/
public BotWorld getWorld(int dimension) {
return worlds.computeIfAbsent(dimension, this::createWorldForDim);
}
/**
* Creates a new {@link BotWorld} for the given dimension id.
*
* @param dimension The dimension id
* @return The new world
*/
private BotWorld createWorldForDim(int dimension) {
return new BotWorld(GENERIC_WORLD_SETTINGS, dimension);
}
public void tick() {
this.worlds.forEach((dim, world) -> world.updateEntities());
}
}

View File

@@ -0,0 +1,203 @@
/*
* 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.bot;
import baritone.api.BaritoneAPI;
import baritone.api.bot.IBaritoneUser;
import baritone.api.bot.IUserManager;
import baritone.api.bot.connect.IConnectionResult;
import baritone.api.event.events.TickEvent;
import baritone.api.event.events.type.EventState;
import baritone.api.event.listener.AbstractGameEventListener;
import baritone.api.utils.Helper;
import baritone.api.utils.IPlayerContext;
import baritone.bot.connect.ConnectionResult;
import baritone.bot.handler.BotNetHandlerLoginClient;
import baritone.bot.impl.BotPlayer;
import baritone.bot.impl.BotWorld;
import baritone.utils.accessor.IIntegratedServer;
import baritone.utils.accessor.IThreadLanServerPing;
import net.minecraft.client.Minecraft;
import net.minecraft.client.multiplayer.ServerAddress;
import net.minecraft.client.multiplayer.ServerData;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.handshake.client.C00Handshake;
import net.minecraft.network.login.client.CPacketLoginStart;
import net.minecraft.util.Session;
import net.minecraft.util.text.ITextComponent;
import java.net.InetAddress;
import java.net.UnknownHostException;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
import static baritone.api.bot.connect.ConnectionStatus.*;
/**
* @author Brady
* @since 11/6/2018
*/
public enum UserManager implements IUserManager, AbstractGameEventListener {
INSTANCE;
private static final Minecraft mc = Minecraft.getMinecraft();
private final List<IBaritoneUser> users;
private final BotWorldProvider worldProvider;
UserManager() {
BaritoneAPI.getProvider().getPrimaryBaritone().getGameEventHandler().registerEventListener(this);
this.users = new CopyOnWriteArrayList<>();
this.worldProvider = new BotWorldProvider();
}
@Override
public void onTick(TickEvent event) {
if (event.getState() != EventState.PRE) {
return;
}
this.users.forEach(user -> {
switch (event.getType()) {
case IN: {
final IPlayerContext ctx = user.getPlayerContext();
if (ctx.player() != null) {
ctx.playerController().syncHeldItem();
}
if (user.getNetworkManager().isChannelOpen()) {
user.getNetworkManager().processReceivedPackets();
} else {
user.getNetworkManager().handleDisconnection();
}
break;
}
case OUT: {
this.disconnect(user, null);
break;
}
}
});
this.worldProvider.tick();
}
/**
* Connects a new user with the specified {@link Session} to the current server.
*
* @param session The user session
* @return The result of the attempted connection
*/
@Override
public final IConnectionResult connect(Session session) {
if (mc.getIntegratedServer() != null && mc.getIntegratedServer().getPublic()) {
try {
IIntegratedServer integratedServer = (IIntegratedServer) mc.getIntegratedServer();
IThreadLanServerPing lanServerPing = (IThreadLanServerPing) integratedServer.getLanServerPing();
int port = Integer.parseInt(lanServerPing.getAddress());
return connect0(session, new ServerData(lanServerPing.getMotd(), "localhost:" + port, true));
} catch (Exception e) {
e.printStackTrace();
return ConnectionResult.failed(CANT_RESOLVE_LAN);
}
}
ServerData data = mc.getCurrentServerData();
if (data == null) {
return ConnectionResult.failed(NO_CURRENT_CONNECTION);
}
// Connect to the server from the parsed server data
return connect0(session, data);
}
/**
* Connects a new user with the specified {@link Session} to the specified server.
* <p>
* Hi Mickey :)
*
* @param session The user session
* @param data The address of the server to connect to
* @return The result of the attempted connection
*/
private IConnectionResult connect0(Session session, ServerData data) {
ServerAddress address = ServerAddress.fromString(data.serverIP);
InetAddress inetAddress;
try {
inetAddress = InetAddress.getByName(address.getIP());
} catch (UnknownHostException e) {
return ConnectionResult.failed(CANT_RESOLVE_HOST);
}
try {
// Initialize Connection
NetworkManager networkManager = NetworkManager.createNetworkManagerAndConnect(
inetAddress,
address.getPort(),
mc.gameSettings.isUsingNativeTransport()
);
// Create User
BaritoneUser user = new BaritoneUser(this, networkManager, session, data);
this.users.add(user);
// Setup login handler and send connection packets
networkManager.setNetHandler(new BotNetHandlerLoginClient(networkManager, user));
networkManager.sendPacket(new C00Handshake(address.getIP(), address.getPort(), EnumConnectionState.LOGIN));
networkManager.sendPacket(new CPacketLoginStart(session.getProfile()));
return ConnectionResult.success(user);
} catch (Exception e) {
e.printStackTrace();
return ConnectionResult.failed(CONNECTION_FAILED);
}
}
/**
* @return The bot world provider
*/
public final BotWorldProvider getWorldProvider() {
return this.worldProvider;
}
@Override
public final void disconnect(IBaritoneUser user, ITextComponent reason) {
if (this.users.contains(user)) {
if (user.getNetworkManager().isChannelOpen()) {
user.getNetworkManager().closeChannel(reason);
}
BaritoneAPI.getProvider().destroyBaritone(user.getBaritone());
this.users.remove(user);
Helper.HELPER.logDirect(user.getSession().getUsername() + " Disconnected: " +
(reason == null ? "Unknown" : reason.getUnformattedText()));
final IPlayerContext ctx = user.getPlayerContext();
if (ctx.player() != null && ctx.world() != null) {
((BotWorld) ctx.world()).handleWorldRemove((BotPlayer) ctx.player());
}
}
}
@Override
public final List<IBaritoneUser> getUsers() {
return Collections.unmodifiableList(this.users);
}
}

View File

@@ -0,0 +1,95 @@
/*
* 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.bot.connect;
import baritone.api.bot.IBaritoneUser;
import baritone.api.bot.connect.ConnectionStatus;
import baritone.api.bot.connect.IConnectionResult;
import java.util.Objects;
import java.util.Optional;
import static baritone.api.bot.connect.ConnectionStatus.SUCCESS;
/**
* @author Brady
* @since 11/6/2018
*/
public final class ConnectionResult implements IConnectionResult {
/**
* The result status
*/
private final ConnectionStatus status;
/**
* The user created, if the status is {@link ConnectionStatus#SUCCESS}
*/
private final IBaritoneUser user;
private ConnectionResult(ConnectionStatus status, IBaritoneUser user) {
this.status = status;
this.user = user;
}
@Override
public ConnectionStatus getStatus() {
return this.status;
}
@Override
public Optional<IBaritoneUser> getUser() {
return Optional.ofNullable(user);
}
/**
* Creates a new failed {@link ConnectionResult}.
*
* @param status The failed connection status
* @return The connection result
* @throws IllegalArgumentException if {@code status} is {@link ConnectionStatus#SUCCESS}
*/
public static ConnectionResult failed(ConnectionStatus status) {
if (status == SUCCESS) {
throw new IllegalArgumentException("Status must be a failure type");
}
return new ConnectionResult(status, null);
}
/**
* Creates a new success {@link ConnectionResult}.
*
* @param user The user created
* @return The connection result
* @throws IllegalArgumentException if {@code user} is {@code null}
*/
public static ConnectionResult success(IBaritoneUser user) {
Objects.requireNonNull(user);
return new ConnectionResult(SUCCESS, user);
}
@Override
public String toString() {
return "ConnectionResult{" +
"status=" + status +
", user=" + user +
'}';
}
}

View File

@@ -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 baritone.bot.handler;
import baritone.bot.BaritoneUser;
import baritone.bot.impl.BotMinecraft;
import net.minecraft.client.Minecraft;
import net.minecraft.client.network.NetHandlerLoginClient;
import net.minecraft.network.EnumConnectionState;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.login.server.SPacketLoginSuccess;
import net.minecraft.util.text.ITextComponent;
import javax.annotation.Nonnull;
/**
* Handles the login stage when connecting to a server.
*
* @author Brady
* @since 10/29/2018
*/
public final class BotNetHandlerLoginClient extends NetHandlerLoginClient {
/**
* The {@link NetworkManager} that is managing the connection with the server.
*/
private final NetworkManager networkManager;
/**
* The {@link Minecraft} game instance
*/
private final BotMinecraft mc;
/**
* The bot of this connection
*/
private final BaritoneUser user;
public BotNetHandlerLoginClient(NetworkManager networkManager, BaritoneUser user) {
super(networkManager, user.getPlayerContext().minecraft(), null);
this.networkManager = networkManager;
this.mc = (BotMinecraft) user.getPlayerContext().minecraft();
this.user = user;
}
@Override
public void handleLoginSuccess(SPacketLoginSuccess packetIn) {
this.networkManager.setConnectionState(EnumConnectionState.PLAY);
this.networkManager.setNetHandler(new BotNetHandlerPlayClient(this.networkManager, this.user, this.mc, packetIn.getProfile()));
}
@Override
public void onDisconnect(@Nonnull ITextComponent reason) {
// It's important that we don't call the superclass method because that would mess up GUIs and make us upset
this.user.getManager().disconnect(this.user, reason);
}
}

View File

@@ -0,0 +1,521 @@
/*
* 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.bot.handler;
import baritone.api.utils.Helper;
import baritone.bot.BaritoneUser;
import baritone.bot.impl.BotPlayer;
import baritone.bot.impl.BotMinecraft;
import baritone.bot.impl.BotWorld;
import baritone.utils.accessor.INetHandlerPlayClient;
import com.mojang.authlib.GameProfile;
import io.netty.buffer.Unpooled;
import net.minecraft.client.multiplayer.ClientAdvancementManager;
import net.minecraft.client.multiplayer.PlayerControllerMP;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.client.util.RecipeBookClient;
import net.minecraft.entity.Entity;
import net.minecraft.network.NetworkManager;
import net.minecraft.network.PacketBuffer;
import net.minecraft.network.PacketThreadUtil;
import net.minecraft.network.play.client.CPacketClientStatus;
import net.minecraft.network.play.client.CPacketCustomPayload;
import net.minecraft.network.play.client.CPacketResourcePackStatus;
import net.minecraft.network.play.server.*;
import net.minecraft.stats.StatisticsManager;
import net.minecraft.util.text.ITextComponent;
import javax.annotation.Nonnull;
// Notes
// - Make some sort of system that prevents repetition of entity info updating
// - For some packets, such as ones that modify position, we can check if the existing server state matches the packet proposed state
// - For other things, we'll actually need the system
/**
* @author Brady
* @since 10/22/2018
*/
public final class BotNetHandlerPlayClient extends NetHandlerPlayClient {
/**
* The {@link NetworkManager} that is managing the connection with the server.
*/
private final NetworkManager networkManager;
/**
* The bot's minecraft game instance
*/
private final BotMinecraft client;
/**
* The bot of this connection
*/
private final BaritoneUser user;
/**
* The bot player
*/
private BotPlayer player;
/**
* The current world.
*/
private BotWorld world;
/**
* The current player controller
*/
private PlayerControllerMP playerController;
BotNetHandlerPlayClient(NetworkManager networkManager, BaritoneUser user, BotMinecraft client, GameProfile profile) {
// noinspection ConstantConditions
super(client, null, networkManager, profile);
this.networkManager = networkManager;
this.client = client;
this.user = user;
// Notify the user that we're ingame
this.user.onLoginSuccess(profile);
}
@Override
public void handleSpawnObject(@Nonnull SPacketSpawnObject packetIn) {
super.handleSpawnObject(packetIn);
}
@Override
public void handleSpawnExperienceOrb(@Nonnull SPacketSpawnExperienceOrb packetIn) {
super.handleSpawnExperienceOrb(packetIn);
}
@Override
public void handleSpawnGlobalEntity(@Nonnull SPacketSpawnGlobalEntity packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (this.world != null) {
if (this.world.weatherEffects.stream().noneMatch(entity -> entity.getEntityId() == packetIn.getEntityId())) {
super.handleSpawnGlobalEntity(packetIn);
}
}
}
@Override
public void handleSpawnMob(@Nonnull SPacketSpawnMob packetIn) {}
@Override
public void handleScoreboardObjective(@Nonnull SPacketScoreboardObjective packetIn) {}
@Override
public void handleSpawnPainting(@Nonnull SPacketSpawnPainting packetIn) {}
@Override
public void handleSpawnPlayer(@Nonnull SPacketSpawnPlayer packetIn) {}
@Override
public void handleAnimation(@Nonnull SPacketAnimation packetIn) {
super.handleAnimation(packetIn);
}
@Override
public void handleStatistics(@Nonnull SPacketStatistics packetIn) {
super.handleStatistics(packetIn);
}
@Override
public void handleRecipeBook(@Nonnull SPacketRecipeBook packetIn) {}
@Override
public void handleBlockBreakAnim(@Nonnull SPacketBlockBreakAnim packetIn) {
super.handleBlockBreakAnim(packetIn);
}
@Override
public void handleSignEditorOpen(@Nonnull SPacketSignEditorOpen packetIn) {}
@Override
public void handleUpdateTileEntity(@Nonnull SPacketUpdateTileEntity packetIn) {}
@Override
public void handleBlockAction(@Nonnull SPacketBlockAction packetIn) {}
@Override
public void handleBlockChange(@Nonnull SPacketBlockChange packetIn) {
super.handleBlockChange(packetIn);
}
@Override
public void handleChat(@Nonnull SPacketChat packetIn) {}
@Override
public void handleTabComplete(@Nonnull SPacketTabComplete packetIn) {}
@Override
public void handleMultiBlockChange(@Nonnull SPacketMultiBlockChange packetIn) {
super.handleMultiBlockChange(packetIn);
}
@Override
public void handleMaps(@Nonnull SPacketMaps packetIn) {}
@Override
public void handleConfirmTransaction(@Nonnull SPacketConfirmTransaction packetIn) {
super.handleConfirmTransaction(packetIn);
}
@Override
public void handleCloseWindow(@Nonnull SPacketCloseWindow packetIn) {
super.handleCloseWindow(packetIn);
}
@Override
public void handleWindowItems(@Nonnull SPacketWindowItems packetIn) {
super.handleWindowItems(packetIn);
}
@Override
public void handleOpenWindow(@Nonnull SPacketOpenWindow packetIn) {}
@Override
public void handleWindowProperty(@Nonnull SPacketWindowProperty packetIn) {
super.handleWindowProperty(packetIn);
}
@Override
public void handleSetSlot(@Nonnull SPacketSetSlot packetIn) {
super.handleSetSlot(packetIn);
}
@Override
public void handleCustomPayload(@Nonnull SPacketCustomPayload packetIn) {}
@Override
public void handleDisconnect(@Nonnull SPacketDisconnect packetIn) {
super.handleDisconnect(packetIn);
}
@Override
public void handleUseBed(@Nonnull SPacketUseBed packetIn) {}
@Override
public void handleEntityStatus(@Nonnull SPacketEntityStatus packetIn) {
super.handleEntityStatus(packetIn);
}
@Override
public void handleEntityAttach(@Nonnull SPacketEntityAttach packetIn) {
super.handleEntityAttach(packetIn);
}
@Override
public void handleSetPassengers(@Nonnull SPacketSetPassengers packetIn) {}
@Override
public void handleExplosion(@Nonnull SPacketExplosion packetIn) {
super.handleExplosion(packetIn);
}
@Override
public void handleChangeGameState(@Nonnull SPacketChangeGameState packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (packetIn.getGameState() == 4) {
this.client.player.connection.sendPacket(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
} else if (packetIn.getGameState() != 5) {
super.handleChangeGameState(packetIn);
}
}
@Override
public void handleKeepAlive(@Nonnull SPacketKeepAlive packetIn) {
super.handleKeepAlive(packetIn);
}
@Override
public void handleChunkData(@Nonnull SPacketChunkData packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (packetIn.isFullChunk()) {
if (!this.world.handlePreChunk(this.player, packetIn.getChunkX(), packetIn.getChunkZ(), true)) {
return;
}
}
super.handleChunkData(packetIn);
}
@Override
public void processChunkUnload(@Nonnull SPacketUnloadChunk packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (this.world.handlePreChunk(this.player, packetIn.getX(), packetIn.getZ(), false)) {
super.processChunkUnload(packetIn);
}
}
@Override
public void handleEffect(@Nonnull SPacketEffect packetIn) {}
@Override
public void handleJoinGame(@Nonnull SPacketJoinGame packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
this.playerController = new PlayerControllerMP(this.user.getPlayerContext().minecraft(), this);
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimension());
((INetHandlerPlayClient) (Object) this).setWorld(this.world);
this.player = new BotPlayer(this.user, this.client, this.world, this, new StatisticsManager(), new RecipeBookClient());
this.user.onWorldLoad(this.world, this.player, this.playerController);
this.player.preparePlayerToSpawn();
this.player.setEntityId(packetIn.getPlayerId());
this.player.dimension = packetIn.getDimension();
this.world.addEntityToWorld(packetIn.getPlayerId(), this.player);
this.playerController.setGameType(packetIn.getGameType());
packetIn.getGameType().configurePlayerCapabilities(this.player.capabilities);
this.client.gameSettings.sendSettingsToServer();
this.networkManager.sendPacket(new CPacketCustomPayload("MC|Brand", new PacketBuffer(Unpooled.buffer()).writeString("vanilla")));
Helper.HELPER.logDirect("Initialized Player and World");
}
@Override
public void handleEntityMovement(@Nonnull SPacketEntity packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
Entity e = packetIn.getEntity(this.world);
if (e instanceof BotPlayer && !e.equals(this.player)) {
return;
}
super.handleEntityMovement(packetIn);
}
@Override
public void handlePlayerPosLook(@Nonnull SPacketPlayerPosLook packetIn) {
super.handlePlayerPosLook(packetIn);
}
@Override
public void handleParticles(@Nonnull SPacketParticles packetIn) {}
@Override
public void handlePlayerAbilities(@Nonnull SPacketPlayerAbilities packetIn) {
super.handlePlayerAbilities(packetIn);
}
@Override
public void handlePlayerListItem(@Nonnull SPacketPlayerListItem packetIn) {
super.handlePlayerListItem(packetIn);
}
@Override
public void handleDestroyEntities(@Nonnull SPacketDestroyEntities packetIn) {
super.handleDestroyEntities(packetIn);
}
@Override
public void handleRemoveEntityEffect(@Nonnull SPacketRemoveEntityEffect packetIn) {
super.handleRemoveEntityEffect(packetIn);
}
@Override
public void handleRespawn(@Nonnull SPacketRespawn packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
if (packetIn.getDimensionID() != this.player.dimension) {
this.world.handleWorldRemove(this.player);
this.world = this.user.getManager().getWorldProvider().getWorld(packetIn.getDimensionID());
((INetHandlerPlayClient) (Object) this).setWorld(this.world);
}
BotPlayer prev = this.player;
this.player = new BotPlayer(this.user, this.client, this.world, this, prev.getStatFileWriter(), prev.getRecipeBook());
this.user.onWorldLoad(this.world, this.player, this.playerController);
// noinspection ConstantConditions
this.player.getDataManager().setEntryValues(prev.getDataManager().getAll());
this.player.preparePlayerToSpawn();
this.player.setEntityId(prev.getEntityId());
this.player.dimension = packetIn.getDimensionID();
this.player.setServerBrand(prev.getServerBrand());
this.world.addEntityToWorld(prev.getEntityId(), this.player);
this.playerController.setGameType(packetIn.getGameType());
}
@Override
public void handleEntityHeadLook(@Nonnull SPacketEntityHeadLook packetIn) {}
@Override
public void handleHeldItemChange(@Nonnull SPacketHeldItemChange packetIn) {
super.handleHeldItemChange(packetIn);
}
@Override
public void handleDisplayObjective(@Nonnull SPacketDisplayObjective packetIn) {}
@Override
public void handleEntityMetadata(@Nonnull SPacketEntityMetadata packetIn) {
super.handleEntityMetadata(packetIn);
}
@Override
public void handleEntityVelocity(@Nonnull SPacketEntityVelocity packetIn) {
super.handleEntityVelocity(packetIn);
}
@Override
public void handleEntityEquipment(@Nonnull SPacketEntityEquipment packetIn) {
super.handleEntityEquipment(packetIn);
}
@Override
public void handleSetExperience(@Nonnull SPacketSetExperience packetIn) {
super.handleSetExperience(packetIn);
}
@Override
public void handleUpdateHealth(@Nonnull SPacketUpdateHealth packetIn) {
super.handleUpdateHealth(packetIn);
}
@Override
public void handleTeams(@Nonnull SPacketTeams packetIn) {}
@Override
public void handleUpdateScore(@Nonnull SPacketUpdateScore packetIn) {}
@Override
public void handleSpawnPosition(@Nonnull SPacketSpawnPosition packetIn) { /* We probably don't need to know this, the server handles everything related to spawn psoition? */ }
@Override
public void handleTimeUpdate(@Nonnull SPacketTimeUpdate packetIn) {
super.handleTimeUpdate(packetIn);
}
@Override
public void handleSoundEffect(@Nonnull SPacketSoundEffect packetIn) {}
@Override
public void handleCustomSound(@Nonnull SPacketCustomSound packetIn) {}
@Override
public void handleCollectItem(@Nonnull SPacketCollectItem packetIn) {
super.handleCollectItem(packetIn);
}
@Override
public void handleEntityTeleport(@Nonnull SPacketEntityTeleport packetIn) {
super.handleEntityTeleport(packetIn);
}
@Override
public void handleEntityProperties(@Nonnull SPacketEntityProperties packetIn) {
super.handleEntityProperties(packetIn);
}
@Override
public void handleEntityEffect(@Nonnull SPacketEntityEffect packetIn) {
super.handleEntityEffect(packetIn);
}
@Override
public void handleCombatEvent(@Nonnull SPacketCombatEvent packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
// We only care if we died
if (packetIn.eventType == SPacketCombatEvent.Event.ENTITY_DIED) {
if (packetIn.playerId == this.player.getEntityId()) {
// Perform an instantaneous respawn
this.networkManager.sendPacket(new CPacketClientStatus(CPacketClientStatus.State.PERFORM_RESPAWN));
user.getBaritone().getGameEventHandler().onPlayerDeath();
}
}
}
@Override
public void handleServerDifficulty(@Nonnull SPacketServerDifficulty packetIn) {}
@Override
public void handleCamera(SPacketCamera packetIn) {}
@Override
public void handleWorldBorder(@Nonnull SPacketWorldBorder packetIn) {
super.handleWorldBorder(packetIn);
}
@Override
public void handleTitle(@Nonnull SPacketTitle packetIn) {}
@Override
public void handlePlayerListHeaderFooter(@Nonnull SPacketPlayerListHeaderFooter packetIn) {}
@Override
public void handleResourcePack(@Nonnull SPacketResourcePackSend packetIn) {
PacketThreadUtil.checkThreadAndEnqueue(packetIn, this, this.client);
// Lie to the server and tell them we accepted it in response
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.ACCEPTED));
this.networkManager.sendPacket(new CPacketResourcePackStatus(CPacketResourcePackStatus.Action.SUCCESSFULLY_LOADED));
}
@Override
public void handleUpdateBossInfo(@Nonnull SPacketUpdateBossInfo packetIn) {}
@Override
public void handleCooldown(@Nonnull SPacketCooldown packetIn) {
super.handleCooldown(packetIn);
}
@Override
public void handleMoveVehicle(@Nonnull SPacketMoveVehicle packetIn) {
super.handleMoveVehicle(packetIn);
}
@Override
public void handleAdvancementInfo(@Nonnull SPacketAdvancementInfo packetIn) {
super.handleAdvancementInfo(packetIn);
}
@Override
public void handleSelectAdvancementsTab(@Nonnull SPacketSelectAdvancementsTab packetIn) {
super.handleSelectAdvancementsTab(packetIn);
}
@Override
public void func_194307_a(@Nonnull SPacketPlaceGhostRecipe p_194307_1_) {}
@Override
public void onDisconnect(@Nonnull ITextComponent reason) {
// TODO Maybe more world unloading
this.world.removeEntity(this.player);
this.user.getManager().disconnect(this.user, reason);
}
@Nonnull
@Override
public ClientAdvancementManager getAdvancementManager() {
throw new UnsupportedOperationException("This method shouldn't have been called; That is unepic!");
}
public BotPlayer player() {
return player;
}
public BotWorld world() {
return world;
}
}

View File

@@ -0,0 +1,53 @@
/*
* 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.bot.impl;
import baritone.api.bot.IBaritoneUser;
import net.minecraft.client.Minecraft;
import net.minecraft.client.gui.inventory.GuiInventory;
import javax.annotation.Nonnull;
/**
* @author Brady
*/
public final class BotGuiInventory extends GuiInventory {
private final IBaritoneUser user;
public BotGuiInventory(IBaritoneUser user) {
super(user.getPlayerContext().player());
this.user = user;
}
@Override
public void setWorldAndResolution(@Nonnull Minecraft primary, int width, int height) {
final Minecraft mc = this.user.getPlayerContext().minecraft();
mc.displayWidth = primary.displayWidth;
mc.displayHeight = primary.displayHeight;
super.setWorldAndResolution(mc, width, height);
}
@Override
protected void drawGuiContainerBackgroundLayer(float partialTicks, int mouseX, int mouseY) {
final BotPlayer player = (BotPlayer) this.user.getPlayerContext().player();
player.isUser = false;
super.drawGuiContainerBackgroundLayer(partialTicks, mouseX, mouseY);
player.isUser = true;
}
}

View File

@@ -0,0 +1,187 @@
/*
* 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.bot.impl;
import baritone.api.bot.IBaritoneUser;
import baritone.utils.ObjectAllocator;
import baritone.utils.accessor.IGameSettings;
import baritone.utils.accessor.IMinecraft;
import com.google.common.util.concurrent.ListenableFuture;
import com.mojang.authlib.minecraft.MinecraftSessionService;
import net.minecraft.client.Minecraft;
import net.minecraft.client.audio.SoundHandler;
import net.minecraft.client.gui.GuiScreen;
import net.minecraft.client.gui.toasts.GuiToast;
import net.minecraft.client.main.GameConfiguration;
import net.minecraft.client.renderer.RenderItem;
import net.minecraft.client.renderer.entity.RenderManager;
import net.minecraft.client.renderer.texture.TextureManager;
import net.minecraft.client.renderer.texture.TextureMap;
import net.minecraft.client.settings.GameSettings;
import net.minecraft.client.settings.KeyBinding;
import net.minecraft.client.tutorial.Tutorial;
import net.minecraft.entity.Entity;
import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.EnumHandSide;
import net.minecraft.util.Session;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
import java.util.HashSet;
import java.util.concurrent.Callable;
/**
* "Implementation" of {@link Minecraft} which gets allocated without receiving a constructor call.
* This allows us to avoid the game's setup process (moreso in versions after 1.12 than 1.12 itself).
*
* @author Brady
* @since 3/3/2020
*/
public final class BotMinecraft extends Minecraft {
private static final Minecraft mc = Minecraft.getMinecraft();
private IBaritoneUser user;
private Tutorial tutorial;
private GuiToast toastGui;
private BotMinecraft(GameConfiguration gameConfig) {
super(gameConfig);
}
@Nullable
@Override
public Entity getRenderViewEntity() {
return mc.getRenderViewEntity();
}
@Nonnull
@Override
public Session getSession() {
return this.user.getSession();
}
@Override
public @Nonnull MinecraftSessionService getSessionService() {
return mc.getSessionService();
}
@Override
public <V> @Nonnull ListenableFuture<V> addScheduledTask(@Nonnull Callable<V> callableToSchedule) {
return mc.addScheduledTask(callableToSchedule);
}
@Override
public boolean isCallingFromMinecraftThread() {
return mc.isCallingFromMinecraftThread();
}
@Nonnull
@Override
public Tutorial getTutorial() {
return this.tutorial;
}
@Nonnull
@Override
public SoundHandler getSoundHandler() {
return BotSoundHandler.INSTANCE;
}
@Nonnull
@Override
public GuiToast getToastGui() {
return this.toastGui;
}
@Override
public void displayGuiScreen(@Nullable GuiScreen guiScreenIn) {
// do nothing
if (guiScreenIn == null) {
if (mc.currentScreen instanceof BotGuiInventory) {
mc.displayGuiScreen(null);
}
}
}
@Nonnull
@Override
public TextureManager getTextureManager() {
return mc.getTextureManager();
}
@Nonnull
@Override
public RenderItem getRenderItem() {
return mc.getRenderItem();
}
@Nonnull
@Override
public TextureMap getTextureMapBlocks() {
return mc.getTextureMapBlocks();
}
@Override
public void dispatchKeypresses() {
// Do nothing
}
public static BotMinecraft allocate(IBaritoneUser user) {
BotMinecraft bm = ObjectAllocator.allocate(BotMinecraft.class);
((IMinecraft) (Object) bm).setGameDir(mc.gameDir);
// Gui Compatibility
bm.fontRenderer = mc.fontRenderer;
bm.user = user;
bm.tutorial = new Tutorial(bm);
bm.gameSettings = createGameSettings(bm);
bm.effectRenderer = BotParticleManager.INSTANCE;
bm.toastGui = new GuiToast(bm);
return bm;
}
private static GameSettings createGameSettings(BotMinecraft bm) {
GameSettings settings = ObjectAllocator.allocate(GameSettings.class);
// Settings that get accessed on entity tick
settings.keyBindSprint = ObjectAllocator.allocate(KeyBinding.class);
settings.autoJump = false;
// Settings that are sent to the server
settings.language = "en_us";
settings.renderDistanceChunks = 8;
settings.chatVisibility = EntityPlayer.EnumChatVisibility.FULL;
settings.chatColours = true;
settings.mainHand = EnumHandSide.RIGHT;
// Gui Compatibility
settings.keyBindPickBlock = mc.gameSettings.keyBindPickBlock;
settings.keyBindsHotbar = mc.gameSettings.keyBindsHotbar;
settings.keyBindInventory = mc.gameSettings.keyBindInventory;
settings.keyBindDrop = mc.gameSettings.keyBindDrop;
// Private fields that must be initialized
IGameSettings accessor = (IGameSettings) settings;
accessor.setMc(bm);
accessor.setSetModelParts(new HashSet<>());
return settings;
}
}

View File

@@ -0,0 +1,43 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.bot.impl;
import net.minecraft.client.particle.ParticleManager;
import net.minecraft.entity.Entity;
import net.minecraft.util.EnumParticleTypes;
import javax.annotation.Nonnull;
/**
* @author Brady
* @since 3/8/2020
*/
public final class BotParticleManager extends ParticleManager {
public static final BotParticleManager INSTANCE = new BotParticleManager();
private BotParticleManager() {
super(null, null);
}
@Override
public void emitParticleAtEntity(Entity entityIn, @Nonnull EnumParticleTypes particleTypes) {}
@Override
public void emitParticleAtEntity(Entity p_191271_1_, @Nonnull EnumParticleTypes p_191271_2_, int p_191271_3_) {}
}

View File

@@ -0,0 +1,187 @@
/*
* 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.bot.impl;
import baritone.Baritone;
import baritone.api.bot.IBaritoneUser;
import baritone.utils.PlayerMovementInput;
import net.minecraft.client.Minecraft;
import net.minecraft.client.entity.EntityPlayerSP;
import net.minecraft.client.network.NetHandlerPlayClient;
import net.minecraft.client.network.NetworkPlayerInfo;
import net.minecraft.entity.Entity;
import net.minecraft.entity.IMerchant;
import net.minecraft.entity.passive.AbstractHorse;
import net.minecraft.inventory.IInventory;
import net.minecraft.item.ItemStack;
import net.minecraft.stats.RecipeBook;
import net.minecraft.stats.StatisticsManager;
import net.minecraft.tileentity.CommandBlockBaseLogic;
import net.minecraft.tileentity.TileEntityCommandBlock;
import net.minecraft.tileentity.TileEntitySign;
import net.minecraft.tileentity.TileEntityStructure;
import net.minecraft.util.EnumHand;
import net.minecraft.util.text.ITextComponent;
import net.minecraft.world.GameType;
import net.minecraft.world.IInteractionObject;
import net.minecraft.world.World;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
// Some Notes:
// - Inventory handling!
// - If chest deposit gets added it will be most useful for bot-system
/**
* @author Brady
* @since 10/23/2018
*/
@SuppressWarnings("EntityConstructor")
public final class BotPlayer extends EntityPlayerSP {
private final IBaritoneUser user;
private NetworkPlayerInfo playerInfo;
public boolean isUser;
public BotPlayer(IBaritoneUser user, Minecraft mc, World world, NetHandlerPlayClient netHandlerPlayClient, StatisticsManager statisticsManager, RecipeBook recipeBook) {
super(mc, world, netHandlerPlayClient, statisticsManager, recipeBook);
this.user = user;
this.movementInput = new PlayerMovementInput(this.user.getBaritone().getInputOverrideHandler());
this.isUser = true;
}
@Override
public void onUpdate() {
this.entityCollisionReduction = Baritone.settings().botCollision.value ? 0.0F : 1.0F;
super.onUpdate();
}
@Override
public boolean isUser() {
// Used by BotGuiInventory to fix player model rendering in the gui
return this.isUser;
}
@Override
public double getDistanceSq(@Nonnull Entity entityIn) {
if (entityIn == Minecraft.getMinecraft().getRenderViewEntity()) {
// Always render nametag in BotGuiInventory
return 0.0;
} else {
return super.getDistanceSq(entityIn);
}
}
@Override
public void sendStatusMessage(@Nonnull ITextComponent chatComponent, boolean actionBar) {
// TODO: Custom message handling
}
@Override
public void sendMessage(@Nonnull ITextComponent component) {
// TODO: Custom message handling
}
@Override
public void openEditSign(@Nonnull TileEntitySign signTile) {
// TODO: Custom GUI handling
}
@Override
public void displayGuiEditCommandCart(@Nonnull CommandBlockBaseLogic commandBlock) {
// TODO: Custom GUI handling
}
@Override
public void displayGuiCommandBlock(@Nonnull TileEntityCommandBlock commandBlock) {
// TODO: Custom GUI handling
}
@Override
public void openEditStructure(@Nonnull TileEntityStructure structure) {
// TODO: Custom GUI handling
}
@Override
public void openBook(ItemStack stack, EnumHand hand) {
// TODO: Custom GUI handling
}
@Override
public void displayGUIChest(@Nonnull IInventory chestInventory) {
// TODO: Custom GUI handling
}
@Override
public void openGuiHorseInventory(@Nonnull AbstractHorse horse, IInventory inventoryIn) {
// TODO: Custom GUI handling
}
@Override
public void displayGui(IInteractionObject guiOwner) {
// TODO: Custom GUI handling
}
@Override
public void displayVillagerTradeGui(IMerchant villager) {
// TODO: Custom GUI handling
}
@Override
public void onCriticalHit(@Nonnull Entity entityHit) {
// Don't render
}
@Override
public void onEnchantmentCritical(@Nonnull Entity entityHit) {
// Don't render
}
@Override
protected boolean isCurrentViewEntity() {
return true;
}
@Override
public boolean isSpectator() {
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
// noinspection ConstantConditions
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.SPECTATOR;
}
@Override
public boolean isCreative() {
NetworkPlayerInfo networkplayerinfo = this.connection.getPlayerInfo(this.getGameProfile().getId());
// noinspection ConstantConditions
return networkplayerinfo != null && networkplayerinfo.getGameType() == GameType.CREATIVE;
}
@Nullable
@Override
protected NetworkPlayerInfo getPlayerInfo() {
return this.playerInfo == null ? (this.playerInfo = this.connection.getPlayerInfo(this.getUniqueID())) : null;
}
@Override
public boolean isAutoJumpEnabled() {
return false;
}
}

View File

@@ -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.bot.impl;
import net.minecraft.client.audio.ISound;
import net.minecraft.client.audio.SoundHandler;
import javax.annotation.Nonnull;
/**
* @author Brady
* @since 3/7/2020
*/
public final class BotSoundHandler extends SoundHandler {
public static final BotSoundHandler INSTANCE = new BotSoundHandler();
private BotSoundHandler() {
super(null, null);
}
@Override
public void playSound(@Nonnull ISound sound) {}
}

View File

@@ -0,0 +1,106 @@
/*
* 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.bot.impl;
import it.unimi.dsi.fastutil.ints.*;
import net.minecraft.client.multiplayer.WorldClient;
import net.minecraft.entity.Entity;
import net.minecraft.profiler.Profiler;
import net.minecraft.util.SoundCategory;
import net.minecraft.util.SoundEvent;
import net.minecraft.util.math.ChunkPos;
import net.minecraft.world.EnumDifficulty;
import net.minecraft.world.WorldSettings;
import javax.annotation.Nullable;
import java.util.HashMap;
import java.util.Map;
/**
* @author Brady
* @since 11/7/2018
*/
public final class BotWorld extends WorldClient {
private static Profiler BOT_WORLD_PROFILER = new Profiler();
private final Map<ChunkPos, IntSet> loadedChunksMap;
public BotWorld(WorldSettings settings, int dimension) {
super(null, settings, dimension, EnumDifficulty.EASY, BOT_WORLD_PROFILER);
this.loadedChunksMap = new HashMap<>();
}
@Override
public void playSound(double x, double y, double z, SoundEvent soundIn, SoundCategory category, float volume, float pitch, boolean distanceDelay) {
// Do nothing
}
@Override
public void addEntityToWorld(int entityID, Entity entity) {
this.removeEntityFromWorld(entityID);
this.spawnEntity(entity);
this.entitiesById.addKey(entityID, entity);
}
@Override
public Entity removeEntityFromWorld(int entityID) {
Entity entity = this.entitiesById.lookup(entityID);
if (entity != null && !(entity instanceof BotPlayer)) {
this.removeEntity(entity);
this.entitiesById.removeObject(entityID);
}
return entity;
}
@Nullable
@Override
public Entity getEntityByID(int id) {
return this.entitiesById.lookup(id);
}
/**
* @param bot The bot requesting the chunk
* @param chunkX The chunk X position
* @param chunkZ The chunk Z position
* @param load {@code true} if the chunk is being loaded, {@code false} if the chunk is being unloaded.
* @return Whether or not the chunk needs to be loaded or unloaded accordingly.
*/
public boolean handlePreChunk(BotPlayer bot, int chunkX, int chunkZ, boolean load) {
IntSet bots = this.loadedChunksMap.computeIfAbsent(new ChunkPos(chunkX, chunkZ), $ -> new IntArraySet());
if (load) {
boolean wasEmpty = bots.isEmpty();
bots.add(bot.getEntityId());
return wasEmpty;
} else {
bots.remove(bot.getEntityId());
return bots.isEmpty();
}
}
public void handleWorldRemove(BotPlayer bot) {
// Remove Bot from world
this.removeEntity(bot);
this.entitiesById.removeObject(bot.getEntityId());
// Unload all chunks that are no longer loaded by the removed Bot
this.loadedChunksMap.entrySet().stream()
.peek(entry -> entry.getValue().remove(bot.getEntityId()))
.filter(entry -> entry.getValue().isEmpty())
.forEach(entry -> this.doPreChunk(entry.getKey().x, entry.getKey().z, false));
}
}

View File

@@ -18,6 +18,7 @@
package baritone.cache;
import baritone.Baritone;
import baritone.api.BaritoneAPI;
import baritone.api.cache.IWorldProvider;
import baritone.api.utils.IPlayerContext;
import baritone.utils.accessor.IAnvilChunkLoader;
@@ -160,6 +161,10 @@ public class WorldProvider implements IWorldProvider {
readmeDir = baritone.getDirectory();
}
if (this.baritone != BaritoneAPI.getProvider().getPrimaryBaritone()) {
worldDir = worldDir.resolve("bot");
}
return Optional.of(new Tuple<>(worldDir, readmeDir));
}

View File

@@ -0,0 +1,168 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.command.defaults;
import baritone.Baritone;
import baritone.api.IBaritone;
import baritone.api.bot.IBaritoneUser;
import baritone.api.bot.connect.IConnectionResult;
import baritone.api.command.Command;
import baritone.api.command.argument.IArgConsumer;
import baritone.api.command.exception.CommandException;
import baritone.api.command.exception.CommandInvalidTypeException;
import baritone.api.event.events.ChatEvent;
import baritone.bot.UserManager;
import baritone.bot.impl.BotGuiInventory;
import net.minecraft.util.Session;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import static baritone.api.command.IBaritoneChatControl.FORCE_COMMAND_PREFIX;
/**
* @author Brady
* @since 3/2/2020
*/
public class BotCommand extends Command {
public BotCommand(IBaritone baritone) {
super(baritone, "bot");
}
@Override
public void execute(String label, IArgConsumer args) throws CommandException {
final Action action = Action.getByName(args.getString());
if (action == null) {
throw new CommandInvalidTypeException(args.consumed(), "an action");
}
if (action == Action.ADD) {
final String username = args.hasAny() ? args.getString() : "Bot" + System.currentTimeMillis() % 1000;
final Session session = new Session(username, UUID.randomUUID().toString(), "", "");
final IConnectionResult result = UserManager.INSTANCE.connect(session);
logDirect(result.toString());
} else if (action.requiresBotSelector()) {
final String selector = args.getString();
final List<IBaritoneUser> bots;
if (selector.equals("*")) {
bots = UserManager.INSTANCE.getUsers();
} else if (selector.contains(",")) {
bots = Arrays.stream(selector.split(","))
.map(UserManager.INSTANCE::getUserByName)
.filter(Optional::isPresent)
.map(Optional::get)
.collect(Collectors.toList());
} else {
bots = UserManager.INSTANCE.getUserByName(selector)
.map(Collections::singletonList)
.orElseGet(Collections::emptyList);
}
if (bots.isEmpty()) {
throw new CommandInvalidTypeException(args.consumed(), "selector didn't match any bots");
}
if (action == Action.INVENTORY) {
// Only display one inventory lol
final IBaritoneUser bot = bots.get(0);
((Baritone) baritone).showScreen(new BotGuiInventory(bot));
return;
}
switch (action) {
case DISCONNECT: {
bots.forEach(bot -> UserManager.INSTANCE.disconnect(bot, null));
break;
}
case SAY: {
final String message = args.rawRest();
bots.forEach(bot -> bot.getPlayerContext().player().sendChatMessage(message));
break;
}
case EXECUTE: {
final String command = FORCE_COMMAND_PREFIX + args.rawRest();
bots.forEach(bot -> bot.getBaritone().getGameEventHandler().onSendChatMessage(new ChatEvent(command)));
break;
}
}
}
}
@Override
public Stream<String> tabComplete(String label, IArgConsumer args) {
return Stream.empty();
}
@Override
public String getShortDesc() {
return "Manage bots";
}
@Override
public List<String> getLongDesc() {
return Arrays.asList(
"Spawns a bot",
"",
"Usage:",
"> bot add/a <name>",
"> bot inventory/i [bot]",
"> bot disconnect/d [bot]",
"> bot say/s [bot] [args...]",
"> bot execute/e [bot] [args...]"
);
}
private enum Action {
ADD("add", "a"),
INVENTORY("inventory", "i"),
DISCONNECT("disconnect", "d"),
SAY("say", "s"),
EXECUTE("execute", "e");
private final String[] names;
Action(String... names) {
this.names = names;
}
public boolean requiresBotSelector() {
return this == INVENTORY || this == DISCONNECT || this == SAY || this == EXECUTE;
}
public static Action getByName(String name) {
for (Action action : Action.values()) {
for (String alias : action.names) {
if (alias.equalsIgnoreCase(name)) {
return action;
}
}
}
return null;
}
public static String[] getAllNames() {
Set<String> names = new HashSet<>();
for (Action action : Action.values()) {
names.addAll(Arrays.asList(action.names));
}
return names.toArray(new String[0]);
}
}
}

View File

@@ -46,6 +46,7 @@ public final class DefaultCommands {
new LitematicaCommand(baritone),
new ComeCommand(baritone),
new AxisCommand(baritone),
new BotCommand(baritone),
new ForceCancelCommand(baritone),
new GcCommand(baritone),
new InvertCommand(baritone),

View File

@@ -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.utils;
import sun.misc.Unsafe;
import java.lang.reflect.Field;
/**
* Hacky util to allocate objects without needing to invoke their constructor.
*
* @author Brady
* @since 3/3/2020
*/
public final class ObjectAllocator {
private static final Unsafe theUnsafe;
static {
try {
Class<?> clazz = Class.forName("sun.misc.Unsafe");
Field field = clazz.getDeclaredField("theUnsafe");
field.setAccessible(true);
theUnsafe = (Unsafe) field.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
private ObjectAllocator() {}
public static <T> T allocate(Class<T> clazz) {
try {
// noinspection unchecked
return (T) theUnsafe.allocateInstance(clazz);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
}

View File

@@ -56,7 +56,7 @@ public final class PathRenderer implements IRenderer {
if (ctx.world() == null) {
return;
}
if (ctx.minecraft().currentScreen instanceof GuiClick) {
if (ctx.minecraft().currentScreen instanceof GuiClick && behavior.baritone == BaritoneAPI.getProvider().getPrimaryBaritone()) {
((GuiClick) ctx.minecraft().currentScreen).onRender();
}

View File

@@ -17,14 +17,15 @@
package baritone.utils;
import baritone.api.utils.IInputOverrideHandler;
import baritone.api.utils.input.Input;
import net.minecraft.util.MovementInput;
public class PlayerMovementInput extends MovementInput {
private final InputOverrideHandler handler;
private final IInputOverrideHandler handler;
PlayerMovementInput(InputOverrideHandler handler) {
public PlayerMovementInput(IInputOverrideHandler handler) {
this.handler = handler;
}

View File

@@ -0,0 +1,34 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils.accessor;
import net.minecraft.client.Minecraft;
import net.minecraft.entity.player.EnumPlayerModelParts;
import java.util.Set;
/**
* @author Brady
* @since 3/6/2020
*/
public interface IGameSettings {
void setSetModelParts(Set<EnumPlayerModelParts> setModelParts);
void setMc(Minecraft mc);
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils.accessor;
import net.minecraft.client.multiplayer.ThreadLanServerPing;
/**
* @author Brady
* @since 3/4/2020
*/
public interface IIntegratedServer {
ThreadLanServerPing getLanServerPing();
}

View File

@@ -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.utils.accessor;
import java.io.File;
/**
* @author Brady
*/
public interface IMinecraft {
void setGameDir(File gameDir);
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils.accessor;
import net.minecraft.client.multiplayer.WorldClient;
/**
* @author Brady
* @since 3/8/2020
*/
public interface INetHandlerPlayClient {
void setWorld(WorldClient world);
}

View File

@@ -0,0 +1,29 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.utils.accessor;
/**
* @author Brady
* @since 3/4/2020
*/
public interface IThreadLanServerPing {
String getMotd();
String getAddress();
}

View File

@@ -72,6 +72,11 @@ public final class BaritonePlayerController implements IPlayerController {
return mc.playerController.windowClick(windowId, slotId, mouseButton, type, player);
}
@Override
public void setGameType(GameType type) {
mc.playerController.setGameType(type);
}
@Override
public GameType getGameType() {
return mc.playerController.getCurrentGameType();