public static IntegrationJournalData GetIntegrationJournalData(UserJournal journalItem, UserJournal lastJournal, string integrationKey) { IntegrationJournalData ijd; if (journalItem.IntegrationData.ContainsKey(integrationKey)) { ijd = journalItem.IntegrationData[integrationKey]; } else { EDGameState oldState = null; if (lastJournal != null && lastJournal.IntegrationData != null && lastJournal.IntegrationData.ContainsKey(integrationKey) && lastJournal.IntegrationData[integrationKey].CurrentGameState != null) { oldState = lastJournal.IntegrationData[integrationKey].CurrentGameState; } ijd = new IntegrationJournalData { FullySent = false, LastSentLineNumber = 0, CurrentGameState = oldState ?? new EDGameState() }; journalItem.IntegrationData.TryAdd(integrationKey, ijd); } ijd.CurrentGameState.SendEvents = true; return(ijd); }
public async static Task <(EDGameState gameState, UserJournal lastJournal)> LoadGameState(MSSQLDB db, Guid userIdentifier, List <UserJournal> userJournals, string integrationKey, PerformContext context) { EDGameState previousGameState = null; UserJournal lastJournal = null; var firstAvailableGameState = userJournals.FirstOrDefault(); if (firstAvailableGameState != null) { lastJournal = await db.ExecuteSingleRowAsync <UserJournal>( "SELECT TOP 1 * FROM user_journal WHERE user_identifier = @user_identifier AND journal_id <= @journal_id AND last_processed_line_number > 0 AND integration_data IS NOT NULL ORDER BY journal_date DESC", new SqlParameter("user_identifier", userIdentifier), new SqlParameter("journal_id", firstAvailableGameState.JournalId) ); if (lastJournal != null && lastJournal.IntegrationData.ContainsKey(integrationKey)) { previousGameState = lastJournal.IntegrationData[integrationKey].CurrentGameState; context.WriteLine($"Found previous gamestate: {JsonSerializer.Serialize(previousGameState, new JsonSerializerOptions { WriteIndented = true })}"); } } return(previousGameState, lastJournal); }
private static void SetSystemAddress(EDGameState gameState, Dictionary <string, JsonElement> elementAsDictionary, bool nullIfMissing) { if (elementAsDictionary.ContainsKey("SystemAddress")) { gameState.SystemAddress = elementAsDictionary["SystemAddress"].GetInt64(); } else { if (nullIfMissing) { gameState.SystemAddress = null; } } }
private static void SetStarSystem(EDGameState gameState, Dictionary <string, JsonElement> elementAsDictionary, bool nullIfMissing) { if (elementAsDictionary.ContainsKey("StarSystem")) { gameState.SystemName = elementAsDictionary["StarSystem"].GetString(); } else { if (nullIfMissing) { gameState.SystemName = null; } } }
private static void SetStarPos(EDGameState gameState, Dictionary <string, JsonElement> elementAsDictionary, bool nullIfMissing) { if (elementAsDictionary.ContainsKey("StarPos")) { gameState.SystemCoordinates = elementAsDictionary["StarPos"]; } else { if (nullIfMissing) { gameState.SystemCoordinates = null; } } }
private static void SetBodyID(EDGameState gameState, Dictionary <string, JsonElement> elementAsDictionary, bool nullIfMissing) { if (elementAsDictionary.ContainsKey("BodyID")) { gameState.BodyId = elementAsDictionary["BodyID"].GetInt64(); } else { if (nullIfMissing) { gameState.BodyId = null; } } }
public static async Task SetSystemCache(EDGameState gameState, IDatabase _rdb, bool setCache) { /*if (!setCache && gameState.SystemAddress.HasValue && gameState.SystemCoordinates.HasValue && !string.IsNullOrWhiteSpace(gameState.SystemName)) * { * await _rdb.StringSetAsyncWithRetries( * $"SystemAddress:{gameState.SystemAddress}", * JsonSerializer.Serialize(new * { * SystemAddress = gameState.SystemAddress, * StarSystem = gameState.SystemName, * StarPos = gameState.SystemCoordinates * }), * TimeSpan.FromHours(10), * flags: CommandFlags.FireAndForget * ); * }*/ }
public static async Task <JsonElement> SetGamestateProperties(JsonElement element, EDGameState gameState, string commander, StarSystemChecker starSystemChecker) { return(await GameStateHandler.SetGamestateProperties(element, gameState, commander, starSystemChecker, (newState) => new { _systemAddress = gameState.SystemAddress, _systemName = gameState.SystemName, _systemCoordinates = gameState.SystemCoordinates, _marketId = gameState.MarketId, _stationName = gameState.StationName, _shipId = gameState.ShipId, _odyssey = gameState.Odyssey }, (transientState, elementAsDictionary) => { elementAsDictionary["_systemAddress"] = transientState.GetProperty("_systemAddress"); elementAsDictionary["_systemName"] = transientState.GetProperty("_systemName"); elementAsDictionary["_systemCoordinates"] = transientState.GetProperty("_systemCoordinates"); elementAsDictionary["_marketId"] = transientState.GetProperty("_marketId"); elementAsDictionary["_stationName"] = transientState.GetProperty("_stationName"); elementAsDictionary["_shipId"] = transientState.GetProperty("_shipId"); } )); }
public static async Task <(int errorCode, string resultContent, TimeSpan executionTime, bool sentData)> UploadJournalItemToEDSM(HttpClient hc, string journalRow, Guid userIdentifier, EDSMIntegrationSettings edsmSettings, EDGameState gameState, StarSystemChecker starSystemChecker) { var element = JsonDocument.Parse(journalRow).RootElement; if (!element.TryGetProperty("event", out JsonElement journalEvent)) { return(303, string.Empty, TimeSpan.Zero, false); } Stopwatch sw = new Stopwatch(); sw.Start(); try { element = await SetGamestateProperties(element, gameState, edsmSettings.CommanderName.Trim(), starSystemChecker); if (System.Enum.TryParse(typeof(IgnoredEvents), journalEvent.GetString(), false, out _)) { return(304, string.Empty, TimeSpan.Zero, false); } if (!gameState.SendEvents) { return(104, string.Empty, TimeSpan.Zero, false); } var formContent = new MultipartFormDataContent(); var json = JsonSerializer.Serialize(element, new JsonSerializerOptions() { WriteIndented = true }); formContent.Add(new StringContent(edsmSettings.CommanderName.Trim()), "commanderName"); formContent.Add(new StringContent(edsmSettings.ApiKey), "apiKey"); formContent.Add(new StringContent("Journal Limpet"), "fromSoftware"); formContent.Add(new StringContent(SharedSettings.VersionNumber), "fromSoftwareVersion"); formContent.Add(new StringContent(json), "message"); await SSEActivitySender.SendUserLogDataAsync(userIdentifier, new { fromIntegration = "EDSM", data = element }); var policy = Policy .HandleResult <HttpResponseMessage>(res => !res.IsSuccessStatusCode) .Or <HttpRequestException>() .WaitAndRetryAsync(30, retryCount => TimeSpan.FromSeconds(retryCount * 5)); var status = await policy.ExecuteAsync(() => hc.PostAsync("https://www.edsm.net/api-journal-v1", formContent)); var postResponseBytes = await status.Content.ReadAsByteArrayAsync(); var postResponse = System.Text.Encoding.UTF8.GetString(postResponseBytes); if (!status.IsSuccessStatusCode) { return((int)status.StatusCode, postResponse, TimeSpan.FromSeconds(30), true); } var resp = JsonSerializer.Deserialize <EDSMApiResponse>(postResponse); sw.Stop(); return(resp.ResultCode, postResponse, sw.Elapsed, true); } catch (InvalidTimestampException) { return(206, string.Empty, TimeSpan.FromMilliseconds(100), false); } }
public static async Task <JsonElement> SetGamestateProperties(JsonElement element, EDGameState gameState, string commander, StarSystemChecker starSystemChecker) { return(await GameStateHandler.SetGamestateProperties(element, gameState, commander, starSystemChecker, (newState) => { return new { systemName = gameState.SystemName, systemAddress = gameState.SystemAddress, systemCoordinates = gameState.SystemCoordinates, bodyName = gameState.BodyName, bodyId = gameState.BodyId, clientVersion = "Journal Limpet: " + SharedSettings.VersionNumber, odyssey = gameState.Odyssey, isBeta = false }; })); }
public static async Task <Dictionary <string, object> > UploadJournalItemToCanonnRD(string journalRow, string cmdrName, EDGameState gameState, List <CanonnEventDefinition> validCanonnEvents, StarSystemChecker starSystemChecker) { var element = JsonDocument.Parse(journalRow).RootElement; if (!element.TryGetProperty("event", out JsonElement journalEvent)) { return(null); } Stopwatch sw = new Stopwatch(); sw.Start(); try { var newGameState = await SetGamestateProperties(element, gameState, cmdrName, starSystemChecker); var matchingValidEvents = validCanonnEvents.Where(e => e.Event == journalEvent.GetString()); if (!matchingValidEvents.Any()) { return(null); } bool foundMatchingEvent = false; foreach (var matchingValidEvent in matchingValidEvents) { var fieldsToMatch = matchingValidEvent.ExtensionData ?? new Dictionary <string, object>(); if (fieldsToMatch.Count > 0) { var elementAsDictionary = JsonSerializer.Deserialize <Dictionary <string, object> >(element.GetRawText()); if (fieldsToMatch.All(k => elementAsDictionary.ContainsKey(k.Key) && elementAsDictionary[k.Key].ToString() == k.Value.ToString())) { foundMatchingEvent = true; break; } } else { foundMatchingEvent = true; break; } } if (!foundMatchingEvent) { return(null); } if (!gameState.SendEvents) { return(null); } var eddnItem = new Dictionary <string, object>() { { "gameState", newGameState }, { "rawEvent", element }, { "eventType", journalEvent.GetString() }, { "cmdrName", cmdrName } }; return(eddnItem); } catch (InvalidTimestampException) { return(null); } }
public static void GameStateFixer(EDGameState gameState, string commander, Dictionary <string, JsonElement> elementAsDictionary) { var eventName = elementAsDictionary["event"].GetString(); var timestamp = elementAsDictionary["timestamp"].GetDateTimeOffset(); gameState.Timestamp = timestamp; if (OdysseyEvents.Contains(eventName)) { gameState.Odyssey = true; } if (elementAsDictionary.ContainsKey("SystemAddress")) { if (!IgnoredChangedSystemAddressEvents.Contains(eventName)) { if (elementAsDictionary["SystemAddress"].GetInt64() != gameState.SystemAddress) { gameState.SystemAddress = null; gameState.SystemName = null; gameState.SystemCoordinates = null; gameState.MarketId = null; gameState.StationName = null; gameState.BodyId = null; gameState.BodyName = null; } } } // We'll disable this reset for now, since commanders do re-log at times // And for some reason, Location wasn't written to the journals, // maybe it only appears if you actually restart the entire game? if (eventName == "LoadGame") { //gameState.SystemAddress = null; //gameState.SystemName = null; //gameState.SystemCoordinates = null; //gameState.MarketId = null; //gameState.StationName = null; //gameState.ShipId = null; //gameState.BodyId = null; //gameState.BodyName = null; if (elementAsDictionary.ContainsKey("Odyssey")) { gameState.Odyssey = elementAsDictionary["Odyssey"].GetBoolean(); } } if (eventName == "Rank") { if (elementAsDictionary.ContainsKey("Soldier") || elementAsDictionary.ContainsKey("Exobiologist")) { gameState.Odyssey = true; } } if (eventName == "SetUserShipName") { gameState.ShipId = elementAsDictionary["ShipID"].GetInt64(); } if (eventName == "ShipyardBuy") { gameState.ShipId = null; } if (eventName == "ShipyardSwap") { gameState.ShipId = elementAsDictionary["ShipID"].GetInt64(); } if (eventName == "Loadout") { gameState.ShipId = elementAsDictionary["ShipID"].GetInt64(); } if (eventName == "NavBeaconScan") { SetSystemAddress(gameState, elementAsDictionary, false); } if (eventName == "Undocked") { gameState.MarketId = null; gameState.StationName = null; gameState.BodyId = null; gameState.BodyName = null; } if (eventName == "ApproachBody") { SetStarSystem(gameState, elementAsDictionary, false); SetSystemAddress(gameState, elementAsDictionary, false); SetBodyName(gameState, elementAsDictionary, false); SetBodyID(gameState, elementAsDictionary, false); } if (eventName == "LeaveBody") { gameState.BodyId = null; gameState.BodyName = null; } if (eventName == "SupercruiseEntry") { if (elementAsDictionary.ContainsKey("StarSystem")) { if (elementAsDictionary["StarSystem"].GetString() != gameState.SystemName) { gameState.SystemCoordinates = null; gameState.SystemAddress = null; gameState.BodyId = null; gameState.BodyName = null; } SetStarSystem(gameState, elementAsDictionary, false); } SetSystemAddress(gameState, elementAsDictionary, false); gameState.BodyName = null; gameState.BodyId = null; } if (eventName == "ShipLockerMaterials") { gameState.Odyssey = true; } if (eventName == "SupercruiseExit") { SetStarSystem(gameState, elementAsDictionary, false); SetBodyName(gameState, elementAsDictionary, true); SetBodyID(gameState, elementAsDictionary, true); } if (new[] { "Location", "FSDJump", "Docked", "CarrierJump" }.Contains(eventName)) { // Docked don"t have coordinates, if system changed reset if (elementAsDictionary["StarSystem"].GetString() != gameState.SystemName) { gameState.SystemCoordinates = null; gameState.SystemAddress = null; gameState.BodyId = null; gameState.BodyName = null; } if (elementAsDictionary.ContainsKey("StationServices")) { /*if (elementAsDictionary["StationServices"].GetRawText().Contains("socialspace")) * { * gameState.Odyssey = true; * }*/ } if (elementAsDictionary["StarSystem"].GetString() != "ProvingGround" && elementAsDictionary["StarSystem"].GetString() != "CQC") { SetSystemAddress(gameState, elementAsDictionary, false); SetStarSystem(gameState, elementAsDictionary, false); SetStarPos(gameState, elementAsDictionary, false); SetBodyName(gameState, elementAsDictionary, false); SetBodyID(gameState, elementAsDictionary, false); } else { gameState.SystemAddress = null; gameState.SystemName = null; gameState.SystemCoordinates = null; gameState.BodyId = null; gameState.BodyName = null; } if (elementAsDictionary.ContainsKey("MarketID")) { gameState.MarketId = elementAsDictionary["MarketID"].GetInt64(); } if (elementAsDictionary.ContainsKey("StationName")) { gameState.StationName = elementAsDictionary["StationName"].GetString(); } } if (new[] { "FSSBodySignals", "SAASignalsFound", "SAAScanComplete", "Scan", }.Contains(eventName)) { SetSystemAddress(gameState, elementAsDictionary, false); SetStarSystem(gameState, elementAsDictionary, false); SetStarPos(gameState, elementAsDictionary, false); } if (new[] { "FSSDiscoveryScan", "CodexEntry", "FSSAllBodiesFound", "Touchdown", "Liftoff", "ApproachSettlement", "Disembark", "Embark" }.Contains(eventName)) { SetSystemAddress(gameState, elementAsDictionary, false); SetStarSystem(gameState, elementAsDictionary, false); SetStarPos(gameState, elementAsDictionary, false); SetBodyName(gameState, elementAsDictionary, false); SetBodyID(gameState, elementAsDictionary, false); } if (new[] { "JoinACrew", "QuitACrew" }.Contains(eventName)) { if (eventName == "JoinACrew" && elementAsDictionary.ContainsKey("Captain") && elementAsDictionary["Captain"].GetString() != commander) { gameState.SendEvents = false; } else { gameState.SendEvents = true; } gameState.SystemAddress = null; gameState.SystemName = null; gameState.SystemCoordinates = null; gameState.MarketId = null; gameState.StationName = null; gameState.ShipId = null; gameState.BodyId = null; gameState.BodyName = null; } if (elementAsDictionary.ContainsKey("Taxi")) { gameState.Odyssey = true; } if (elementAsDictionary.ContainsKey("OnFoot")) { gameState.Odyssey = true; } }
public async static Task <JsonElement> SetGamestateProperties(JsonElement element, EDGameState gameState, string commander, StarSystemChecker starSystemChecker, Func <EDGameState, object> setProperties, Action <JsonElement, Dictionary <string, JsonElement> > addStateToElement = null) { var _rdb = SharedSettings.RedisClient.GetDatabase(1); var elementAsDictionary = JsonSerializer.Deserialize <Dictionary <string, JsonElement> >(element.GetRawText()); if (elementAsDictionary.TryGetValue("timestamp", out var timeStampElement)) { if (!timeStampElement.TryGetDateTimeOffset(out _)) { throw new InvalidTimestampException(); } } bool setCache = await EDSystemCache.GetSystemCache(elementAsDictionary, _rdb, starSystemChecker); GameStateChanger.GameStateFixer(gameState, commander, elementAsDictionary); var addItems = setProperties(gameState); var transientState = JsonDocument.Parse(JsonSerializer.Serialize(addItems)).RootElement; await EDSystemCache.SetSystemCache(gameState, _rdb, setCache); if (addStateToElement != null) { addStateToElement(transientState, elementAsDictionary); var json = JsonSerializer.Serialize(elementAsDictionary); return(JsonDocument.Parse(json).RootElement); } return(transientState); }