Compare commits

...

3 Commits

Author SHA1 Message Date
b754a4746d Handle player teleport packet 2020-12-14 04:27:06 +00:00
c49ce127b9 Redefine what trees are 2020-12-14 00:38:22 +00:00
93c1ab7c0a Track player positions and add !here 2020-12-13 11:38:30 +00:00
6 changed files with 144 additions and 43 deletions

View File

@ -3,7 +3,7 @@ from munch import Munch
import minecraft_data import minecraft_data
mcd = minecraft_data('1.16.2') mcd = minecraft_data('1.16.4')
with open('mcdata/registries.json') as f: with open('mcdata/registries.json') as f:
DATA = json.load(f) DATA = json.load(f)

121
game.py
View File

@ -20,7 +20,7 @@ from protocol.packets import (
ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket, ClickWindowPacket, CloseWindowPacket, ServerWindowConfirmationPacket,
ClientWindowConfirmationPacket, EntityMetadataPacket, ClientWindowConfirmationPacket, EntityMetadataPacket,
SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket, SpawnLivingEntityPacket, EntityPositionRotationPacket, DestroyEntitiesPacket,
EntityActionPacket, SpawnPlayerPacket, EntityActionPacket, EntityTeleport,
) )
from protocol.types import Slot from protocol.types import Slot
@ -97,30 +97,35 @@ class MCWorld:
# crawl to the bottom log # crawl to the bottom log
while self.block_at(*utils.padd(log, path.BLOCK_BELOW)) in blocks.LOG_IDS: while self.block_at(*utils.padd(log, path.BLOCK_BELOW)) in blocks.LOG_IDS:
log = utils.padd(log, path.BLOCK_BELOW) log = utils.padd(log, path.BLOCK_BELOW)
base = log
# make sure we are on the ground if base in found_trees:
if self.block_at(*utils.padd(log, path.BLOCK_BELOW)) in blocks.NON_SOLID_IDS:
continue continue
# crawl to the top log to count # make sure we are on the ground
if self.block_at(*utils.padd(base, path.BLOCK_BELOW)) in blocks.NON_SOLID_IDS:
continue
# crawl to the top log to count and check leaves
log_count = 1 log_count = 1
good_leaves = False
while self.block_at(*utils.padd(log, path.BLOCK_ABOVE)) in blocks.LOG_IDS: while self.block_at(*utils.padd(log, path.BLOCK_ABOVE)) in blocks.LOG_IDS:
log = utils.padd(log, path.BLOCK_ABOVE) log = utils.padd(log, path.BLOCK_ABOVE)
log_count += 1 log_count += 1
for offset in path.CHECK_DIRECTIONS:
if self.block_at(*utils.padd(log, offset)) not in blocks.LEAF_IDS:
break
else: # for:
good_leaves = True
# make sure it's a good tree # make sure it's a good tree
if self.block_at(*utils.padd(log, path.BLOCK_ABOVE)) not in blocks.LEAF_IDS or log_count < 3: if not good_leaves or log_count < 3:
continue continue
# crawl back to the bottom log found_trees.append(base)
while self.block_at(*utils.padd(log, path.BLOCK_BELOW)) in blocks.LOG_IDS:
log = utils.padd(log, path.BLOCK_BELOW)
if log in found_trees: yield base
continue
found_trees.append(log)
yield log
def find_tree_openings(self, tree): def find_tree_openings(self, tree):
# returns coords in a cardinal direction where we can stand by tree # returns coords in a cardinal direction where we can stand by tree
@ -325,8 +330,10 @@ class Game:
register(self.handle_entity_position, clientbound.play.EntityPositionDeltaPacket) register(self.handle_entity_position, clientbound.play.EntityPositionDeltaPacket)
register(self.handle_entity_position_rotation, EntityPositionRotationPacket) register(self.handle_entity_position_rotation, EntityPositionRotationPacket)
register(self.handle_destroy_entities, DestroyEntitiesPacket) register(self.handle_destroy_entities, DestroyEntitiesPacket)
register(self.handle_spawn_player, SpawnPlayerPacket) register(self.handle_spawn_player, clientbound.play.SpawnPlayerPacket)
register(self.handle_respawn, clientbound.play.RespawnPacket) register(self.handle_respawn, clientbound.play.RespawnPacket)
register(self.handle_player_list, clientbound.play.PlayerListItemPacket)
register(self.handle_entity_teleport, EntityTeleport)
#register(self.handle_entity_velocity, clientbound.play.EntityVelocityPacket) #register(self.handle_entity_velocity, clientbound.play.EntityVelocityPacket)
#register(self.handle_packet, Packet, early=True) #register(self.handle_packet, Packet, early=True)
@ -454,7 +461,7 @@ class Game:
reply = data reply = data
if command == 'pos': if command == 'pos':
reply = str(utils.pint(self.g.pos))[1:-1] reply = str(utils.pint(self.g.pos))[1:-1] + ', ' + self.g.dimension
if command == 'afk': if command == 'afk':
if not self.g.afk: if not self.g.afk:
@ -512,6 +519,14 @@ class Game:
if command == 'loaded': if command == 'loaded':
reply = str(self.g.chunks.get_loaded_area()) reply = str(self.g.chunks.get_loaded_area())
if command == 'players':
if data == 'clear':
self.g.players = {}
reply = 'ok'
else:
for k, v in self.g.players.items():
print(str(k) + ':', v, self.g.player_names[v.player_uuid])
if command == 'objects': if command == 'objects':
if data == 'clear': if data == 'clear':
self.g.objects = {} self.g.objects = {}
@ -568,6 +583,11 @@ class Game:
else: else:
reply = '/afk' reply = '/afk'
if command == 'tree':
pos = utils.pint(self.g.pos)
tree = next(self.g.world.find_trees(pos, 50))
reply = str(tree)[1:-1]
################# Specific commands ########################## ################# Specific commands ##########################
if for_me: if for_me:
@ -672,6 +692,37 @@ class Game:
self.g.job.state = self.g.job.fill_blocks self.g.job.state = self.g.job.fill_blocks
reply = 'filling ' + str(utils.pvolume(coord1, coord2)) + ' with ' + blocks.BLOCKS[block] reply = 'filling ' + str(utils.pvolume(coord1, coord2)) + ' with ' + blocks.BLOCKS[block]
if command == 'here':
try:
sender_uuid = self.g.player_names[sender]
except KeyError:
reply = 'can\'t find your uuid'
if not reply:
for p in self.g.players.values():
if p.player_uuid == sender_uuid:
player = p
break
else: # for
reply = 'can\'t find you'
if not reply:
pos = utils.pint(self.g.pos)
goal = utils.pint((p.x, p.y, p.z))
start = time.time()
navpath = self.g.world.path_to_place(pos, goal)
if navpath:
self.g.path = navpath
if self.g.job:
self.g.job.stop()
print(len(navpath))
print(navpath)
print(round(time.time() - start, 3), 'seconds')
reply = 'ok'
else:
reply = 'no path'
################# Authorized commands ########################## ################# Authorized commands ##########################
if authed: if authed:
@ -867,7 +918,7 @@ class Game:
print(packet) print(packet)
self.g.players[packet.entity_id] = Munch( self.g.players[packet.entity_id] = Munch(
entity_id=packet.entity_id, entity_id=packet.entity_id,
player_uuid=packet.player_uuid, player_uuid=packet.player_UUID,
x=packet.x, x=packet.x,
y=packet.y, y=packet.y,
z=packet.z, z=packet.z,
@ -936,6 +987,14 @@ class Game:
mob.y += packet.delta_y / 4096.0 mob.y += packet.delta_y / 4096.0
mob.z += packet.delta_z / 4096.0 mob.z += packet.delta_z / 4096.0
player = self.g.players.get(packet.entity_id, None)
if player:
player.x += packet.delta_x / 4096.0
player.y += packet.delta_y / 4096.0
player.z += packet.delta_z / 4096.0
if player.player_uuid == '0c123cfa-1697-4427-9413-4b645dee7ec0': print(packet)
def handle_entity_position_rotation(self, packet): def handle_entity_position_rotation(self, packet):
mob = self.g.mobs.get(packet.entity_id, None) mob = self.g.mobs.get(packet.entity_id, None)
if mob: if mob:
@ -943,6 +1002,29 @@ class Game:
mob.y += packet.delta_y / 4096.0 mob.y += packet.delta_y / 4096.0
mob.z += packet.delta_z / 4096.0 mob.z += packet.delta_z / 4096.0
player = self.g.players.get(packet.entity_id, None)
if player:
player.x += packet.delta_x / 4096.0
player.y += packet.delta_y / 4096.0
player.z += packet.delta_z / 4096.0
if player.player_uuid == '0c123cfa-1697-4427-9413-4b645dee7ec0': print(packet)
def handle_entity_teleport(self, packet):
mob = self.g.mobs.get(packet.entity_id, None)
if mob:
mob.x = packet.x
mob.y = packet.y
mob.z = packet.z
player = self.g.players.get(packet.entity_id, None)
if player:
player.x = packet.x
player.y = packet.y
player.z = packet.z
if player.player_uuid == '0c123cfa-1697-4427-9413-4b645dee7ec0': print(packet)
def handle_entity_velocity(self, packet): def handle_entity_velocity(self, packet):
obj = self.g.objects.get(packet.entity_id, None) obj = self.g.objects.get(packet.entity_id, None)
if obj: if obj:
@ -957,6 +1039,8 @@ class Game:
del self.g.objects[eid] del self.g.objects[eid]
if eid in self.g.mobs: if eid in self.g.mobs:
del self.g.mobs[eid] del self.g.mobs[eid]
if eid in self.g.players:
del self.g.players[eid]
def leave_bed(self): def leave_bed(self):
packet = EntityActionPacket() packet = EntityActionPacket()
@ -969,6 +1053,11 @@ class Game:
print(packet) print(packet)
self.g.dimension = packet.world_name.replace('minecraft:', '') self.g.dimension = packet.world_name.replace('minecraft:', '')
def handle_player_list(self, packet):
for action in packet.actions:
if isinstance(action, packet.AddPlayerAction):
self.g.player_names[action.uuid] = action.name
self.g.player_names[action.name] = action.uuid # porque no los dos?
def tick(self): def tick(self):
if self.g.breaking: if self.g.breaking:

View File

@ -24,6 +24,7 @@ g.inv = {}
g.objects = {} g.objects = {}
g.mobs = {} g.mobs = {}
g.players = {} g.players = {}
g.player_names = {}
g.window = None g.window = None
g.job = None g.job = None
g.correction_count = 0 g.correction_count = 0

View File

@ -11,20 +11,13 @@ def get_packets(old_get_packets):
mc_packets.add(packets.AcknowledgePlayerDiggingPacket) mc_packets.add(packets.AcknowledgePlayerDiggingPacket)
mc_packets.add(packets.BlockBreakAnimationPacket) mc_packets.add(packets.BlockBreakAnimationPacket)
mc_packets.add(packets.SetSlotPacket) mc_packets.add(packets.SetSlotPacket)
#mc_packets.add(packets.PlayerDiggingPacket)
#mc_packets.add(packets.PickItemPacket)
#mc_packets.add(packets.HeldItemChangePacket)
mc_packets.add(packets.OpenWindowPacket) mc_packets.add(packets.OpenWindowPacket)
#mc_packets.add(packets.CloseWindowPacket)
#mc_packets.add(packets.ClickWindowPacket)
mc_packets.add(packets.ClientWindowConfirmationPacket) mc_packets.add(packets.ClientWindowConfirmationPacket)
#mc_packets.add(packets.ServerWindowConfirmationPacket)
mc_packets.add(packets.EntityMetadataPacket) mc_packets.add(packets.EntityMetadataPacket)
mc_packets.add(packets.SpawnLivingEntityPacket) mc_packets.add(packets.SpawnLivingEntityPacket)
mc_packets.add(packets.EntityPositionRotationPacket) mc_packets.add(packets.EntityPositionRotationPacket)
mc_packets.add(packets.DestroyEntitiesPacket) mc_packets.add(packets.DestroyEntitiesPacket)
#mc_packets.add(packets.EntityActionPacket) mc_packets.add(packets.EntityTeleport)
mc_packets.add(packets.SpawnPlayerPacket)
return mc_packets return mc_packets

View File

@ -330,6 +330,23 @@ class SpawnLivingEntityPacket(Packet):
{'velocity_z': Short}, {'velocity_z': Short},
] ]
class EntityTeleport(Packet):
# Sent by the server when an entity moves more than 8 blocks
# https://wiki.vg/Protocol#Entity_Teleport
id = 0x56
packet_name = 'entity teleport'
definition = [
{'entity_id': VarInt},
{'x': Double},
{'y': Double},
{'z': Double},
{'yaw': Angle},
{'pitch': Angle},
{'on_ground': Boolean},
]
class EntityPositionRotationPacket(Packet): class EntityPositionRotationPacket(Packet):
# Sent by the server when an entity rotates and moves # Sent by the server when an entity rotates and moves
# https://wiki.vg/Protocol#Entity_Position_and_Rotation # https://wiki.vg/Protocol#Entity_Position_and_Rotation
@ -374,19 +391,3 @@ class EntityActionPacket(Packet):
{'action_id': VarInt}, {'action_id': VarInt},
{'jump_boost': VarInt}, {'jump_boost': VarInt},
] ]
class SpawnPlayerPacket(Packet):
# https://wiki.vg/Protocol#Spawn_Player
id = 0x04
packet_name = 'spawn player'
definition = [
{'entity_id': VarInt},
{'player_uuid': UUID},
{'x': Double},
{'y': Double},
{'z': Double},
{'yaw': Angle},
{'pitch': Angle},
]

