Allocation time
This commit is contained in:
@@ -17,7 +17,9 @@
|
||||
|
||||
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;
|
||||
|
||||
@@ -32,7 +34,9 @@ import java.util.UUID;
|
||||
public interface IUserManager {
|
||||
|
||||
/**
|
||||
* Connects a new user with the specified {@link Session} to the current server.
|
||||
* 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
|
||||
@@ -40,7 +44,8 @@ public interface IUserManager {
|
||||
IConnectionResult connect(Session session);
|
||||
|
||||
/**
|
||||
* Disconnects the specified {@link IBaritoneUser} from its current server.
|
||||
* 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}.
|
||||
*
|
||||
* @param user The user to disconnect
|
||||
*/
|
||||
@@ -53,7 +58,9 @@ public interface IUserManager {
|
||||
* @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() : users().stream().filter(user -> user.getProfile().equals(profile)).findFirst();
|
||||
return profile == null
|
||||
? Optional.empty()
|
||||
: this.getUsers().stream().filter(user -> user.getProfile().equals(profile)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -63,11 +70,13 @@ public interface IUserManager {
|
||||
* @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() : users().stream().filter(user -> user.getProfile().getId().equals(uuid)).findFirst();
|
||||
return uuid == null
|
||||
? Optional.empty()
|
||||
: this.getUsers().stream().filter(user -> user.getProfile().getId().equals(uuid)).findFirst();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return All of the users held by this manager
|
||||
*/
|
||||
List<IBaritoneUser> users();
|
||||
List<IBaritoneUser> getUsers();
|
||||
}
|
||||
|
||||
@@ -58,7 +58,7 @@ public final class BaritoneProvider implements IBaritoneProvider {
|
||||
public List<IBaritone> getAllBaritones() {
|
||||
List<IBaritone> baritones = new ArrayList<>();
|
||||
baritones.add(getPrimaryBaritone());
|
||||
for (IBaritoneUser ibu : UserManager.INSTANCE.users()) {
|
||||
for (IBaritoneUser ibu : UserManager.INSTANCE.getUsers()) {
|
||||
baritones.add(ibu.getBaritone());
|
||||
}
|
||||
return baritones;
|
||||
|
||||
@@ -20,8 +20,8 @@ package baritone.bot;
|
||||
import baritone.Baritone;
|
||||
import baritone.api.IBaritone;
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.api.bot.IUserManager;
|
||||
import baritone.api.utils.IPlayerController;
|
||||
import baritone.bot.spec.BotMinecraft;
|
||||
import baritone.bot.spec.BotWorld;
|
||||
import baritone.bot.spec.EntityBot;
|
||||
import com.mojang.authlib.GameProfile;
|
||||
@@ -44,6 +44,7 @@ public class BaritoneUser implements IBaritoneUser {
|
||||
private GameProfile profile;
|
||||
private INetHandlerPlayClient netHandlerPlayClient;
|
||||
|
||||
private BotMinecraft mc;
|
||||
private BotWorld world;
|
||||
private EntityBot player;
|
||||
private IPlayerController playerController;
|
||||
@@ -51,6 +52,7 @@ public class BaritoneUser implements IBaritoneUser {
|
||||
private final Baritone baritone;
|
||||
|
||||
BaritoneUser(UserManager manager, NetworkManager networkManager, Session session) {
|
||||
this.mc = BotMinecraft.allocate(this);
|
||||
this.manager = manager;
|
||||
this.networkManager = networkManager;
|
||||
this.session = session;
|
||||
@@ -107,4 +109,8 @@ public class BaritoneUser implements IBaritoneUser {
|
||||
public IBaritone getBaritone() {
|
||||
return baritone;
|
||||
}
|
||||
|
||||
public BotMinecraft getMinecraft() {
|
||||
return this.mc;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -151,14 +151,16 @@ public final class UserManager implements IUserManager, Helper {
|
||||
|
||||
@Override
|
||||
public final void disconnect(IBaritoneUser user) {
|
||||
// It's probably fine to pass null to this, because the handlers aren't doing anything with it
|
||||
// noinspection ConstantConditions
|
||||
user.getNetworkManager().closeChannel(null);
|
||||
this.users.remove(user);
|
||||
if (this.users.contains(user)) {
|
||||
// It's probably fine to pass null to this, because the handlers aren't doing anything with it
|
||||
// noinspection ConstantConditions
|
||||
user.getNetworkManager().closeChannel(null);
|
||||
this.users.remove(user);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public final List<IBaritoneUser> users() {
|
||||
public final List<IBaritoneUser> getUsers() {
|
||||
return Collections.unmodifiableList(this.users);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -62,52 +62,16 @@ public class BotNetHandlerLoginClient extends NetHandlerLoginClient {
|
||||
private final BaritoneUser user;
|
||||
|
||||
public BotNetHandlerLoginClient(NetworkManager networkManager, BaritoneUser user) {
|
||||
super(networkManager, Minecraft.getMinecraft(), null);
|
||||
super(networkManager, user.getMinecraft(), null);
|
||||
this.networkManager = networkManager;
|
||||
this.mc = Minecraft.getMinecraft();
|
||||
this.mc = user.getMinecraft();
|
||||
this.user = user;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleEncryptionRequest(SPacketEncryptionRequest packetIn) {
|
||||
SecretKey secretkey = CryptManager.createNewSharedKey();
|
||||
PublicKey publicKey = packetIn.getPublicKey();
|
||||
|
||||
// Setup joinServer payload info
|
||||
GameProfile profile = this.user.getSession().getProfile();
|
||||
String authenticationToken = this.user.getSession().getToken();
|
||||
String serverId = new BigInteger(CryptManager.getServerIdHash(packetIn.getServerId(), publicKey, secretkey)).toString(16);
|
||||
|
||||
if (this.mc.getCurrentServerData() != null && this.mc.getCurrentServerData().isOnLAN()) {
|
||||
try {
|
||||
this.mc.getSessionService().joinServer(profile, authenticationToken, serverId);
|
||||
} catch (AuthenticationException e) {
|
||||
// Couldn't connect to auth servers but will continue to join LAN
|
||||
}
|
||||
} else {
|
||||
try {
|
||||
this.mc.getSessionService().joinServer(profile, authenticationToken, serverId);
|
||||
} catch (AuthenticationUnavailableException e) {
|
||||
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", new TextComponentTranslation("disconnect.loginFailedInfo.serversUnavailable")));
|
||||
return;
|
||||
} catch (InvalidCredentialsException e) {
|
||||
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", new TextComponentTranslation("disconnect.loginFailedInfo.invalidSession")));
|
||||
return;
|
||||
} catch (AuthenticationException e) {
|
||||
this.networkManager.closeChannel(new TextComponentTranslation("disconnect.loginFailedInfo", e.getMessage()));
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// noinspection unchecked
|
||||
this.networkManager.sendPacket(new CPacketEncryptionResponse(secretkey, publicKey, packetIn.getVerifyToken()),
|
||||
future -> BotNetHandlerLoginClient.this.networkManager.enableEncryption(secretkey));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void handleLoginSuccess(SPacketLoginSuccess packetIn) {
|
||||
this.networkManager.setConnectionState(EnumConnectionState.PLAY);
|
||||
this.networkManager.setNetHandler(new BotNetHandlerPlayClient(this.networkManager, this.user, Minecraft.getMinecraft(), packetIn.getProfile()));
|
||||
this.networkManager.setNetHandler(new BotNetHandlerPlayClient(this.networkManager, this.user, this.mc, packetIn.getProfile()));
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
73
src/main/java/baritone/bot/spec/BotMinecraft.java
Normal file
73
src/main/java/baritone/bot/spec/BotMinecraft.java
Normal file
@@ -0,0 +1,73 @@
|
||||
/*
|
||||
* 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.spec;
|
||||
|
||||
import baritone.api.bot.IBaritoneUser;
|
||||
import baritone.api.utils.Helper;
|
||||
import baritone.utils.ObjectAllocator;
|
||||
import com.google.common.util.concurrent.ListenableFuture;
|
||||
import com.mojang.authlib.minecraft.MinecraftSessionService;
|
||||
import net.minecraft.client.Minecraft;
|
||||
import net.minecraft.client.main.GameConfiguration;
|
||||
import net.minecraft.client.multiplayer.ServerData;
|
||||
import net.minecraft.util.Session;
|
||||
|
||||
import javax.annotation.Nonnull;
|
||||
import javax.annotation.Nullable;
|
||||
import java.util.concurrent.Callable;
|
||||
|
||||
/**
|
||||
* @author Brady
|
||||
* @since 3/3/2020
|
||||
*/
|
||||
public final class BotMinecraft extends Minecraft implements Helper {
|
||||
|
||||
private IBaritoneUser user;
|
||||
|
||||
private BotMinecraft(GameConfiguration gameConfig) {
|
||||
super(gameConfig);
|
||||
}
|
||||
|
||||
@Nonnull
|
||||
@Override
|
||||
public Session getSession() {
|
||||
return this.user.getSession();
|
||||
}
|
||||
|
||||
@Nullable
|
||||
@Override
|
||||
public ServerData getCurrentServerData() {
|
||||
return mc.getCurrentServerData();
|
||||
}
|
||||
|
||||
@Override
|
||||
public MinecraftSessionService getSessionService() {
|
||||
return mc.getSessionService();
|
||||
}
|
||||
|
||||
@Override
|
||||
public <V> ListenableFuture<V> addScheduledTask(Callable<V> callableToSchedule) {
|
||||
return mc.addScheduledTask(callableToSchedule);
|
||||
}
|
||||
|
||||
public static BotMinecraft allocate(IBaritoneUser user) {
|
||||
BotMinecraft mc = ObjectAllocator.allocate(BotMinecraft.class);
|
||||
mc.user = user;
|
||||
return mc;
|
||||
}
|
||||
}
|
||||
@@ -68,9 +68,6 @@ public final class GameEventHandler implements IEventBus, Helper {
|
||||
|
||||
@Override
|
||||
public final void onSendChatMessage(ChatEvent event) {
|
||||
// Ensure UserManager is created to prevent a ConcurrentModificationException
|
||||
Objects.requireNonNull(UserManager.INSTANCE);
|
||||
|
||||
listeners.forEach(l -> l.onSendChatMessage(event));
|
||||
}
|
||||
|
||||
|
||||
55
src/main/java/baritone/utils/ObjectAllocator.java
Normal file
55
src/main/java/baritone/utils/ObjectAllocator.java
Normal 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);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user