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()