minecraft-bot/mosfet/bot.py

294 lines
7.5 KiB
Python
Raw Normal View History

if __name__ == '__main__':
print('Run main.py instead.')
exit(1)
2020-09-07 22:32:19 +00:00
import os
import time
import importlib
2020-09-08 21:33:42 +00:00
from math import floor, ceil
2020-10-15 07:37:47 +00:00
from copy import copy
2020-09-07 22:32:19 +00:00
USERNAME = os.environ['USERNAME']
PASSWORD = os.environ['PASSWORD']
SERVER = os.environ['SERVER']
PORT = int(os.environ.get('PORT', 25565))
2021-04-22 00:46:54 +00:00
from . import monkey_patch # must be before any possible pyCraft imports
from minecraft import authentication
from minecraft.exceptions import YggdrasilError
from minecraft.networking.connection import Connection
from minecraft.networking.packets import Packet, clientbound, serverbound
2021-04-22 00:46:54 +00:00
from mosfet.protocol.managers import DataManager, ChunksManager, ChatManager, ChunkNotLoadedException
2020-09-08 01:28:56 +00:00
from munch import Munch
2021-04-22 00:46:54 +00:00
from mosfet import blocks
from mosfet import game
from mosfet import items
from mosfet import job
from mosfet import mcdata
from mosfet import mobs
from mosfet import path
from mosfet import print_help
from mosfet import utils
from mosfet import vector
2021-04-19 07:51:48 +00:00
for module in [
blocks,
game,
items,
job,
mcdata,
mobs,
path,
print_help,
utils,
vector,
]:
importlib.reload(module)
2020-09-08 01:28:56 +00:00
last_tick = time.time()
2021-04-22 00:46:54 +00:00
PITCH_ANGLE_DIR = vector.Vector3D((0, 1, 0))
YAW_ANGLE_DIR = vector.Vector3D((0, 0, -1))
YAW_ANGLE_REF = vector.Vector3D((0, 1, 0))
2020-09-08 21:33:42 +00:00
YAW_LOOK_AHEAD = 4
def tick(global_state):
g = global_state
p = g.pos
target = None
2020-09-25 21:51:36 +00:00
# make sure current chunks are loaded for physics
2021-02-23 21:37:14 +00:00
if not g.chunks.check_loaded(p, 288):
if not g.chunks.loading:
print('Loading chunks', end='', flush=True)
g.chunks.loading = True
2020-09-25 21:51:36 +00:00
packet = serverbound.play.PositionAndLookPacket(x=p.x, feet_y=p.y, z=p.z, pitch=0, yaw=0, on_ground=True)
g.connection.write_packet(packet, force=True)
2020-09-08 21:33:42 +00:00
return
2021-02-23 21:37:14 +00:00
else:
if g.chunks.loading:
print()
print('Chunks loaded.')
g.chunks.loading = False
2020-09-08 21:33:42 +00:00
2020-09-25 21:51:36 +00:00
g.chunks.unload_chunks(p)
2020-09-08 21:33:42 +00:00
########## object physics ##########
2020-10-18 05:35:43 +00:00
# note: it's possible the chunk data is out of date when this runs
2020-10-15 07:37:47 +00:00
for eid, obj in copy(g.objects).items():
if obj.velocity_x:
obj.x += obj.velocity_x / 8000
if obj.velocity_y:
obj.y += obj.velocity_y / 8000
if obj.velocity_z:
obj.z += obj.velocity_z / 8000
2020-10-17 18:41:41 +00:00
block_below = g.chunks.get_block_at(floor(obj.x), floor(obj.y-0.20), floor(obj.z))
in_air = block_below in blocks.NON_SOLID_IDS
if in_air:
obj.velocity_x *= 0.988
obj.velocity_y -= 390
obj.velocity_z *= 0.988
else:
obj.y = int(obj.y-0.20)+1
obj.velocity_x *= 0.5
obj.velocity_y = 0
obj.velocity_z *= 0.5
2020-10-17 18:41:41 +00:00
# float object back up in case it clipped through multiple blocks
2020-10-18 05:35:43 +00:00
if g.chunks.get_block_at(floor(obj.x), floor(obj.y), floor(obj.z)) not in blocks.NON_SOLID_IDS:
obj.y += 0.05
2020-10-17 18:41:41 +00:00
if abs(obj.velocity_x) < 1: obj.velocity_x = 0
if abs(obj.velocity_z) < 1: obj.velocity_z = 0
########## player physics ##########
if g.path and len(g.path):
2021-04-22 00:46:54 +00:00
target = vector.Point3D(g.path[0])
2020-09-08 21:33:42 +00:00
target.x += 0.5
target.z += 0.5
2020-12-18 04:15:09 +00:00
if g.afk_timeout > 0:
target = None
g.afk_timeout -= utils.TICK
2020-09-08 21:33:42 +00:00
if target:
d = p - target
# jump up block
if d.y < -0.9 and not g.y_v:
g.y_v = 8.5
g.y_a = -36.0
2020-09-08 21:33:42 +00:00
# jump gap
if d.xz.length() > 1.6 and not g.y_v:
g.y_v = 8.5
g.y_a = -36.0
2020-09-08 21:33:42 +00:00
if d.length() > 0:
if g.y_v < 5:
2020-09-08 21:33:42 +00:00
p.x -= utils.cap(d.x, 0.2)
p.z -= utils.cap(d.z, 0.2)
if len(g.path) > 1 and d.length() < 0.2:
2020-09-08 21:33:42 +00:00
# removes some jitter in walking
g.path.pop(0)
2020-09-08 21:33:42 +00:00
elif d.length() == 0:
g.path.pop(0)
2020-09-08 21:33:42 +00:00
if g.y_v or g.y_a:
p.y += g.y_v * utils.TICK
g.y_v += g.y_a * utils.TICK
2020-09-08 21:33:42 +00:00
block_below = g.chunks.get_block_at(floor(p.x), ceil(p.y-1), floor(p.z))
block_above = g.chunks.get_block_at(floor(p.x), ceil(p.y+1), floor(p.z))
2020-12-01 00:48:02 +00:00
in_void = p.y < 0
in_air = block_below in blocks.NON_SOLID_IDS or in_void
2020-12-02 11:12:51 +00:00
in_water = block_below in blocks.WATER_IDS
g.crawling = block_above not in blocks.NON_SOLID_IDS
2020-09-08 21:33:42 +00:00
if in_air:
g.y_a = -36.0
2020-12-02 11:12:51 +00:00
elif in_water:
g.y_a = -16.0
2020-09-08 21:33:42 +00:00
else:
p.y = ceil(p.y)
g.y_v = 0
g.y_a = 0
if g.look_at:
2021-04-22 00:46:54 +00:00
look_at = vector.Point3D(g.look_at)
elif g.path and len(g.path) > YAW_LOOK_AHEAD:
2021-04-22 00:46:54 +00:00
look_at = vector.Point3D(g.path[YAW_LOOK_AHEAD])
elif g.path and len(g.path):
2021-04-22 00:46:54 +00:00
look_at = vector.Point3D(g.path[-1])
2020-09-08 21:33:42 +00:00
else:
look_at = None
if look_at:
look_at.x += 0.5
look_at.z += 0.5
look_at_d = p - look_at
if look_at_d.length() > 0.6:
target_pitch = look_at_d.normalized().angleDeg(PITCH_ANGLE_DIR)
target_pitch = (target_pitch - 90) * -1
target_pitch_d = target_pitch - g.pitch
g.pitch += utils.cap(target_pitch_d, 10)
2020-09-08 21:33:42 +00:00
# remove vertical component for yaw calculation
look_at_d.y = 0
2020-09-08 21:33:42 +00:00
if look_at_d.length() > 0.6:
2020-09-08 21:33:42 +00:00
target_yaw = look_at_d.normalized().signedAngleDeg(other=YAW_ANGLE_DIR, ref=YAW_ANGLE_REF)
target_yaw_d = target_yaw - g.yaw
2020-09-08 21:33:42 +00:00
target_yaw_d = (target_yaw_d + 180) % 360 - 180
g.yaw += utils.cap(target_yaw_d, 30)
2020-09-08 21:33:42 +00:00
else:
target_pitch_d = 0 - g.pitch
g.pitch += utils.cap(target_pitch_d, 10)
2020-09-08 21:33:42 +00:00
packet = serverbound.play.PositionAndLookPacket(x=p.x, feet_y=p.y, z=p.z, pitch=g.pitch, yaw=g.yaw, on_ground=(not in_air))
2020-12-12 21:11:00 +00:00
g.connection.write_packet(packet)
2020-09-08 21:33:42 +00:00
2020-09-16 06:02:36 +00:00
g.game.tick()
2020-09-17 01:12:01 +00:00
g.job.tick()
2020-09-16 06:02:36 +00:00
2020-09-08 21:33:42 +00:00
def init(global_state):
g = global_state
g.time = 0
2020-09-08 21:33:42 +00:00
g.path = []
g.look_at = None
g.y_v = 0
g.y_a = 0
g.yaw = 360
g.pitch = 0
g.crawling = False
2020-09-08 21:33:42 +00:00
g.breaking = None
g.break_time = 0
2020-09-08 21:33:42 +00:00
g.dumping = None
2021-02-15 08:56:41 +00:00
g.draining = False
g.item_lock = False
g.command_lock = False
2021-02-22 01:44:55 +00:00
g.trades = []
2021-04-19 01:34:54 +00:00
g.job = job.JobStates(g)
g.chopped_tree = False
2020-09-08 01:28:56 +00:00
2020-12-18 04:15:09 +00:00
g.afk_timeout = 0
2020-12-04 02:49:22 +00:00
g.filling = False
2021-04-18 22:41:03 +00:00
g.minimum_cache_slots = 27
g.maximum_supply_slots = 33
def bot(global_state):
g = global_state
2020-09-09 01:52:50 +00:00
if not g.mcdata:
2020-12-14 05:40:17 +00:00
g.mcdata = DataManager('./minecraft_data')
2020-09-08 01:28:56 +00:00
if not g.connection:
auth_token = authentication.AuthenticationToken()
try:
auth_token.authenticate(USERNAME, PASSWORD)
except YggdrasilError as e:
print(e)
sys.exit()
print("Logged in as %s..." % auth_token.username)
g.connection = Connection(SERVER, PORT, auth_token=auth_token)
g.chunks = ChunksManager(g.mcdata)
g.connection.connect()
2020-09-09 01:52:50 +00:00
g.chunks.register(g.connection)
2020-09-08 23:51:27 +00:00
g.chat = ChatManager(g)
2020-09-16 06:02:36 +00:00
g.game = game.Game(g)
2020-09-16 20:09:14 +00:00
g.world = game.MCWorld(g)
2020-09-08 23:51:27 +00:00
2020-09-08 01:28:56 +00:00
try:
2020-09-08 21:33:42 +00:00
while not g.pos:
time.sleep(utils.TICK)
2020-09-08 21:33:42 +00:00
print('Player loaded.')
init(g)
2021-02-23 07:50:40 +00:00
g.game.close_window()
2020-09-17 01:12:01 +00:00
print('Initialized.')
2020-09-08 01:28:56 +00:00
while g.running:
2020-09-08 21:33:42 +00:00
tick(g)
2020-09-08 01:28:56 +00:00
global last_tick
sleep_time = utils.TICK + last_tick - time.time()
2020-09-08 01:28:56 +00:00
if sleep_time < 0: sleep_time = 0
time.sleep(sleep_time)
last_tick = time.time()
finally:
print('Removing listeners...')
g.connection.packet_listeners = []
g.connection.early_packet_listeners = []
g.connection.outgoing_packet_listeners = []
g.connection.early_outgoing_packet_listeners = []
print('Bot module loaded.')