public void RemoveKnownHash(ImageHashData hashData) { for (int idx = customHashes.Count - 1; idx >= 0; idx--) { ImageHashData testHash = customHashes[idx]; if (hashData.IsMatching(testHash, 0, out int dummyDistance)) { customHashes.RemoveAt(idx); ImageHashDB.Get().hashes.Remove(testHash); MarkDirty(); } } }
public void AddKnownHash(ImageHashData hashData) { foreach (ImageHashData testHash in customHashes) { if (hashData.IsMatching(testHash, 0, out int dummyDistance)) { Logger.WriteLine("Adding hash ({0}: {1}) failed! Colision with already known ({2}: {3})", hashData.type, hashData.ownerOb, testHash.type, testHash.ownerOb); return; } } customHashes.Add(hashData); ImageHashDB.Get().hashes.Add(hashData); MarkDirty(); }
static public List <object> GenerateHashOwnerOptions(ImageHashData hashData) { List <object> list = new List <object>(); switch (hashData.type) { case EImageHashType.Rule: foreach (TriadGameModifier mod in ImageHashDB.Get().modObjects) { list.Add(new HashOwnerItem(mod)); } break; case EImageHashType.CardImage: foreach (TriadCard card in TriadCardDB.Get().sameNumberMap[((TriadCard)hashData.ownerOb).SameNumberId]) { list.Add(new HashOwnerItem(card)); } break; case EImageHashType.CardNumber: for (int number = 1; number <= 10; number++) { list.Add(new HashOwnerItem(number)); } break; case EImageHashType.Cactpot: for (int number = 1; number <= 9; number++) { list.Add(new HashOwnerItem(number)); } break; default: break; } return(list); }
private int ParseCactpotCircle(FastBitmapHSV bitmap, Rectangle circleBox, string debugName) { float[] values = ExtractCirclePattern(bitmap, circleBox); int result; ImageHashData pattern = new ImageHashData() { type = EImageHashType.Cactpot, previewBounds = circleBox, isKnown = true }; pattern.CalculateHash(values); // allow overwrites in case there is a user defined value, must be exact match ImageHashData overridePattern = ImageHashDB.Get().FindExactMatch(pattern); if (overridePattern != null) { result = (int)overridePattern.ownerOb; } else { result = classifierCactpot.Calculate(values, out float DummyPct); pattern.isAuto = true; } pattern.ownerOb = result; screenAnalyzer.AddImageHash(pattern); Rectangle previewBounds = new Rectangle(circleBox.X + circleBox.Width, circleBox.Y, 8, 16); debugHashes.Add(new ImageUtils.HashPreview() { hashValues = values, bounds = previewBounds }); debugShapes.Add(GetCirclePatternBounds(circleBox)); return(result); }
public static void RunTest(string configPath, bool debugMode) { string testName = System.IO.Path.GetFileNameWithoutExtension(configPath); string configText = System.IO.File.ReadAllText(configPath); JsonParser.ObjectValue configOb = JsonParser.ParseJson(configText); if (configOb["type"] != "Solver") { return; } TriadGameSession testSession = new TriadGameSession(); // intial state ScannerTriad.VerifyConfig configData = new ScannerTriad.VerifyConfig(); configData.Load(configOb); if (mapValidationRules == null) { mapValidationRules = new Dictionary <string, TriadGameModifier>(); foreach (TriadGameModifier mod in ImageHashDB.Get().modObjects) { mapValidationRules.Add(mod.GetCodeName(), mod); } } foreach (string modName in configData.rules) { testSession.modifiers.Add(mapValidationRules[modName]); } testSession.UpdateSpecialRules(); TriadGameData testGameData = new TriadGameData() { bDebugRules = debugMode }; if (configData.board.Length > 0) { Func <ScannerTriad.VerifyCard, TriadCard> ConvertToTriadCard = configCard => { if (configCard.state == ScannerTriad.ECardState.None) { return(null); } if (configCard.state == ScannerTriad.ECardState.Hidden) { return(TriadCardDB.Get().hiddenCard); } TriadCard matchingCard = !string.IsNullOrEmpty(configCard.name) ? TriadCardDB.Get().Find(configCard.name) : TriadCardDB.Get().Find(configCard.sides[0], configCard.sides[1], configCard.sides[2], configCard.sides[3]); if (matchingCard == null) { string exceptionMsg = string.Format("Test {0} failed! Can't match validation card: '{1}' [{2},{3},{4},{5}]", testName, configCard.name, configCard.sides[0], configCard.sides[1], configCard.sides[2], configCard.sides[3]); throw new Exception(exceptionMsg); } return(matchingCard); }; for (int idx = 0; idx < configData.board.Length; idx++) { var configState = configData.board[idx].state; if (configState != ScannerTriad.ECardState.None) { testGameData.board[idx] = new TriadCardInstance(ConvertToTriadCard(configData.board[idx]), (configState == ScannerTriad.ECardState.PlacedBlue) ? ETriadCardOwner.Blue : (configState == ScannerTriad.ECardState.PlacedRed) ? ETriadCardOwner.Red : ETriadCardOwner.Unknown); } } } var deckRed = new TriadDeck(); var deckBlue = new TriadDeck(); testGameData.deckBlue = new TriadDeckInstanceManual(deckBlue); testGameData.deckRed = new TriadDeckInstanceManual(deckRed); JsonParser.ArrayValue moveArr = configOb.entries["moves"] as JsonParser.ArrayValue; for (int idx = 0; idx < moveArr.entries.Count; idx++) { var move = new VerifyMove(); move.Load(moveArr.entries[idx] as JsonParser.ObjectValue); var useDeck = (move.owner == ETriadCardOwner.Blue) ? deckBlue : deckRed; useDeck.knownCards.Add(move.card); if (idx == 0) { testGameData.state = (move.owner == ETriadCardOwner.Blue) ? ETriadGameState.InProgressBlue : ETriadGameState.InProgressRed; } if (debugMode) { Logger.WriteLine("move[{0}]: [{1}] {2}: {3}", idx, move.boardPos, move.owner, move.card); } bool result = testSession.PlaceCard(testGameData, move.card, move.owner, move.boardPos); if (!result) { string exceptionMsg = string.Format("Test {0} failed! Can't place card!", testName); throw new Exception(exceptionMsg); } result = move.VerifyState(testGameData, debugMode); if (!result) { string exceptionMsg = string.Format("Test {0} failed! Finished with bad state!", testName); throw new Exception(exceptionMsg); } } }
public static object FindMatchingHash(FastBitmapHash hashData, EImageHashType hashType, out int bestDistance, bool bDebugMode = false) { string debugDesc = bDebugMode ? hashData.Hash + " >> " : ""; int debugDescParts = 0; object bestMatchOb = null; bestDistance = -1; bool bIsLocked = PlayerSettingsDB.Get().IsLockedHash(hashData.Hash); foreach (ImageHashData hashInfo in PlayerSettingsDB.Get().customHashes) { if (hashInfo.Type == hashType) { bool bIsMatching = hashInfo.IsHashMatching(hashData.Hash, out int testDistance); if (bDebugMode) { debugDesc += ((hashType == EImageHashType.Card) ? ((TriadCard)hashInfo.Owner).ToShortString() : hashInfo.Owner.ToString()) + ":" + testDistance + ", "; debugDescParts++; } if (bIsLocked && testDistance != 0) { continue; } if (bIsMatching && (bestDistance < 0 || bestDistance > testDistance)) { bestDistance = testDistance; bestMatchOb = hashInfo.Owner; } } } if (bestDistance < 0) { foreach (ImageHashData hashInfo in ImageHashDB.Get().hashes) { if (hashInfo.Type == hashType) { bool bIsMatching = hashInfo.IsHashMatching(hashData.Hash, out int testDistance); if (bDebugMode) { debugDesc += ((hashType == EImageHashType.Card) ? ((TriadCard)hashInfo.Owner).ToShortString() : hashInfo.Owner.ToString()) + ":" + testDistance + ", "; debugDescParts++; } if (bIsLocked && testDistance != 0) { continue; } if (bIsMatching && (bestDistance < 0 || bestDistance > testDistance)) { bestDistance = testDistance; bestMatchOb = hashInfo.Owner; } } } } if (bDebugMode) { if (debugDescParts > 0) { debugDesc = debugDesc.Remove(debugDesc.Length - 2, 2); } debugDesc += " >> "; debugDesc += (bestMatchOb == null) ? "unknown" : ((hashType == EImageHashType.Card) ? ((TriadCard)bestMatchOb).ToShortString() : bestMatchOb.ToString()); Logger.WriteLine(debugDesc); } return(bestMatchOb); }
public bool LoadFromXmlStream(Stream stream) { TriadCardDB cardDB = TriadCardDB.Get(); TriadNpcDB npcDB = TriadNpcDB.Get(); try { XmlDocument xdoc = new XmlDocument(); xdoc.Load(stream); foreach (XmlNode testNode in xdoc.DocumentElement.ChildNodes) { try { XmlElement testElem = (XmlElement)testNode; if (testElem != null && testElem.Name == "ui") { int autoScanNum = int.Parse(testElem.GetAttribute("autoScan")); useAutoScan = (autoScanNum == 1); } else if (testElem != null && testElem.Name == "cloud") { int useNum = int.Parse(testElem.GetAttribute("use")); useCloudStorage = (useNum == 1); cloudToken = testElem.HasAttribute("token") ? testElem.GetAttribute("token") : null; } else if (testElem != null && testElem.Name == "card") { int cardId = int.Parse(testElem.GetAttribute("id")); ownedCards.Add(cardDB.cards[cardId]); } else if (testElem != null && testElem.Name == "npc") { int npcId = int.Parse(testElem.GetAttribute("id")); completedNpcs.Add(npcDB.npcs[npcId]); } else if (testElem != null && testElem.Name == "deck") { int npcId = int.Parse(testElem.GetAttribute("id")); TriadNpc npc = TriadNpcDB.Get().npcs[npcId]; if (npc != null) { TriadDeck deckCards = new TriadDeck(); foreach (XmlAttribute attr in testElem.Attributes) { if (attr.Name.StartsWith("card")) { string cardNumStr = attr.Name.Substring(4); int cardNum = int.Parse(cardNumStr); while (deckCards.knownCards.Count < (cardNum + 1)) { deckCards.knownCards.Add(null); } int cardId = int.Parse(attr.Value); deckCards.knownCards[cardNum] = TriadCardDB.Get().cards[cardId]; } } lastDeck.Add(npc, deckCards); } } else { ImageHashData customHash = ImageHashDB.Get().LoadHashEntry(testElem); if (customHash != null) { customHashes.Add(customHash); } else { ImagePatternDigit customDigit = ImageHashDB.Get().LoadDigitEntry(testElem); if (customDigit.Value > 0) { customDigits.Add(customDigit); } } } } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } } } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } return(ownedCards.Count > 0); }
public string SaveToJson(bool bLimitedMode = false) { JsonWriter jsonWriter = new JsonWriter(); try { jsonWriter.WriteObjectStart(); if (!bLimitedMode) { jsonWriter.WriteObjectStart("ui"); jsonWriter.WriteBool(useAutoScan, "autoScan"); jsonWriter.WriteObjectEnd(); } if (!bLimitedMode) { jsonWriter.WriteObjectStart("cloud"); jsonWriter.WriteBool(useCloudStorage, "use"); if (cloudToken != null) { jsonWriter.WriteString(cloudToken, "token"); } jsonWriter.WriteObjectEnd(); } { List <int> listIds = new List <int>(); foreach (TriadCard card in ownedCards) { listIds.Add(card.Id); } listIds.Sort(); jsonWriter.WriteArrayStart("cards"); foreach (int id in listIds) { jsonWriter.WriteInt(id); } jsonWriter.WriteArrayEnd(); } { List <int> listIds = new List <int>(); foreach (TriadNpc npc in completedNpcs) { listIds.Add(npc.Id); } listIds.Sort(); jsonWriter.WriteArrayStart("npcs"); foreach (int id in listIds) { jsonWriter.WriteInt(id); } jsonWriter.WriteArrayEnd(); } { jsonWriter.WriteArrayStart("decks"); foreach (KeyValuePair <TriadNpc, TriadDeck> kvp in lastDeck) { jsonWriter.WriteObjectStart(); jsonWriter.WriteInt(kvp.Key.Id, "id"); jsonWriter.WriteArrayStart("cards"); for (int Idx = 0; Idx < kvp.Value.knownCards.Count; Idx++) { jsonWriter.WriteInt(kvp.Value.knownCards[Idx].Id); } jsonWriter.WriteArrayEnd(); jsonWriter.WriteObjectEnd(); } jsonWriter.WriteArrayEnd(); } { jsonWriter.WriteArrayStart("favDecks"); foreach (TriadDeckNamed deck in favDecks) { jsonWriter.WriteObjectStart(); if (deck != null) { jsonWriter.WriteString(deck.Name, "name"); jsonWriter.WriteArrayStart("cards"); for (int Idx = 0; Idx < deck.knownCards.Count; Idx++) { jsonWriter.WriteInt(deck.knownCards[Idx].Id); } jsonWriter.WriteArrayEnd(); } jsonWriter.WriteObjectEnd(); } jsonWriter.WriteArrayEnd(); } if (!bLimitedMode) { jsonWriter.WriteObjectStart("images"); ImageHashDB.Get().StoreImageHashes(customHashes, jsonWriter); jsonWriter.WriteObjectEnd(); jsonWriter.WriteArrayStart("digits"); ImageHashDB.Get().StoreDigitHashes(customDigits, jsonWriter); jsonWriter.WriteArrayEnd(); } jsonWriter.WriteObjectEnd(); } catch (Exception ex) { Logger.WriteLine("Saving failed! Exception:" + ex); } return(jsonWriter.ToString()); }
public bool LoadFromJson(string jsonStr) { TriadCardDB cardDB = TriadCardDB.Get(); TriadNpcDB npcDB = TriadNpcDB.Get(); try { JsonParser.ObjectValue jsonOb = JsonParser.ParseJson(jsonStr); JsonParser.ObjectValue uiOb = (JsonParser.ObjectValue)jsonOb["ui", null]; if (uiOb != null) { useAutoScan = (JsonParser.BoolValue)uiOb["autoScan", JsonParser.BoolValue.Empty]; } JsonParser.ObjectValue cloudOb = (JsonParser.ObjectValue)jsonOb["cloud", null]; if (cloudOb != null) { useCloudStorage = (JsonParser.BoolValue)cloudOb["use", JsonParser.BoolValue.Empty]; cloudToken = (JsonParser.StringValue)cloudOb["token", null]; } JsonParser.ArrayValue cardsArr = (JsonParser.ArrayValue)jsonOb["cards", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in cardsArr.entries) { int cardId = (JsonParser.IntValue)value; ownedCards.Add(cardDB.cards[cardId]); } JsonParser.ArrayValue npcsArr = (JsonParser.ArrayValue)jsonOb["npcs", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in npcsArr.entries) { int npcId = (JsonParser.IntValue)value; completedNpcs.Add(npcDB.npcs[npcId]); } JsonParser.ArrayValue decksArr = (JsonParser.ArrayValue)jsonOb["decks", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in decksArr.entries) { JsonParser.ObjectValue deckOb = (JsonParser.ObjectValue)value; int npcId = (JsonParser.IntValue)deckOb["id"]; TriadNpc npc = TriadNpcDB.Get().npcs[npcId]; if (npc != null) { TriadDeck deckCards = new TriadDeck(); cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value cardValue in cardsArr.entries) { int cardId = (JsonParser.IntValue)cardValue; deckCards.knownCards.Add(cardDB.cards[cardId]); } lastDeck.Add(npc, deckCards); } } JsonParser.ArrayValue favDecksArr = (JsonParser.ArrayValue)jsonOb["favDecks", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in favDecksArr.entries) { JsonParser.ObjectValue deckOb = (JsonParser.ObjectValue)value; TriadDeckNamed deckCards = new TriadDeckNamed(); cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value cardValue in cardsArr.entries) { int cardId = (JsonParser.IntValue)cardValue; deckCards.knownCards.Add(cardDB.cards[cardId]); } if (deckCards.knownCards.Count > 0) { deckCards.Name = deckOb["name", JsonParser.StringValue.Empty]; favDecks.Add(deckCards); } } JsonParser.ObjectValue imageHashesOb = (JsonParser.ObjectValue)jsonOb["images", null]; if (imageHashesOb != null) { customHashes = ImageHashDB.Get().LoadImageHashes(imageHashesOb); } JsonParser.ArrayValue digitHashesArr = (JsonParser.ArrayValue)jsonOb["digits", null]; if (digitHashesArr != null) { customDigits = ImageHashDB.Get().LoadDigitHashes(digitHashesArr); } } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } return(ownedCards.Count > 0); }
public static void RunTest(string configPath, bool debugMode) { string testName = System.IO.Path.GetFileNameWithoutExtension(configPath); string configText = System.IO.File.ReadAllText(configPath); JsonParser.ObjectValue rootOb = JsonParser.ParseJson(configText); if (rootOb["type"] != "Screen") { return; } ScannerTriad.VerifyConfig configData = new ScannerTriad.VerifyConfig(); configData.Load(rootOb); // setup npc & modifiers TriadNpc testNpc = TriadNpcDB.Get().Find(configData.npc); if (testNpc == null) { string exceptionMsg = string.Format("Test {0} failed! Can't find npc: {1}", testName, configData.npc); throw new Exception(exceptionMsg); } ScannerTriad.GameState screenGame = new ScannerTriad.GameState(); if (mapValidationRules == null) { mapValidationRules = new Dictionary <string, TriadGameModifier>(); foreach (TriadGameModifier mod in ImageHashDB.Get().modObjects) { mapValidationRules.Add(mod.GetCodeName(), mod); } } foreach (string modName in configData.rules) { screenGame.mods.Add(mapValidationRules[modName]); } Func <ScannerTriad.VerifyCard, TriadCard> ConvertToTriadCard = configCard => { if (configCard.state == ScannerTriad.ECardState.None) { return(null); } if (configCard.state == ScannerTriad.ECardState.Hidden) { return(TriadCardDB.Get().hiddenCard); } TriadCard matchingCard = !string.IsNullOrEmpty(configCard.name) ? TriadCardDB.Get().Find(configCard.name) : TriadCardDB.Get().Find(configCard.sides[0], configCard.sides[1], configCard.sides[2], configCard.sides[3]); if (matchingCard == null) { string exceptionMsg = string.Format("Test {0} failed! Can't match validation card: '{1}' [{2},{3},{4},{5}]", testName, configCard.name, configCard.sides[0], configCard.sides[1], configCard.sides[2], configCard.sides[3]); throw new Exception(exceptionMsg); } return(matchingCard); }; bool needsLockedBlue = false; for (int idx = 0; idx < 5; idx++) { screenGame.blueDeck[idx] = ConvertToTriadCard(configData.deckBlue[idx]); screenGame.redDeck[idx] = ConvertToTriadCard(configData.deckRed[idx]); if (configData.deckBlue[idx].state == ScannerTriad.ECardState.Locked) { needsLockedBlue = true; } } if (needsLockedBlue) { for (int idx = 0; idx < 5; idx++) { if (configData.deckBlue[idx].state == ScannerTriad.ECardState.Visible) { screenGame.forcedBlueCard = screenGame.blueDeck[idx]; break; } } } for (int idx = 0; idx < 9; idx++) { screenGame.board[idx] = ConvertToTriadCard(configData.board[idx]); screenGame.boardOwner[idx] = configData.board[idx].state == ScannerTriad.ECardState.PlacedBlue ? ETriadCardOwner.Blue : configData.board[idx].state == ScannerTriad.ECardState.PlacedRed ? ETriadCardOwner.Red : ETriadCardOwner.Unknown; } TriadGameScreenMemory screenMemory = new TriadGameScreenMemory { logScan = false }; screenMemory.OnNewScan(screenGame, testNpc); screenMemory.gameSession.SolverFindBestMove(screenMemory.gameState, out int solverBoardPos, out TriadCard solverTriadCard, out TriadGameResultChance bestChance); if (bestChance.expectedResult == ETriadGameState.BlueLost && bestChance.winChance <= 0.0f && bestChance.drawChance <= 0.0f) { string exceptionMsg = string.Format("Test {0} failed! Can't find move!", testName); throw new Exception(exceptionMsg); } }
public string SaveToJson(bool bLimitedMode = false) { JsonWriter jsonWriter = new JsonWriter(); try { jsonWriter.WriteObjectStart(); if (!bLimitedMode) { jsonWriter.WriteObjectStart("ui"); jsonWriter.WriteBool(useXInput, "xInput"); jsonWriter.WriteBool(alwaysOnTop, "onTop"); jsonWriter.WriteString(forcedLanguage, "lang"); jsonWriter.WriteInt(lastNpcId, "lastNpcId"); jsonWriter.WriteFloat(lastWidth, "lastWidth"); jsonWriter.WriteFloat(lastHeight, "lastHeight"); jsonWriter.WriteFloat(fontSize, "fontSize"); jsonWriter.WriteFloat(markerDurationCard, "markerCard"); jsonWriter.WriteFloat(markerDurationSwap, "markerSwap"); jsonWriter.WriteFloat(markerDurationCactpot, "markerCactpot"); jsonWriter.WriteObjectEnd(); } if (!bLimitedMode) { jsonWriter.WriteObjectStart("cloud"); jsonWriter.WriteBool(useCloudStorage, "use"); if (cloudToken != null) { jsonWriter.WriteString(cloudToken, "token"); } jsonWriter.WriteObjectEnd(); } { List <int> listIds = new List <int>(); foreach (TriadCard card in ownedCards) { listIds.Add(card.Id); } listIds.Sort(); jsonWriter.WriteArrayStart("cards"); foreach (int id in listIds) { jsonWriter.WriteInt(id); } jsonWriter.WriteArrayEnd(); } { List <int> listIds = new List <int>(); foreach (TriadNpc npc in completedNpcs) { listIds.Add(npc.Id); } listIds.Sort(); jsonWriter.WriteArrayStart("npcs"); foreach (int id in listIds) { jsonWriter.WriteInt(id); } jsonWriter.WriteArrayEnd(); } { jsonWriter.WriteArrayStart("decks"); foreach (KeyValuePair <TriadNpc, TriadDeck> kvp in lastDeck) { jsonWriter.WriteObjectStart(); jsonWriter.WriteInt(kvp.Key.Id, "id"); jsonWriter.WriteArrayStart("cards"); for (int Idx = 0; Idx < kvp.Value.knownCards.Count; Idx++) { jsonWriter.WriteInt(kvp.Value.knownCards[Idx].Id); } jsonWriter.WriteArrayEnd(); jsonWriter.WriteObjectEnd(); } jsonWriter.WriteArrayEnd(); } { jsonWriter.WriteArrayStart("favDecks"); foreach (TriadDeckNamed deck in favDecks) { jsonWriter.WriteObjectStart(); if (deck != null) { jsonWriter.WriteString(deck.Name, "name"); jsonWriter.WriteArrayStart("cards"); for (int Idx = 0; Idx < deck.knownCards.Count; Idx++) { jsonWriter.WriteInt(deck.knownCards[Idx].Id); } jsonWriter.WriteArrayEnd(); } jsonWriter.WriteObjectEnd(); } jsonWriter.WriteArrayEnd(); } if (!bLimitedMode) { jsonWriter.WriteObjectStart("images"); ImageHashDB.Get().StoreHashes(customHashes, jsonWriter); jsonWriter.WriteObjectEnd(); } jsonWriter.WriteObjectEnd(); } catch (Exception ex) { Logger.WriteLine("Saving failed! Exception:" + ex); } return(jsonWriter.ToString()); }
public bool LoadFromJson(string jsonStr) { TriadCardDB cardDB = TriadCardDB.Get(); TriadNpcDB npcDB = TriadNpcDB.Get(); ownedCards.Clear(); completedNpcs.Clear(); lastDeck.Clear(); favDecks.Clear(); try { JsonParser.ObjectValue jsonOb = JsonParser.ParseJson(jsonStr); JsonParser.ObjectValue uiOb = (JsonParser.ObjectValue)jsonOb["ui", null]; if (uiOb != null) { JsonParser.Value BoolTrue = new JsonParser.BoolValue(true); JsonParser.Value BoolFalse = new JsonParser.BoolValue(false); useXInput = (JsonParser.BoolValue)uiOb["xInput", BoolTrue]; alwaysOnTop = (JsonParser.BoolValue)uiOb["onTop", BoolFalse]; forcedLanguage = (JsonParser.StringValue)uiOb["lang", null]; TryGettingFloatValue(uiOb, "fontSize", ref fontSize); TryGettingFloatValue(uiOb, "markerCard", ref markerDurationCard); TryGettingFloatValue(uiOb, "markerSwap", ref markerDurationSwap); TryGettingFloatValue(uiOb, "markerCactpot", ref markerDurationCactpot); TryGettingIntValue(uiOb, "lastNpcId", ref lastNpcId); TryGettingFloatValue(uiOb, "lastWidth", ref lastWidth); TryGettingFloatValue(uiOb, "lastHeight", ref lastHeight); fontSize = Math.Min(Math.Max(fontSize, 10), 40); } JsonParser.ObjectValue cloudOb = (JsonParser.ObjectValue)jsonOb["cloud", null]; if (cloudOb != null) { useCloudStorage = (JsonParser.BoolValue)cloudOb["use", JsonParser.BoolValue.Empty]; cloudToken = (JsonParser.StringValue)cloudOb["token", null]; } JsonParser.ArrayValue cardsArr = (JsonParser.ArrayValue)jsonOb["cards", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in cardsArr.entries) { int cardId = (JsonParser.IntValue)value; ownedCards.Add(cardDB.cards[cardId]); } JsonParser.ArrayValue npcsArr = (JsonParser.ArrayValue)jsonOb["npcs", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in npcsArr.entries) { int npcId = (JsonParser.IntValue)value; completedNpcs.Add(npcDB.npcs[npcId]); } JsonParser.ArrayValue decksArr = (JsonParser.ArrayValue)jsonOb["decks", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in decksArr.entries) { JsonParser.ObjectValue deckOb = (JsonParser.ObjectValue)value; int npcId = (JsonParser.IntValue)deckOb["id"]; TriadNpc npc = TriadNpcDB.Get().npcs[npcId]; if (npc != null) { TriadDeck deckCards = new TriadDeck(); cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value cardValue in cardsArr.entries) { int cardId = (JsonParser.IntValue)cardValue; deckCards.knownCards.Add(cardDB.cards[cardId]); } lastDeck.Add(npc, deckCards); } } JsonParser.ArrayValue favDecksArr = (JsonParser.ArrayValue)jsonOb["favDecks", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value value in favDecksArr.entries) { JsonParser.ObjectValue deckOb = (JsonParser.ObjectValue)value; TriadDeckNamed deckCards = new TriadDeckNamed(); cardsArr = (JsonParser.ArrayValue)deckOb["cards", JsonParser.ArrayValue.Empty]; foreach (JsonParser.Value cardValue in cardsArr.entries) { int cardId = (JsonParser.IntValue)cardValue; deckCards.knownCards.Add(cardDB.cards[cardId]); } if (deckCards.knownCards.Count > 0) { deckCards.Name = deckOb["name", JsonParser.StringValue.Empty]; favDecks.Add(deckCards); } } JsonParser.ObjectValue imageHashesOb = (JsonParser.ObjectValue)jsonOb["images", null]; if (imageHashesOb != null) { customHashes = ImageHashDB.Get().LoadImageHashes(imageHashesOb); ImageHashDB.Get().hashes.AddRange(customHashes); } } catch (Exception ex) { Logger.WriteLine("Loading failed! Exception:" + ex); } Logger.WriteLine("Loaded player cards: " + ownedCards.Count + ", npcs: " + completedNpcs.Count + ", hashes: " + customHashes.Count); return(ownedCards.Count > 0); }