View File

@ -1,23 +1,40 @@
appdirs==1.4.3
astar==0.92 astar==0.92
CacheControl==0.12.6
certifi==2020.6.20 certifi==2020.6.20
cffi==1.14.2 cffi==1.14.2
chardet==3.0.4 chardet==3.0.4
click==7.1.2 click==7.1.2
colorama==0.4.3
contextlib2==0.6.0
cryptography==3.1 cryptography==3.1
distlib==0.3.0
distro==1.4.0
Flask==1.1.2 Flask==1.1.2
html5lib==1.0.1
idna==2.10 idna==2.10
ipaddr==2.2.0
itsdangerous==1.1.0 itsdangerous==1.1.0
Jinja2==2.11.2 Jinja2==2.11.2
lockfile==0.12.2
MarkupSafe==1.1.1 MarkupSafe==1.1.1
minecraft-data==2.67.0 minecraft-data==2.70.1
msgpack==0.6.2
munch==2.5.0 munch==2.5.0
packaging==20.3
panda3d==1.10.6.post2 panda3d==1.10.6.post2
pathtools==0.1.2 pathtools==0.1.2
pep517==0.8.2
progress==1.5
pycparser==2.20 pycparser==2.20
pyCraft @ git+https://github.com/ammaraskar/pyCraft.git@2813d02ae7fb8182c3e5227a73de2240b09878d9 pyCraft==0.7.0
PyNBT==3.0.0 PyNBT==3.0.0
pyparsing==2.4.6
pytoml==0.1.21
requests==2.24.0 requests==2.24.0
retrying==1.3.3
six==1.15.0 six==1.15.0
urllib3==1.25.10 urllib3==1.25.10
watchdog==0.10.3 watchdog==0.10.3
webencodings==0.5.1
Werkzeug==1.0.1 Werkzeug==1.0.1