import unittest from munch import Munch from minecraft.networking.modern import ClientTickEnd from minecraft.networking.packets import PacketBuffer from mosfet.game import Game from mosfet.info import items from mosfet.jobs.eat_food import EatFoodStates from mosfet.protocol.modern import UseItemPacket from mosfet.protocol.types import Slot class FakeConnection: def __init__(self): self.packets = [] def write_packet(self, packet, force=False): self.packets.append((packet, force)) class FakeGame: def __init__(self, state): self.state = state self.used_hands = [] def select_item(self, item_ids): for slot, item in self.state.g.inv.items(): if item.present and item.item_id in item_ids: self.state.g.holding = item.item_id self.state.g.holding_hand = 0 self.state.g.holding_slot = slot - 36 return True return False def use_item(self, hand=0): self.used_hands.append(hand) class TestEatFood(unittest.TestCase): def test_use_item_packet_encodes_hand_sequence_and_rotation(self): packet = UseItemPacket(hand=1, sequence=300, yaw=90.0, pitch=-30.0) buffer = PacketBuffer() packet.write_fields(buffer) self.assertEqual(packet.id, 0x43) self.assertEqual(buffer.get_writable(), bytes.fromhex( '01ac0242b40000c1f00000')) def test_game_use_item_sends_packet_and_tick_end(self): connection = FakeConnection() game = Game.__new__(Game) game.g = Munch(connection=connection, yaw=45.0, pitch=-5.0) game.sequence = 0 game.use_item(1) packet, forced = connection.packets[0] self.assertIsInstance(packet, UseItemPacket) self.assertEqual((packet.hand, packet.sequence, packet.yaw, packet.pitch), (1, 1, 45.0, -5.0)) self.assertTrue(forced) self.assertIsInstance(connection.packets[1][0], ClientTickEnd) def test_eat_uses_authoritative_hunger_and_waits_for_confirmation(self): food_id = next(iter(items.FOOD_IDS)) state = EatFoodStates(Munch( food=8, health=20.0, food_saturation=0.0, inv={36: Slot(True, food_id, 3)}, holding_hand=0, holding_slot=0, job=None)) fake_game = FakeGame(state) state.g.game = fake_game state.init() self.assertEqual(state.state, state.select_food) state.select_food() self.assertEqual(state.state, state.wait_for_selection) state.wait_for_selection() self.assertEqual(state.state, state.eat_food) state.eat_food() self.assertEqual(fake_game.used_hands, [0]) self.assertEqual(state.state, state.wait) # Don't declare success until the server sends a hunger/saturation # update or confirms that it consumed the selected stack. state.wait() self.assertEqual(state.state, state.wait) state.g.food = 16 state.g.food_saturation = 4.0 state.wait() self.assertEqual(state.state, state.cleanup) def test_no_hunger_packet_does_not_eat(self): state = EatFoodStates(Munch(food=None, health=None)) state.init() self.assertEqual(state.state, state.cleanup) if __name__ == '__main__': unittest.main()