Compare commits

...

61 Commits

Author SHA1 Message Date
Leijurv 060741bfdc
fixes 2018-11-24 19:17:30 -08:00
Leijurv 2a21a1ca18
simplify 2018-11-24 12:53:09 -08:00
Leijurv 8ece179912
recalculate on allocation size change 2018-11-24 11:32:23 -08:00
Leijurv c79f40a5f1
tenor comms integration, and priority allocation caching 2018-11-24 11:01:23 -08:00
Leijurv 3b7e1adf24
add default lol 2018-11-23 19:24:14 -08:00
Leijurv 01bec5d8f9
computation requests on the tenor side 2018-11-23 19:06:35 -08:00
Leijurv 82c64d4d06
Merge branch 'comms' into tenor 2018-11-23 16:35:35 -08:00
Leijurv 11e44acf65
helper to handle pending msgs 2018-11-23 16:35:03 -08:00
Leijurv c73751ef98
Merge branch 'comms' into tenor 2018-11-23 16:10:06 -08:00
Leijurv 16fec4a1a0
buffered connection creation helper 2018-11-23 16:09:59 -08:00
Leijurv 81c95a2d43
fix tenor build after comms refactor 2018-11-23 13:36:06 -08:00
Leijurv 07970f803f
Merge branch 'calc-request' into tenor 2018-11-23 13:35:03 -08:00
Leijurv 5ae4f23886
Merge branch 'comms' into calc-request 2018-11-23 13:34:48 -08:00
Leijurv f222980a1a
move comms to cabaletta.comms 2018-11-23 13:32:18 -08:00
Leijurv 7f1fb2a8fe
Merge branch 'calc-request' into tenor 2018-11-23 13:17:42 -08:00
Leijurv c57f65f832
complete new segmented calculation system 2018-11-23 13:17:03 -08:00
Leijurv 85a6ec022e
Merge branch 'comms' into calc-request 2018-11-23 13:13:35 -08:00
Leijurv c1032da828
Merge branch 'master' into comms 2018-11-23 13:12:38 -08:00
Leijurv 806c2a4af1
tenor dependency on comms 2018-11-23 13:08:38 -08:00
Leijurv c5ecb9bb9b
Merge branch 'calc-request' into tenor 2018-11-23 12:57:08 -08:00
Leijurv e0d894d296
computation request and response 2018-11-23 12:09:35 -08:00
Leijurv 27c818f873
Merge branch 'comms' into calc-request 2018-11-23 11:49:49 -08:00
Leijurv fdd758bc90
too much log spam 2018-11-23 11:48:01 -08:00
Leijurv 3a2620192b
too much log spam 2018-11-23 11:46:47 -08:00
Leijurv c423d5f575
report path start position 2018-11-23 11:35:13 -08:00
Leijurv 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 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
Leijurv 87a44e4093
Merge branch 'master' into tenor 2018-11-12 16:16:03 -08:00
Brady d082d25253
Tenor Sourceset 2018-11-12 18:09:57 -06:00
Leijurv 1cf6768e27
misc 2018-11-09 12:59:46 -08:00
Leijurv 890dbec852
bunch of stuff 2018-10-31 20:04:32 -07:00
Leijurv 24bb0c541c
split up singular and quantized single parent priority allocators 2018-10-31 13:30:37 -07:00
Leijurv e7a09c34ea
cleanup and combine single parent priority allocation 2018-10-31 13:19:48 -07:00
Brady 9642950b54
oppa 2018-10-30 20:30:44 -05:00
Brady f76736a378
Minecraft imports should only be in minecraft task implementations 2018-10-30 20:05:35 -05:00
Leijurv 91c6baead1
dont allocate parent tasks with empty priority 2018-10-30 17:42:58 -07:00
Leijurv e81b01a8f3
fix priority allocation method 2018-10-30 17:18:08 -07:00
Brady f2a45b9eeb
Streams are nice 2018-10-30 18:21:09 -05:00
Leijurv 5e2ccdac08
i love generics 2018-10-30 15:44:52 -07:00
Leijurv 473f872d2f
you are no longer being poisoned by a toxic cloud 2018-10-30 15:31:02 -07:00
Brady 3d03f15749
Fix bad interface naming 2018-10-30 17:30:03 -05:00
Leijurv 15e91c7c7c
quite cool that this can now be done 2018-10-30 15:28:04 -07:00
Leijurv 5089c62ada
generics LOL 2018-10-30 15:23:14 -07:00
Leijurv 7c69a188f6
pog 2018-10-30 15:07:16 -07:00
Leijurv ef6b36b2cc
wew lad 2018-10-30 15:05:17 -07:00
Brady f2f806669c
Generify pt 1 2018-10-30 15:51:19 -05:00
Leijurv c887b27df9
in too deep 2018-10-30 11:51:49 -07:00
Leijurv e1bb8fd570
here we go LOL 2018-10-29 23:15:08 -07:00
66 changed files with 3128 additions and 32 deletions

36
PROTOCOL.md Normal file
View File

