FAForever / server

The servercode for the Forged Alliance Forever lobby
http://www.faforever.com
GNU General Public License v3.0
66 stars 61 forks source link

Coop replays missing mapname in the replay file #372

Open speed2CZ opened 5 years ago

speed2CZ commented 5 years ago

When opening the replay files I found out that the coop replays are missing the mapname. The client is then not showing them properly in the online vault, and downlord's client can't even lauch the replays.

I dont know if it would completelly fix the issue with coop replays, but it would surely be a good start.

Some examples of the replays files: Coop Game:

{"num_players": 1, "featured_mod_versions": {"1": 55, "2": 55, "3": 49, "4": 49, "5": 49, "6": 49, "7": 51, "8": 49, "9": 50, "10": 50, "11": 50, "12": 50, "13": 50, "14": 50, "15": 49, "16": 49, "17": 50, "18": 51, "19": 50, "20": 50, "21": 51, "22": 49}, "game_end": 1544305811.890091, "uid": 8945286, "title": "Wastefield's game", "game_type": 3, "teams": {}, "mapname": "", "featured_mod": "coop", "complete": true}

"mapname": ""

FAF game

{"num_players": 2, "featured_mod_versions": {}, "game_end": 1544306269.963174, "uid": 8945278, "title": "FaReNoy Vs bisq01", "game_type": 0, "teams": {"1": ["FaReNoy"]}, "mapname": "x1mp_017", "host": "FaReNoy", "featured_mod": "ladder1v1", "complete": true}

"mapname": "x1mp_017"

Brutus5000 commented 5 years ago

How does the python client know which map to load if the mapname is not specified? Are all maps in the feature mod files?

Wesmania commented 5 years ago

I believe there's a mapname in the lua replay header. Some data is duplicated between it and the json header, probably to make it easier for the client do parse replays in bulk.

Wesmania commented 5 years ago

This is the query that the legacy replayserver does to pull out info including the mapname:

"SELECT game_featuredMods.gamemod, gameType, filename, gameName, host, login, playerId, AI, team FROM `game_stats` LEFT JOIN game_player_stats ON `game_player_stats`.`gameId` = game_stats.id LEFT JOIN table_map ON `game_stats`.`mapId` = table_map.id LEFT JOIN login ON login.id = `game_player_stats`.`playerId`  LEFT JOIN  game_featuredMods ON `game_stats`.`gameMod` = game_featuredMods.id WHERE game_stats.id = %i" % self.uid
Askaholic commented 5 years ago

Looks like the legacy replay server tries to get filename from table table_map which appears to be deprecated. The Java API uses table map_version instead to store the filename.

The map x1mp_017 is "Eye of the Storm" which is a super old map so I would bet that it has an entry in the table_map table and therefore the filename is found by the replay server.

@speed2CZ Which map is that coop game using? Was it maybe uploaded using the Java API and therefore has no entry in table_map?

speed2CZ commented 5 years ago

coop has its own maps, each mission is just a map with extended script. Its not uploaded as a normal map. They are taken from the git repo https://github.com/FAForever/faf-coop-maps/ and some script in the server renames then to correct version and packs them

Askaholic commented 5 years ago

Root cause of the issue:

Here is where the replay server get's the map name: https://github.com/FAForever/legacy-replay-server/blob/1c9d06c9d09a76b641800a85ccdc14442b48945a/liveReplay/replays.py#L148. It dumps that to a file (on line 283).

Solutions:

  1. Manually add the missing maps to the map_version and table_map tables.
    • Pro: Requires no code changes. Can be done immediately.
    • Con: Not scalable
  2. Have the server automatically create new entries in map_version and table_map tables for maps that it hasn't seen before.
    • Pro: Will support all future maps
    • Con: Would lead to inconsistencies where the map name exists in the database, but the files don't exist on the content server.