diff --git a/src/api/java/baritone/api/IBaritoneProvider.java b/src/api/java/baritone/api/IBaritoneProvider.java index 84a8abbbd..55d208e03 100644 --- a/src/api/java/baritone/api/IBaritoneProvider.java +++ b/src/api/java/baritone/api/IBaritoneProvider.java @@ -21,6 +21,7 @@ import baritone.api.cache.IWorldScanner; import baritone.api.command.ICommand; import baritone.api.command.ICommandSystem; import baritone.api.schematic.ISchematicSystem; +import net.minecraft.client.Minecraft; import net.minecraft.client.entity.EntityPlayerSP; import java.util.List; @@ -52,15 +53,13 @@ public interface IBaritoneProvider { List getAllBaritones(); /** - * Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. This will likely be - * replaced with or be overloaded in addition to {@code #getBaritoneForUser(IBaritoneUser)} when - * {@code bot-system} is merged into {@code master}. + * Provides the {@link IBaritone} instance for a given {@link EntityPlayerSP}. * * @param player The player * @return The {@link IBaritone} instance. */ default IBaritone getBaritoneForPlayer(EntityPlayerSP player) { - for (IBaritone baritone : getAllBaritones()) { + for (IBaritone baritone : this.getAllBaritones()) { if (Objects.equals(player, baritone.getPlayerContext().player())) { return baritone; } @@ -68,6 +67,39 @@ public interface IBaritoneProvider { return null; } + /** + * Provides the {@link IBaritone} instance for a given {@link Minecraft}. + * + * @param minecraft The minecraft + * @return The {@link IBaritone} instance. + */ + default IBaritone getBaritoneForMinecraft(Minecraft minecraft) { + for (IBaritone baritone : this.getAllBaritones()) { + if (Objects.equals(minecraft, baritone.getPlayerContext().minecraft())) { + return baritone; + } + } + return null; + } + + /** + * Creates and registers a new {@link IBaritone} instance using the specified {@link Minecraft}. The existing + * instance is returned if already registered. + * + * @param minecraft The minecraft + * @return The {@link IBaritone} instance + */ + IBaritone createBaritone(Minecraft minecraft); + + /** + * Destroys and removes the specified {@link IBaritone} instance. If the specified instance is the + * {@link #getPrimaryBaritone() primary baritone}, this operation has no effect and will return {@code false}. + * + * @param baritone The baritone instance to remove + * @return Whether the baritone instance was removed + */ + boolean destroyBaritone(IBaritone baritone); + /** * Returns the {@link IWorldScanner} instance. This is not a type returned by * {@link IBaritone} implementation, because it is not linked with {@link IBaritone}. diff --git a/src/main/java/baritone/BaritoneProvider.java b/src/main/java/baritone/BaritoneProvider.java index 4593fefbc..b96cf03f7 100644 --- a/src/main/java/baritone/BaritoneProvider.java +++ b/src/main/java/baritone/BaritoneProvider.java @@ -28,8 +28,9 @@ import baritone.command.ExampleBaritoneControl; import baritone.utils.schematic.SchematicSystem; import net.minecraft.client.Minecraft; -import java.util.AbstractList; +import java.util.Collections; import java.util.List; +import java.util.concurrent.CopyOnWriteArrayList; /** * @author Brady @@ -37,25 +38,40 @@ import java.util.List; */ public final class BaritoneProvider implements IBaritoneProvider { - private final Baritone primary; private final List all; + private final List allView; - { - this.primary = new Baritone(Minecraft.getMinecraft()); - this.all = this.new BaritoneList(); + public BaritoneProvider() { + this.all = new CopyOnWriteArrayList<>(); + this.allView = Collections.unmodifiableList(this.all); // Setup chat control, just for the primary instance - this.primary.registerBehavior(ExampleBaritoneControl::new); + final Baritone primary = (Baritone) this.createBaritone(Minecraft.getMinecraft()); + primary.registerBehavior(ExampleBaritoneControl::new); } @Override public IBaritone getPrimaryBaritone() { - return this.primary; + return this.all.get(0); } @Override public List getAllBaritones() { - return this.all; + return this.allView; + } + + @Override + public synchronized IBaritone createBaritone(Minecraft minecraft) { + IBaritone baritone = this.getBaritoneForMinecraft(minecraft); + if (baritone == null) { + this.all.add(baritone = new Baritone(minecraft)); + } + return baritone; + } + + @Override + public synchronized boolean destroyBaritone(IBaritone baritone) { + return baritone != this.getPrimaryBaritone() && this.all.remove(baritone); } @Override @@ -72,20 +88,4 @@ public final class BaritoneProvider implements IBaritoneProvider { public ISchematicSystem getSchematicSystem() { return SchematicSystem.INSTANCE; } - - private final class BaritoneList extends AbstractList { - - @Override - public int size() { - return 1; - } - - @Override - public IBaritone get(int index) { - if (index == 0) { - return BaritoneProvider.this.primary; - } - throw new IndexOutOfBoundsException(); - } - } }