Compare commits

...

7 Commits

6 changed files with 108 additions and 46 deletions

View File

@@ -1,5 +1,6 @@
import re import re
import time import time
from datetime import datetime, timedelta
import random import random
from itertools import count from itertools import count
from munch import Munch from munch import Munch
@@ -22,7 +23,7 @@ class Commands:
def handle_chat(self, message): def handle_chat(self, message):
source, sender, text = message source, sender, text = message
reply = None reply = ''
private = False private = False
for_me = False for_me = False
authed = sender == '0c123cfa-1697-4427-9413-4b645dee7ec0' authed = sender == '0c123cfa-1697-4427-9413-4b645dee7ec0'
@@ -140,7 +141,10 @@ class Commands:
## !time - replies with Minecraft world time ## !time - replies with Minecraft world time
if command == 'time': if command == 'time':
reply = str(self.g.time) seconds = self.g.time * 3.6
start = datetime(2000, 1, 1, hour=6)
mctime = start + timedelta(seconds=seconds)
reply = str(self.g.time) + ' - ' + mctime.strftime('%I:%M %p')
## !count [id] - counts the number of items with that id ## !count [id] - counts the number of items with that id
if command == 'count' and data: if command == 'count' and data:
@@ -240,23 +244,67 @@ class Commands:
tree = next(self.g.world.find_trees(pos, 50)) tree = next(self.g.world.find_trees(pos, 50))
reply = str(tree)[1:-1] reply = str(tree)[1:-1]
## !block x y z - replies what block is at (x, y, z) ## !info [query] - replies with info on a coordinate, block, item, or player
if command == 'block': if command == 'info':
try: if not reply:
data = data.replace('(', ' ').replace(')', ' ').replace(',', ' ') try:
x1, y1, z1 = [int(x) for x in data.split()] check = data.replace('(', ' ').replace(')', ' ').replace(',', ' ')
except (AttributeError, ValueError): x1, y1, z1 = [int(x) for x in check.split()]
reply = 'usage: !block x1 y1 z1' coord = (x1, y1, z1)
block = self.g.world.block_at(*coord)
if not reply and block is None:
reply = 'coord out of range'
if not reply:
reply = 'Block: ' + blocks.BLOCKS[block] + ':' + str(block)
if blocks.PROPS[block]:
reply += ' - ' + ', '.join(['{}:{}'.format(k, v) for k, v in blocks.PROPS[block].items()])
except (AttributeError, ValueError):
pass
if not reply: if not reply:
coord = (x1, y1, z1) try:
block = self.g.world.block_at(*coord) check = int(data)
if not reply and block is None: if check in blocks.BLOCKS:
reply = 'first coord out of range' block = check
reply += 'Block: ' + blocks.BLOCKS[block] + ':' + str(block)
if blocks.PROPS[block]:
reply += ' - ' + ', '.join(['{}:{}'.format(k, v) for k, v in blocks.PROPS[block].items()])
if not reply: if check in blocks.BLOCKS and check in items.ITEM_NAMES:
reply = blocks.BLOCKS[block] + ':' + str(block) reply += ' / '
if check in items.ITEM_NAMES:
item = check
reply += 'Item: ' + items.ITEM_NAMES[item] + ':' + str(item)
except ValueError:
pass
check = data.lower()
if not reply and check in self.g.player_names:
uuid = self.g.player_names[check]
for p in self.g.players.values():
if p.player_uuid == uuid:
player = p
break
else: # for
reply = 'player out of range'
if not reply:
reply += 'Player: '
results = []
for k, v in player.items():
try:
results.append('{}:{}'.format(k, int(v)))
except ValueError:
results.append('{}:{}'.format(k, str(v)))
reply += ', '.join(results)
################# Specific commands ########################## ################# Specific commands ##########################

View File

@@ -49,6 +49,7 @@ class Game:
register(self.handle_spawn_living, SpawnLivingEntityPacket) register(self.handle_spawn_living, SpawnLivingEntityPacket)
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_entity_look, clientbound.play.EntityLookPacket)
register(self.handle_destroy_entities, DestroyEntitiesPacket) register(self.handle_destroy_entities, DestroyEntitiesPacket)
register(self.handle_spawn_player, clientbound.play.SpawnPlayerPacket) register(self.handle_spawn_player, clientbound.play.SpawnPlayerPacket)
register(self.handle_respawn, clientbound.play.RespawnPacket) register(self.handle_respawn, clientbound.play.RespawnPacket)
@@ -442,8 +443,14 @@ class Game:
player.x += packet.delta_x / 4096.0 player.x += packet.delta_x / 4096.0
player.y += packet.delta_y / 4096.0 player.y += packet.delta_y / 4096.0
player.z += packet.delta_z / 4096.0 player.z += packet.delta_z / 4096.0
player.yaw = packet.yaw
player.pitch = packet.pitch
#if player.player_uuid == '0c123cfa-1697-4427-9413-4b645dee7ec0': print(packet) def handle_entity_look(self, packet):
player = self.g.players.get(packet.entity_id, None)
if player:
player.yaw = packet.yaw
player.pitch = packet.pitch
def handle_entity_teleport(self, packet): def handle_entity_teleport(self, packet):
mob = self.g.mobs.get(packet.entity_id, None) mob = self.g.mobs.get(packet.entity_id, None)
@@ -493,7 +500,8 @@ class Game:
for action in packet.actions: for action in packet.actions:
if isinstance(action, packet.AddPlayerAction): if isinstance(action, packet.AddPlayerAction):
self.g.player_names[action.uuid] = action.name self.g.player_names[action.uuid] = action.name
self.g.player_names[action.name] = action.uuid # porque no los dos? self.g.player_names[action.name] = action.uuid
self.g.player_names[action.name.lower()] = action.uuid # porque no los dos?
def handle_update_health(self, packet): def handle_update_health(self, packet):
print(packet) print(packet)

