Fix: When sending items via send or getitem, only consider items that belong to that world
Fix: Allow cheat-sending items into unconnected slots
This commit is contained in:
parent
38bc3d47ad
commit
9821e05386
|
@ -25,6 +25,8 @@ import prompt_toolkit
|
||||||
from prompt_toolkit.patch_stdout import patch_stdout
|
from prompt_toolkit.patch_stdout import patch_stdout
|
||||||
from fuzzywuzzy import process as fuzzy_process
|
from fuzzywuzzy import process as fuzzy_process
|
||||||
|
|
||||||
|
from worlds.AutoWorld import AutoWorldRegister
|
||||||
|
proxy_worlds = {name: world(None, 0) for name, world in AutoWorldRegister.world_types.items()}
|
||||||
from worlds.alttp import Items, Regions
|
from worlds.alttp import Items, Regions
|
||||||
from worlds import network_data_package, lookup_any_item_id_to_name, lookup_any_item_name_to_id, \
|
from worlds import network_data_package, lookup_any_item_id_to_name, lookup_any_item_name_to_id, \
|
||||||
lookup_any_location_id_to_name, lookup_any_location_name_to_id
|
lookup_any_location_id_to_name, lookup_any_location_name_to_id
|
||||||
|
@ -55,6 +57,7 @@ class Client(Endpoint):
|
||||||
self.messageprocessor = client_message_processor(ctx, self)
|
self.messageprocessor = client_message_processor(ctx, self)
|
||||||
self.ctx = weakref.ref(ctx)
|
self.ctx = weakref.ref(ctx)
|
||||||
|
|
||||||
|
team_slot = typing.Tuple[int, int]
|
||||||
|
|
||||||
class Context(Node):
|
class Context(Node):
|
||||||
simple_options = {"hint_cost": int,
|
simple_options = {"hint_cost": int,
|
||||||
|
@ -75,7 +78,8 @@ class Context(Node):
|
||||||
self.data_filename = None
|
self.data_filename = None
|
||||||
self.save_filename = None
|
self.save_filename = None
|
||||||
self.saving = False
|
self.saving = False
|
||||||
self.player_names = {}
|
self.player_names: typing.Dict[team_slot, str] = {}
|
||||||
|
self.player_name_lookup: typing.Dict[str, team_slot] = {}
|
||||||
self.connect_names = {} # names of slots clients can connect to
|
self.connect_names = {} # names of slots clients can connect to
|
||||||
self.allow_forfeits = {}
|
self.allow_forfeits = {}
|
||||||
self.remote_items = set()
|
self.remote_items = set()
|
||||||
|
@ -87,21 +91,21 @@ class Context(Node):
|
||||||
self.server = None
|
self.server = None
|
||||||
self.countdown_timer = 0
|
self.countdown_timer = 0
|
||||||
self.received_items = {}
|
self.received_items = {}
|
||||||
self.name_aliases: typing.Dict[typing.Tuple[int, int], str] = {}
|
self.name_aliases: typing.Dict[team_slot, str] = {}
|
||||||
self.location_checks = collections.defaultdict(set)
|
self.location_checks = collections.defaultdict(set)
|
||||||
self.hint_cost = hint_cost
|
self.hint_cost = hint_cost
|
||||||
self.location_check_points = location_check_points
|
self.location_check_points = location_check_points
|
||||||
self.hints_used = collections.defaultdict(int)
|
self.hints_used = collections.defaultdict(int)
|
||||||
self.hints: typing.Dict[typing.Tuple[int, int], typing.Set[NetUtils.Hint]] = collections.defaultdict(set)
|
self.hints: typing.Dict[team_slot, typing.Set[NetUtils.Hint]] = collections.defaultdict(set)
|
||||||
self.forfeit_mode: str = forfeit_mode
|
self.forfeit_mode: str = forfeit_mode
|
||||||
self.remaining_mode: str = remaining_mode
|
self.remaining_mode: str = remaining_mode
|
||||||
self.item_cheat = item_cheat
|
self.item_cheat = item_cheat
|
||||||
self.running = True
|
self.running = True
|
||||||
self.client_activity_timers: typing.Dict[
|
self.client_activity_timers: typing.Dict[
|
||||||
typing.Tuple[int, int], datetime.datetime] = {} # datetime of last new item check
|
team_slot, datetime.datetime] = {} # datetime of last new item check
|
||||||
self.client_connection_timers: typing.Dict[
|
self.client_connection_timers: typing.Dict[
|
||||||
typing.Tuple[int, int], datetime.datetime] = {} # datetime of last connection
|
team_slot, datetime.datetime] = {} # datetime of last connection
|
||||||
self.client_game_state: typing.Dict[typing.Tuple[int, int], int] = collections.defaultdict(int)
|
self.client_game_state: typing.Dict[team_slot, int] = collections.defaultdict(int)
|
||||||
self.er_hint_data: typing.Dict[int, typing.Dict[int, str]] = {}
|
self.er_hint_data: typing.Dict[int, typing.Dict[int, str]] = {}
|
||||||
self.auto_shutdown = auto_shutdown
|
self.auto_shutdown = auto_shutdown
|
||||||
self.commandprocessor = ServerCommandProcessor(self)
|
self.commandprocessor = ServerCommandProcessor(self)
|
||||||
|
@ -111,7 +115,7 @@ class Context(Node):
|
||||||
self.auto_saver_thread = None
|
self.auto_saver_thread = None
|
||||||
self.save_dirty = False
|
self.save_dirty = False
|
||||||
self.tags = ['AP']
|
self.tags = ['AP']
|
||||||
self.games = {}
|
self.games: typing.Dict[int, str] = {}
|
||||||
self.minimum_client_versions: typing.Dict[int, Utils.Version] = {}
|
self.minimum_client_versions: typing.Dict[int, Utils.Version] = {}
|
||||||
self.seed_name = ""
|
self.seed_name = ""
|
||||||
|
|
||||||
|
@ -147,7 +151,8 @@ class Context(Node):
|
||||||
|
|
||||||
for team, names in enumerate(decoded_obj['names']):
|
for team, names in enumerate(decoded_obj['names']):
|
||||||
for player, name in enumerate(names, 1):
|
for player, name in enumerate(names, 1):
|
||||||
self.player_names[(team, player)] = name
|
self.player_names[team, player] = name
|
||||||
|
self.player_name_lookup[name] = team, player
|
||||||
self.seed_name = decoded_obj["seed_name"]
|
self.seed_name = decoded_obj["seed_name"]
|
||||||
self.connect_names = decoded_obj['connect_names']
|
self.connect_names = decoded_obj['connect_names']
|
||||||
self.remote_items = decoded_obj['remote_items']
|
self.remote_items = decoded_obj['remote_items']
|
||||||
|
@ -573,8 +578,7 @@ def json_format_send_event(net_item: NetworkItem, receiving_player: int):
|
||||||
"item": net_item}
|
"item": net_item}
|
||||||
|
|
||||||
|
|
||||||
def get_intended_text(input_text: str, possible_answers: typing.Iterable[str] = all_console_names) -> typing.Tuple[
|
def get_intended_text(input_text: str, possible_answers) -> typing.Tuple[str, bool, str]:
|
||||||
str, bool, str]:
|
|
||||||
picks = fuzzy_process.extract(input_text, possible_answers, limit=2)
|
picks = fuzzy_process.extract(input_text, possible_answers, limit=2)
|
||||||
if len(picks) > 1:
|
if len(picks) > 1:
|
||||||
dif = picks[0][1] - picks[1][1]
|
dif = picks[0][1] - picks[1][1]
|
||||||
|
@ -865,7 +869,8 @@ class ClientMessageProcessor(CommonCommandProcessor):
|
||||||
def _cmd_getitem(self, item_name: str) -> bool:
|
def _cmd_getitem(self, item_name: str) -> bool:
|
||||||
"""Cheat in an item, if it is enabled on this server"""
|
"""Cheat in an item, if it is enabled on this server"""
|
||||||
if self.ctx.item_cheat:
|
if self.ctx.item_cheat:
|
||||||
item_name, usable, response = get_intended_text(item_name, Items.item_table.keys())
|
item_name, usable, response = get_intended_text(item_name,
|
||||||
|
proxy_worlds[self.ctx.games[self.client.slot]].item_names)
|
||||||
if usable:
|
if usable:
|
||||||
new_item = NetworkItem(Items.item_table[item_name][2], -1, self.client.slot)
|
new_item = NetworkItem(Items.item_table[item_name][2], -1, self.client.slot)
|
||||||
get_received_items(self.ctx, self.client.team, self.client.slot).append(new_item)
|
get_received_items(self.ctx, self.client.team, self.client.slot).append(new_item)
|
||||||
|
@ -1224,17 +1229,16 @@ class ServerCommandProcessor(CommonCommandProcessor):
|
||||||
"""Sends an item to the specified player"""
|
"""Sends an item to the specified player"""
|
||||||
seeked_player, usable, response = get_intended_text(player_name, self.ctx.player_names.values())
|
seeked_player, usable, response = get_intended_text(player_name, self.ctx.player_names.values())
|
||||||
if usable:
|
if usable:
|
||||||
|
team, slot = self.ctx.player_name_lookup[seeked_player]
|
||||||
item = " ".join(item_name)
|
item = " ".join(item_name)
|
||||||
item, usable, response = get_intended_text(item, all_items)
|
item, usable, response = get_intended_text(item, proxy_worlds[self.ctx.games[slot]].item_names)
|
||||||
if usable:
|
if usable:
|
||||||
for client in self.ctx.endpoints:
|
new_item = NetworkItem(lookup_any_item_name_to_id[item], -1, 0)
|
||||||
if client.name == seeked_player:
|
get_received_items(self.ctx, team, slot).append(new_item)
|
||||||
new_item = NetworkItem(lookup_any_item_name_to_id[item], -1, 0)
|
self.ctx.notify_all('Cheat console: sending "' + item + '" to ' +
|
||||||
get_received_items(self.ctx, client.team, client.slot).append(new_item)
|
self.ctx.get_aliased_name(team, slot))
|
||||||
self.ctx.notify_all('Cheat console: sending "' + item + '" to ' +
|
send_new_items(self.ctx)
|
||||||
self.ctx.get_aliased_name(client.team, client.slot))
|
return True
|
||||||
send_new_items(self.ctx)
|
|
||||||
return True
|
|
||||||
else:
|
else:
|
||||||
self.output(response)
|
self.output(response)
|
||||||
return False
|
return False
|
||||||
|
@ -1249,7 +1253,7 @@ class ServerCommandProcessor(CommonCommandProcessor):
|
||||||
for (team, slot), name in self.ctx.player_names.items():
|
for (team, slot), name in self.ctx.player_names.items():
|
||||||
if name == seeked_player:
|
if name == seeked_player:
|
||||||
item = " ".join(item_or_location)
|
item = " ".join(item_or_location)
|
||||||
item, usable, response = get_intended_text(item)
|
item, usable, response = get_intended_text(item, all_console_names)
|
||||||
if usable:
|
if usable:
|
||||||
if item in Items.item_name_groups:
|
if item in Items.item_name_groups:
|
||||||
hints = []
|
hints = []
|
||||||
|
|
Loading…
Reference in New Issue