Skip to content

Commit

Permalink
Add order warnings, try with resources, whitespace, and remove unnece…
Browse files Browse the repository at this point in the history
…ssary public
  • Loading branch information
Sheikah45 committed May 5, 2024
1 parent deb9e70 commit 1f548d8
Show file tree
Hide file tree
Showing 5 changed files with 144 additions and 138 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -52,14 +52,14 @@ public class ReplayDataParser {
@Getter
private Map<String, Map<String, ?>> mods;
@Getter
private final Map<Integer, Map<String, Object>> armies = new HashMap<>();
private final Map<Integer, Map<String, Object>> armies = new HashMap<>();
private int randomSeed;
@Getter
private final List<ChatMessage> chatMessages = new ArrayList<>();
private final List<ChatMessage> chatMessages = new ArrayList<>();
@Getter
private final List<ModeratorEvent> moderatorEvents = new ArrayList<>();
private final List<ModeratorEvent> moderatorEvents = new ArrayList<>();
@Getter
private final Map<Integer, Map<Integer, AtomicInteger>> commandsPerMinuteByPlayer = new HashMap<>();
private final Map<Integer, Map<Integer, AtomicInteger>> commandsPerMinuteByPlayer = new HashMap<>();

private int ticks;

Expand Down Expand Up @@ -368,8 +368,8 @@ private void parseGiveResourcesToPlayer(LuaData.Table lua) {
return;
}

int fromArmy = (int)(luaFromArmy - 1);
if ((int) fromArmy == -2) {
int fromArmy = (int) luaFromArmy - 1;
if (fromArmy == -2) {
return;
}

Expand Down Expand Up @@ -410,7 +410,7 @@ void parseModeratorEvent(LuaData.Table lua, Integer player) {
}

if (lua.value().get("From") instanceof LuaData.Number(float luaFrom)) {
fromArmy = (int)luaFrom - 1;
fromArmy = (int) luaFrom - 1;


if (fromArmy != -2) {
Expand Down Expand Up @@ -441,10 +441,10 @@ private Duration tickToTime(int tick) {

private void parse() throws IOException, CompressorException {
readReplayData(path);
LittleEndianDataInputStream dataStream = new LittleEndianDataInputStream(new ByteArrayInputStream(data));
parseHeader(dataStream);

tokens = Tokenizer.tokenize(dataStream);
try (LittleEndianDataInputStream dataStream = new LittleEndianDataInputStream(new ByteArrayInputStream(data))) {
parseHeader(dataStream);
tokens = Tokenizer.tokenize(dataStream);
}
events = Parser.parseTokens(tokens);
interpretEvents(events);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
package com.faforever.commons.replay.body.event;

import lombok.Getter;

@Getter
public enum EventCommandType {
// Order is crucial
NONE("NONE"),
STOP("Stop"),
MOVE("Move"),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,10 @@

public sealed interface LuaData {

public record Number(float value) implements LuaData {}
public record String(java.lang.String value) implements LuaData {}
public record Nil() implements LuaData {}
public record Table(Map<java.lang.String, LuaData> value) implements LuaData {}
public record Bool(boolean value) implements LuaData {}
record Number(float value) implements LuaData {}
record String(java.lang.String value) implements LuaData {}
record Nil() implements LuaData {}
record Table(Map<java.lang.String, LuaData> value) implements LuaData {}
record Bool(boolean value) implements LuaData {}

}
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import java.util.*;

public class Parser {
public static List<Event> parseTokens (List<Token> tokens) throws IOException {
public static List<Event> parseTokens(List<Token> tokens) throws IOException {
return tokens.stream().parallel().map((token) -> {
try {
return parseToken(token);
Expand Down Expand Up @@ -149,7 +149,7 @@ private static LuaData parseLua(LittleEndianDataInputStream dataStream) throws I
while (peek(dataStream) != LUA_TABLE_END) {
LuaData key = parseLua(dataStream);

switch(key) {
switch (key) {
case LuaData.String(String str) -> value.put(str, parseLua(dataStream));

case LuaData.Number(float num) -> value.put(String.valueOf(num), parseLua(dataStream));
Expand All @@ -167,163 +167,164 @@ private static LuaData parseLua(LittleEndianDataInputStream dataStream) throws I
}
}

private static Event parseToken(Token token) throws IOException {
private static Event parseToken(Token token) throws IOException {

LittleEndianDataInputStream stream = new LittleEndianDataInputStream((new ByteArrayInputStream(token.tokenContent())));

return switch (token.tokenId()) {
case CMDST_ADVANCE -> {
int ticks = stream.readInt();
yield new Event.Advance(ticks);
}

case CMDST_SET_COMMAND_SOURCE -> {
int playerIndex = stream.readByte();
yield new Event.SetCommandSource(playerIndex);
}
try (LittleEndianDataInputStream stream = new LittleEndianDataInputStream((new ByteArrayInputStream(token.tokenContent())))) {
return switch (token.tokenId()) {
case CMDST_ADVANCE -> {
int ticks = stream.readInt();
yield new Event.Advance(ticks);
}

case CMDST_COMMAND_SOURCE_TERMINATED -> new Event.CommandSourceTerminated();
case CMDST_SET_COMMAND_SOURCE -> {
int playerIndex = stream.readByte();
yield new Event.SetCommandSource(playerIndex);
}

case CMDST_VERIFY_CHECKSUM -> {
String hash = HexFormat.of().formatHex(stream.readNBytes(16));
int tick = stream.readInt();
case CMDST_COMMAND_SOURCE_TERMINATED -> new Event.CommandSourceTerminated();

yield new Event.VerifyChecksum(hash, tick);
}
case CMDST_VERIFY_CHECKSUM -> {
String hash = HexFormat.of().formatHex(stream.readNBytes(16));
int tick = stream.readInt();

case CMDST_REQUEST_PAUSE -> new Event.RequestPause();
yield new Event.VerifyChecksum(hash, tick);
}

case CMDST_RESUME -> new Event.RequestResume();
case CMDST_REQUEST_PAUSE -> new Event.RequestPause();

case CMDST_SINGLE_STEP -> new Event.SingleStep();
case CMDST_RESUME -> new Event.RequestResume();

case CMDST_CREATE_UNIT -> {
int playerIndex = stream.readByte();
String blueprintId = parseString(stream);
float px = stream.readFloat();
float pz = stream.readFloat();
float heading = stream.readFloat();
case CMDST_SINGLE_STEP -> new Event.SingleStep();

yield new Event.CreateUnit(playerIndex, blueprintId, px, pz, heading);
}
case CMDST_CREATE_UNIT -> {
int playerIndex = stream.readByte();
String blueprintId = parseString(stream);
float px = stream.readFloat();
float pz = stream.readFloat();
float heading = stream.readFloat();

case CMDST_CREATE_PROP -> {
String blueprintId = parseString(stream);
float px = stream.readFloat();
float pz = stream.readFloat();
float heading = stream.readFloat();
yield new Event.CreateUnit(playerIndex, blueprintId, px, pz, heading);
}

yield new Event.CreateProp(blueprintId, px, pz, heading);
}
case CMDST_CREATE_PROP -> {
String blueprintId = parseString(stream);
float px = stream.readFloat();
float pz = stream.readFloat();
float heading = stream.readFloat();

case CMDST_DESTROY_ENTITY -> {
int entityId = stream.readInt();
yield new Event.DestroyEntity(entityId);
}
yield new Event.CreateProp(blueprintId, px, pz, heading);
}

case CMDST_WARP_ENTITY -> {
int entityId = stream.readInt();
float px = stream.readFloat();
float py = stream.readFloat();
float pz = stream.readFloat();
yield new Event.WarpEntity(entityId, px, py, pz);
}
case CMDST_DESTROY_ENTITY -> {
int entityId = stream.readInt();
yield new Event.DestroyEntity(entityId);
}

case CMDST_PROCESS_INFO_PAIR -> {
int entityId = stream.read();
String arg1 = parseString(stream);
String arg2 = parseString(stream);
yield new Event.ProcessInfoPair(entityId, arg1, arg2);
}
case CMDST_WARP_ENTITY -> {
int entityId = stream.readInt();
float px = stream.readFloat();
float py = stream.readFloat();
float pz = stream.readFloat();
yield new Event.WarpEntity(entityId, px, py, pz);
}

case CMDST_ISSUE_COMMAND -> {
Event.CommandUnits commandUnits = parseCommandUnits(stream);
Event.CommandData commandData = parseCommandData(stream);
case CMDST_PROCESS_INFO_PAIR -> {
int entityId = stream.read();
String arg1 = parseString(stream);
String arg2 = parseString(stream);
yield new Event.ProcessInfoPair(entityId, arg1, arg2);
}

yield new Event.IssueCommand(commandUnits, commandData);
}
case CMDST_ISSUE_COMMAND -> {
Event.CommandUnits commandUnits = parseCommandUnits(stream);
Event.CommandData commandData = parseCommandData(stream);

case CMDST_ISSUE_FACTORY_COMMAND -> {
Event.CommandUnits commandUnits = parseCommandUnits(stream);
Event.CommandData commandData = parseCommandData(stream);
yield new Event.IssueCommand(commandUnits, commandData);
}

yield new Event.IssueFactoryCommand(commandUnits, commandData);
}
case CMDST_ISSUE_FACTORY_COMMAND -> {
Event.CommandUnits commandUnits = parseCommandUnits(stream);
Event.CommandData commandData = parseCommandData(stream);

case CMDST_INCREASE_COMMAND_COUNT -> {
int commandId = stream.readInt();
int delta = stream.readInt();
yield new Event.IncreaseCommandCount(commandId, delta);
}
yield new Event.IssueFactoryCommand(commandUnits, commandData);
}

case CMDST_DECRASE_COMMAND_COUNT -> {
int commandId = stream.readInt();
int delta = stream.readInt();
yield new Event.DecreaseCommandCount(commandId, delta);
}
case CMDST_INCREASE_COMMAND_COUNT -> {
int commandId = stream.readInt();
int delta = stream.readInt();
yield new Event.IncreaseCommandCount(commandId, delta);
}

case CMDST_SET_COMMAND_TARGET -> {
int commandId = stream.readInt();
Event.CommandTarget commandTarget = parseCommandTarget(stream);
yield new Event.SetCommandTarget(commandId, commandTarget);
}
case CMDST_DECRASE_COMMAND_COUNT -> {
int commandId = stream.readInt();
int delta = stream.readInt();
yield new Event.DecreaseCommandCount(commandId, delta);
}

case CMDST_SET_COMMAND_TYPE -> {
int commandId = stream.readInt();
int targetCommandType = stream.readInt();
yield new Event.SetCommandType(commandId, targetCommandType);
}
case CMDST_SET_COMMAND_TARGET -> {
int commandId = stream.readInt();
Event.CommandTarget commandTarget = parseCommandTarget(stream);
yield new Event.SetCommandTarget(commandId, commandTarget);
}

case CMDST_SET_COMMAND_CELLS -> {
int commandId = stream.readInt();
LuaData parametersLua = parseLua(stream);
if (!(parametersLua instanceof LuaData.Nil)) {
stream.readNBytes(1);
case CMDST_SET_COMMAND_TYPE -> {
int commandId = stream.readInt();
int targetCommandType = stream.readInt();
yield new Event.SetCommandType(commandId, targetCommandType);
}

float px = stream.readFloat();
float py = stream.readFloat();
float pz = stream.readFloat();
case CMDST_SET_COMMAND_CELLS -> {
int commandId = stream.readInt();
LuaData parametersLua = parseLua(stream);
if (!(parametersLua instanceof LuaData.Nil)) {
stream.readNBytes(1);
}

yield new Event.SetCommandCells(commandId, parametersLua, px, py, pz);
}
float px = stream.readFloat();
float py = stream.readFloat();
float pz = stream.readFloat();

case CMDST_REMOVE_COMMAND_FROM_QUEUE -> {
int commandId = stream.readInt();
int unitId = stream.readInt();
yield new Event.RemoveCommandFromQueue(commandId, unitId);
}
yield new Event.SetCommandCells(commandId, parametersLua, px, py, pz);
}

case CMDST_DEBUG_COMMAND -> new Event.Unprocessed(token, "CMDST_DEBUG_COMMAND");
case CMDST_REMOVE_COMMAND_FROM_QUEUE -> {
int commandId = stream.readInt();
int unitId = stream.readInt();
yield new Event.RemoveCommandFromQueue(commandId, unitId);
}

case CMDST_EXECUTE_LUA_IN_SIM -> {
String luaCode = parseString(stream);
yield new Event.ExecuteLuaInSim(luaCode);
}
case CMDST_DEBUG_COMMAND -> new Event.Unprocessed(token, "CMDST_DEBUG_COMMAND");

case CMDST_LUA_SIM_CALLBACK -> {
String func = parseString(stream);
LuaData args = parseLua(stream);
Event.CommandUnits commandUnits = null;

// suspicion that this is just flat out wrong! Whether there's a selection in the data is not related to whether there are Lua arguments
if (args != null) {
commandUnits = parseCommandUnits(stream);
} else {
// the '4' we read here is the size, I suspect the 3 bytes are maybe to align the data somehow? No idea
stream.readNBytes(4 + 3);
case CMDST_EXECUTE_LUA_IN_SIM -> {
String luaCode = parseString(stream);
yield new Event.ExecuteLuaInSim(luaCode);
}

yield new Event.LuaSimCallback(func, args, commandUnits);
}
case CMDST_LUA_SIM_CALLBACK -> {
String func = parseString(stream);
LuaData args = parseLua(stream);
Event.CommandUnits commandUnits = null;

// suspicion that this is just flat out wrong! Whether there's a selection in the data is not related to whether there are Lua arguments
if (!(args instanceof LuaData.Nil)) {
commandUnits = parseCommandUnits(stream);
} else {
// the '4' we read here is the size, I suspect the 3 bytes are maybe to align the data somehow? No idea
stream.readNBytes(4 + 3);
}

case CMDST_END_GAME -> new Event.EndGame();
yield new Event.LuaSimCallback(func, args, commandUnits);
}

case CMDST_END_GAME -> new Event.EndGame();

default -> new Event.Unprocessed(token, "Unknown");
};
case null -> new Event.Unprocessed(token, "Unknown");
};
}
}

private enum CommandTargetType {
// Order is crucial
NONE,
ENTITY,
POSITION
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
public record Token(TokenId tokenId, int tokenSize, byte[] tokenContent) {

public enum TokenId {
// Order is crucial
CMDST_ADVANCE,
CMDST_SET_COMMAND_SOURCE,
CMDST_COMMAND_SOURCE_TERMINATED,
Expand Down

0 comments on commit 1f548d8

Please sign in to comment.