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
+4 -1
View File
@@ -11,14 +11,17 @@ class TestCropCaching(unittest.TestCase):
old_wanted = items.WANTED_ITEMS
crop_state = object()
cache_state = Munch(silent=False)
sleep_state = Munch(silent=False)
jobs = JobStates.__new__(JobStates)
jobs.gather_crop_states = crop_state
jobs.cache_items_states = cache_state
jobs.sleep_with_bed_states = sleep_state
try:
machines = JobStates.farm_crop(jobs)
self.assertEqual(machines, [crop_state, cache_state])
self.assertEqual(machines, [crop_state, sleep_state, cache_state])
self.assertTrue(cache_state.silent)
self.assertTrue(sleep_state.silent)
self.assertTrue({
items.CARROT_ID, items.POTATO_ID,
items.WHEAT_SEEDS_ID, items.BEETROOT_SEEDS_ID,
+132
View File
@@ -0,0 +1,132 @@
import io
import unittest
from munch import Munch
from minecraft.networking.packets import PacketBuffer
from minecraft.networking.types import Float, Long, VarInt, VarLong
from mosfet.game import Game
from mosfet.info import blocks, items
from mosfet.protocol.types import Slot
from mosfet.jobs.sleep_with_bed import SleepWithBedStates
from mosfet.protocol.modern import PlayerCommandPacket, UpdateTimePacket
from minecraft.networking.modern import ClientTickEnd
class FakeConnection:
def __init__(self):
self.packets = []
def write_packet(self, packet, force=False):
self.packets.append((packet, force))
class FakeWorld:
def __init__(self, block=blocks.AIR):
self.block = block
def block_at(self, *position):
return self.block
class FakeGame:
def __init__(self):
self.placements = []
def place_block(self, location, face, hand=0):
self.placements.append((location, face, hand))
class TestSleepWithBed(unittest.TestCase):
def test_update_time_packet_decodes_clock_updates(self):
payload = PacketBuffer()
Long.send(123456, payload)
VarInt.send(1, payload)
VarInt.send(0, payload)
VarLong.send(13000, payload)
Float.send(0.5, payload)
Float.send(1.0, payload)
packet = UpdateTimePacket()
packet.read(io.BytesIO(payload.get_writable()))
self.assertEqual(packet.id, 0x73)
self.assertEqual(packet.age, 123456)
self.assertEqual(packet.clock_updates, [{
'clock_id': 0, 'total_ticks': 13000,
'partial_tick': 0.5, 'rate': 1.0,
}])
def test_player_command_encodes_stop_sleeping(self):
packet = PlayerCommandPacket(
entity_id=7, action_id=0, jump_boost=0)
payload = PacketBuffer()
packet.write_fields(payload)
self.assertEqual(packet.id, 0x2A)
self.assertEqual(payload.get_writable(), b'\x07\x00\x00')
def test_game_leave_bed_sends_protocol_777_stop_sleeping(self):
connection = FakeConnection()
game = Game.__new__(Game)
game.g = Munch(connection=connection, eid=42)
game.leave_bed()
packet, force = connection.packets[0]
self.assertIsInstance(packet, PlayerCommandPacket)
self.assertEqual((packet.entity_id, packet.action_id,
packet.jump_boost), (42, 0, 0))
self.assertTrue(force)
self.assertIsInstance(connection.packets[1][0], ClientTickEnd)
def test_bed_in_offhand_is_selectable_without_swapping_inventory(self):
connection = FakeConnection()
game = Game.__new__(Game)
bed_id = next(iter(items.BED_IDS))
game.g = Munch(
connection=connection, inv={45: Slot(True, bed_id, 1)},
holding_hand=0)
self.assertTrue(game.select_item(items.BED_IDS))
self.assertEqual(game.g.holding, bed_id)
self.assertEqual(game.g.holding_hand, 1)
self.assertIsInstance(connection.packets[0][0], ClientTickEnd)
def test_daytime_sleep_aborts_cleanly(self):
state = SleepWithBedStates(Munch(time=1000, dimension='overworld'))
state.init()
self.assertEqual(state.state, state.cleanup)
def test_placing_bed_uses_support_block_face_top(self):
game = FakeGame()
state = SleepWithBedStates(Munch(
game=game, world=FakeWorld(), path=[], look_at=None,
holding_hand=1))
state.area = (4, 70, 5)
state.place_bed()
self.assertEqual(len(game.placements), 1)
location, face, hand = game.placements[0]
self.assertEqual(location, (4, 69, 5))
self.assertEqual(int(face), 1)
self.assertEqual(hand, 1)
self.assertTrue(state.my_bed)
self.assertEqual(state.state, state.wait_use)
def test_wait_use_aborts_if_server_rejects_bed_placement(self):
state = SleepWithBedStates(Munch(
game=FakeGame(), world=FakeWorld(block=blocks.AIR),
path=[], look_at=None))
state.area = (4, 70, 5)
state.my_bed = True
state.wait_time = 0
state.wait_use()
self.assertIn(state.area, state.bad_areas)
self.assertFalse(state.my_bed)
self.assertEqual(state.state, state.cleanup)
if __name__ == '__main__':
unittest.main()