Clear stale sign data when signs break

This commit is contained in:
Tanner
2026-11-07 23:21:41 +00:00
parent 11add13779
commit 930f4f3868
3 changed files with 67 additions and 1 deletions
+14 -1
View File
@@ -283,11 +283,21 @@ class WorldState:
return chunk.get_block_at(floor(x), floor(y), floor(z)) return chunk.get_block_at(floor(x), floor(y), floor(z))
def set_block_entity(self, position, entity_type, data): def set_block_entity(self, position, entity_type, data):
self.block_entities[tuple(position)] = { position = tuple(position)
if data is None:
self.block_entities.pop(position, None)
return
self.block_entities[position] = {
'type': entity_type, 'type': entity_type,
'data': nbt_plain(data), 'data': nbt_plain(data),
} }
@staticmethod
def _is_sign_state(block_state_id):
from mosfet.info import blocks
name = blocks.BLOCKS.get(block_state_id)
return name is not None and name.endswith('_sign')
def set_block_at(self, x, y, z, block_state_id): def set_block_at(self, x, y, z, block_state_id):
x, y, z = floor(x), floor(y), floor(z) x, y, z = floor(x), floor(y), floor(z)
chunk = self.get_chunk(floor(x / 16), floor(z / 16)) chunk = self.get_chunk(floor(x / 16), floor(z / 16))
@@ -297,6 +307,9 @@ class WorldState:
pos = (x, y, z) pos = (x, y, z)
if previous in self.indexed_ids: if previous in self.indexed_ids:
self.index.get(previous, set()).discard(pos) self.index.get(previous, set()).discard(pos)
if (self._is_sign_state(previous) and
not self._is_sign_state(block_state_id)):
self.block_entities.pop(pos, None)
if block_state_id in self.indexed_ids: if block_state_id in self.indexed_ids:
self.index.setdefault(block_state_id, set()).add(pos) self.index.setdefault(block_state_id, set()).add(pos)
return True return True
+11
View File
@@ -25,6 +25,11 @@ class World:
def block_at(self, x, y, z): def block_at(self, x, y, z):
return self.g.chunks.get_block_at(x, y, z) return self.g.chunks.get_block_at(x, y, z)
@staticmethod
def _is_sign_state(state_id):
name = blocks.BLOCKS.get(state_id)
return name is not None and name.endswith('_sign')
@staticmethod @staticmethod
def _sign_component_text(value): def _sign_component_text(value):
if value is None: if value is None:
@@ -58,6 +63,12 @@ class World:
for position, entity in self.g.chunks.block_entities.items(): for position, entity in self.g.chunks.block_entities.items():
if utils.phyp(center, position) > distance: if utils.phyp(center, position) > distance:
continue continue
get_block_at = getattr(self.g.chunks, 'get_block_at', None)
if callable(get_block_at):
state_id = get_block_at(*position)
if (state_id is not None and
not self._is_sign_state(state_id)):
continue
data = entity.get('data') or {} data = entity.get('data') or {}
for side in ('front', 'back'): for side in ('front', 'back'):
text_data = data.get(side + '_text') text_data = data.get(side + '_text')
+42
View File
@@ -3,6 +3,7 @@ from unittest.mock import patch
from munch import Munch from munch import Munch
from mosfet.commands import Commands from mosfet.commands import Commands
from mosfet.info import blocks
from mosfet.protocol.managers import EntityManager, WorldState from mosfet.protocol.managers import EntityManager, WorldState
from mosfet.world import World from mosfet.world import World
@@ -45,6 +46,47 @@ class SignReadingTests(unittest.TestCase):
signs = World(Munch(chunks=chunks)).find_signs((4, 65, -2), 1) signs = World(Munch(chunks=chunks)).find_signs((4, 65, -2), 1)
self.assertEqual(signs[0]['lines'], ('Farm', '', '', '')) self.assertEqual(signs[0]['lines'], ('Farm', '', '', ''))
def test_broken_sign_block_update_removes_cached_sign_entity(self):
position = (4, 65, -2)
sign_state = blocks.MCD_BLOCKS['oak_wall_sign']['minStateId']
class FakeColumn:
def __init__(self):
self.states = {}
def get_block_at(self, x, y, z):
return self.states.get((x, y, z), blocks.AIR)
def set_block_at(self, x, y, z, state_id):
previous = self.get_block_at(x, y, z)
self.states[(x, y, z)] = state_id
return previous
chunks = WorldState()
chunks.chunks[(0, -1)] = FakeColumn()
chunks.set_block_at(*position, sign_state)
chunks.set_block_entity(position, 7, {
'front_text': {'messages': ['mosfet1 stay', 'within 8 square', '', '']},
})
world = World(Munch(chunks=chunks))
self.assertEqual(len(world.find_signs(position, 1)), 1)
chunks.set_block_at(*position, blocks.AIR)
self.assertNotIn(position, chunks.block_entities)
self.assertEqual(world.find_signs(position, 1), [])
def test_sign_search_ignores_stale_block_entity_for_non_sign_block(self):
position = (4, 65, -2)
chunks = Munch(
block_entities={position: {'data': {'front_text': {
'messages': ['mosfet1 stay', 'within 8 square', '', ''],
}}}},
get_block_at=lambda *_position: blocks.AIR,
)
self.assertEqual(World(Munch(chunks=chunks)).find_signs(position, 1), [])
def test_group_and_individual_sign_addresses(self): def test_group_and_individual_sign_addresses(self):
group_world = World(Munch(chunks=Munch(block_entities={ group_world = World(Munch(chunks=Munch(block_entities={
(0, 64, 0): {'data': {'front_text': {'messages': [ (0, 64, 0): {'data': {'front_text': {'messages': [