View File

@@ -15,6 +15,11 @@ for name, data in JSON_BLOCKS.items():
for state in data['states']: for state in data['states']:
BLOCKS[state['id']] = name.replace('minecraft:', '') BLOCKS[state['id']] = name.replace('minecraft:', '')
PROPS = {}
for name, data in JSON_BLOCKS.items():
for state in data['states']:
PROPS[state['id']] = state.get('properties', {})
BREAK_DISTANCE = 6 BREAK_DISTANCE = 6
AIR = 0 AIR = 0

View File

@@ -72,15 +72,7 @@ class GatherCropStates:
def break_crop(self): def break_crop(self):
self.g.game.break_block(self.crop) self.g.game.break_block(self.crop)
self.wait_time = 0.5 self.state = self.select_seed
self.state = self.wait
def wait(self):
# wait for the item
if self.wait_time > 0:
self.wait_time -= utils.TICK
else:
self.state = self.select_seed
def select_seed(self): def select_seed(self):
p = utils.pint(self.g.pos) p = utils.pint(self.g.pos)
@@ -91,18 +83,17 @@ class GatherCropStates:
blocks.MATURE_CARROT_ID: items.CARROT_ID, blocks.MATURE_CARROT_ID: items.CARROT_ID,
blocks.MATURE_BEETROOT_ID: items.BEETROOT_SEEDS_ID, blocks.MATURE_BEETROOT_ID: items.BEETROOT_SEEDS_ID,
} }
self.target_seed = crop_seeds[self.type_id]
if self.g.game.select_item([crop_seeds[self.type_id]]): if self.g.game.select_item([self.target_seed]):
self.state = self.wait_select self.state = self.wait_select
self.wait_time = 0.5
else: else:
print('Aborting planting, no crop') print('Havent picked up seed yet')
self.state = self.cleanup return
def wait_select(self): def wait_select(self):
# wait a bit to select if self.target_seed != self.g.holding:
if self.wait_time > 0: return
self.wait_time -= utils.TICK
else: else:
self.state = self.place_crop self.state = self.place_crop
@@ -111,12 +102,11 @@ class GatherCropStates:
self.g.game.place_block(p, BlockFace.TOP) self.g.game.place_block(p, BlockFace.TOP)
print('Placed crop') print('Placed crop')
self.state = self.wait_place self.state = self.wait_place
self.wait_time = 0.5
def wait_place(self): def wait_place(self):
# wait a bit for chunk data to update w = self.g.world
if self.wait_time > 0: if w.block_at(*self.crop) == blocks.AIR:
self.wait_time -= utils.TICK return
else: else:
self.state = self.cleanup self.state = self.cleanup
@@ -134,8 +124,8 @@ class GatherCropStates:
self.crop = None self.crop = None
self.type_id = None self.type_id = None
self.target_seed = None
self.bad_crops = [] self.bad_crops = []
self.wait_time = 0
def run(self): def run(self):
self.state() self.state()

View File

@@ -139,7 +139,15 @@ class SleepWithBedStates:
print('Placing bed') print('Placing bed')
self.g.game.place_block(self.area, BlockFace.TOP) self.g.game.place_block(self.area, BlockFace.TOP)
self.my_bed = True self.my_bed = True
self.state = self.use_bed self.wait_time = 0.5
self.state = self.wait_use
def wait_use(self):
# wait to use the bed
if self.wait_time > 0:
self.wait_time -= utils.TICK
else:
self.state = self.use_bed
def use_bed(self): def use_bed(self):
w = self.g.world w = self.g.world

View File

@@ -280,13 +280,13 @@ class World:
def check_bed_occupied(self, bed): def check_bed_occupied(self, bed):
# returns true if the bed is occupied by a player # returns true if the bed is occupied by a player
print('Checking bed occupancy:', bed) bid = self.g.chunks.get_block_at(*bed)
for player in self.g.players.values(): if blocks.PROPS[bid]['occupied'] == 'true':
ppos = utils.pint((player.x, player.y, player.z)) print('Checking bed occupancy:', bed, '-> occupied')
if utils.phyp(bed, ppos) <= 1 and player.y - int(player.y) == 0.6875: return True
print('Bed is occupied by:', player, self.g.player_names[player.player_uuid]) else:
return True print('Checking bed occupancy:', bed, '-> free')
return False return False
def find_cache_openings(self, area): def find_cache_openings(self, area):
return self.find_bed_openings(area) return self.find_bed_openings(area)
@@ -312,6 +312,7 @@ class World:
if utils.phyp(center, pos) > distance: if utils.phyp(center, pos) > distance:
continue continue
result.append(mob) result.append(mob)
result.sort(key=lambda mob: utils.phyp(center, (mob.x, mob.y, mob.z)))
return result return result
def find_threats(self, center, distance): def find_threats(self, center, distance):
@@ -324,6 +325,7 @@ class World:
if not self.check_air_column(pos, distance): if not self.check_air_column(pos, distance):
continue continue
result.append(mob) result.append(mob)
result.sort(key=lambda mob: utils.phyp(center, (mob.x, mob.y, mob.z)))
return result return result
def find_villagers(self, center, distance): def find_villagers(self, center, distance):
@@ -336,6 +338,7 @@ class World:
if utils.phyp(center, pos) > distance: if utils.phyp(center, pos) > distance:
continue continue
result.append(mob) result.append(mob)
result.sort(key=lambda mob: utils.phyp(center, (mob.x, mob.y, mob.z)))
return result return result
def find_villager_openings(self, villager): def find_villager_openings(self, villager):