Zillion: fix invalid slot data from race condition
This commit is contained in:
parent
c3fe341736
commit
b7d46004e2
|
@ -258,6 +258,10 @@ class ZillionContext(CommonContext):
|
||||||
assert id_ in id_to_loc
|
assert id_ in id_to_loc
|
||||||
self.loc_mem_to_id[mem] = id_
|
self.loc_mem_to_id[mem] = id_
|
||||||
|
|
||||||
|
if len(self.loc_mem_to_id) != 394:
|
||||||
|
logger.warn("invalid Zillion `Connected` packet, "
|
||||||
|
f"`slot_data` missing locations in `loc_mem_to_id` - len {len(self.loc_mem_to_id)}")
|
||||||
|
|
||||||
self.got_slot_data.set()
|
self.got_slot_data.set()
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
|
|
|
@ -251,7 +251,10 @@ class World(metaclass=AutoWorldRegister):
|
||||||
def fill_slot_data(self) -> Dict[str, Any]: # json of WebHostLib.models.Slot
|
def fill_slot_data(self) -> Dict[str, Any]: # json of WebHostLib.models.Slot
|
||||||
"""Fill in the `slot_data` field in the `Connected` network package.
|
"""Fill in the `slot_data` field in the `Connected` network package.
|
||||||
This is a way the generator can give custom data to the client.
|
This is a way the generator can give custom data to the client.
|
||||||
The client will receive this as JSON in the `Connected` response."""
|
The client will receive this as JSON in the `Connected` response.
|
||||||
|
|
||||||
|
The generation does not wait for `generate_output` to complete before calling this.
|
||||||
|
`threading.Event` can be used if you need to wait for something from `generate_output`."""
|
||||||
return {}
|
return {}
|
||||||
|
|
||||||
def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]):
|
def extend_hint_information(self, hint_data: Dict[int, Dict[int, str]]):
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
from collections import deque, Counter
|
from collections import deque, Counter
|
||||||
from contextlib import redirect_stdout
|
from contextlib import redirect_stdout
|
||||||
import functools
|
import functools
|
||||||
|
import threading
|
||||||
from typing import Any, Dict, List, Set, Tuple, Optional, cast
|
from typing import Any, Dict, List, Set, Tuple, Optional, cast
|
||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
@ -101,12 +102,15 @@ class ZillionWorld(World):
|
||||||
"""
|
"""
|
||||||
my_locations: List[ZillionLocation] = []
|
my_locations: List[ZillionLocation] = []
|
||||||
""" This is kind of a cache to avoid iterating through all the multiworld locations in logic. """
|
""" This is kind of a cache to avoid iterating through all the multiworld locations in logic. """
|
||||||
|
slot_data_ready: threading.Event
|
||||||
|
""" This event is set in `generate_output` when the data is ready for `fill_slot_data` """
|
||||||
|
|
||||||
def __init__(self, world: MultiWorld, player: int):
|
def __init__(self, world: MultiWorld, player: int):
|
||||||
super().__init__(world, player)
|
super().__init__(world, player)
|
||||||
self.logger = logging.getLogger("Zillion")
|
self.logger = logging.getLogger("Zillion")
|
||||||
self.lsi = ZillionWorld.LogStreamInterface(self.logger)
|
self.lsi = ZillionWorld.LogStreamInterface(self.logger)
|
||||||
self.zz_system = System()
|
self.zz_system = System()
|
||||||
|
self.slot_data_ready = threading.Event()
|
||||||
|
|
||||||
def _make_item_maps(self, start_char: Chars) -> None:
|
def _make_item_maps(self, start_char: Chars) -> None:
|
||||||
_id_to_name, _id_to_zz_id, id_to_zz_item = make_id_to_others(start_char)
|
_id_to_name, _id_to_zz_id, id_to_zz_item = make_id_to_others(start_char)
|
||||||
|
@ -338,6 +342,7 @@ class ZillionWorld(World):
|
||||||
zz_patcher.write_locations(self.zz_system.randomizer.regions,
|
zz_patcher.write_locations(self.zz_system.randomizer.regions,
|
||||||
zz_options.start_char,
|
zz_options.start_char,
|
||||||
self.zz_system.randomizer.loc_name_2_pretty)
|
self.zz_system.randomizer.loc_name_2_pretty)
|
||||||
|
self.slot_data_ready.set()
|
||||||
zz_patcher.all_fixes_and_options(zz_options)
|
zz_patcher.all_fixes_and_options(zz_options)
|
||||||
zz_patcher.set_external_item_interface(zz_options.start_char, zz_options.max_level)
|
zz_patcher.set_external_item_interface(zz_options.start_char, zz_options.max_level)
|
||||||
zz_patcher.set_multiworld_items(multi_items)
|
zz_patcher.set_multiworld_items(multi_items)
|
||||||
|
@ -385,6 +390,7 @@ class ZillionWorld(World):
|
||||||
assert self.zz_system.randomizer, "didn't get randomizer from generate_early"
|
assert self.zz_system.randomizer, "didn't get randomizer from generate_early"
|
||||||
|
|
||||||
rescues: Dict[str, Any] = {}
|
rescues: Dict[str, Any] = {}
|
||||||
|
self.slot_data_ready.wait()
|
||||||
for i in (0, 1):
|
for i in (0, 1):
|
||||||
if i in zz_patcher.rescue_locations:
|
if i in zz_patcher.rescue_locations:
|
||||||
ri = zz_patcher.rescue_locations[i]
|
ri = zz_patcher.rescue_locations[i]
|
||||||
|
|
Loading…
Reference in New Issue