public GameEvent ProcessGame(Game game, DateTime timestamp) { if (m_batchStarted && !m_batchUpdating) { throw new InvalidOperationException("Called ProcessGame after BatchStart - use BatchProcess instead."); } // Add new games if needed if (!m_trackedGames.ContainsKey(game._id)) { GameEventParser parser = new GameEventParser(); parser.StartNewGame(game, timestamp); m_trackedGames[game._id] = parser; } else { // Update a current game GameEventParser parser = m_trackedGames[game._id]; GameEvent latest = parser.ParseGameUpdate(game, timestamp); if (latest != null) { return(latest); } } return(null); }
/// <summary> /// Process all the JSON objects on a given stream and write output to another stream /// </summary> /// <param name="newlineDelimitedJson">Incoming JSON objects, newline delimited, in blaseball game update format</param> /// <param name="outJson">SIBR Game Event schema JSON objects, newline delimited</param> public void Process(StreamReader newlineDelimitedJson, StreamWriter outJson) { // I like camel case for my C# properties, sue me JsonSerializerOptions serializerOptions = new JsonSerializerOptions(); serializerOptions.PropertyNamingPolicy = JsonNamingPolicy.CamelCase; while (!newlineDelimitedJson.EndOfStream) { string obj = newlineDelimitedJson.ReadLine(); Update update = JsonSerializer.Deserialize <Update>(obj, serializerOptions); // Currently we only care about the 'schedule' field that has the game updates foreach (var game in update.Schedule) { // Add new games if needed if (!m_trackedGames.ContainsKey(game._id)) { GameEventParser parser = new GameEventParser(); parser.StartNewGame(game); m_trackedGames[game._id] = parser; } else { // Update a current game GameEventParser parser = m_trackedGames[game._id]; GameEvent latest = parser.ParseGameUpdate(game); if (latest != null) { // Write out the latest game event outJson.WriteLine(JsonSerializer.Serialize(latest)); } } } } Console.WriteLine($"Processed updates for {m_trackedGames.Keys.Count} games."); }
/// <summary> /// Process a single game update object /// </summary> /// <param name="game">update object</param> /// <param name="timestamp">time this object was perceived</param> /// <param name="hash">unique hash for this update</param> public async Task ProcessGameObject(Game game, DateTime?inTimestamp) { DateTime timestamp; // If timestamp is missing or stupid, look it up in our list of known bummers if (inTimestamp == null || inTimestamp == TimestampConverter.unixEpoch || inTimestamp == DateTime.MinValue) { timestamp = GetKnownBummerTimestamp(game.season, game.day); } else { timestamp = inTimestamp.Value; } // Add new games if needed if (!m_trackedGames.ContainsKey(game.gameId)) { GameEventParser parser = new GameEventParser(); parser.EventComplete += GameEventCompleteInternal; parser.GameComplete += GameCompleteInternal; bool networkOutcomes = parser.StartNewGame(game, timestamp); if (networkOutcomes) { m_numNetworkOutcomes++; } else { m_numLocalOutcomes++; } m_trackedGames[game.gameId] = parser; } else { // Update a current game GameEventParser parser = m_trackedGames[game.gameId]; await parser.ParseGameUpdate(game, timestamp); } }