Implement 26.3 bed sleeping

This commit is contained in:
Tanner
2026-11-04 19:20:15 +00:00
parent 9fd565c3c9
commit 1ecec547ae
10 changed files with 404 additions and 75 deletions
+42 -3
View File
@@ -23,6 +23,7 @@ from mosfet.protocol.packets import (
)
from mosfet.protocol.types import Slot
from mosfet.protocol.modern import PlayerCommandPacket, UpdateTimePacket
from mosfet import utils
from mosfet import path
@@ -164,7 +165,32 @@ class LegacyGame:
self.g.path = new_path
def handle_time_update(self, packet):
self.g.time = packet.time_of_day % 24000
if hasattr(packet, 'time_of_day'):
self.g.time = packet.time_of_day % 24000
return
updates = getattr(packet, 'clock_updates', ())
if not updates:
return
registries = getattr(self.g.connection, 'registry_ids', {})
clock_names = {
index: name
for name, index in registries.get(
'minecraft:world_clock', {}).items()
}
dimension = self.g.get('dimension', 'overworld')
preferred = [
update for update in updates
if clock_names.get(update['clock_id'], '').removeprefix(
'minecraft:') in (dimension, 'overworld')
]
update = preferred[0] if preferred else updates[0]
self.g.time = update['total_ticks'] % 24000
self.g.clock_id = update['clock_id']
self.g.clock_name = clock_names.get(update['clock_id'])
self.g.clock_rate = update['rate']
self.g.world_age = packet.age
def handle_set_slot(self, packet):
g = self.g
@@ -632,8 +658,11 @@ class Game(LegacyGame):
for packet in reactor.__class__.get_clientbound_packets(context)
}
reactor.clientbound_packets[SetHealthPacket.id] = SetHealthPacket
reactor.clientbound_packets[UpdateTimePacket.id] = UpdateTimePacket
self.g.connection.register_packet_listener(
self.handle_set_health, SetHealthPacket)
self.g.connection.register_packet_listener(
self.handle_time_update, UpdateTimePacket)
if not self.g.get('health_update_received', False):
self.g.health = None
@@ -680,6 +709,10 @@ class Game(LegacyGame):
self.break_deadline = time.monotonic() + max(0.05, hardness_time)
return True
def leave_bed(self):
self._send_action(PlayerCommandPacket(
entity_id=self.g.eid, action_id=0, jump_boost=0))
def start_drain(self):
slots = [slot for slot, item in sorted(self.g.inv.items())
if 9 <= slot <= 45 and getattr(item, 'present', False)]
@@ -783,6 +816,12 @@ class Game(LegacyGame):
slot, item = next(
((slot, item) for slot, item in matches if 36 <= slot <= 44),
matches[0])
if slot == 45:
self.g.holding = item.item_id
self.g.holding_hand = 1
self.g.connection.write_packet(ClientTickEnd(), force=True)
return True
self.g.holding_hand = 0
if 36 <= slot <= 44:
hotbar_slot = slot - 36
elif 9 <= slot <= 35:
@@ -807,10 +846,10 @@ class Game(LegacyGame):
self.g.connection.write_packet(ClientTickEnd(), force=True)
return True
def place_block(self, location, face):
def place_block(self, location, face, hand=0):
location = tuple(int(value) for value in location)
packet = UseItemOnBlockPacket(
hand=0, location=location, face=int(face),
hand=hand, location=location, face=int(face),
cursor_x=0.5, cursor_y=0.99 if int(face) == 1 else 0.5,
cursor_z=0.5, inside_block=False, world_border_hit=False,
sequence=self._next_sequence())