@ -0,0 +1,36 @@
# Baritone Comms Protocol
## Data Types
| Name | Descriptor | Java |
|------------|-----------------------------------------------------------|-----------------------------|
| coordinate | Big endian 8-byte floating point number | [readDouble], [writeDouble] |
| string | unsigned short (length) followed by UTF-8 character bytes | [readUTF], [writeUTF] |
## Inbound
Allows the server to execute a chat command on behalf of the client's player
### Chat
| Name | Type |
|---------|--------|
| Message | string |
## Outbound
Update the player position with the server
### Status
| Name | Type |
|------|------------|
| X | coordinate |
| Y | coordinate |
| Z | coordinate |
<!-- External links -->
[readUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readUTF()
[writeUTF]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeUTF(java.lang.String)
[readDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataInputStream.html#readDouble()
[writeDouble]: https://docs.oracle.com/javase/7/docs/api/java/io/DataOutputStream.html#writeDouble(double)

View File

@ -51,9 +51,19 @@ compileJava {
}
sourceSets {
comms {}
main {
compileClasspath += comms.compileClasspath + comms.output
}
launch {
compileClasspath += main.compileClasspath + main.runtimeClasspath + main.output
}
tenor {
compileClasspath += comms.compileClasspath + comms.output
}
main {
compileClasspath += tenor.compileClasspath + tenor.output
}
}
minecraft {
@ -99,7 +109,7 @@ mixin {
}
jar {
from sourceSets.launch.output, sourceSets.api.output
from sourceSets.comms.output, sourceSets.launch.output, sourceSets.api.output
preserveFileTimestamps = false
reproducibleFileOrder = true
}

View File

@ -22,6 +22,7 @@ import baritone.api.behavior.IMemoryBehavior;
import baritone.api.behavior.IPathingBehavior;
import baritone.api.cache.IWorldProvider;
import baritone.api.event.listener.IEventBus;
import baritone.api.pathing.calc.IPathingControlManager;
import baritone.api.process.ICustomGoalProcess;
import baritone.api.process.IFollowProcess;
import baritone.api.process.IGetToBlockProcess;
@ -59,6 +60,8 @@ public interface IBaritone {
*/
IMineProcess getMineProcess();
IPathingControlManager getPathingControlManager();
/**
* @return The {@link IPathingBehavior} instance
* @see IPathingBehavior

View File

@ -104,7 +104,7 @@ public interface IPath {
* Returns the estimated number of ticks to complete the path from the given node index.
*
* @param pathPosition The index of the node we're calculating from
* @return The estimated number of ticks remaining frm the given position
* @return The estimated number of ticks remaining from the given position
*/
default double ticksRemainingFrom(int pathPosition) {
double sum = 0;
@ -115,6 +115,15 @@ public interface IPath {
return sum;
}
/**
* Returns the estimated amount of time needed to complete this path from start to finish
*
* @return The estimated amount of time, in ticks
*/
default double totalTicks() {
return ticksRemainingFrom(0);
}
/**
* Cuts off this path at the loaded chunk border, and returns the resulting path. Default
* implementation just returns this path, without the intended functionality.

View File

@ -0,0 +1,98 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.EOFException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Do you not like having a blocking "receiveMessage" thingy?
* <p>
* Do you prefer just being able to get a list of all messages received since the last tick?
* <p>
* If so, this class is for you!
*
* @author leijurv
*/
public class BufferedConnection implements IConnection {
private final IConnection wrapped;
private final LinkedBlockingQueue<iMessage> queue;
private volatile transient IOException thrownOnRead;
public BufferedConnection(IConnection wrapped) {
this(wrapped, Integer.MAX_VALUE); // LinkedBlockingQueue accepts this as "no limit"
}
public BufferedConnection(IConnection wrapped, int maxInternalQueueSize) {
this.wrapped = wrapped;
this.queue = new LinkedBlockingQueue<>();
this.thrownOnRead = null;
new Thread(() -> {
try {
while (thrownOnRead == null) {
queue.put(wrapped.receiveMessage());
}
} catch (IOException e) {
thrownOnRead = e;
} catch (InterruptedException e) {
thrownOnRead = new IOException("Interrupted while enqueueing", e);
}
}).start();
}
@Override
public void sendMessage(iMessage message) throws IOException {
wrapped.sendMessage(message);
}
@Override
public iMessage receiveMessage() {
throw new UnsupportedOperationException("BufferedConnection can only be read from non-blockingly");
}
@Override
public void close() {
wrapped.close();
thrownOnRead = new EOFException("Closed");
}
public List<iMessage> receiveMessagesNonBlocking() throws IOException {
ArrayList<iMessage> msgs = new ArrayList<>();
queue.drainTo(msgs); // preserves order -- first message received will be first in this arraylist
if (msgs.isEmpty() && thrownOnRead != null) {
IOException up = new IOException("BufferedConnection wrapped", thrownOnRead);
throw up;
}
return msgs;
}
public void handleAllPendingMessages(IMessageListener listener) throws IOException {
receiveMessagesNonBlocking().forEach(msg -> msg.handle(listener));
}
public static BufferedConnection makeBuffered(IConnection conn) {
if (conn instanceof BufferedConnection) {
return (BufferedConnection) conn;
} else {
return new BufferedConnection(conn);
}
}
}

View File

@ -0,0 +1,54 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.DataInputStream;
import java.io.IOException;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public enum ConstructingDeserializer implements MessageDeserializer {
INSTANCE;
private final List<Class<? extends iMessage>> MSGS;
ConstructingDeserializer() {
MSGS = new ArrayList<>();
// imagine doing something in reflect but it's actually concise and you don't need to catch 42069 different exceptions. huh.
for (Method m : IMessageListener.class.getDeclaredMethods()) {
if (m.getName().equals("handle")) {
MSGS.add((Class<? extends iMessage>) m.getParameterTypes()[0]);
}
}
}
@Override
public synchronized iMessage deserialize(DataInputStream in) throws IOException {
int type = ((int) in.readByte()) & 0xff;
try {
return MSGS.get(type).getConstructor(DataInputStream.class).newInstance(in);
} catch (NoSuchMethodException | IllegalAccessException | InstantiationException | InvocationTargetException ex) {
throw new IOException("Unknown message type " + type, ex);
}
}
public byte getHeader(Class<? extends iMessage> klass) {
return (byte) MSGS.indexOf(klass);
}
}

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 cabaletta.comms;
import java.io.IOException;
public interface IConnection {
void sendMessage(iMessage message) throws IOException;
iMessage receiveMessage() throws IOException;
void close();
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import cabaletta.comms.downward.MessageChat;
import cabaletta.comms.downward.MessageComputationRequest;
import cabaletta.comms.upward.MessageComputationResponse;
import cabaletta.comms.upward.MessageStatus;
public interface IMessageListener {
default void handle(MessageStatus message) {
unhandled(message);
}
default void handle(MessageChat message) {
unhandled(message);
}
default void handle(MessageComputationRequest message) {
unhandled(message);
}
default void handle(MessageComputationResponse message) {
unhandled(message);
}
default void unhandled(iMessage msg) {
// can override this to throw UnsupportedOperationException, if you want to make sure you're handling everything
// default is to silently ignore messages without handlers
}
}

View File

@ -0,0 +1,25 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.DataInputStream;
import java.io.IOException;
public interface MessageDeserializer {
iMessage deserialize(DataInputStream in) throws IOException;
}

View File

@ -0,0 +1,99 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.EOFException;
import java.io.IOException;
import java.util.Optional;
import java.util.concurrent.LinkedBlockingQueue;
/**
* Do you want a socket to localhost without actually making a gross real socket to localhost?
*/
public class Pipe<T extends iMessage> {
private final LinkedBlockingQueue<Optional<iMessage>> AtoB;
private final LinkedBlockingQueue<Optional<iMessage>> BtoA;
private final PipedConnection A;
private final PipedConnection B;
private volatile boolean closed;
public Pipe() {
this.AtoB = new LinkedBlockingQueue<>();
this.BtoA = new LinkedBlockingQueue<>();
this.A = new PipedConnection(BtoA, AtoB);
this.B = new PipedConnection(AtoB, BtoA);
}
public PipedConnection getA() {
return A;
}
public PipedConnection getB() {
return B;
}
public class PipedConnection implements IConnection {
private final LinkedBlockingQueue<Optional<iMessage>> in;
private final LinkedBlockingQueue<Optional<iMessage>> out;
private PipedConnection(LinkedBlockingQueue<Optional<iMessage>> in, LinkedBlockingQueue<Optional<iMessage>> out) {
this.in = in;
this.out = out;
}
@Override
public void sendMessage(iMessage message) throws IOException {
if (closed) {
throw new EOFException("Closed");
}
try {
out.put(Optional.of(message));
} catch (InterruptedException e) {
// this can never happen since the LinkedBlockingQueues are not constructed with a maximum capacity, see above
}
}
@Override
public iMessage receiveMessage() throws IOException {
if (closed) {
throw new EOFException("Closed");
}
try {
Optional<iMessage> t = in.take();
if (!t.isPresent()) {
throw new EOFException("Closed");
}
return t.get();
} catch (InterruptedException e) {
// again, cannot happen
// but we have to throw something
throw new IllegalStateException(e);
}
}
@Override
public void close() {
closed = true;
try {
AtoB.put(Optional.empty()); // unstick threads
BtoA.put(Optional.empty());
} catch (InterruptedException e) {
}
}
}
}

View File

@ -0,0 +1,59 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.*;
public class SerializedConnection implements IConnection {
private final DataInputStream in;
private final DataOutputStream out;
private final MessageDeserializer deserializer;
public SerializedConnection(InputStream in, OutputStream out) {
this(ConstructingDeserializer.INSTANCE, in, out);
}
public SerializedConnection(MessageDeserializer d, InputStream in, OutputStream out) {
this.in = new DataInputStream(in);
this.out = new DataOutputStream(out);
this.deserializer = d;
}
@Override
public synchronized void sendMessage(iMessage message) throws IOException {
message.writeHeader(out);
message.write(out);
}
@Override
public iMessage receiveMessage() throws IOException {
return deserializer.deserialize(in);
}
@Override
public void close() {
try {
in.close();
} catch (IOException e) {
}
try {
out.close();
} catch (IOException e) {
}
}
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms;
import java.io.IOException;
import java.net.Socket;
public class SocketConnection extends SerializedConnection {
public SocketConnection(Socket s) throws IOException {
super(s.getInputStream(), s.getOutputStream());
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms.downward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageChat implements iMessage {
public final String msg;
public MessageChat(DataInputStream in) throws IOException {
this.msg = in.readUTF();
}
public MessageChat(String msg) {
this.msg = msg;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeUTF(msg);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

View File

@ -0,0 +1,62 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms.downward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageComputationRequest implements iMessage {
public final long computationID;
public final int startX;
public final int startY;
public final int startZ;
public final String goal; // TODO find a better way to do this lol
public MessageComputationRequest(DataInputStream in) throws IOException {
this.computationID = in.readLong();
this.startX = in.readInt();
this.startY = in.readInt();
this.startZ = in.readInt();
this.goal = in.readUTF();
}
public MessageComputationRequest(long computationID, int startX, int startY, int startZ, String goal) {
this.computationID = computationID;
this.startX = startX;
this.startY = startY;
this.startZ = startZ;
this.goal = goal;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeLong(computationID);
out.writeInt(startX);
out.writeInt(startY);
out.writeUTF(goal);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

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 cabaletta.comms;
import java.io.DataOutputStream;
import java.io.IOException;
/**
* hell yeah
* <p>
* <p>
* dumb android users cant read this file
* <p>
*
* @author leijurv
*/
public interface iMessage {
void write(DataOutputStream out) throws IOException;
default void writeHeader(DataOutputStream out) throws IOException {
out.writeByte(getHeader());
}
default byte getHeader() {
return ConstructingDeserializer.INSTANCE.getHeader(getClass());
}
void handle(IMessageListener listener);
}

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 cabaletta.comms.upward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageComputationResponse implements iMessage {
public final long computationID;
public final int pathLength;
public final double pathCost;
public final boolean endsInGoal;
public final int endX;
public final int endY;
public final int endZ;
public MessageComputationResponse(DataInputStream in) throws IOException {
this.computationID = in.readLong();
this.pathLength = in.readInt();
this.pathCost = in.readDouble();
this.endsInGoal = in.readBoolean();
this.endX = in.readInt();
this.endY = in.readInt();
this.endZ = in.readInt();
}
public MessageComputationResponse(long computationID, int pathLength, double pathCost, boolean endsInGoal, int endX, int endY, int endZ) {
this.computationID = computationID;
this.pathLength = pathLength;
this.pathCost = pathCost;
this.endsInGoal = endsInGoal;
this.endX = endX;
this.endY = endY;
this.endZ = endZ;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeLong(computationID);
out.writeInt(pathLength);
out.writeDouble(pathCost);
out.writeBoolean(endsInGoal);
out.writeInt(endX);
out.writeInt(endY);
out.writeInt(endZ);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

View File

@ -0,0 +1,124 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package cabaletta.comms.upward;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
public class MessageStatus implements iMessage {
public final double x;
public final double y;
public final double z;
public final float yaw;
public final float pitch;
public final boolean onGround;
public final float health;
public final float saturation;
public final int foodLevel;
public final int pathStartX;
public final int pathStartY;
public final int pathStartZ;
public final boolean hasCurrentSegment;
public final boolean hasNextSegment;
public final boolean calcInProgress;
public final double ticksRemainingInCurrent;
public final boolean calcFailedLastTick;
public final boolean safeToCancel;
public final String currentGoal;
public final String currentProcess;
public MessageStatus(DataInputStream in) throws IOException {
this.x = in.readDouble();
this.y = in.readDouble();
this.z = in.readDouble();
this.yaw = in.readFloat();
this.pitch = in.readFloat();
this.onGround = in.readBoolean();
this.health = in.readFloat();
this.saturation = in.readFloat();
this.foodLevel = in.readInt();
this.pathStartX = in.readInt();
this.pathStartY = in.readInt();
this.pathStartZ = in.readInt();
this.hasCurrentSegment = in.readBoolean();
this.hasNextSegment = in.readBoolean();
this.calcInProgress = in.readBoolean();
this.ticksRemainingInCurrent = in.readDouble();
this.calcFailedLastTick = in.readBoolean();
this.safeToCancel = in.readBoolean();
this.currentGoal = in.readUTF();
this.currentProcess = in.readUTF();
}
public MessageStatus(double x, double y, double z, float yaw, float pitch, boolean onGround, float health, float saturation, int foodLevel, int pathStartX, int pathStartY, int pathStartZ, boolean hasCurrentSegment, boolean hasNextSegment, boolean calcInProgress, double ticksRemainingInCurrent, boolean calcFailedLastTick, boolean safeToCancel, String currentGoal, String currentProcess) {
this.x = x;
this.y = y;
this.z = z;
this.yaw = yaw;
this.pitch = pitch;
this.onGround = onGround;
this.health = health;
this.saturation = saturation;
this.foodLevel = foodLevel;
this.pathStartX = pathStartX;
this.pathStartY = pathStartY;
this.pathStartZ = pathStartZ;
this.hasCurrentSegment = hasCurrentSegment;
this.hasNextSegment = hasNextSegment;
this.calcInProgress = calcInProgress;
this.ticksRemainingInCurrent = ticksRemainingInCurrent;
this.calcFailedLastTick = calcFailedLastTick;
this.safeToCancel = safeToCancel;
this.currentGoal = currentGoal;
this.currentProcess = currentProcess;
}
@Override
public void write(DataOutputStream out) throws IOException {
out.writeDouble(x);
out.writeDouble(y);
out.writeDouble(z);
out.writeFloat(yaw);
out.writeFloat(pitch);
out.writeBoolean(onGround);
out.writeFloat(health);
out.writeFloat(saturation);
out.writeInt(foodLevel);
out.writeInt(pathStartX);
out.writeInt(pathStartY);
out.writeInt(pathStartZ);
out.writeBoolean(hasCurrentSegment);
out.writeBoolean(hasNextSegment);
out.writeBoolean(calcInProgress);
out.writeDouble(ticksRemainingInCurrent);
out.writeBoolean(calcFailedLastTick);
out.writeBoolean(safeToCancel);
out.writeUTF(currentGoal);
out.writeUTF(currentProcess);
}
@Override
public void handle(IMessageListener listener) {
listener.handle(this);
}
}

View File

@ -22,10 +22,7 @@ import baritone.api.IBaritone;
import baritone.api.Settings;
import baritone.api.event.listener.IEventBus;
import baritone.api.utils.IPlayerContext;
import baritone.behavior.Behavior;
import baritone.behavior.LookBehavior;
import baritone.behavior.MemoryBehavior;
import baritone.behavior.PathingBehavior;
import baritone.behavior.*;
import baritone.cache.WorldProvider;
import baritone.event.GameEventHandler;
import baritone.process.CustomGoalProcess;
@ -77,6 +74,7 @@ public class Baritone implements IBaritone {
private GameEventHandler gameEventHandler;
private List<Behavior> behaviors;
private ControllerBehavior controllerBehavior;
private PathingBehavior pathingBehavior;
private LookBehavior lookBehavior;
private MemoryBehavior memoryBehavior;
@ -107,6 +105,7 @@ public class Baritone implements IBaritone {
this.behaviors = new ArrayList<>();
{
// the Behavior constructor calls baritone.registerBehavior(this) so this populates the behaviors arraylist
controllerBehavior = new ControllerBehavior(this);
pathingBehavior = new PathingBehavior(this);
lookBehavior = new LookBehavior(this);
memoryBehavior = new MemoryBehavior(this);
@ -131,10 +130,6 @@ public class Baritone implements IBaritone {
this.initialized = true;
}
public PathingControlManager getPathingControlManager() {
return this.pathingControlManager;
}
public List<Behavior> getBehaviors() {
return this.behaviors;
}
@ -144,11 +139,20 @@ public class Baritone implements IBaritone {
this.gameEventHandler.registerEventListener(behavior);
}
@Override
public PathingControlManager getPathingControlManager() {
return this.pathingControlManager;
}
@Override
public InputOverrideHandler getInputOverrideHandler() {
return this.inputOverrideHandler;
}
public ControllerBehavior getControllerBehavior() {
return this.controllerBehavior;
}
@Override
public CustomGoalProcess getCustomGoalProcess() { // Iffy
return this.customGoalProcess;
@ -160,18 +164,8 @@ public class Baritone implements IBaritone {
}
@Override
public IPlayerContext getPlayerContext() {
return this.playerContext;
}
@Override
public FollowProcess getFollowProcess() {
return this.followProcess;
}
@Override
public LookBehavior getLookBehavior() {
return this.lookBehavior;
public PathingBehavior getPathingBehavior() {
return this.pathingBehavior;
}
@Override
@ -180,13 +174,13 @@ public class Baritone implements IBaritone {
}
@Override
public MineProcess getMineProcess() {
return this.mineProcess;
public IPlayerContext getPlayerContext() {
return this.playerContext;
}
@Override
public PathingBehavior getPathingBehavior() {
return this.pathingBehavior;
public FollowProcess getFollowProcess() {
return this.followProcess;
}
@Override
@ -199,6 +193,20 @@ public class Baritone implements IBaritone {
return this.gameEventHandler;
}
@Override
public LookBehavior getLookBehavior() {
return this.lookBehavior;
}
@Override
public MineProcess getMineProcess() {
return this.mineProcess;
}
public static Executor getExecutor() {
return threadPool;
}
public static Settings settings() {
return BaritoneAPI.getSettings();
}
@ -206,8 +214,4 @@ public class Baritone implements IBaritone {
public static File getDir() {
return dir;
}
public static Executor getExecutor() {
return threadPool;
}
}

View File

@ -0,0 +1,163 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package baritone.behavior;
import baritone.Baritone;
import baritone.api.event.events.ChatEvent;
import baritone.api.event.events.TickEvent;
import baritone.api.pathing.goals.Goal;
import baritone.api.pathing.goals.GoalYLevel;
import baritone.api.process.IBaritoneProcess;
import baritone.api.utils.BetterBlockPos;
import baritone.pathing.movement.CalculationContext;
import baritone.utils.Helper;
import baritone.utils.pathing.SegmentedCalculator;
import cabaletta.comms.BufferedConnection;
import cabaletta.comms.IConnection;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.downward.MessageChat;
import cabaletta.comms.downward.MessageComputationRequest;
import cabaletta.comms.iMessage;
import cabaletta.comms.upward.MessageComputationResponse;
import cabaletta.comms.upward.MessageStatus;
import net.minecraft.util.math.BlockPos;
import java.io.IOException;
import java.util.Objects;
public class ControllerBehavior extends Behavior implements IMessageListener {
public ControllerBehavior(Baritone baritone) {
super(baritone);
}
private BufferedConnection conn;
@Override
public void onTick(TickEvent event) {
if (event.getType() == TickEvent.Type.OUT) {
return;
}
trySend(buildStatus());
readAndHandle();
}
public MessageStatus buildStatus() {
// TODO report inventory and echest contents
// TODO figure out who should remember echest contents when it isn't open, baritone or tenor?
BlockPos pathStart = baritone.getPathingBehavior().pathStart();
return new MessageStatus(
ctx.player().posX,
ctx.player().posY,
ctx.player().posZ,
ctx.player().rotationYaw,
ctx.player().rotationPitch,
ctx.player().onGround,
ctx.player().getHealth(),
ctx.player().getFoodStats().getSaturationLevel(),
ctx.player().getFoodStats().getFoodLevel(),
pathStart.getX(),
pathStart.getY(),
pathStart.getZ(),
baritone.getPathingBehavior().getCurrent() != null,
baritone.getPathingBehavior().getNext() != null,
baritone.getPathingBehavior().getInProgress().isPresent(),
baritone.getPathingBehavior().ticksRemainingInSegment().orElse(0D),
baritone.getPathingBehavior().calcFailedLastTick(),
baritone.getPathingBehavior().isSafeToCancel(),
baritone.getPathingBehavior().getGoal() + "",
baritone.getPathingControlManager().mostRecentInControl().map(IBaritoneProcess::displayName).orElse("")
);
}
private void readAndHandle() {
if (conn == null) {
return;
}
try {
conn.handleAllPendingMessages(this);
} catch (IOException e) {
e.printStackTrace();
disconnect();
}
}
public boolean trySend(iMessage msg) {
if (conn == null) {
return false;
}
try {
conn.sendMessage(msg);
return true;
} catch (IOException e) {
e.printStackTrace();
disconnect();
return false;
}
}
public void connectTo(IConnection conn) {
disconnect();
this.conn = BufferedConnection.makeBuffered(conn);
}
public void disconnect() {
if (conn != null) {
conn.close();
}
conn = null;
}
@Override
public void handle(MessageChat msg) { // big brain
ChatEvent event = new ChatEvent(ctx.player(), msg.msg);
baritone.getGameEventHandler().onSendChatMessage(event);
}
@Override
public void handle(MessageComputationRequest msg) {
BetterBlockPos start = new BetterBlockPos(msg.startX, msg.startY, msg.startZ);
// TODO this may require scanning the world for blocks of a certain type, idk how to manage that
Goal goal = new GoalYLevel(Integer.parseInt(msg.goal)); // im already winston
SegmentedCalculator.calculateSegmentsThreaded(start, goal, new CalculationContext(baritone), path -> {
if (!Objects.equals(path.getGoal(), goal)) {
throw new IllegalStateException(); // sanity check
}
try {
BetterBlockPos dest = path.getDest();
conn.sendMessage(new MessageComputationResponse(msg.computationID, path.length(), path.totalTicks(), path.getGoal().isInGoal(dest), dest.x, dest.y, dest.z));
} catch (IOException e) {
// nothing we can do about this, we just completed a computation but our tenor connection was closed in the meantime
// just discard the path we made for them =((
e.printStackTrace(); // and complain =)
}
}, () -> {
try {
conn.sendMessage(new MessageComputationResponse(msg.computationID, 0, 0, false, 0, 0, 0));
} catch (IOException e) {
// same deal
e.printStackTrace();
}
});
}
@Override
public void unhandled(iMessage msg) {
Helper.HELPER.logDebug("Unhandled message received by ControllerBehavior " + msg);
}
}

View File

@ -358,7 +358,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
}
if (MovementHelper.canWalkOn(ctx, possibleSupport.down()) && MovementHelper.canWalkThrough(ctx, possibleSupport) && MovementHelper.canWalkThrough(ctx, possibleSupport.up())) {
// this is plausible
logDebug("Faking path start assuming player is standing off the edge of a block");
//logDebug("Faking path start assuming player is standing off the edge of a block");
return possibleSupport;
}
}
@ -367,7 +367,7 @@ public final class PathingBehavior extends Behavior implements IPathingBehavior,
// !onGround
// we're in the middle of a jump
if (MovementHelper.canWalkOn(ctx, feet.down().down())) {
logDebug("Faking path start assuming player is midair and falling");
//logDebug("Faking path start assuming player is midair and falling");
return feet.down();
}
}

View File

@ -32,6 +32,7 @@ import baritone.pathing.movement.CalculationContext;
import baritone.pathing.movement.Movement;
import baritone.pathing.movement.Moves;
import baritone.process.CustomGoalProcess;
import cabaletta.comms.SocketConnection;
import net.minecraft.block.Block;
import net.minecraft.client.multiplayer.ChunkProviderClient;
import net.minecraft.entity.Entity;
@ -39,6 +40,8 @@ import net.minecraft.entity.player.EntityPlayer;
import net.minecraft.util.math.BlockPos;
import net.minecraft.world.chunk.Chunk;
import java.io.IOException;
import java.net.Socket;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;
@ -463,6 +466,23 @@ public class ExampleBaritoneControl extends Behavior implements Helper {
}
return true;
}
if (msg.startsWith("connect")) {
String dest = msg.substring(7).trim();
String[] parts = dest.split(" ");
if (parts.length != 2) {
logDirect("Unable to parse");
return true;
}
try {
Socket s = new Socket(parts[0], Integer.parseInt(parts[1]));
SocketConnection conn = new SocketConnection(s);
baritone.getControllerBehavior().connectTo(conn);
logDirect("Created and attached socket connection");
} catch (IOException | NumberFormatException e) {
logDirect("Unable to connect " + e);
}
return true;
}
if (msg.equals("damn")) {
logDirect("daniel");
}

View File

@ -0,0 +1,113 @@
/*
* 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 tenor;
import cabaletta.comms.BufferedConnection;
import cabaletta.comms.IConnection;
import cabaletta.comms.IMessageListener;
import cabaletta.comms.iMessage;
import cabaletta.comms.upward.MessageComputationResponse;
import cabaletta.comms.upward.MessageStatus;
import java.io.IOException;
public class Bot implements IMessageListener {
public final BotTaskRegistry taskRegistry = new BotTaskRegistry(this);
private final BufferedConnection connectionToBot;
private volatile MessageStatus mostRecentUpdate;
public Bot(IConnection conn) {
this.connectionToBot = BufferedConnection.makeBuffered(conn);
// TODO event loop calling tick?
}
public int getCurrentQuantityInInventory(String item) {
// TODO get this information from the most recent update
throw new UnsupportedOperationException("oppa");
}
public void tick() {
// TODO i have no idea what tenor's threading model will be
// probably single threaded idk
ComputationRequestManager.INSTANCE.dispatchAll();
receiveMessages();
TaskLeaf<?> curr = decideWhatToDoNow();
iMessage command = doTheTask(curr);
try {
connectionToBot.sendMessage(command);
} catch (IOException e) {
e.printStackTrace();
disconnect();
}
}
public void receiveMessages() {
try {
connectionToBot.handleAllPendingMessages(this);
} catch (IOException e) {
e.printStackTrace();
disconnect();
}
}
public void disconnect() {
// TODO i have no idea how to handle this
// this destroys the task tree
// wew lad?
connectionToBot.close();
}
public TaskLeaf<?> decideWhatToDoNow() {
// TODO idk lol
throw new UnsupportedOperationException();
}
public iMessage doTheTask(TaskLeaf<?> task) {
// TODO idk lol
throw new UnsupportedOperationException();
}
public void send(iMessage msg) {
try {
connectionToBot.sendMessage(msg);
} catch (IOException e) {
e.printStackTrace();
disconnect();
}
}
public MessageStatus getMostRecentUpdate() {
return mostRecentUpdate;
}
public String getHostIdentifier() {
// return ((SocketConnection) ((BufferedConnection) connectionToBot).getUnderlying()).getSocket().getHostname()
return "localhost";
}
@Override
public void handle(MessageStatus msg) {
mostRecentUpdate = msg;
}
@Override
public void handle(MessageComputationResponse msg) {
ComputationRequestManager.INSTANCE.onRecv(this, msg);
}
}

View File

@ -0,0 +1,115 @@
/*
* 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 tenor;
import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class BotTaskRegistry {
Bot target;
Map<Class<? extends ITask>, ITask<?>> singletonRegistry; // GetToCraftingTableTask
Map<Class<? extends ITask>, Map<String, ITask<?>>> itemBased; // MineTask, AquireItemTask
List<ITask<?>> allOthers; // AquireCraftingItems
List<ITask<?>> totalList; // everything from all lists
public BotTaskRegistry(Bot parent) {
this.target = parent;
this.singletonRegistry = new HashMap<>();
this.itemBased = new HashMap<>();
this.allOthers = new ArrayList<>();
this.totalList = new ArrayList<>();
}
public void register(ITask<?> task) {
if (task.bot() != target) {
throw new IllegalStateException();
}
if (totalList.contains(task)) {
throw new IllegalStateException();
}
totalList.add(task);
allOthers.add(task);
}
public void registerSingleton(ITask<?> task) {
if (!totalList.contains(task)) {
throw new IllegalStateException();
}
if (!allOthers.contains(task)) {
throw new IllegalStateException();
}
if (singletonRegistry.containsKey(task.getClass())) {
throw new IllegalStateException();
}
allOthers.remove(task);
singletonRegistry.put(task.getClass(), task);
}
public <T extends ITask<?>> T getSingleton(Class<T> klass) {
if (singletonRegistry.containsKey(klass)) {
return (T) singletonRegistry.get(klass);
}
try {
T result = klass.getConstructor(Bot.class).newInstance(target);
if (!singletonRegistry.containsKey(klass)) {
throw new IllegalStateException();
}
return result;
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new IllegalStateException(e);
}
}
public void registerItemBased(ITask<?> task, String key) {
if (!totalList.contains(task)) {
throw new IllegalStateException();
}
if (!allOthers.contains(task)) {
throw new IllegalStateException();
}
Map<String, ITask<?>> specificMap = itemBased.computeIfAbsent(task.getClass(), x -> new HashMap<>());
if (specificMap.containsKey(key)) {
throw new IllegalStateException();
}
allOthers.remove(task);
specificMap.put(key, task);
}
public <T extends ITask<?>> T getItemBased(Class<T> klass, String key) {
Map<String, ITask<?>> specificMap = itemBased.computeIfAbsent(klass, x -> new HashMap<>());
if (specificMap.containsKey(key)) {
return (T) specificMap.get(key);
}
try {
T result = klass.getConstructor(Bot.class, String.class).newInstance(target, key);
if (!specificMap.containsKey(key)) {
throw new IllegalStateException();
}
return result;
} catch (InstantiationException | IllegalAccessException | InvocationTargetException | NoSuchMethodException e) {
throw new IllegalStateException(e);
}
}
}

View File

@ -0,0 +1,94 @@
/*
* 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 tenor;
import cabaletta.comms.upward.MessageComputationResponse;
import java.util.HashSet;
import java.util.Set;
public class ComputationRequest {
public final Bot bot;
public final String goal;
private final Set<SingularTaskLeaf> parents; // TODO quantized UGH
private MessageComputationResponse resp;
ComputationRequest(Bot bot, String goal) {
this.bot = bot;
this.goal = goal;
this.parents = new HashSet<>();
this.resp = null;
}
public MessageComputationResponse getResp() {
return resp;
}
public void receivedResponse(MessageComputationResponse mcrn) {
resp = mcrn;
// TODO notify parent tasks?
}
public Status getStatus() {
// :woke
// make this a huge nested ternary when
if (resp != null) {
if (resp.pathLength == 0) {
return Status.RECV_FAILURE;
} else {
return Status.RECV_SUCCESS;
}
} else {
if (ComputationRequestManager.INSTANCE.inProgress(this)) {
return Status.IN_PROGRESS;
} else {
return Status.QUEUED;
}
}
}
public void addParentTask(SingularTaskLeaf parent) {
parents.add(parent);
}
// hmmmmm this has parent tasks and has a cost and a priority.... god forbid should i make this a SingularTaskLeaf itself?!?!??!?
public Double cost() {
switch (getStatus()) {
case RECV_FAILURE:
return 1000000000D;
case RECV_SUCCESS:
return resp.pathCost;
case IN_PROGRESS:
case QUEUED:
default:
return null;
}
}
public double priority() {
return parents.stream().mapToDouble(SingularTaskLeaf::priority).sum();
}
public enum Status {
QUEUED,
IN_PROGRESS,
RECV_SUCCESS,
RECV_FAILURE,
}
}

View File

@ -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 <https://www.gnu.org/licenses/>.
*/
package tenor;
import cabaletta.comms.downward.MessageComputationRequest;
import cabaletta.comms.upward.MessageComputationResponse;
import cabaletta.comms.upward.MessageStatus;
import java.security.SecureRandom;
import java.util.*;
import java.util.function.Function;
import java.util.stream.Collectors;
public enum ComputationRequestManager {
INSTANCE;
public static final int MAX_SIMUL_COMPUTATIONS_PER_HOST = 2;
private Map<Long, ComputationRequest> inProgress = new HashMap<>();
private Map<Bot, Map<String, ComputationRequest>> byGoal = new HashMap<>();
public Function<Bot, String> botToHostMapping = Bot::toString; // TODO map bots to hosts by connection maybe?
public ComputationRequest getByGoal(SingularTaskLeaf task, String goal) {
Map<String, ComputationRequest> thisBot = byGoal.computeIfAbsent(task.bot, x -> new HashMap<>());
ComputationRequest req = thisBot.computeIfAbsent(goal, g -> new ComputationRequest(task.bot, goal));
req.addParentTask(task);
return req;
}
public void dispatchAll() {
Map<String, List<ComputationRequest>> highestPriorityByHost = byGoal.values().stream().map(Map::values).flatMap(Collection::stream).filter(c -> c.getStatus() == ComputationRequest.Status.QUEUED).collect(Collectors.groupingBy(req -> botToHostMapping.apply(req.bot), Collectors.collectingAndThen(Collectors.toList(), l -> l.stream().sorted(Comparator.comparingDouble(ComputationRequest::priority).reversed()).collect(Collectors.toList()))));
inProgress.values().stream().collect(Collectors.groupingBy(req -> botToHostMapping.apply(req.bot), Collectors.collectingAndThen(Collectors.counting(), count -> MAX_SIMUL_COMPUTATIONS_PER_HOST - count))).entrySet().stream().flatMap(entry -> highestPriorityByHost.get(entry.getKey()).subList(0, entry.getValue().intValue()).stream()).forEach(this::dispatch);
}
private void dispatch(ComputationRequest req) {
if (inProgress(req)) {
throw new IllegalStateException();
}
long key = new SecureRandom().nextLong();
inProgress.put(key, req);
MessageStatus status = req.bot.getMostRecentUpdate();
req.bot.send(new MessageComputationRequest(key, status.pathStartX, status.pathStartY, status.pathStartZ, req.goal));
}
public void onRecv(Bot receivedFrom, MessageComputationResponse mcrn) {
ComputationRequest req = inProgress.remove(mcrn.computationID);
if (req == null) {
throw new IllegalStateException("Received completed computation that we didn't ask for");
}
if (!Objects.equals(req.bot, receivedFrom)) {
throw new IllegalStateException("Received completed computation from the wrong connection?????");
}
req.receivedResponse(mcrn);
}
public boolean inProgress(ComputationRequest req) {
return inProgress.values().contains(req);
}
}

View File

@ -0,0 +1,22 @@
/*
* 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 tenor;
public enum DependencyType {
SERIAL, PARALLEL_ALL, ANY_ONE_OF;
}

View File

@ -0,0 +1,21 @@
/*
* 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 tenor;
public interface IChildTaskRelationship {
}

View File

@ -0,0 +1,23 @@
/*
* 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 tenor;
public interface IClaimProvider {
int quantityCompletedForParent(IQuantizedChildTaskRelationship relationship);
}

View File

@ -0,0 +1,21 @@
/*
* 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 tenor;
public interface IParentTaskRelationship {
}

View File

@ -0,0 +1,23 @@
/*
* 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 tenor;
public interface IQuantityRelationship {
double value(int quantity);
}

View File

@ -0,0 +1,32 @@
/*
* 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 tenor;
public interface IQuantizedChildTaskRelationship<T extends ITaskNodeBase> extends ITaskRelationshipBase<T, IQuantizedTask>, IChildTaskRelationship {
double allocatedPriority(int quantity);
default boolean childProvidesClaimTo(int quantity) {
return quantityCompleted() >= quantity;
}
default int quantityCompleted() {
// TODO: Resolve this cast, should QuantizedTask implement ClaimProvider?
return ((IClaimProvider) childTask()).quantityCompletedForParent(this);
}
}

View File

@ -0,0 +1,41 @@
/*
* 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 tenor;
public interface IQuantizedDependentCostCalculator extends IQuantizedTaskNode {
@Override
default IQuantityRelationship cost() {
switch (type()) {
case SERIAL:
case PARALLEL_ALL:
return q -> childTasks().stream()
.map(IQuantizedParentTaskRelationship::cost)
.mapToDouble(relationship -> relationship.value(q))
.sum();
case ANY_ONE_OF: // TODO this could be smarter about allocating
return q -> childTasks().stream()
.map(IQuantizedParentTaskRelationship::cost)
.mapToDouble(relationship -> relationship.value(q))
.min().orElse(-1);
default:
throw new UnsupportedOperationException();
}
}
}

View File

@ -0,0 +1,23 @@
/*
* 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 tenor;
public interface IQuantizedParentTaskRelationship<T extends ITask> extends ITaskRelationshipBase<IQuantizedTaskNode, T>, IParentTaskRelationship {
IQuantityRelationship cost();
}

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 tenor;
public interface IQuantizedTask extends ITask<IQuantizedChildTaskRelationship> {
/*default QuantityRelationship priority() {
return q -> {
double sum = 0;
for (IQuantizedChildTaskRelationship parent : parents()) {
sum += parent.allocatedPriority(q);
}
return sum;
};
}*/
IQuantityRelationship priority();
IQuantityRelationship cost();
default IQuantizedChildTaskRelationship createRelationshipToParent(ITaskNodeBase parent) {
if (parent instanceof IQuantizedTask) {
return new QuantizedToQuantizedTaskRelationship((IQuantizedTaskNode) parent, this);
} else {
throw new UnsupportedOperationException("SingularToQuantized must be constructed manually since it needs a quantity");
}
}
}

View File

@ -0,0 +1,48 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package tenor;
/**
* @author Brady
* @since 10/30/2018
*/
public interface IQuantizedTaskNode extends ITaskNodeBase<IQuantizedChildTaskRelationship, IQuantizedParentTaskRelationship>, IQuantizedTask {
// if the child task were able to provide this amount, how much priority would that be?
double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity);
default int quantityExecutingInto(QuantizedToSingularTaskRelationship child) {
if (type() != DependencyType.SERIAL) {
throw new UnsupportedOperationException(this + " " + child);
}
// need to calculate from scratch
int ind = childTasks().indexOf(child);
if (ind <= 0) {
throw new IllegalStateException(childTasks() + "");
}
int minQuantity = -1;
for (int i = 0; i < childTasks().indexOf(child); i++) {
IQuantizedChildTaskRelationship relationship = (IQuantizedChildTaskRelationship) childTasks().get(i);
IClaimProvider claim = (IClaimProvider) relationship.childTask();
int amt = claim.quantityCompletedForParent(relationship);
if (minQuantity == -1 || amt < minQuantity) {
minQuantity = amt;
}
}
return minQuantity;
}
}

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 tenor;
public interface ISingleParentQuantizedPriorityAllocator extends IQuantizedTask {
@Override
default IQuantityRelationship priority() {
if (parentTasks().size() != 1) {
throw new IllegalStateException();
}
return parentTasks().get(0)::allocatedPriority;
}
}

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 tenor;
public interface ISingleParentSingularPriorityAllocator extends ISingularTask {
@Override
default double priority() {
if (parentTasks().size() != 1) {
throw new IllegalStateException();
}
return parentTasks().get(0).allocatedPriority();
}
}

View File

@ -0,0 +1,23 @@
/*
* 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 tenor;
public interface ISingularChildTaskRelationship<T extends ITaskNodeBase> extends ITaskRelationshipBase<T, ISingularTask>, IChildTaskRelationship {
double allocatedPriority();
}

View File

@ -0,0 +1,23 @@
/*
* 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 tenor;
public interface ISingularParentTaskRelationship<T extends ITask> extends ITaskRelationshipBase<ISingularTaskNode, T>, IParentTaskRelationship {
double cost();
}

View File

@ -0,0 +1,32 @@
/*
* 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 tenor;
public interface ISingularTask extends ITask<ISingularChildTaskRelationship> {
double cost();
double priority();
default ISingularChildTaskRelationship<? extends ITaskNodeBase> createRelationshipToParent(ITaskNodeBase parent) {
if (parent instanceof IQuantizedTask) {
return new QuantizedToSingularTaskRelationship((IQuantizedTaskNode) parent, this);
} else {
return new SingularToSingularTaskRelationship((ISingularTaskNode) parent, this);
}
}
}

View File

@ -0,0 +1,26 @@
/*
* 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 tenor;
/**
* @author Brady
* @since 10/30/2018
*/
public interface ISingularTaskNode extends ITaskNodeBase<ISingularChildTaskRelationship, ISingularParentTaskRelationship>, ISingularTask {
double priorityAllocatedToChild(ISingularParentTaskRelationship relationship);
}

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 tenor;
import java.util.List;
public interface ITask<T extends IChildTaskRelationship & ITaskRelationshipBase> {
List<T> parentTasks();
T createRelationshipToParent(ITaskNodeBase parent);
void addParent(T relationship);
default void addParent(ITaskNodeBase parent) {
addParent(createRelationshipToParent(parent));
}
Bot bot();
default BotTaskRegistry registry() {
return bot().taskRegistry;
}
}

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 tenor;
import java.util.List;
public interface ITaskNodeBase<T extends IChildTaskRelationship & ITaskRelationshipBase, S extends IParentTaskRelationship & ITaskRelationshipBase> extends ITask<T> {
List<S> childTasks();
DependencyType type();
void addChild(S relationship);
}

View File

@ -0,0 +1,27 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package tenor;
public interface ITaskRelationshipBase<P extends ITaskNodeBase, C extends ITask> {
P parentTask();
C childTask();
DependencyType type();
}

View File

@ -0,0 +1,24 @@
/*
* 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 tenor;
public abstract class QuantizedTaskLeaf extends TaskLeaf<IQuantizedChildTaskRelationship> implements IQuantizedTask {
public QuantizedTaskLeaf(Bot bot) {
super(bot);
}
}

View File

@ -0,0 +1,24 @@
/*
* 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 tenor;
public abstract class QuantizedTaskNode extends TaskNode<IQuantizedChildTaskRelationship, IQuantizedParentTaskRelationship> implements IQuantizedTaskNode {
public QuantizedTaskNode(Bot bot, DependencyType type) {
super(bot, type);
}
}

View File

@ -0,0 +1,141 @@
/*
* 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 tenor;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public abstract class QuantizedTaskPriorityAllocationCache extends QuantizedTaskNode {
private final Map<Integer, Allocation> allocationByQuantity;
public QuantizedTaskPriorityAllocationCache(Bot bot, DependencyType type) {
super(bot, type);
this.allocationByQuantity = new HashMap<>();
}
@Override
public final double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
Allocation allocation = allocationByQuantity.get(quantity);
if (allocation == null || allocation.total != effectiveAllocationSize(quantity)) {
allocation = allocationStrategy(quantity);
allocationByQuantity.put(quantity, allocation);
}
return allocation.allocatedTo(child);
}
protected Allocation allocationStrategy(int quantity) { // overridable
double amount = effectiveAllocationSize(quantity);
Allocation alloc = new Allocation(amount);
List<IQuantizedParentTaskRelationship> children = childTasks();
if (children.size() < 2) {
return alloc.distributeEqually(); // 0 or 1 cannot be anything but equal distribution
}
double[] costs = new double[children.size()];
for (int i = 0; i < costs.length; i++) {
costs[i] = children.get(i).cost().value(quantity);
}
applyAllocation(alloc, costs);
return alloc;
}
protected void applyAllocation(Allocation alloc, double[] childCosts) { // overridable
switch (type) {
case ANY_ONE_OF:
// by default, give it all to the lowest cost
// this is stable
int lowestInd = 0;
for (int i = 1; i < childCosts.length; i++) {
if (childCosts[i] < childCosts[lowestInd]) {
lowestInd = i;
}
}
alloc.givePriority(lowestInd, alloc.unallocated());
case SERIAL:
// give it all to the first nonzero cost? maybe?
for (int i = 1; i < childCosts.length; i++) {
if (childCosts[i] > 0) {
alloc.givePriority(i, alloc.unallocated());
return;
}
}
break;
default:
throw new UnsupportedOperationException("Not implemented yet");
}
}
protected Allocation blend(Allocation previous, Allocation current) { // overridable
if (previous.priorities.length != current.priorities.length) {
return current;
}
Allocation blended = new Allocation(current.total);
for (int i = 0; i < current.priorities.length; i++) {
blended.givePriority(i, current.priorities[i] * 0.1d + previous.priorities[i] * 0.9d);
}
return blended;
}
protected double effectiveAllocationSize(int quantity) { // overridable
return priority().value(quantity);
}
protected class Allocation {
private final double[] priorities; // always sums up to 1 or less
private final double total;
public Allocation(double total) {
this.priorities = new double[childTasks().size()];
this.total = total;
}
public double unallocated() {
return 1 - allocated();
}
public double allocated() {
double sum = 0;
for (double d : priorities) {
sum += d;
}
return sum;
}
public Allocation distributeEqually() {
int count = priorities.length;
double toDistribute = unallocated();
double priorityToEach = toDistribute / count;
for (int i = 0; i < count; i++) {
priorities[i] += priorityToEach;
}
return this;
}
public void givePriority(int childTaskIndex, double amount) {
if (amount > unallocated()) {
throw new IllegalStateException("not enough space");
}
priorities[childTaskIndex] += amount;
}
public double allocatedTo(IQuantizedParentTaskRelationship childRelationship) {
return priorities[childTasks().indexOf(childRelationship)];
}
}
}

View File

@ -0,0 +1,37 @@
/*
* 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 tenor;
public class QuantizedToQuantizedTaskRelationship
extends TaskRelationship<IQuantizedTaskNode, IQuantizedTask>
implements IQuantizedChildTaskRelationship<IQuantizedTaskNode>, IQuantizedParentTaskRelationship<IQuantizedTask> {
public QuantizedToQuantizedTaskRelationship(IQuantizedTaskNode parent, IQuantizedTask child) {
super(parent, child);
}
@Override
public double allocatedPriority(int quantity) {
return parentTask().priorityAllocatedTo(this, quantity);
}
@Override
public IQuantityRelationship cost() {
return childTask().cost();
}
}

View File

@ -0,0 +1,37 @@
/*
* 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 tenor;
public class QuantizedToSingularTaskRelationship
extends TaskRelationship<IQuantizedTaskNode, ISingularTask>
implements ISingularChildTaskRelationship<IQuantizedTaskNode>, IQuantizedParentTaskRelationship<ISingularTask> {
public QuantizedToSingularTaskRelationship(IQuantizedTaskNode parent, ISingularTask child) {
super(parent, child);
}
@Override
public IQuantityRelationship cost() {
return x -> childTask().cost();
}
@Override
public double allocatedPriority() {
return parentTask().priorityAllocatedTo(this, parentTask().quantityExecutingInto(this));
}
}

View File

@ -0,0 +1,80 @@
/*
* 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 tenor;
import java.util.List;
public class ScarceParentPriorityAllocator {
public static PriorityAllocation priorityAllocation(int quantity, List<IQuantizedChildTaskRelationship> parents) {
if (quantity == 0) {
return new PriorityAllocation(new int[parents.size()], 0D);
}
double[][] priorities = new double[parents.size()][quantity];
for (int i = 0; i < parents.size(); i++) {
for (int j = 1; j < quantity; j++) {
priorities[i][j] = parents.get(i).allocatedPriority(j);
}
}
int filled = 0;
double totalPriority = 0;
int[] taken = new int[parents.size()];
while (true) {
double bestRatio = 0;
int bestParent = -1;
int bestQuantity = -1;
for (int i = 0; i < priorities.length; i++) {
for (int j = 1; j < quantity - filled; j++) {
double ratio = priorities[i][j] / j;
if (ratio > bestRatio) {
bestRatio = ratio;
bestParent = i;
bestQuantity = j;
}
}
}
if (bestParent == -1 || bestRatio == 0) {
return new PriorityAllocation(taken, totalPriority);
}
taken[bestParent] += bestQuantity;
filled += bestQuantity;
double priorityTaken = priorities[bestParent][bestQuantity];
totalPriority += priorityTaken;
double[] repl = new double[priorities[bestParent].length - bestQuantity];
for (int i = 0; i < repl.length; i++) {
repl[i] = priorities[bestParent][i + bestQuantity] - priorityTaken;
}
priorities[bestParent] = repl;
}
}
public static class PriorityAllocation {
public final int[] parentAllocationQuantity;
public final double totalPriority;
public PriorityAllocation(int[] parentAllocationQuantity, double totalPriority) {
this.parentAllocationQuantity = parentAllocationQuantity;
this.totalPriority = totalPriority;
}
}
}

View File

@ -0,0 +1,24 @@
/*
* 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 tenor;
public abstract class SingularTaskLeaf extends TaskLeaf<ISingularChildTaskRelationship> implements ISingularTask {
public SingularTaskLeaf(Bot bot) {
super(bot);
}
}

View File

@ -0,0 +1,25 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package tenor;
public abstract class SingularTaskNode extends TaskNode<ISingularChildTaskRelationship, ISingularParentTaskRelationship> implements ISingularTaskNode {
public SingularTaskNode(Bot bot, DependencyType type) {
super(bot, type);
}
}

View File

@ -0,0 +1,40 @@
/*
* 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 tenor;
public class SingularToQuantizedTaskRelationship
extends TaskRelationship<ISingularTaskNode, IQuantizedTask>
implements IQuantizedChildTaskRelationship<ISingularTaskNode>, ISingularParentTaskRelationship<IQuantizedTask> {
public int quantityRequired;
public SingularToQuantizedTaskRelationship(ISingularTaskNode parent, IQuantizedTask child, int quantityRequired) {
super(parent, child);
this.quantityRequired = quantityRequired;
}
@Override
public double allocatedPriority(int quantity) {
return quantity >= quantityRequired ? parentTask().priorityAllocatedToChild(this) : 0;
}
@Override
public double cost() {
return childTask().cost().value(quantityRequired);
}
}

View File

@ -0,0 +1,37 @@
/*
* 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 tenor;
public class SingularToSingularTaskRelationship
extends TaskRelationship<ISingularTaskNode, ISingularTask>
implements ISingularChildTaskRelationship<ISingularTaskNode>, ISingularParentTaskRelationship<ISingularTask> {
public SingularToSingularTaskRelationship(ISingularTaskNode parent, ISingularTask child) {
super(parent, child);
}
@Override
public double allocatedPriority() {
return parentTask().priorityAllocatedToChild(this);
}
@Override
public double cost() {
return childTask().cost();
}
}

View File

@ -0,0 +1,52 @@
/*
* 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 tenor;
import java.util.ArrayList;
import java.util.List;
public abstract class Task<T extends IChildTaskRelationship & ITaskRelationshipBase> implements ITask<T> {
public final Bot bot;
private final List<T> parentRelationships = new ArrayList<>();
public Task(Bot bot) {
this.bot = bot;
registry().register(this);
}
@Override
public Bot bot() {
return bot;
}
@Override
public List<T> parentTasks() {
return parentRelationships;
}
@Override
public void addParent(T relationship) {
if (relationship.childTask() != this) {
throw new IllegalArgumentException();
}
relationship.parentTask().addChild((IParentTaskRelationship) relationship);
parentRelationships.add(relationship);
}
}

View File

@ -0,0 +1,24 @@
/*
* 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 tenor;
public abstract class TaskLeaf<T extends IChildTaskRelationship & ITaskRelationshipBase> extends Task<T> {
public TaskLeaf(Bot bot) {
super(bot);
}
}

View File

@ -0,0 +1,56 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package tenor;
import java.util.ArrayList;
import java.util.List;
public abstract class TaskNode<T extends IChildTaskRelationship & ITaskRelationshipBase, S extends IParentTaskRelationship & ITaskRelationshipBase> extends Task<T> implements ITaskNodeBase<T, S> {
private final List<S> childRelationships = new ArrayList<>();
public final DependencyType type;
public TaskNode(Bot bot, DependencyType type) {
super(bot);
this.type = type;
if (type == null) {
throw new IllegalArgumentException();
}
}
@Override
public List<S> childTasks() {
return childRelationships;
}
@Override
public DependencyType type() {
return type;
}
@Override
public void addChild(S relationship) {
if (relationship.parentTask() != this) {
throw new IllegalArgumentException();
}
if (relationship.type() != type) {
throw new IllegalArgumentException();
}
childRelationships.add(relationship);
}
}

View File

@ -0,0 +1,49 @@
/*
* 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 tenor;
public class TaskRelationship<P extends ITaskNodeBase, C extends ITask> implements ITaskRelationshipBase<P, C> {
public final P parent;
public final C child;
public final DependencyType type;
public TaskRelationship(P parent, C child) {
this.parent = parent;
this.child = child;
this.type = parent.type();
if (parent.bot() != child.bot()) {
throw new IllegalArgumentException();
}
}
@Override
public P parentTask() {
return parent;
}
@Override
public C childTask() {
return child;
}
@Override
public DependencyType type() {
return type;
}
}

View File

@ -0,0 +1,86 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package tenor.game;
import tenor.*;
public class AquireCraftingItems extends QuantizedTaskNode implements IClaimProvider, ISingleParentQuantizedPriorityAllocator {
final CraftingTask parent;
public AquireCraftingItems(CraftingTask parent) {
super(parent.bot, DependencyType.PARALLEL_ALL);
this.parent = parent;
addParent(parent);
}
@Override
public double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
AquireItemTask resource = (AquireItemTask) child.childTask(); // all our dependents are aquire item tasks
int amount = parent.inputSizeFor(resource);
// they could provide us with quantity
int actualQuantity = (int) Math.ceil(quantity * 1.0D / amount);
// so we could do the crafting recipe this many times
// how good would that be?
return priority().value(actualQuantity);
}
@Override
public IQuantityRelationship cost() {
return x -> {
// cost to get x copies of these items
double sum = 0;
for (IQuantizedParentTaskRelationship resource : childTasks()) {
int amountPerCraft = parent.inputSizeFor((AquireItemTask) resource.childTask());
int totalAmountNeeded = x * amountPerCraft;
int amountForUs = ((IQuantizedChildTaskRelationship) resource).quantityCompleted();
totalAmountNeeded -= amountForUs;
if (totalAmountNeeded <= 0) {
continue;
}
sum += resource.cost().value(totalAmountNeeded);
}
return sum;
};
}
@Override
public int quantityCompletedForParent(IQuantizedChildTaskRelationship relationship) {
if (relationship != parentTasks().get(0)) {
throw new IllegalStateException();
}
// our only parent is the crafting task
int minCompletion = Integer.MAX_VALUE;
for (IQuantizedParentTaskRelationship resource : childTasks()) {
int amountForUs = ((IQuantizedChildTaskRelationship) resource).quantityCompleted();
int amountPerCraft = parent.inputSizeFor((AquireItemTask) resource.childTask());
int actualQuantity = (int) Math.ceil(amountForUs * 1.0D / amountPerCraft);
if (actualQuantity < minCompletion || minCompletion == Integer.MAX_VALUE) {
minCompletion = actualQuantity; // any missing ingredient and we aren't really done
}
}
return minCompletion;
}
}

View File

@ -0,0 +1,81 @@
/*
* 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 tenor.game;
import tenor.*;
import java.util.HashMap;
import java.util.List;
public class AquireItemTask extends QuantizedTaskPriorityAllocationCache implements IClaimProvider, IQuantizedDependentCostCalculator {
HashMap<IQuantizedChildTaskRelationship, Integer> allocation; // allocation of what tasks have claim over what items in our inventory i guess
String item;
public AquireItemTask(Bot bot, String item) {
super(bot, DependencyType.ANY_ONE_OF);
this.item = item;
registry().registerItemBased(this, item);
}
@Override
public int quantityCompletedForParent(IQuantizedChildTaskRelationship relationship) {
return allocation.get(relationship);
}
public void reallocate() {
int amountToAllocate = getCurrentQuantityInInventory();
if (amountToAllocate == cachedCurrentQuantity()) {
// no change
return;
}
List<IQuantizedChildTaskRelationship> parents = parentTasks();
allocation = null;
HashMap<IQuantizedChildTaskRelationship, Integer> tmp = new HashMap<>();
int[] newAmounts = ScarceParentPriorityAllocator.priorityAllocation(amountToAllocate, parents).parentAllocationQuantity;
for (int i = 0; i < parents.size(); i++) {
tmp.put(parents.get(i), newAmounts[i]);
}
allocation = tmp;
}
public int getCurrentQuantityInInventory() {
return bot.getCurrentQuantityInInventory(item);
}
public int cachedCurrentQuantity() {
return allocation.values().stream().mapToInt(x -> x).sum();
}
@Override
public IQuantityRelationship priority() { // TODO cache
return x -> ScarceParentPriorityAllocator.priorityAllocation(x, parentTasks()).totalPriority;
}
@Override
public double effectiveAllocationSize(int quantity) {
// how much of our priority would go to this child if it could provide us with quantity of the item we need
// here's the thing honey, we *already have* some, so you're really asking what's the priority of getting quantity MORE
int curr = cachedCurrentQuantity();
return priority().value(quantity + curr) - priority().value(curr);
}
}

View File

@ -0,0 +1,77 @@
/*
* 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 tenor.game;
import tenor.*;
import java.util.List;
public class CraftingTask extends QuantizedTaskNode implements ISingleParentQuantizedPriorityAllocator {
int outputQuantity;
List<RecipeInput> recipe;
final AquireCraftingItems inputs;
final GetToCraftingTableTask step2;
final DoCraft step3;
final AquireItemTask parent;
public CraftingTask(AquireItemTask parent) {
super(parent.bot, DependencyType.SERIAL);
this.inputs = new AquireCraftingItems(this); // this adds the relationship
this.step2 = registry().getSingleton(GetToCraftingTableTask.class);
step2.addParent(this);
this.step3 = new DoCraft(this);
this.parent = parent;
addParent(parent);
}
@Override
public IQuantityRelationship cost() {
return x -> {
int actualQuantity = (int) Math.ceil(x * 1.0D / outputQuantity);
return inputs.cost().value(actualQuantity) + step2.cost() + step3.cost();
};
}
@Override
public double priorityAllocatedTo(IQuantizedParentTaskRelationship child, int quantity) {
// how much priority would we give this child if they could provide us this quantity?
int amountWeWouldProvide = quantity * outputQuantity;
double desirability = priority().value(amountWeWouldProvide);
return desirability;
}
public int inputSizeFor(AquireItemTask task) {
for (RecipeInput item : recipe) {
if (item.task.equals(task)) {
return item.quantity;
}
}
throw new IllegalStateException();
}
private class RecipeInput {
private AquireItemTask task;
private int quantity;
}
}

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 tenor.game;
import tenor.ISingleParentSingularPriorityAllocator;
import tenor.SingularTaskLeaf;
public class DoCraft extends SingularTaskLeaf implements ISingleParentSingularPriorityAllocator { // TODO this should be quantized!
public final CraftingTask parent;
public DoCraft(CraftingTask parent) {
super(parent.bot);
this.parent = parent;
addParent(parent);
}
@Override
public double cost() {
// this is a dummy task to represent actually completing the crafting, given that we have all the ingredients and are at a crafting table
// it's effectively free, so let's say it takes 1 second (20 ticks)
return 20D;
}
}

View File

@ -0,0 +1,37 @@
/*
* 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 tenor.game;
import tenor.IQuantityRelationship;
import tenor.ISingleParentQuantizedPriorityAllocator;
import tenor.QuantizedTaskLeaf;
public class DoMine extends QuantizedTaskLeaf implements ISingleParentQuantizedPriorityAllocator {
final MineWithToolTask parent;
public DoMine(MineWithToolTask parent) {
super(parent.bot);
this.parent = parent;
addParent(parent);
}
@Override
public IQuantityRelationship cost() {
return null;
}
}

View File

@ -0,0 +1,46 @@
/*
* This file is part of Baritone.
*
* Baritone is free software: you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation, either version 3 of the License, or
* (at your option) any later version.
*
* Baritone is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with Baritone. If not, see <https://www.gnu.org/licenses/>.
*/
package tenor.game;
import tenor.*;
public class GetToCraftingTableTask extends SingularTaskLeaf {
private final ComputationRequest craftingTable;
public GetToCraftingTableTask(Bot bot) {
super(bot);
registry().registerSingleton(this);
this.craftingTable = ComputationRequestManager.INSTANCE.getByGoal(this, "GoalGetToBlock crafting_table"); // idk
}
@Override
public double cost() {
Double d = craftingTable.cost();
if (d == null) {
// unknown, has not been calculated yet either way
return 1000D; // estimate
}
return d;
}
@Override
public double priority() {
return parentTasks().stream().mapToDouble(ISingularChildTaskRelationship::allocatedPriority).sum();
}
}

View File

@ -0,0 +1,57 @@
/*
* 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 tenor.game;
import tenor.DependencyType;
import tenor.IQuantizedDependentCostCalculator;
import tenor.ISingleParentQuantizedPriorityAllocator;
import tenor.QuantizedTaskPriorityAllocationCache;
public class MineTask extends QuantizedTaskPriorityAllocationCache implements ISingleParentQuantizedPriorityAllocator, IQuantizedDependentCostCalculator {
// TODO shared claims of block locations in the world across all mine tasks across all bots
final AquireItemTask parent;
final MineWithToolTask[] children;
public MineTask(AquireItemTask parent) {
super(parent.bot, DependencyType.ANY_ONE_OF);
this.parent = parent;
addParent(parent);
String[] tools = getToolsCapableOfMining(parent.item);
children = new MineWithToolTask[tools.length];
for (int i = 0; i < children.length; i++) {
children[i] = new MineWithToolTask(this, tools[i]);
}
}
static String[] getToolsCapableOfMining(String block) {
switch (block) {
case "iron_ore":
return new String[]{"stone_pickaxe"};
case "stone":
case "cobblestone":
return new String[]{"wooden_pickaxe"};
case "log":
return new String[]{"hand"};
default:
throw new IllegalStateException(block);
}
}
}

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 tenor.game;
import tenor.DependencyType;
import tenor.IQuantizedDependentCostCalculator;
import tenor.ISingleParentQuantizedPriorityAllocator;
import tenor.QuantizedTaskPriorityAllocationCache;
public class MineWithToolTask extends QuantizedTaskPriorityAllocationCache implements ISingleParentQuantizedPriorityAllocator, IQuantizedDependentCostCalculator {
public final String tool;
MineTask parent;
AquireItemTask aquireTool;
// TODO locate task?
DoMine doMine;
public MineWithToolTask(MineTask parent, String tool) {
super(parent.bot, DependencyType.SERIAL);
this.tool = tool;
this.parent = parent;
addParent(parent);
this.aquireTool = registry().getItemBased(AquireItemTask.class, tool);
aquireTool.addParent(this); // we aren't constructing this, so need to add us as a parent manually
this.doMine = new DoMine(this);
}
}