Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Network: implement 0.4 marked compatibility removals #757

Merged
merged 12 commits into from
Dec 11, 2022
4 changes: 0 additions & 4 deletions Main.py
Original file line number Diff line number Diff line change
Expand Up @@ -362,10 +362,6 @@ def precollect_hint(location):
"names": names, # TODO: remove around 0.2.5 in favor of slot_info
"games": games, # TODO: remove around 0.2.5 in favor of slot_info
"connect_names": {name: (0, player) for player, name in world.player_name.items()},
"remote_items": {player for player in world.player_ids if
world.worlds[player].remote_items},
"remote_start_inventory": {player for player in world.player_ids if
world.worlds[player].remote_start_inventory},
"locations": locations_data,
"checks_in_area": checks_in_area,
"server_options": baked_server_options,
Expand Down
34 changes: 7 additions & 27 deletions MultiServer.py
Original file line number Diff line number Diff line change
Expand Up @@ -146,8 +146,6 @@ def __init__(self, host: str, port: int, server_password: str, password: str, lo
self.player_name_lookup: typing.Dict[str, team_slot] = {}
self.connect_names = {} # names of slots clients can connect to
self.allow_forfeits = {}
self.remote_items = set()
self.remote_start_inventory = set()
# player location_id item_id target_player_id
self.locations = {}
self.host = host
Expand Down Expand Up @@ -362,8 +360,6 @@ def _load(self, decoded_obj: dict, use_embedded_server_options: bool):
self.seed_name = decoded_obj["seed_name"]
self.random.seed(self.seed_name)
self.connect_names = decoded_obj['connect_names']
self.remote_items = decoded_obj['remote_items']
self.remote_start_inventory = decoded_obj.get('remote_start_inventory', decoded_obj['remote_items'])
self.locations = decoded_obj['locations']
self.slot_data = decoded_obj['slot_data']
self.er_hint_data = {int(player): {int(address): name for address, name in loc_data.items()}
Expand Down Expand Up @@ -532,7 +528,7 @@ def set_save(self, savedata: dict):

if "stored_data" in savedata:
self.stored_data = savedata["stored_data"]
# count items and slots from lists for item_handling = remote
# count items and slots from lists for items_handling = remote
logging.info(
f'Loaded save file with {sum([len(v) for k, v in self.received_items.items() if k[2]])} received items '
f'for {sum(k[2] for k in self.received_items)} players')
Expand Down Expand Up @@ -676,19 +672,14 @@ async def on_client_connected(ctx: Context, client: Client):
await ctx.send_msgs(client, [{
'cmd': 'RoomInfo',
'password': bool(ctx.password),
# TODO remove around 0.4
'players': players,
# TODO convert to list of games present in 0.4
'games': [ctx.games[x] for x in range(1, len(ctx.games) + 1)],
'games': {ctx.games[x] for x in range(1, len(ctx.games) + 1)},
# tags are for additional features in the communication.
# Name them by feature or fork, as you feel is appropriate.
'tags': ctx.tags,
'version': Utils.version_tuple,
'permissions': get_permissions(ctx),
'hint_cost': ctx.hint_cost,
'location_check_points': ctx.location_check_points,
'datapackage_version': sum(game_data["version"] for game_data in ctx.gamespackage.values())
if all(game_data["version"] for game_data in ctx.gamespackage.values()) else 0,
'datapackage_versions': {game: game_data["version"] for game, game_data
in ctx.gamespackage.items()},
'seed_name': ctx.seed_name,
Expand Down Expand Up @@ -1502,27 +1493,16 @@ async def process_client_cmd(ctx: Context, client: Client, args: dict):
else:
team, slot = ctx.connect_names[args['name']]
game = ctx.games[slot]
ignore_game = "IgnoreGame" in args["tags"] or ( # IgnoreGame is deprecated. TODO: remove after 0.3.3?
("TextOnly" in args["tags"] or "Tracker" in args["tags"]) and not args.get("game"))
ignore_game = ("TextOnly" in args["tags"] or "Tracker" in args["tags"]) and not args.get("game")
if not ignore_game and args['game'] != game:
errors.add('InvalidGame')
minver = min_client_version if ignore_game else ctx.minimum_client_versions[slot]
if minver > args['version']:
errors.add('IncompatibleVersion')
if args.get('items_handling', None) is None:
# fall back to load from multidata
client.no_items = False
client.remote_items = slot in ctx.remote_items
client.remote_start_inventory = slot in ctx.remote_start_inventory
await ctx.send_msgs(client, [{
"cmd": "Print", "text":
"Warning: Client is not sending items_handling flags, "
"which will not be supported in the future."}])
else:
try:
client.items_handling = args['items_handling']
except (ValueError, TypeError):
errors.add('InvalidItemsHandling')
try:
client.items_handling = args['items_handling']
except (ValueError, TypeError):
errors.add('InvalidItemsHandling')

# only exact version match allowed
if ctx.compatibility == 0 and args['version'] != version_tuple:
Expand Down
2 changes: 1 addition & 1 deletion SNIClient.py
Original file line number Diff line number Diff line change
Expand Up @@ -1050,7 +1050,7 @@ async def game_watcher(ctx: Context):
# versions lower than 0.3.0 dont have item handling flag nor remote item support
romVersion = int(game_name[2:5].decode('UTF-8'))
if romVersion < 30:
ctx.items_handling = 0b001 # full local
ctx.items_handling = 0b001 # full local
else:
item_handling = await snes_read(ctx, SM_REMOTE_ITEM_FLAG_ADDR, 1)
ctx.items_handling = 0b001 if item_handling is None else item_handling[0]
Expand Down
3 changes: 2 additions & 1 deletion WebHostLib/api/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,10 +39,11 @@ def get_datapackage():

@api_endpoints.route('/datapackage_version')
@cache.cached()

def get_datapackage_versions():
from worlds import network_data_package, AutoWorldRegister

version_package = {game: world.data_version for game, world in AutoWorldRegister.world_types.items()}
version_package["version"] = network_data_package["version"]
return version_package


Expand Down
1 change: 0 additions & 1 deletion docs/network protocol.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,6 @@ Sent to clients when they connect to an Archipelago server.
| hint_cost | int | The amount of points it costs to receive a hint from the server. |
| location_check_points | int | The amount of hint points you receive per item/location check completed. ||
| games | list\[str\] | List of games present in this multiworld. |
| datapackage_version | int | Sum of individual games' datapackage version. Deprecated. Use `datapackage_versions` instead. |
| datapackage_versions | dict\[str, int\] | Data versions of the individual games' data packages the server will send. Used to decide which games' caches are outdated. See [Data Package Contents](#Data-Package-Contents). |
| seed_name | str | uniquely identifying name of this generation |
| time | float | Unix time stamp of "now". Send for time synchronization if wanted for things like the DeathLink Bounce. |
Expand Down
12 changes: 0 additions & 12 deletions worlds/AutoWorld.py
Original file line number Diff line number Diff line change
Expand Up @@ -149,18 +149,6 @@ class World(metaclass=AutoWorldRegister):

hint_blacklist: FrozenSet[str] = frozenset() # any names that should not be hintable

# NOTE: remote_items and remote_start_inventory are now available in the network protocol for the client to set.
# These values will be removed.
# if a world is set to remote_items, then it just needs to send location checks to the server and the server
# sends back the items
# if a world is set to remote_items = False, then the server never sends an item where receiver == finder,
# the client finds its own items in its own world.
remote_items: bool = True

# If remote_start_inventory is true, the start_inventory/world.precollected_items is sent on connection,
# otherwise the world implementation is in charge of writing the items to their output data.
remote_start_inventory: bool = True

# For games where after a victory it is impossible to go back in and get additional/remaining Locations checked.
# this forces forfeit: auto for those games.
forced_auto_forfeit: bool = False
Expand Down
2 changes: 0 additions & 2 deletions worlds/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,11 @@ class WorldSource(typing.NamedTuple):
lookup_any_location_id_to_name.update(world.location_id_to_name)

network_data_package = {
"version": sum(world.data_version for world in AutoWorldRegister.world_types.values()),
"games": games,
}

# Set entire datapackage to version 0 if any of them are set to 0
if any(not world.data_version for world in AutoWorldRegister.world_types.values()):
network_data_package["version"] = 0
import logging

logging.warning(f"Datapackage is in custom mode. Custom Worlds: "
Expand Down
2 changes: 0 additions & 2 deletions worlds/alttp/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -119,8 +119,6 @@ class ALTTPWorld(World):
location_name_to_id = lookup_name_to_id

data_version = 8
remote_items: bool = False
remote_start_inventory: bool = False
required_client_version = (0, 3, 2)
web = ALTTPWeb()

Expand Down
1 change: 1 addition & 0 deletions worlds/ff1/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ class FF1World(World):
option_definitions = ff1_options
game = "Final Fantasy"
topology_present = False

remote_items = True
Berserker66 marked this conversation as resolved.
Show resolved Hide resolved
data_version = 2
remote_start_inventory = True
Berserker66 marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
2 changes: 0 additions & 2 deletions worlds/oot/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,8 +100,6 @@ class OOTWorld(World):
item_name_to_id = {item_name: oot_data_to_ap_id(data, False) for item_name, data in item_table.items() if
data[2] is not None}
location_name_to_id = location_name_to_id
remote_items: bool = False
remote_start_inventory: bool = False
web = OOTWeb()

data_version = 2
Expand Down
3 changes: 0 additions & 3 deletions worlds/sm/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -85,9 +85,6 @@ class SMWorld(World):
location_name_to_id = {key: locations_start_id + value.Id for key, value in locationsDict.items() if value.Id != None}
web = SMWeb()

remote_items: bool = False
remote_start_inventory: bool = False

# changes to client DeathLink handling for 0.2.1
# changes to client Remote Item handling for 0.2.6
required_client_version = (0, 2, 6)
Expand Down
7 changes: 2 additions & 5 deletions worlds/smz3/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -74,9 +74,6 @@ class SMZ3World(World):
for key, value in TotalSMZ3World(Config(), "", 0, "").locationLookup.items()}
web = SMZ3Web()

remote_items: bool = False
remote_start_inventory: bool = False

locationNamesGT: Set[str] = {loc.Name for loc in GanonsTower(None, None).Locations}

# first added for 0.2.6
Expand Down Expand Up @@ -484,9 +481,9 @@ def remove(self, state: CollectionState, item: Item) -> bool:
return False

def create_item(self, name: str) -> Item:
return SMZ3Item(name,
return SMZ3Item(name,
ItemClassification.progression if SMZ3World.isProgression(TotalSMZ3Item.ItemType[name]) else ItemClassification.filler,
TotalSMZ3Item.ItemType[name], self.item_name_to_id[name],
TotalSMZ3Item.ItemType[name], self.item_name_to_id[name],
self.player,
TotalSMZ3Item.Item(TotalSMZ3Item.ItemType[name], self))

Expand Down
1 change: 0 additions & 1 deletion worlds/soe/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,7 +153,6 @@ class SoEWorld(World):
game: str = "Secret of Evermore"
option_definitions = soe_options
topology_present = False
remote_items = False
data_version = 3
web = SoEWebWorld()
required_client_version = (0, 3, 3)
Expand Down
1 change: 0 additions & 1 deletion worlds/timespinner/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ class TimespinnerWorld(World):
option_definitions = timespinner_options
game = "Timespinner"
topology_present = True
remote_items = False
data_version = 10
web = TimespinnerWebWorld()

Expand Down