diff --git a/src/main/java/baritone/bot/BaritoneUser.java b/src/main/java/baritone/bot/BaritoneUser.java
new file mode 100644
index 00000000..5da75eda
--- /dev/null
+++ b/src/main/java/baritone/bot/BaritoneUser.java
@@ -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 .
+ */
+
+package baritone.bot;
+
+import baritone.bot.entity.EntityBot;
+import com.mojang.authlib.GameProfile;
+import net.minecraft.network.NetworkManager;
+import net.minecraft.util.Session;
+
+/**
+ * Implementation of {@link IBaritoneUser}
+ *
+ * @author Brady
+ * @since 11/6/2018
+ */
+class BaritoneUser implements IBaritoneUser {
+
+ private final NetworkManager networkManager;
+ private final Session session;
+
+ private GameProfile profile;
+
+ BaritoneUser(NetworkManager networkManager, Session session) {
+ this.networkManager = networkManager;
+ this.session = session;
+ }
+
+ @Override
+ public void onLoginSuccess(GameProfile profile) {
+ this.profile = profile;
+ }
+
+ @Override
+ public NetworkManager getNetworkManager() {
+ return this.networkManager;
+ }
+
+ @Override
+ public EntityBot getEntity() {
+ // TODO
+ return null;
+ }
+
+ @Override
+ public Session getSession() {
+ return this.session;
+ }
+
+ @Override
+ public GameProfile getProfile() {
+ return this.profile;
+ }
+}
diff --git a/src/main/java/baritone/bot/IBaritoneUser.java b/src/main/java/baritone/bot/IBaritoneUser.java
index 89d590c3..9fbcd4b9 100644
--- a/src/main/java/baritone/bot/IBaritoneUser.java
+++ b/src/main/java/baritone/bot/IBaritoneUser.java
@@ -18,7 +18,7 @@
package baritone.bot;
import baritone.bot.entity.EntityBot;
-import net.minecraft.client.entity.EntityOtherPlayerMP;
+import com.mojang.authlib.GameProfile;
import net.minecraft.network.NetworkManager;
import net.minecraft.util.Session;
@@ -28,29 +28,33 @@ import net.minecraft.util.Session;
*/
public interface IBaritoneUser {
+ /**
+ * Called when the user successfully logs into a server.
+ */
+ void onLoginSuccess(GameProfile profile);
+
/**
* @return The network manager that is responsible for the current connection.
*/
NetworkManager getNetworkManager();
/**
- * @return The locally managed entity for this bot.
+ * @return The locally managed entity for this user.
*/
- EntityBot getLocalEntity();
-
- /**
- * Returns the remote entity reported by the server that represents this bot connection. This is only
- * provided when this bot goes into the range of another connection that is being managed.
- *
- * @return The remote entity for this bot
- */
- EntityOtherPlayerMP getRemoteEntity();
+ EntityBot getEntity();
/**
* Returns the user login session. Should never be {@code null}, as this should be set when the
* user is constructed.
*
- * @return The bot's login session
+ * @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();
}
diff --git a/src/main/java/baritone/bot/UserManager.java b/src/main/java/baritone/bot/UserManager.java
new file mode 100644
index 00000000..7c68048b
--- /dev/null
+++ b/src/main/java/baritone/bot/UserManager.java
@@ -0,0 +1,112 @@
+/*
+ * 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 .
+ */
+
+package baritone.bot;
+
+import baritone.bot.connect.ConnectionResult;
+import baritone.bot.connect.ConnectionStatus;
+import baritone.bot.handler.BotNetHandlerLoginClient;
+import baritone.utils.Helper;
+import com.mojang.authlib.GameProfile;
+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 java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Optional;
+import java.util.UUID;
+
+import static baritone.bot.connect.ConnectionStatus.*;
+
+/**
+ * @author Brady
+ * @since 11/6/2018
+ */
+public class UserManager implements Helper {
+
+ private final List users = new ArrayList<>();
+
+ /**
+ * 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
+ */
+ public final ConnectionResult connect(Session session) {
+ ServerData data = mc.getCurrentServerData();
+ if (data == null) {
+ return ConnectionResult.failed(NO_CURRENT_CONNECTION);
+ }
+
+ // Connect to the server from the parsed server data
+ return connect(session, ServerAddress.fromString(data.serverIP));
+ }
+
+ /**
+ * Connects a new user with the specified {@link Session} to the specified server.
+ *
+ * @param session The user session
+ * @param address The address of the server to connect to
+ * @return The result of the attempted connection
+ */
+ private ConnectionResult connect(Session session, ServerAddress address) {
+ 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
+ IBaritoneUser user = new BaritoneUser(networkManager, session);
+ 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.failed(SUCCESS);
+ } catch (Exception e) {
+ return ConnectionResult.failed(CONNECTION_FAILED);
+ }
+ }
+
+ public final Optional getUserByProfile(GameProfile profile) {
+ return this.users.stream().filter(user -> user.getSession().getProfile().equals(profile)).findFirst();
+ }
+
+ public final Optional getUserByUUID(UUID uuid) {
+ return this.users.stream().filter(user -> user.getSession().getProfile().getId().equals(uuid)).findFirst();
+ }
+}
diff --git a/src/main/java/baritone/bot/connect/ConnectionResult.java b/src/main/java/baritone/bot/connect/ConnectionResult.java
new file mode 100644
index 00000000..277f93f0
--- /dev/null
+++ b/src/main/java/baritone/bot/connect/ConnectionResult.java
@@ -0,0 +1,74 @@
+/*
+ * 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 .
+ */
+
+package baritone.bot.connect;
+
+import baritone.bot.IBaritoneUser;
+
+import java.util.Objects;
+
+import static baritone.bot.connect.ConnectionStatus.SUCCESS;
+
+/**
+ * @author Brady
+ * @since 11/6/2018
+ */
+public class ConnectionResult {
+
+ /**
+ * The result status
+ */
+ public final ConnectionStatus status;
+
+ /**
+ * The user created, if the status is {@link ConnectionStatus#SUCCESS}
+ */
+ public final IBaritoneUser user;
+
+ private ConnectionResult(ConnectionStatus status, IBaritoneUser user) {
+ this.status = status;
+ this.user = 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);
+ }
+}
diff --git a/src/main/java/baritone/bot/connect/ConnectionStatus.java b/src/main/java/baritone/bot/connect/ConnectionStatus.java
new file mode 100644
index 00000000..915c6146
--- /dev/null
+++ b/src/main/java/baritone/bot/connect/ConnectionStatus.java
@@ -0,0 +1,45 @@
+/*
+ * This file is part of Baritone.
+ *
+ * Baritone is free software: you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * Baritone is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with Baritone. If not, see .
+ */
+
+package baritone.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 connection initialization failed.
+ */
+ CONNECTION_FAILED,
+
+ /**
+ * The connection was a success
+ */
+ SUCCESS
+}
diff --git a/src/main/java/baritone/bot/handler/BotNetHandlerPlayClient.java b/src/main/java/baritone/bot/handler/BotNetHandlerPlayClient.java
index 05cd687b..6fb6f65f 100644
--- a/src/main/java/baritone/bot/handler/BotNetHandlerPlayClient.java
+++ b/src/main/java/baritone/bot/handler/BotNetHandlerPlayClient.java
@@ -86,6 +86,9 @@ public class BotNetHandlerPlayClient extends NetHandlerPlayClient {
this.networkManager = networkManager;
this.client = client;
this.user = user;
+
+ // Notify the user that we're ingame
+ this.user.onLoginSuccess(profile);
}
@Override