Track protocol 777 health and hunger

This commit is contained in:
Tanner
2026-11-04 17:14:15 +00:00
parent 4129686b07
commit 6dbc61284a
9 changed files with 126 additions and 7 deletions
+8
View File
@@ -107,6 +107,14 @@ class Commands:
if command == 'pos':
reply = str(utils.pint(self.g.pos))[1:-1] + ', ' + self.g.dimension
## !health - replies with health, hunger, and saturation
if command == 'health':
if not self.g.get('health_update_received'):
reply = 'health status not received yet'
else:
reply = 'health {:.1f}, hunger {}/20, saturation {:.2f}'.format(
self.g.health, self.g.food, self.g.food_saturation)
## !afk - goes AFK with /afk
if command == 'afk':
if not self.g.afk:
+38
View File
@@ -583,6 +583,44 @@ class Game(LegacyGame):
self.break_deadline = None
self.breaking_state = None
from mosfet.protocol.packets import SetHealthPacket
# Health is a protocol-777 packet, not the legacy UpdateHealthPacket.
# Register its decoder on an already-running reactor as well, so a
# hot reload can enable health tracking without reconnecting. Rebuild
# the base map first to remove any stale decoder for an earlier ID.
reactor = self.g.connection.reactor
if hasattr(reactor, 'clientbound_packets'):
context = self.g.connection.context
reactor.clientbound_packets = {
packet.get_id(context): packet
for packet in reactor.__class__.get_clientbound_packets(context)
}
reactor.clientbound_packets[SetHealthPacket.id] = SetHealthPacket
self.g.connection.register_packet_listener(
self.handle_set_health, SetHealthPacket)
if not self.g.get('health_update_received', False):
self.g.health = None
self.g.food = None
self.g.hunger = None
self.g.food_saturation = None
self.g.saturation = None
self.g.health_update_received = False
self.g.health_updated_at = None
self.g.dead = False
def handle_set_health(self, packet):
self.g.health = float(packet.health)
self.g.food = int(packet.food)
self.g.hunger = self.g.food
self.g.food_saturation = float(packet.food_saturation)
self.g.saturation = self.g.food_saturation
self.g.health_update_received = True
self.g.health_updated_at = time.time()
self.g.dead = self.g.health <= 0
print('[status] health={:.1f} hunger={} saturation={:.2f}'.format(
self.g.health, self.g.food, self.g.food_saturation), flush=True)
def _send_action(self, packet):
self.g.connection.write_packet(packet, force=True)
self.g.connection.write_packet(ClientTickEnd(), force=True)
+11
View File
@@ -13,6 +13,17 @@ from .types import Nbt, Slot, Entry, Trade
from mosfet.info import blocks
class SetHealthPacket(Packet):
"""Minecraft 26.3 (protocol 777) clientbound health/food update."""
id = 0x6A
packet_name = 'set health'
definition = [
{'health': Float},
{'food': VarInt},
{'food_saturation': Float},
]
class ChunkDataPacket(Packet):
id = 0x20
packet_name = 'chunk data'