In this article, I suppose you are using C++. For other languages see other languages section in README.md
See examples/
in project's root for some example bots.
You need to include mtbotter.h
in your project and create
a subclass of MtBotter
class whose definition goes as below:
class MtBotter {
private:
Client *m_client;
MapDrawControl m_mpc;
NodeDefManager *m_nodemgr;
IWritableItemDefManager *m_itemdef;
EventManager *m_emgr;
Address m_address;
float m_pitch;
float m_yaw;
float m_hit;
PointedThing getPointedThing();
public:
MtBotter(const char* botname,
const std::string &password,
const std::string &address_name,
const std::string hostname,
const unsigned short port,
bool ipv6);
~MtBotter();
bool connect();
void start();
void turnRight(float deg);
void turnRight();
void turnLeft(float deg);
void turnLeft();
void turnHeadUp(float deg);
void turnHeadUp();
void turnHeadDown(float deg);
void turnHeadDown();
float getHeadingV();
float getHeadingH();
void move(unsigned flags);
short getPosX();
short getPosY();
short getPosZ();
bool punch();
bool place();
bool place(bool noplace);
bool dig();
bool activate();
void sendChat(std::wstring message);
void step(float dtime);
std::list<SomeObject> getNearestObjects(float max_d);
bool getNearestObject(float max_d, SomeObject &obj);
unsigned short getHP();
unsigned short getBreath();
bool isDead();
std::list<std::string> getPlayerNames();
void setWieldIndex(unsigned short index);
unsigned short getWieldIndex();
SomeItemStack getWieldedItem();
PThing getPThing();
SomeNode getNode(short x, short y, short z);
protected:
virtual void onRemoveNode(short pos[]) = 0;
virtual void onAddNode(short pos[]) = 0;
virtual void onChatMessage(unsigned char type, std::wstring sender, std::wstring message) = 0;
virtual void onConnect() = 0;
virtual void onDisconnect(std::string reason) = 0;
virtual void onTime(unsigned short t) = 0;
virtual void onInventoryUpdate() = 0;
virtual void onPlayerMove(float pos[]) = 0;
virtual void run() = 0;
};
You should override all virtual methods(even if you don't need
to use them) and you can use public methods of MtBotter
class. run()
is called upon starting the bot. You should
put a loop there and do whatever the bot should do.
Don't forget to call step()
regularly in your loop so
that your bot can receive events and its commands will
be sent to server.
MtBotter(const char* botname,
const std::string &password,
const std::string &address_name,
const std::string hostname,
const unsigned short port,
bool ipv6)
botname
,password
andport
explain themselves.ipv6
indicates if you are going to connect to an IPv6 server.hostname
is the (IP) address of the server you want to connect to.address_name
can be whatever you like but you'd better make it the same as hostname.
Disconnects from server and deletes the created instances.
Connects to server.
Runs the bot. Should be called after connect()
.
Turns bot's body to right.
Turns bot's body to left.
Turns bot's head up.
Turns bot's head down.
In order, they return current vertical heading(pitch) and current horizontal heading(yaw) of bot.
Move the bot or jump and sneak with this. You should use one or more of these flags:
FORWARD, BACKWARD, LEFT, RIGHT, JUMP, SNEAK
Examples:
move(FORWARD); // moves forward
move(FORWARD | JUMP); // move forward and jump at the same time
They return the current position of the bot in the world.
Punchs the pointed node or object. Returns false
if failed.
Place the node which is wielded in bot's inventory.
If noplace
is true, right clicks on the pointed node instead
of placing a new node.
Returns false
if failed.
Digs the pointed node and returns true
if successful.
Activates(rightclick in air) and returns true if successful.
Sends the message to chat.
Steps the client and receives the event. dtime
can be from 0 to 2.
This should be called in order to have a working bot so that
commands(move, dig, place, ...) will be sent to server and
events will be recieved.
Returns a list of objects in max_d
radius.
SomeObject
is defined as below:
struct SomeObject {
unsigned short id;
std::unordered_map<std::string, int> groups;
bool immortal, localplayer;
}
Assigns obj
to the nearest object which is not bot itself
and returns true
if successful.
Returns current HP of the bot.
Returns the current Oxygen level of the bot.
Returns true
if the bot is dead.
Because MtBotter respawns the bot when it dies, you may rarely
(or never?) get true
from this method.
Returns a list of players who are online in the server.
Sets the current selected item's index to index
.
Returns the current selected/wielded item index.
Returns the current selected/wielded item in bot's inventory. SomeItemStack is defined like this:
struct SomeItemStack {
std::string name;
unsigned short count, wear;
}
Gets the current pointed thing. PThing is defined as below:
struct PThing {
PThingType type;
short node_undersurface[3]; // X, Y, Z
short node_abovesurface[3];
}
type
is one of PTHING_NOTHING
, PTHING_NODE
, PTHING_OBJECT
.
Returns the node at given position.
SomeNode is defined like this:
struct SomeNode {
std::string name; // empty if unknown
bool is_ground_content, walkable, pointable, diggable;
bool climbable, buildable_to, rightclickable;
unsigned long dmg_p_sec; // damage per second
}
You should override all of these even if you don't need to. You can keep the one you don't need empty
pos -> X, Y, Z
Currently unused(won't be called at all)
pos -> X, Y, Z
The main code of bot is here. Don't forget to use step()
regularly here. When the end of this method is reached, bot stops and with delete
you can disconnect it.