minecraft-bot/bot.py

228 lines
5.9 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-09-07 22:32:19 +00:00
USERNAME = os.environ['USERNAME']
PASSWORD = os.environ['PASSWORD']
SERVER = os.environ['SERVER']
import monkey_patch # must be before any possible pyCraft imports
from custom.managers import DataManager, ChunksManager, ChatManager
from minecraft import authentication
from minecraft.exceptions import YggdrasilError
from minecraft.networking.connection import Connection
from minecraft.networking.packets import Packet, clientbound, serverbound
2020-09-08 01:28:56 +00:00
from custom.networking.packets.clientbound.play.block_change_packet import BlockChangePacket
2020-09-08 21:33:42 +00:00
from bunch import Bunch
from panda3d.core import LPoint3f, LVector3f
2020-09-08 20:07:09 +00:00
import packet_handlers
importlib.reload(packet_handlers)
2020-09-08 21:33:42 +00:00
import blocks
importlib.reload(blocks)
import utils
importlib.reload(utils)
import path
importlib.reload(path)
2020-09-08 01:28:56 +00:00
TICK = 0.05
last_tick = time.time()
2020-09-08 21:33:42 +00:00
PITCH_ANGLE_DIR = LVector3f(x=0, y=1, z=0)
YAW_ANGLE_DIR = LVector3f(x=0, y=0, z=-1)
YAW_ANGLE_REF = LVector3f(x=0, y=1, z=0)
YAW_LOOK_AHEAD = 4
def tick(global_state):
g = global_state
l = g.local_state
p = g.pos
target = None
try:
g.chunks.get_block_at(*utils.pint(p))
except chunks.ChunkNotLoadedException:
return
#l.jobstate.run()
if l.path and len(l.path):
target = LPoint3f(l.path[0])
target.x += 0.5
target.z += 0.5
if target:
d = p - target
# jump up block
if d.y < -0.9 and not l.y_v:
l.y_v = 8.5
l.y_a = -36.0
# jump gap
if d.xz.length() > 1.6 and not l.y_v:
l.y_v = 8.5
l.y_a = -36.0
if d.length() > 0:
if l.y_v < 5:
p.x -= utils.cap(d.x, 0.2)
p.z -= utils.cap(d.z, 0.2)
if len(l.path) > 1 and d.length() < 0.2:
# removes some jitter in walking
l.path.pop(0)
elif d.length() == 0:
l.path.pop(0)
if l.y_v or l.y_a:
p.y += l.y_v * TICK
l.y_v += l.y_a * TICK
block_below = g.chunks.get_block_at(floor(p.x), ceil(p.y-1), floor(p.z))
in_air = block_below in blocks.NON_SOLID_IDS
if in_air:
l.y_a = -36.0
else:
p.y = ceil(p.y)
l.y_v = 0
l.y_a = 0
if l.look_at:
look_at = LPoint3f(l.look_at)
elif l.path and len(l.path) > YAW_LOOK_AHEAD:
look_at = LPoint3f(l.path[YAW_LOOK_AHEAD])
elif l.path and len(l.path):
look_at = LPoint3f(l.path[-1])
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 - l.pitch
l.pitch += utils.cap(target_pitch_d, 10)
# remove vertical component for yaw calculation
look_at_d.y = 0
target_yaw = look_at_d.normalized().signedAngleDeg(other=YAW_ANGLE_DIR, ref=YAW_ANGLE_REF)
target_yaw_d = target_yaw - l.yaw
target_yaw_d = (target_yaw_d + 180) % 360 - 180
l.yaw += utils.cap(target_yaw_d, 30)
else:
target_pitch_d = 0 - l.pitch
l.pitch += utils.cap(target_pitch_d, 10)
packet = serverbound.play.PositionAndLookPacket(x=p.x, feet_y=p.y, z=p.z, pitch=l.pitch, yaw=l.yaw, on_ground=(not in_air))
g.connection.write_packet(packet, force=True)
def init(global_state):
g = global_state
l = g.local_state
l.time = 0
l.path = []
l.look_at = None
l.y_v = 0
l.y_a = 0
l.yaw = 360
l.pitch = 0
#l.break = None
#l.break_time = 0
#l.break_timeout = 0
#l.break_finished_packet = None
#l.jobstate = JobStates(connection, player_info)
#l.jobstate.run()
2020-09-08 01:28:56 +00:00
def bot(global_state):
g = global_state
2020-09-08 21:33:42 +00:00
g.local_state = Bunch()
if 'mcdata' not in g:
g.mcdata = DataManager('./mcdata')
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)
2020-09-08 20:07:09 +00:00
g.connection = Connection(SERVER, 25565, auth_token=auth_token)
g.chunks = ChunksManager(g.mcdata)
g.chunks.register(g.connection)
g.connection.connect()
def packet_wrapper(handler):
def wrapper(packet):
handler(packet, g)
return wrapper
2020-09-08 01:28:56 +00:00
2020-09-08 21:33:42 +00:00
h1 = packet_wrapper(packet_handlers.handle_join_game)
g.connection.register_packet_listener(h1, clientbound.play.JoinGamePacket)
2020-09-08 20:07:09 +00:00
2020-09-08 21:33:42 +00:00
h2 = packet_wrapper(packet_handlers.handle_position_and_look)
g.connection.register_packet_listener(h2, clientbound.play.PlayerPositionAndLookPacket)
2020-09-08 01:28:56 +00:00
2020-09-08 21:33:42 +00:00
h3 = packet_wrapper(packet_handlers.handle_block_change)
g.connection.register_packet_listener(h3, BlockChangePacket)
2020-09-08 20:07:09 +00:00
2020-09-08 23:51:27 +00:00
g.chat = ChatManager(g)
h4 = packet_wrapper(packet_handlers.handle_chat)
g.chat.set_handler(h4)
2020-09-08 01:28:56 +00:00
try:
2020-09-08 21:33:42 +00:00
while not g.pos:
time.sleep(TICK)
print('Player loaded.')
x, y, z = utils.pint(g.pos)
while (floor(x/16), floor(y/16), floor(z/16)) not in g.chunks.chunks:
time.sleep(TICK)
print('Chunks loaded.')
2020-09-08 01:28:56 +00:00
2020-09-08 21:33:42 +00:00
init(g)
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 = TICK + last_tick - time.time()
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.')