diff --git a/faf-commons-data/src/main/java/com/faforever/commons/replay/header/GameMod.java b/faf-commons-data/src/main/java/com/faforever/commons/replay/header/GameMod.java index 6a111f36..acc8b2c9 100644 --- a/faf-commons-data/src/main/java/com/faforever/commons/replay/header/GameMod.java +++ b/faf-commons-data/src/main/java/com/faforever/commons/replay/header/GameMod.java @@ -2,15 +2,17 @@ /** * Populated by the game mods field of the table that is passed to `CLobby:LaunchGame` + * * @param location + * @param icon + * @param copyright * @param name * @param description * @param author * @param uid * @param version * @param url - * @param urlGithub */ -public record GameMod(String location, String name, String description, String author, String uid, String version, - String url, String urlGithub) { +public record GameMod(String location, String icon, String copyright, String name, String description, String author, + String uid, Integer version, String url) { } diff --git a/faf-commons-data/src/main/java/com/faforever/commons/replay/header/ReplayHeaderParser.java b/faf-commons-data/src/main/java/com/faforever/commons/replay/header/ReplayHeaderParser.java index 23de7cf1..eff4af4a 100644 --- a/faf-commons-data/src/main/java/com/faforever/commons/replay/header/ReplayHeaderParser.java +++ b/faf-commons-data/src/main/java/com/faforever/commons/replay/header/ReplayHeaderParser.java @@ -71,9 +71,29 @@ public static ReplayHeader parse(LittleEndianDataInputStream dataStream) throws @Contract(pure = true) private static @Nullable List parseMod(byte[] bytes) throws IOException { try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream((new ByteArrayInputStream(bytes)))) { - LuaData mod = parseLua(stream); - - // TODO: needs implementation + LuaData modInfo = parseLua(stream); + + if (modInfo instanceof LuaData.Table table) { + return table.value().values().stream().map( + e -> { + if (e instanceof LuaData.Table luaModInfo) { + return new GameMod( + luaModInfo.getString("location"), + luaModInfo.getString("icon"), + luaModInfo.getString("copyright"), + luaModInfo.getString("name"), + luaModInfo.getString("description"), + luaModInfo.getString("author"), + luaModInfo.getString("uid"), + luaModInfo.getInteger("version"), + luaModInfo.getString("url") + ); + } + + return null; + } + ).toList(); + } return null; } diff --git a/faf-commons-data/src/test/java/com/faforever/commons/replay/LoadReplayLoaderTest.java b/faf-commons-data/src/test/java/com/faforever/commons/replay/LoadReplayLoaderTest.java index bf0fbeaa..15585d95 100644 --- a/faf-commons-data/src/test/java/com/faforever/commons/replay/LoadReplayLoaderTest.java +++ b/faf-commons-data/src/test/java/com/faforever/commons/replay/LoadReplayLoaderTest.java @@ -150,6 +150,25 @@ public void parseBinary07() throws CompressorException, IOException { ); } + @Test + public void parseBinary08() throws CompressorException, IOException { + assertDoesNotThrow( + () -> { + Path fafReplayFile = temporaryFolder.resolve("mods.fafreplay"); + Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/replay/mods.fafreplay")), fafReplayFile); + ReplayContainer fafReplayContainer = ReplayLoader.loadFAFReplayFromDisk(fafReplayFile); + + assertEquals(2, fafReplayContainer.header().mods().size()); + + assertNoUnprocessedTokens(fafReplayContainer); + assertNoErrorTokens(fafReplayContainer); + + List chatMessages = ReplaySemantics.findChatMessages(fafReplayContainer.header().sources(), fafReplayContainer.registeredEvents()); + assertEquals(3, chatMessages.size()); + } + ); + } + @Test public void compareBinary01() throws CompressorException, IOException { Path fafReplayFile = temporaryFolder.resolve("22338092.fafreplay"); diff --git a/faf-commons-data/src/test/resources/replay/mods.fafreplay b/faf-commons-data/src/test/resources/replay/mods.fafreplay new file mode 100644 index 00000000..e3925d79 --- /dev/null +++ b/faf-commons-data/src/test/resources/replay/mods.fafreplay @@ -0,0 +1,2 @@ +{"compression":null,"host":"Jip","uid":22537068,"title":"epic 4v4 1000+","mapname":"project_tumulus.v0004","options":null,"teams":{"3=[32238]":["Jip"]},"complete":true,"recorder":"Jip","state":"CLOSED","game_type":"UNKNOWN","featured_mod":"fafdevelop","max_players":2,"num_players":1,"sim_mods":{"d883189d-c556-4d68-b1c8-6ad201b3f7ad":"4x Build Rate","fnewm028-v096-55b4-92b6-64398e7ge43f":"M28AI"},"featured_mod_versions":{},"version_info":{"lobby":"dfaf-2024.1.2-alpha-1"},"game_end":1.716218264861E9,"time":0.0,"launched_at":1.716218212527E9} +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 \ No newline at end of file