Skip to content

Commit

Permalink
Discover the byte that is set when queueing orders
Browse files Browse the repository at this point in the history
  • Loading branch information
Garanas committed May 8, 2024
1 parent 8558a85 commit a5467f0
Show file tree
Hide file tree
Showing 8 changed files with 46 additions and 11 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@
import com.faforever.commons.replay.body.ReplayBody;
import com.faforever.commons.replay.header.ReplayHeader;

public record ReplayContainer(ReplayMetadata metadata, ReplayHeader header, ReplayBody body, byte[] bytes) {
public record ReplayContainer(ReplayMetadata metadata, ReplayHeader header, ReplayBody body) {
}
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ private static ReplayContainer loadSCFAReplayFromMemory(ReplayMetadata metadata,
throw new EOFException();
}

return new ReplayContainer(metadata, replayHeader, replayBody, scfaReplayBytes);
return new ReplayContainer(metadata, replayHeader, replayBody);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -182,9 +182,9 @@ record CommandFormation(int formationId, float orientation, float px, float py,
* @param commandTarget
* @param commandFormation
* @param blueprintId
* @param parametersLua
* @param taskParameters
*/
record CommandData(int commandId, ReplayBodyEventCommandType commandType, CommandTarget commandTarget,
CommandFormation commandFormation, String blueprintId, LuaTable parametersLua) {
CommandFormation commandFormation, String blueprintId, LuaTable taskParameters, boolean addToQueue) {
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ public class ReplayBodyParser {

@Contract(pure = true)
public static List<ReplayBodyEvent> parseTokens(List<ReplayBodyToken> tokens) throws IOException {
return tokens.stream().parallel().map((token) -> {
return tokens.stream().map((token) -> {
try {
return parseToken(token);
} catch (Exception exception) {
Expand Down Expand Up @@ -91,21 +91,17 @@ private static ReplayBodyEvent.CommandData parseCommandData(LittleEndianDataInpu

String blueprintId = Utils.readString(stream);
byte[] arg4 = stream.readNBytes(12);
byte[] arg5 = new byte[0];

LuaTable parametersLua = Utils.parseLua(stream);
if (!(parametersLua instanceof LuaTable.Nil)) {
arg5 = stream.readNBytes(1);
}
boolean addToQueue = stream.readByte() > 0;

return new ReplayBodyEvent.CommandData(
commandId, commandType, commandTarget, commandFormation, blueprintId, parametersLua
commandId, commandType, commandTarget, commandFormation, blueprintId, parametersLua, addToQueue
);
}

@Contract(pure = true)
private static ReplayBodyEvent parseToken(ReplayBodyToken token) throws IOException {

try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream((new ByteArrayInputStream(token.tokenContent())))) {
ReplayBodyEvent event = switch (token.tokenId()) {
case CMDST_ADVANCE -> {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,39 @@ public void parseBinary04() throws CompressorException, IOException {
);
}

@Test
public void parseBinary05() throws CompressorException, IOException {
assertDoesNotThrow(
() -> {
Path fafReplayFile = temporaryFolder.resolve("22451957.fafreplay");
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/replay/load/22451957.fafreplay")), fafReplayFile);
ReplayContainer fafReplayContainer = ReplayLoader.loadFAFReplayFromDisk(fafReplayFile);
}
);
}

@Test
public void parseBinary06() throws CompressorException, IOException {
assertDoesNotThrow(
() -> {
Path fafReplayFile = temporaryFolder.resolve("22453414.fafreplay");
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/replay/load/22453414.fafreplay")), fafReplayFile);
ReplayContainer fafReplayContainer = ReplayLoader.loadFAFReplayFromDisk(fafReplayFile);
}
);
}

@Test
public void parseBinary07() throws CompressorException, IOException {
assertDoesNotThrow(
() -> {
Path fafReplayFile = temporaryFolder.resolve("22453511.fafreplay");
Files.copy(Objects.requireNonNull(getClass().getResourceAsStream("/replay/load/22453511.fafreplay")), fafReplayFile);
ReplayContainer fafReplayContainer = ReplayLoader.loadFAFReplayFromDisk(fafReplayFile);
}
);
}

@Test
public void compareBinary01() throws CompressorException, IOException {
Path fafReplayFile = temporaryFolder.resolve("22338092.fafreplay");
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"compression":null,"host":"Jip","uid":22451957,"title":"epic 4v4 1000+","mapname":"scmp_026","options":null,"teams":{"3=[32238]":["Jip"]},"complete":true,"recorder":"Jip","state":"CLOSED","game_type":"UNKNOWN","featured_mod":"faf","max_players":4,"num_players":1,"sim_mods":{"fnewm028-v093-55b4-92b6-64398e7ge43f":"M28AI","62e2j64a-TOMA-3652-01370-146as555a8u3":"Total Mayhem"},"featured_mod_versions":{},"version_info":{"lobby":"dfaf-2024.1.2-alpha-1"},"game_end":1.715186273008E9,"time":0.0,"launched_at":1.715186248175E9}
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
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
{"compression":null,"host":"Jip","uid":22453414,"title":"epic 4v4 1000+","mapname":"scmp_026","options":null,"teams":{"3=[32238]":["Jip"]},"complete":true,"recorder":"Jip","state":"CLOSED","game_type":"UNKNOWN","featured_mod":"faf","max_players":4,"num_players":1,"sim_mods":{"fnewm028-v093-55b4-92b6-64398e7ge43f":"M28AI","62e2j64a-TOMA-3652-01370-146as555a8u3":"Total Mayhem"},"featured_mod_versions":{},"version_info":{"lobby":"dfaf-2024.1.2-alpha-1"},"game_end":1.715198021766E9,"time":0.0,"launched_at":1.715197987223E9}
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
Loading

0 comments on commit a5467f0

Please sign in to comment.