using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.Versioning;
using System.Security;
using System.Security.Permissions;
using System.Text.Json;
using System.Text.Json.Serialization;
using BepInEx;
using BepInEx.Core.Logging.Interpolation;
using BepInEx.Logging;
using BepInEx.Unity.IL2CPP;
using HarmonyLib;
using Il2CppInterop.Runtime.InteropTypes.Arrays;
using Il2CppSystem.Collections.Generic;
using Microsoft.CodeAnalysis;
using Nosebleed.Pancake.Achievements;
using Nosebleed.Pancake.DungeonEnvironment;
using Nosebleed.Pancake.GameCommands;
using Nosebleed.Pancake.GameConfig;
using Nosebleed.Pancake.GameConfig.Accessors;
using Nosebleed.Pancake.GameConfig.ShopConfigs.Arcana;
using Nosebleed.Pancake.GameLogic;
using Nosebleed.Pancake.GameLogic.GameStates;
using Nosebleed.Pancake.Models;
using Nosebleed.Pancake.ProceduralGeneration;
using Nosebleed.Pancake.RuntimeData;
using Nosebleed.Pancake.View;
using Nosebleed.Pancake.Weapons;
using Nosebleed.Util;
using UnityEngine;
using UnityEngine.Localization;
using UnityEngine.Localization.Tables;
[assembly: CompilationRelaxations(8)]
[assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)]
[assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)]
[assembly: TargetFramework(".NETCoreApp,Version=v6.0", FrameworkDisplayName = ".NET 6.0")]
[assembly: AssemblyCompany("VampireMod")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0")]
[assembly: AssemblyProduct("My first plugin")]
[assembly: AssemblyTitle("VampireMod")]
[assembly: SecurityPermission(SecurityAction.RequestMinimum, SkipVerification = true)]
[assembly: AssemblyVersion("1.0.0.0")]
[module: UnverifiableCode]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
internal sealed class EmbeddedAttribute : Attribute
{
}
}
namespace System.Runtime.CompilerServices
{
[CompilerGenerated]
[Microsoft.CodeAnalysis.Embedded]
[AttributeUsage(AttributeTargets.Module, AllowMultiple = false, Inherited = false)]
internal sealed class RefSafetyRulesAttribute : Attribute
{
public readonly int Version;
public RefSafetyRulesAttribute(int P_0)
{
Version = P_0;
}
}
}
namespace VampireMod
{
public class DataSender
{
private long LastUpdateTimestamp = 0L;
public void SendUpdate(List<Plugin.CardDataStatsly> floorCards, List<Plugin.CardDataStatsly> gameCards, bool forceUpdate = false)
{
Plugin.Instance.Log.LogInfo((object)"Sending update to statsly");
if (forceUpdate || IsUpdateNeeded())
{
object data = new { floorCards, gameCards };
var value = new
{
Event = "runUpdate",
Data = data
};
Plugin.Instance.LogToStatsly(JsonSerializer.Serialize(value));
}
}
private bool IsUpdateNeeded()
{
long num = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
long num2 = num - LastUpdateTimestamp;
if (num2 > 5000)
{
LastUpdateTimestamp = num;
return true;
}
return false;
}
}
public static class Dicts
{
public static Dictionary<string, int> CardDevNameToId = new Dictionary<string, int>
{
["Card_A_0_Bone"] = 0,
["Card_A_0_CherryBomb"] = 1,
["Card_A_0_Cross"] = 2,
["Card_A_0_Garlic"] = 3,
["Card_A_0_GorgeousMoon"] = 4,
["Card_A_0_Knife"] = 5,
["Card_A_0_Whip"] = 6,
["Card_A_1_FireWand"] = 7,
["Card_A_1_GattiAmari"] = 8,
["Card_A_1_KingBible"] = 9,
["Card_A_1_MagicWand"] = 10,
["Card_A_1_Runetracer"] = 11,
["Card_A_1_SoulEater"] = 12,
["Card_A_2_BloodyTear"] = 13,
["Card_A_2_Carrello"] = 14,
["Card_A_2_CelestialDusting"] = 15,
["Card_A_2_EightTheSparrow"] = 16,
["Card_A_2_HolyWand"] = 17,
["Card_A_2_LightningRing"] = 18,
["Card_A_2_UnholyVespers"] = 19,
["Card_A_2_ValkyrieTurner"] = 20,
["Card_A_2_ViciousHunger"] = 21,
["Card_A_3_Axe"] = 22,
["Card_A_3_DeathSpiral"] = 23,
["Card_A_3_HeavenSword"] = 24,
["Card_A_3_HellFire"] = 25,
["Card_A_3_NoFuture"] = 26,
["Card_A_3_SantaWater"] = 27,
["Card_A_3_ShadowPinion"] = 28,
["Card_A_3_ThousandEdge"] = 29,
["Card_A_4_LaBorra"] = 30,
["Card_A_4_Pentagram"] = 31,
["Card_A_4_PhieraDerTuphello"] = 32,
["Card_A_4_Phieraggi"] = 33,
["Card_A_4_Thunderloop"] = 34,
["Card_A_5_Peachone"] = 35,
["Card_A_5_Vandalier"] = 36,
["Card_A_6_EbonyWings"] = 37,
["Card_AngeloSpietato"] = 38,
["Card_B_0_EmptyTome"] = 39,
["Card_B_0_RawMana"] = 40,
["Card_B_1_EmptyTome"] = 41,
["Card_B_2_EmptyTome"] = 42,
["Card_B_3_EmptyTome"] = 43,
["Card_Confuse"] = 44,
["Card_CursedLancet"] = 45,
["Card_D_0_Armor"] = 46,
["Card_D_1_Armor"] = 47,
["Card_D_2_Armor"] = 48,
["Card_D_3_ClockLancet"] = 49,
["Card_E_BagOfCoins"] = 50,
["Card_E_CloverPetal"] = 51,
["Card_E_CoinPurse"] = 52,
["Card_E_LargeBagOfCoins"] = 53,
["Card_E_LittleClover"] = 54,
["Card_E_LittleHeart"] = 55,
["Card_E_Orologion"] = 56,
["Card_E_Rosary"] = 57,
["Card_E_Vacuum"] = 58,
["Card_M_0_Wings"] = 59,
["Card_M_3_SongOfMana"] = 60,
["Card_M_5_Mannajja"] = 61,
["Card_ManaBomb"] = 62,
["Card_Muddle"] = 63,
["Card_S_0_Candelabrador"] = 64,
["Card_S_0_SkullOManic"] = 65,
["Card_S_1_Attractorb"] = 66,
["Card_S_1_Candelabrador"] = 67,
["Card_S_1_Crown"] = 68,
["Card_S_1_Duplicator"] = 69,
["Card_S_1_HollowHeart"] = 70,
["Card_S_1_Pummarola"] = 71,
["Card_S_1_SpellBinder"] = 72,
["Card_S_1_Spinach"] = 73,
["Card_S_1_StoneMask"] = 74,
["Card_S_2_Bracer"] = 75,
["Card_S_2_Candelabrador"] = 76,
["Card_S_2_Clover"] = 77,
["Card_S_2_Crown"] = 78,
["Card_S_2_Duplicator"] = 79,
["Card_S_2_HollowHeart"] = 80,
["Card_S_2_Pummarola"] = 81,
["Card_S_2_Spinach"] = 82,
["Card_S_2_Tiramisu"] = 83,
["Card_Shatter"] = 84,
["Card_W_Bracelet"] = 85,
["Card_W_Combo"] = 86,
["Card_W_WildDefence"] = 87,
["FCC_Antonio"] = 88,
["FCC_Arca"] = 89,
["FCC_Cavallo"] = 90,
["FCC_Christine"] = 91,
["FCC_Clerici"] = 92,
["FCC_Concetta"] = 93,
["FCC_Divano"] = 94,
["FCC_Dommario"] = 95,
["FCC_Gallo"] = 96,
["FCC_Gennaro"] = 97,
["FCC_Giovanna"] = 98,
["FCC_Imelda"] = 99,
["FCC_Krochi"] = 100,
["FCC_Lama"] = 101,
["FCC_MissingNo"] = 102,
["FCC_Mortaccio"] = 103,
["FCC_OSole"] = 104,
["FCC_Pasqualina"] = 105,
["FCC_Poe"] = 106,
["FCC_Poppea"] = 107,
["FCC_Porta"] = 108,
["FCC_Pugnala"] = 109,
["FCC_Ramba"] = 110
};
public static Dictionary<string, int> ArcanaDevNameToId = new Dictionary<string, int>
{
["ArcanaConfig_AndAnother"] = 0,
["ArcanaConfig_ChainLink"] = 1,
["ArcanaConfig_ExperimentalMedicine"] = 2,
["ArcanaConfig_JestersHat"] = 3,
["ArcanaConfig_MakeAScene"] = 4,
["ArcanaConfig_ManaSyphon"] = 5,
["ArcanaConfig_OverTheTop"] = 6,
["ArcanaConfig_SharpMind"] = 7,
["ArcanaConfig_ShieldBash"] = 8,
["ArcanaConfig_SwollenFist"] = 9,
["ArcanaConfig_WildStrength"] = 10,
["ArcanaConfig_YourShield"] = 11
};
public static Dictionary<string, int> DungeonDevNameToId = new Dictionary<string, int>
{
["Dungeon_CappellaMagna_01"] = 0,
["Dungeon_CappellaMagna_02"] = 1,
["Dungeon_DairyPlant_01"] = 2,
["Dungeon_DairyPlant_02"] = 3,
["Dungeon_DairyPlant_03"] = 4,
["Dungeon_GalloTower_01"] = 5,
["Dungeon_InlaidLibrary_01"] = 6,
["Dungeon_InlaidLibrary_02"] = 7,
["Dungeon_InlaidLibrary_03"] = 8,
["Dungeon_Madforest_01"] = 9,
["Dungeon_Madforest_02"] = 10,
["Dungeon_Madforest_03"] = 11,
["Dungeon_TinyBridge_01"] = 12,
["Dungeon_TinyBridge_02"] = 13,
["Dungeon_TinyBridge_03"] = 14,
["Dungeon_Tutorial"] = 15
};
public static Dictionary<string, int> EnemyDevNameToId = new Dictionary<string, int>
{
["EnemyConfig_1000Health_Test"] = 0,
["EnemyConfig_1HealthBoss_Test"] = 1,
["EnemyConfig_AmbushMantisElite"] = 2,
["EnemyConfig_ApprenticeWitch"] = 3,
["EnemyConfig_ArchDemon"] = 4,
["EnemyConfig_ArchDemonElite"] = 5,
["EnemyConfig_ArchonOro"] = 6,
["EnemyConfig_ArchonSpada"] = 7,
["EnemyConfig_ArconAscia"] = 8,
["EnemyConfig_Bat"] = 9,
["EnemyConfig_Bat_COWARD"] = 10,
["EnemyConfig_Bat_Elite"] = 11,
["EnemyConfig_Bat_Glowing"] = 12,
["EnemyConfig_Bat_Glowing-T2"] = 13,
["EnemyConfig_Bat_Glowing-T3"] = 14,
["EnemyConfig_Bat_Glowing-T4"] = 15,
["EnemyConfig_Bat_Tutorial00"] = 16,
["EnemyConfig_Bat_Tutorial01"] = 17,
["EnemyConfig_Bat_Tutorial01_NoXP"] = 18,
["EnemyConfig_Bat_Tutorial02"] = 19,
["EnemyConfig_Bat_Tutorial03"] = 20,
["EnemyConfig_Bat_Tutorial03_FullXP"] = 21,
["EnemyConfig_Bat_Tutorial04"] = 22,
["EnemyConfig_Bat_Tutorial05"] = 23,
["EnemyConfig_Bat_Tutorial06"] = 24,
["EnemyConfig_Bat_Weak"] = 25,
["EnemyConfig_BeastDemon"] = 26,
["EnemyConfig_BeastDemonElite"] = 27,
["EnemyConfig_BeastDemonElite_Ambush"] = 28,
["EnemyConfig_Brazier_Weak"] = 29,
["EnemyConfig_BridgeGuardian"] = 30,
["EnemyConfig_CollosalFlameElite"] = 31,
["EnemyConfig_DevilElite"] = 32,
["EnemyConfig_Dragonshrimp"] = 33,
["EnemyConfig_Drowner"] = 34,
["EnemyConfig_Durga"] = 35,
["EnemyConfig_Ecto"] = 36,
["EnemyConfig_EctoElite"] = 37,
["EnemyConfig_EnderEliteP1"] = 38,
["EnemyConfig_EnderEliteP2"] = 39,
["EnemyConfig_EyeBallElite"] = 40,
["EnemyConfig_EyeBallElite_Ambush"] = 41,
["EnemyConfig_FallenAngel"] = 42,
["EnemyConfig_FallenAngelElite"] = 43,
["EnemyConfig_FallenArchangel"] = 44,
["EnemyConfig_FallenThrone"] = 45,
["EnemyConfig_FishmanElite"] = 46,
["EnemyConfig_FlowerWall"] = 47,
["EnemyConfig_FlowerWallThorny"] = 48,
["EnemyConfig_GalloElite"] = 49,
["EnemyConfig_Gallotrice"] = 50,
["EnemyConfig_GallotriceElite"] = 51,
["EnemyConfig_Ghiavolo"] = 52,
["EnemyConfig_Ghost"] = 53,
["EnemyConfig_GhostElite"] = 54,
["EnemyConfig_GhostElite_Ambush"] = 55,
["EnemyConfig_Ghoul"] = 56,
["EnemyConfig_GiantArmouredKnightElite"] = 57,
["EnemyConfig_GiantArmouredKnightElite_Ambush"] = 58,
["EnemyConfig_GiantBat"] = 59,
["EnemyConfig_GiantCrabElite"] = 60,
["EnemyConfig_GiantCrabElite_Ambush"] = 61,
["EnemyConfig_GiantMummy"] = 62,
["EnemyConfig_GiantMummy_Elite"] = 63,
["EnemyConfig_GiantSkulloneElite"] = 64,
["EnemyConfig_GiantSkulloneElite_Ambush"] = 65,
["EnemyConfig_GlowingBat_Elite"] = 66,
["EnemyConfig_GlowingBat_Elite-Mid"] = 67,
["EnemyConfig_GlowingBat_Elite-T3"] = 68,
["EnemyConfig_GlowingBat_Elite-T4"] = 69,
["EnemyConfig_Golem"] = 70,
["EnemyConfig_GolemElite"] = 71,
["EnemyConfig_GreenKnight"] = 72,
["EnemyConfig_GreenKnightElite"] = 73,
["EnemyConfig_Guardian1"] = 74,
["EnemyConfig_Guardian2"] = 75,
["EnemyConfig_Guardian3"] = 76,
["EnemyConfig_Guardian4"] = 77,
["EnemyConfig_Guardian5"] = 78,
["EnemyConfig_HagElite"] = 79,
["EnemyConfig_HarpyElite"] = 80,
["EnemyConfig_Harpy_Weak"] = 81,
["EnemyConfig_Impefinger"] = 82,
["EnemyConfig_Kali"] = 83,
["EnemyConfig_LionHead"] = 84,
["EnemyConfig_LionHeadElite"] = 85,
["EnemyConfig_LizardElite"] = 86,
["EnemyConfig_LizardPawn"] = 87,
["EnemyConfig_LostTwinElite"] = 88,
["EnemyConfig_ManitcoreElite"] = 89,
["EnemyConfig_MantisElite"] = 90,
["EnemyConfig_MasterWitchElite"] = 91,
["EnemyConfig_Merman"] = 92,
["EnemyConfig_MermanElite_Ambush"] = 93,
["EnemyConfig_MilkElemental"] = 94,
["EnemyConfig_MilkElementalElite"] = 95,
["EnemyConfig_Minotaur"] = 96,
["EnemyConfig_MinotaurElite"] = 97,
["EnemyConfig_MinotaurElite_Ambush"] = 98,
["EnemyConfig_MoonAtlantean"] = 99,
["EnemyConfig_MudMan"] = 100,
["EnemyConfig_MudMan_Weak"] = 101,
["EnemyConfig_MudmanElite"] = 102,
["EnemyConfig_NesuferitElite"] = 103,
["EnemyConfig_QueenMedusaElite"] = 104,
["EnemyConfig_QueenMedusaElite_Ambush"] = 105,
["EnemyConfig_Raiju"] = 106,
["EnemyConfig_RedDeath"] = 107,
["EnemyConfig_Scarleton"] = 108,
["EnemyConfig_ShadeBomb"] = 109,
["EnemyConfig_Skeleton2"] = 110,
["EnemyConfig_Skeleton3"] = 111,
["EnemyConfig_Skeleton3_Elite"] = 112,
["EnemyConfig_Skullino"] = 113,
["EnemyConfig_SneakyHead"] = 114,
["EnemyConfig_Succubus"] = 115,
["EnemyConfig_SuccubusElite"] = 116,
["EnemyConfig_SunAtlantean"] = 117,
["EnemyConfig_SwordRussel"] = 118,
["EnemyConfig_SwordiLee"] = 119,
["EnemyConfig_Swordian"] = 120,
["EnemyConfig_TestArmorAction"] = 121,
["EnemyConfig_TestDamageAction"] = 122,
["EnemyConfig_TestDebuffEnemy"] = 123,
["EnemyConfig_TestKnockbackResist"] = 124,
["EnemyConfig_TraineeRedReaper"] = 125,
["EnemyConfig_TreasureBat_Elite"] = 126,
["EnemyConfig_Trickster"] = 127,
["EnemyConfig_TrinacriaElite"] = 128,
["EnemyConfig_TritontElite"] = 129,
["EnemyConfig_TwinDemon"] = 130,
["EnemyConfig_Venus"] = 131,
["EnemyConfig_Werewolf"] = 132,
["EnemyConfig_WerewolfElite"] = 133,
["EnemyConfig_Werewolf_Weak"] = 134,
["EnemyConfig_Zombie"] = 135,
["EnemyConfig_Zombie_Elite"] = 136,
["EnemyConfig_Zombie_Test"] = 137,
["EnemyConfig_Zombie_Test_NoXP"] = 138,
["EnemyConfig_Zombie_Weak"] = 139
};
public static int GetOrCreateId(string value, Dictionary<string, int> knownValues)
{
if (knownValues.TryGetValue(value, out var value2))
{
return value2;
}
int num = -2128831035;
foreach (char c in value)
{
num = (num ^ c) * 16777619;
}
return Math.Abs(num);
}
}
public class FloorTransitionStatePatch
{
[HarmonyPatch(typeof(FloorTransitionState), "OnDungeonGenerated")]
public static class OnDungeonGenerated
{
public static void Prefix(FloorTransitionState __instance, TiledMapData _)
{
Plugin.Instance.rm.OnFloorLoaded(_);
}
}
}
public class RunStartStatePatch
{
[HarmonyPatch(typeof(RunStartState), "OnDungeonLoaded")]
public static class OnDungeonLoaded
{
public static void Prefix(TiledMapData _)
{
Plugin.Instance.rm.ClearCurrentRunFile();
Plugin.Instance.rm.OnFloorLoaded(_);
}
}
}
public class DungeonModelPatch
{
[HarmonyPatch(typeof(DestructibleBehaviour), "SetDestroyed")]
public static class SetDestroyed
{
public static void Prefix(DestructibleBehaviour __instance)
{
//IL_0011: Unknown result type (might be due to invalid IL or missing references)
//IL_0017: Expected O, but got Unknown
//IL_0046: Unknown result type (might be due to invalid IL or missing references)
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
ManualLogSource log = Plugin.Instance.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(13, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("SetDestroyed ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<DestructibleType>(__instance.Type);
}
log.LogInfo(val);
Plugin.Instance.rm.AddDestructible(__instance.Type);
}
}
}
public class Dungeon3DMapModelPatch
{
[HarmonyPatch(typeof(Dungeon3DMapModel), "OnDungeonLoaded")]
public static class OnDungeonLoaded
{
public static void Prefix(Dungeon3DMapModel __instance, DungeonConfig dungeonConfig)
{
TiledMapData mapData = __instance.MapData;
Plugin.Instance.rm.OnFloorLoaded(mapData);
Plugin.Instance.rm.TryLoadCurrentRun();
}
}
}
public class GameModelPatch
{
[HarmonyPatch(typeof(GameModel), "OnDungeonComplete")]
public static class OnDungeonComplete
{
public static void Postfix(GameModel __instance)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_008f: Unknown result type (might be due to invalid IL or missing references)
//IL_0096: Expected O, but got Unknown
ManualLogSource log = Plugin.Instance.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(17, 0, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Dungeon Completed");
}
log.LogInfo(val);
double currentTimeInRun = __instance.CurrentTimeInRun;
int difficultyRating = __instance.Dungeon.DungeonConfig.DifficultyRating;
int playerLevel = __instance.PlayerModel.PlayerLevel;
List<ArcanaConfig> activeArcanas = Globals.PlayerRunSettings._activeArcanas;
List<int> list = new List<int>();
Enumerator<ArcanaConfig> enumerator = activeArcanas.GetEnumerator();
while (enumerator.MoveNext())
{
ArcanaConfig current = enumerator.Current;
ManualLogSource log2 = Plugin.Instance.Log;
val = new BepInExInfoLogInterpolatedStringHandler(7, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("arcana ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<TableReference>(((LocalizedReference)current.LocalizedName).TableReference);
}
log2.LogInfo(val);
list.Add(Dicts.GetOrCreateId(current.AssetId, Dicts.ArcanaDevNameToId));
}
Plugin.Instance.rm.RunEnded(isCompleted: true, currentTimeInRun, difficultyRating, playerLevel, list);
}
}
[HarmonyPatch(typeof(GameModel), "OnGameOver")]
public static class OnGameOver
{
public static void Postfix(GameModel __instance)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0019: Expected O, but got Unknown
//IL_00e7: Unknown result type (might be due to invalid IL or missing references)
//IL_00ee: Expected O, but got Unknown
ManualLogSource log = Plugin.Instance.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(14, 0, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Dungeon failed");
}
log.LogInfo(val);
double currentTimeInRun = __instance.CurrentTimeInRun;
int difficultyRating = __instance.Dungeon.DungeonConfig.DifficultyRating;
int playerLevel = __instance.PlayerModel.PlayerLevel;
List<ArcanaConfig> activeArcanas = Globals.PlayerRunSettings._activeArcanas;
List<int> list = new List<int>();
Enumerator<ArcanaConfig> enumerator = activeArcanas.GetEnumerator();
while (enumerator.MoveNext())
{
ArcanaConfig current = enumerator.Current;
list.Add(Dicts.GetOrCreateId(current.AssetId, Dicts.ArcanaDevNameToId));
}
Plugin.Instance.rm.RunEnded(isCompleted: false, __instance.CurrentTimeInRun, difficultyRating, playerLevel, list);
int num = SingletonMonoBehaviour<AchievementManager>.Instance.NumberOfVisibleAchievementsUnlocked();
int num2 = SingletonMonoBehaviour<AchievementManager>.Instance.NumberOfVisibleAchievements(true);
ManualLogSource log2 = Plugin.Instance.Log;
val = new BepInExInfoLogInterpolatedStringHandler(17, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Achievements: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" / ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(num2);
}
log2.LogInfo(val);
}
}
}
public class DamageEffectPatch
{
[HarmonyPatch(typeof(DamageEffect), "ApplyDamage", new Type[]
{
typeof(PlayerModel),
typeof(CardModel),
typeof(CardConfig),
typeof(IEncounterModel),
typeof(StatSnapshot),
typeof(List<EnemyModel>),
typeof(List<EnemyDamageInfo>),
typeof(List<int>),
typeof(List<int>),
typeof(CritEffectType),
typeof(Il2CppReferenceArray<CardEffect>),
typeof(bool)
})]
public static class ApplyDamage
{
public static void Postfix(PlayerModel playerModel, CardModel cardModel, CardConfig cardConfig, IEncounterModel encounterModel, StatSnapshot playerStats, List<EnemyModel> enemyModels, List<EnemyDamageInfo> enemyDamages, List<int> enemiesPiercedPerAmount, List<int> areaHitCounts, CritEffectType critEffectType, Il2CppReferenceArray<CardEffect> criticalEffects, bool isInCombo)
{
//IL_0028: Unknown result type (might be due to invalid IL or missing references)
//IL_002d: Unknown result type (might be due to invalid IL or missing references)
//IL_0030: Unknown result type (might be due to invalid IL or missing references)
//IL_0036: Unknown result type (might be due to invalid IL or missing references)
int orCreateId = Dicts.GetOrCreateId(cardConfig.AssetId, Dicts.CardDevNameToId);
double num = 0.0;
Enumerator<EnemyDamageInfo> enumerator = enemyDamages.GetEnumerator();
while (enumerator.MoveNext())
{
EnemyDamageInfo current = enumerator.Current;
num += current.healthDamage + current.armorDamage;
}
Plugin.Instance.rm.PlayerDealDamages(orCreateId, num);
}
}
}
public class CardModelPatch
{
[HarmonyPatch(typeof(CardModel), "OnPlayCard")]
public static class OnPlayCard
{
public static void Postfix(CardModel __instance, PlayerModel playerModel, StatSnapshot playerStats, bool wasTriggeredByCardEffect, bool useCommandQueue, bool isCardInCombo)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004c: Expected O, but got Unknown
string assetId = __instance.CardConfig.AssetId;
int orCreateId = Dicts.GetOrCreateId(assetId, Dicts.CardDevNameToId);
bool flag = playerModel.ComboMultiplier - Plugin.Instance.rm.PreviousComboCount >= 0;
ManualLogSource log = Plugin.Instance.Log;
bool flag2 = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(8, 4, ref flag2);
if (flag2)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("card ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(orCreateId);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(isCardInCombo);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<bool>(flag);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(playerModel.ComboMultiplier);
}
log.LogInfo(val);
Plugin.Instance.rm.CardPlayed(orCreateId, flag, playerModel.ComboMultiplier);
Plugin.Instance.rm.PreviousComboCount = playerModel.ComboMultiplier;
}
}
[HarmonyPatch(typeof(CardModel), "TryAddGemToEmptySlot")]
public static class TryAddGemToEmptySlot
{
public static void Postfix(CardModel __instance, ref bool __result, GemConfig gemConfig)
{
if (__result)
{
Plugin.Instance.Log.LogInfo((object)"GEM INSERTED");
Plugin.Instance.rm.OnGemInserted();
}
}
}
}
public class BreakableCardPatch
{
[HarmonyPatch(typeof(BreakableCard), "SetCrackState")]
public static class SetCrackState
{
public static void Postfix(CardCrackState crackState)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Plugin.Instance.rm.CardCracked(crackState);
}
}
}
public class Dungeon3DMapViewPatch
{
[HarmonyPatch(typeof(Dungeon3DMapView), "MoveToMapCoords")]
public static class MoveToMapCoords
{
public static void Postfix(Vector2Int fromCoords, Vector2Int toCoords, TileExitDirections fromDir)
{
//IL_000b: Unknown result type (might be due to invalid IL or missing references)
Plugin.Instance.rm.TileVisited(toCoords);
}
}
}
public class PlayerModelPatch
{
[HarmonyPatch(typeof(PlayerModel), "ResolveDamage")]
public static class ResolveDamage
{
public static void Prefix(PlayerModel __instance, int amount)
{
if (amount <= 160)
{
float value = __instance._playerStats.Armor.Value;
int num = (int)Math.Max(0f, (float)amount - value);
int armored = amount - num;
Plugin.Instance.rm.EnemyDamagesHit(num, armored);
}
}
}
[HarmonyPatch(typeof(PlayerModel), "OnStartTurn")]
public static class OnStartTurn
{
public static void Prefix()
{
Plugin.Instance.rm.PreviousComboCount = 0;
Plugin.Instance.rm.OnPlayerTurnEnded();
}
}
[HarmonyPatch(typeof(PlayerModel), "OnPlayerDeath")]
public static class OnPlayerDeath
{
public static void Prefix()
{
Plugin.Instance.rm.TryAddTimelineEvent(0);
}
}
}
public class EnemyModelPatch
{
[HarmonyPatch(typeof(EnemyModel), "OnDied")]
public static class OnDied
{
public static void Prefix(EnemyModel __instance, CardModel cardThatKilled)
{
int orCreateId = Dicts.GetOrCreateId(cardThatKilled.CardConfig.AssetId, Dicts.CardDevNameToId);
int orCreateId2 = Dicts.GetOrCreateId(__instance.EnemyConfig.AssetId, Dicts.EnemyDevNameToId);
Plugin.Instance.rm.MonsterKilled(orCreateId, orCreateId2);
}
}
[HarmonyPatch(typeof(EnemyModel), "ResolveDamage")]
public static class ResolveDamage
{
public static void Postfix(EnemyModel __instance, ref DamageResult __result, double damage)
{
string assetId = __instance.EnemyConfig.AssetId;
int orCreateId = Dicts.GetOrCreateId(assetId, Dicts.EnemyDevNameToId);
Plugin.Instance.rm.MonsterReceivesDamages(orCreateId, __result.ArmorDamage + __result.HealthDamage, __result.OverkillDamage);
}
}
}
public class EnemyEncounterModelPatch
{
[HarmonyPatch(typeof(EnemyEncounterModel), "OnEncounterDefeated")]
public static class OnEncounterDefeated
{
public static void Prefix()
{
Plugin.Instance.rm.OnEncounterDefeated();
Plugin.Instance.rm.OnPlayerTurnEnded();
}
}
[HarmonyPatch(typeof(EnemyEncounterModel), "PopulateEnemies")]
public static class PopulateEnemies
{
public static void Prefix()
{
Plugin.Instance.rm.TryAddTimelineEvent(1);
}
}
}
[BepInPlugin("VampireMod", "My first plugin", "1.0.0")]
public class Plugin : BasePlugin
{
public struct LogEntry
{
public string Name;
public string AssetId;
}
public class CardDataStatsly
{
public int Id { get; set; }
public int PlayedCount { get; set; }
public long Damages { get; set; }
public int Kills { get; set; }
public double DamagesPerUse { get; set; }
}
public ManualLogSource Log;
public static Plugin Instance;
public RunManager rm = new RunManager();
public override void Load()
{
//IL_001f: Unknown result type (might be due to invalid IL or missing references)
//IL_0025: Expected O, but got Unknown
//IL_0059: Unknown result type (might be due to invalid IL or missing references)
//IL_005f: Expected O, but got Unknown
//IL_008d: Unknown result type (might be due to invalid IL or missing references)
//IL_0093: Expected O, but got Unknown
Instance = this;
Log = ((BasePlugin)this).Log;
ManualLogSource log = Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Plugin ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>("VampireMod");
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" is loaded!");
}
log.LogInfo(val);
Harmony val2 = new Harmony("VampireMod");
val2.PatchAll();
foreach (MethodBase patchedMethod in val2.GetPatchedMethods())
{
ManualLogSource log2 = Log;
val = new BepInExInfoLogInterpolatedStringHandler(10, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Patched: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(patchedMethod.DeclaringType?.Name);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(".");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(patchedMethod.Name);
}
log2.LogInfo(val);
}
}
public void LogToStatsly(string message)
{
using StreamWriter streamWriter = File.AppendText(GetMegaBonkFilePath());
streamWriter.WriteLine(message);
}
private string GetMegaBonkFilePath()
{
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string text = Path.Combine(folderPath, "Statly");
string result = Path.Combine(text, "vampireCrawlers.txt");
if (!Directory.Exists(text))
{
Directory.CreateDirectory(text);
}
return result;
}
public void Localize(string lang)
{
string path = "B:\\DevProjects\\Python\\VampireCrawlersTranslations\\" + lang;
Dictionary<int, string> dictionary = new Dictionary<int, string>();
Dictionary<string, int> trsltArcanas = new Dictionary<string, int>();
LocalizeArcana(Databases.ArcanaConfigs.AndAnother, dictionary, trsltArcanas, 0);
LocalizeArcana(Databases.ArcanaConfigs.ChainLink, dictionary, trsltArcanas, 1);
LocalizeArcana(Databases.ArcanaConfigs.ExperimentalMedicine, dictionary, trsltArcanas, 2);
LocalizeArcana(Databases.ArcanaConfigs.JestersHat, dictionary, trsltArcanas, 3);
LocalizeArcana(Databases.ArcanaConfigs.MakeAScene, dictionary, trsltArcanas, 4);
LocalizeArcana(Databases.ArcanaConfigs.ManaSyphon, dictionary, trsltArcanas, 5);
LocalizeArcana(Databases.ArcanaConfigs.OverTheTop, dictionary, trsltArcanas, 6);
LocalizeArcana(Databases.ArcanaConfigs.SharpMind, dictionary, trsltArcanas, 7);
LocalizeArcana(Databases.ArcanaConfigs.ShieldBash, dictionary, trsltArcanas, 8);
LocalizeArcana(Databases.ArcanaConfigs.SwollenFist, dictionary, trsltArcanas, 9);
LocalizeArcana(Databases.ArcanaConfigs.WildStrength, dictionary, trsltArcanas, 10);
LocalizeArcana(Databases.ArcanaConfigs.YourShield, dictionary, trsltArcanas, 11);
Dictionary<int, string> dictionary2 = new Dictionary<int, string>();
Dictionary<string, int> trsltCards = new Dictionary<string, int>();
LocalizeCards(dictionary2, trsltCards);
Dictionary<int, string> dictionary3 = new Dictionary<int, string>();
Dictionary<string, int> trsltDungeons = new Dictionary<string, int>();
LocalizeDungeons(dictionary3, trsltDungeons);
Dictionary<int, string> monsters = new Dictionary<int, string>();
Dictionary<string, int> trsltMonsters = new Dictionary<string, int>();
LocalizeMonsters(monsters, trsltMonsters);
JsonSerializerOptions options = new JsonSerializerOptions
{
WriteIndented = true
};
File.WriteAllText(Path.Combine(path, "dungeons.json"), JsonSerializer.Serialize(dictionary3, options));
File.WriteAllText(Path.Combine(path, "cards.json"), JsonSerializer.Serialize(dictionary2, options));
File.WriteAllText(Path.Combine(path, "arcanas.json"), JsonSerializer.Serialize(dictionary, options));
}
public static string GetCleanEnemyName(string assetId)
{
if (string.IsNullOrEmpty(assetId))
{
return string.Empty;
}
assetId = assetId.Replace("EnemyConfig_", "");
HashSet<string> ignore = new HashSet<string>(StringComparer.OrdinalIgnoreCase) { "Test", "Tutorial", "NoXP" };
List<string> values = (from p in assetId.Split('_', StringSplitOptions.RemoveEmptyEntries)
where !ignore.Contains(p) && !p.All(char.IsDigit)
select p).ToList();
string text = string.Join(" ", values);
return text.Replace("Elite", "(Elite)").Replace("Ambush", "(Ambush)");
}
private void LocalizeMonsters(Dictionary<int, string> monsters, Dictionary<string, int> trsltMonsters)
{
ValueCollection<string, EnemyConfig> values = ((AssetDatabase<EnemyConfig>)(object)Databases.Enemies)._assetIdMap.Values;
List<LogEntry> list = new List<LogEntry>();
Enumerator<string, EnemyConfig> enumerator = values.GetEnumerator();
while (enumerator.MoveNext())
{
EnemyConfig current = enumerator.Current;
try
{
string assetId = current.AssetId;
list.Add(new LogEntry
{
Name = GetCleanEnemyName(assetId),
AssetId = assetId
});
}
catch
{
}
}
list.Sort((LogEntry a, LogEntry b) => string.CompareOrdinal(a.AssetId, b.AssetId));
int num = 0;
foreach (LogEntry item in list)
{
monsters[num] = item.Name;
trsltMonsters[item.AssetId] = num;
num++;
}
}
private void LocalizeDungeons(Dictionary<int, string> dungeons, Dictionary<string, int> trsltDungeons)
{
//IL_006b: Unknown result type (might be due to invalid IL or missing references)
//IL_0072: Expected O, but got Unknown
List<DungeonConfig> assetList = ((AssetGroup<DungeonConfig>)(object)Databases.Dungeons)._assetList;
List<LogEntry> list = new List<LogEntry>();
Enumerator<DungeonConfig> enumerator = assetList.GetEnumerator();
bool flag = default(bool);
while (enumerator.MoveNext())
{
DungeonConfig current = enumerator.Current;
try
{
if (current.Name != null && current.AssetId != null && !current.AssetId.Contains("TestDungeonConfig"))
{
ManualLogSource log = Instance.Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(9, 2, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("dungeon ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(current.AssetId);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(current.Name);
}
log.LogInfo(val);
list.Add(new LogEntry
{
Name = current.Name,
AssetId = current.AssetId
});
}
}
catch (Exception)
{
}
}
list.Sort((LogEntry a, LogEntry b) => string.CompareOrdinal(a.AssetId, b.AssetId));
int num = 0;
foreach (LogEntry item in list)
{
dungeons[num] = item.Name;
trsltDungeons[item.AssetId] = num;
num++;
}
}
private void LocalizeCards(Dictionary<int, string> cards, Dictionary<string, int> trsltCards)
{
Dictionary<CardGroup, List<CardConfig>> cardGroupCardMap = Databases.CardConfigs._cardGroupCardMap;
List<LogEntry> list = new List<LogEntry>();
Enumerator<CardGroup, List<CardConfig>> enumerator = cardGroupCardMap.GetEnumerator();
while (enumerator.MoveNext())
{
KeyValuePair<CardGroup, List<CardConfig>> current = enumerator.Current;
string groupName = current.Key.groupName;
if (groupName == "Test Card Group")
{
continue;
}
Enumerator<CardConfig> enumerator2 = current.Value.GetEnumerator();
while (enumerator2.MoveNext())
{
CardConfig current2 = enumerator2.Current;
if ((!current2.IsDisabled || !(current2.Name != "Card_D_3_Armor")) && !current2.AssetId.Contains("Test"))
{
list.Add(new LogEntry
{
Name = current2.Name,
AssetId = current2.AssetId
});
}
}
}
list.Sort((LogEntry a, LogEntry b) => string.CompareOrdinal(a.AssetId, b.AssetId));
int num = 0;
foreach (LogEntry item in list)
{
cards[num] = item.Name;
trsltCards[item.AssetId] = num;
num++;
}
}
private void LocalizeArcana(ArcanaConfig config, Dictionary<int, string> arcanas, Dictionary<string, int> trsltArcanas, int index)
{
string assetId = config.AssetId;
string name = config.Name;
arcanas[index] = name;
trsltArcanas[assetId] = index;
}
}
public class RunManager
{
private DataSender Sender { get; set; } = new DataSender();
private List<TimelineEvent> Timeline { get; set; } = new List<TimelineEvent>();
public int PreviousComboCount { get; set; } = 0;
private double TotalDamagesDealt { get; set; } = 0.0;
private int TotalDamagesTaken { get; set; } = 0;
private int TotalDamagesTanked { get; set; } = 0;
private int TotalEncountersDefeatedCount { get; set; } = 0;
private int CurrentFloorIndex { get; set; } = 0;
private int CurrentEncounterStart { get; set; } = 0;
private Dictionary<int, FloorData> FloorsData { get; set; } = new Dictionary<int, FloorData>();
private int TotalMovementsCount { get; set; } = 0;
private int TotalTilesVisited { get; set; } = 0;
private int TotalCardsPlayedCount { get; set; } = 0;
private int TotalCardsInComboCount { get; set; } = 0;
private int MaxComboReached { get; set; } = 0;
private Dictionary<int, int> TotalCardsPlayed { get; set; } = new Dictionary<int, int>();
private Dictionary<int, int> TotalCardsKills { get; set; } = new Dictionary<int, int>();
private Dictionary<int, double> TotalCardsDamages { get; set; } = new Dictionary<int, double>();
private int TotalBestDamageCardId { get; set; } = 0;
private int TotalBestDamageCardDamages { get; set; } = 0;
private int TotalMonstersKilledCount { get; set; } = 0;
private int TotalMonstersKnockedCount { get; set; } = 0;
private double TotalOverkillDamagesCount { get; set; } = 0.0;
private Dictionary<int, double> TotalMonstersDamages { get; set; } = new Dictionary<int, double>();
private Dictionary<int, int> TotalMonstersKills { get; set; } = new Dictionary<int, int>();
private int? CrawlerId { get; set; } = null;
private int? DungeonId { get; set; } = null;
private int BreakingCardCount { get; set; } = 0;
private int FullyBrokenCardCount { get; set; } = 0;
private int EvolutionsCount { get; set; } = 0;
private List<int> Arcanas { get; set; } = new List<int>();
private Dictionary<DestructibleType, int> Destructibles { get; set; } = new Dictionary<DestructibleType, int>();
private int TotalGemsInserted { get; set; } = 0;
public RunManager()
{
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
foreach (DestructibleType value in Enum.GetValues(typeof(DestructibleType)))
{
Destructibles[value] = 0;
}
}
public void TryAddTimelineEvent(int eventId)
{
try
{
int timestamp = (int)SingletonMonoBehaviour<GameModel>.Instance.CurrentTimeInRun;
TimelineEvent item = new TimelineEvent
{
EventId = eventId,
Timestamp = timestamp
};
Timeline.Add(item);
}
catch
{
}
}
private void clear()
{
//IL_014f: Unknown result type (might be due to invalid IL or missing references)
//IL_0154: Unknown result type (might be due to invalid IL or missing references)
//IL_015c: Unknown result type (might be due to invalid IL or missing references)
PreviousComboCount = 0;
TotalDamagesDealt = 0.0;
TotalDamagesTaken = 0;
TotalDamagesTanked = 0;
TotalEncountersDefeatedCount = 0;
CurrentFloorIndex = 0;
FloorsData = new Dictionary<int, FloorData>();
TotalMovementsCount = 0;
TotalTilesVisited = 0;
TotalCardsPlayedCount = 0;
TotalCardsInComboCount = 0;
MaxComboReached = 0;
TotalCardsPlayed = new Dictionary<int, int>();
TotalCardsKills = new Dictionary<int, int>();
TotalCardsDamages = new Dictionary<int, double>();
TotalBestDamageCardId = 0;
TotalBestDamageCardDamages = 0;
TotalGemsInserted = 0;
TotalMonstersKilledCount = 0;
TotalMonstersKnockedCount = 0;
TotalOverkillDamagesCount = 0.0;
TotalMonstersDamages = new Dictionary<int, double>();
TotalMonstersKills = new Dictionary<int, int>();
CrawlerId = null;
DungeonId = null;
BreakingCardCount = 0;
FullyBrokenCardCount = 0;
EvolutionsCount = 0;
Arcanas = new List<int>();
Destructibles = new Dictionary<DestructibleType, int>();
foreach (DestructibleType value in Enum.GetValues(typeof(DestructibleType)))
{
Destructibles[value] = 0;
}
Timeline = new List<TimelineEvent>();
}
public void TileVisited(Vector2Int coords)
{
//IL_0017: Unknown result type (might be due to invalid IL or missing references)
FloorsData[CurrentFloorIndex].TilesVisited.Add(coords);
TotalTilesVisited++;
PlayerMoved();
}
public void OnGemInserted()
{
TotalGemsInserted++;
FloorsData[CurrentFloorIndex].OnGemInserted();
SaveCurrentRun();
}
public void OnFloorLoaded(TiledMapData tiles, Vector2Int? oldCoord = null)
{
//IL_0061: Unknown result type (might be due to invalid IL or missing references)
//IL_0066: Unknown result type (might be due to invalid IL or missing references)
//IL_007d: Unknown result type (might be due to invalid IL or missing references)
//IL_00a7: Unknown result type (might be due to invalid IL or missing references)
//IL_00d3: Unknown result type (might be due to invalid IL or missing references)
//IL_00d9: Invalid comparison between Unknown and I4
if (CurrentFloorIndex != 0)
{
FloorsData[CurrentFloorIndex].OnFloorFinished();
TryAddTimelineEvent(3);
}
CurrentFloorIndex++;
FloorsData[CurrentFloorIndex] = new FloorData();
Vector2Int currentPlayerMapCoords = SingletonMonoBehaviour<GameModel>.Instance.Dungeon3DMapModel.CurrentPlayerMapCoords;
FloorsData[CurrentFloorIndex].TilesVisited.Add(currentPlayerMapCoords);
if (oldCoord.HasValue)
{
FloorsData[CurrentFloorIndex].TilesVisited.Add(oldCoord.Value);
}
foreach (MapTile item in tiles.MapTiles._gridArray)
{
if ((int)item.ValidExits > 0)
{
FloorsData[CurrentFloorIndex].FloorTilesCount++;
}
}
}
public void OnEncounterDefeated()
{
TotalEncountersDefeatedCount++;
FloorsData[CurrentFloorIndex].EncountersDefeatedCount++;
SaveCurrentRun();
(List<Plugin.CardDataStatsly>, List<Plugin.CardDataStatsly>) cardsForUpdate = GetCardsForUpdate();
Sender.SendUpdate(cardsForUpdate.Item2, cardsForUpdate.Item1);
}
public void AddDestructible(DestructibleType type)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
//IL_0052: Unknown result type (might be due to invalid IL or missing references)
if (Destructibles.TryGetValue(type, out var _))
{
Destructibles[type]++;
}
else
{
Destructibles[type] = 1;
}
FloorsData[CurrentFloorIndex].AddDestructible(type);
SaveCurrentRun();
}
public void CardPlayed(int id, bool isCardInCombo, int comboCount)
{
TotalCardsPlayed[id] = ((!TotalCardsPlayed.TryGetValue(id, out var value)) ? 1 : (value + 1));
TotalCardsPlayedCount++;
if (isCardInCombo)
{
TotalCardsInComboCount++;
}
if (comboCount > MaxComboReached)
{
MaxComboReached = comboCount;
}
FloorsData[CurrentFloorIndex].CardPlayed(id, isCardInCombo, comboCount);
SaveCurrentRun();
(List<Plugin.CardDataStatsly>, List<Plugin.CardDataStatsly>) cardsForUpdate = GetCardsForUpdate();
Sender.SendUpdate(cardsForUpdate.Item2, cardsForUpdate.Item1);
}
public void OnPlayerTurnEnded()
{
(List<Plugin.CardDataStatsly>, List<Plugin.CardDataStatsly>) cardsForUpdate = GetCardsForUpdate();
Sender.SendUpdate(cardsForUpdate.Item2, cardsForUpdate.Item1, forceUpdate: true);
}
public void PlayerMoved()
{
TotalMovementsCount++;
FloorsData[CurrentFloorIndex].MovementsCount++;
}
public void PlayerDealDamages(int cardId, double damages)
{
TotalCardsDamages[cardId] = (TotalCardsDamages.TryGetValue(cardId, out var value) ? (value + damages) : damages);
if (damages > (double)TotalBestDamageCardDamages)
{
TotalBestDamageCardDamages = (int)damages;
TotalBestDamageCardId = cardId;
}
TotalDamagesDealt += damages;
FloorsData[CurrentFloorIndex].PlayerDealDamages(cardId, damages);
}
public void MonsterReceivesDamages(int monsterId, double damages, double overKillDamages)
{
TotalOverkillDamagesCount += overKillDamages;
TotalMonstersDamages[monsterId] = (TotalMonstersDamages.TryGetValue(monsterId, out var value) ? (value + damages) : damages);
FloorsData[CurrentFloorIndex].MonsterReceivesDamages(monsterId, damages, overKillDamages);
}
public void EnemyDamagesHit(int damages, int armored)
{
TotalDamagesTaken += damages;
TotalDamagesTanked += armored;
FloorsData[CurrentFloorIndex].DamagesTaken += damages;
FloorsData[CurrentFloorIndex].DamagesTanked += armored;
}
public void MonsterKilled(int cardId, int enemyId)
{
TotalMonstersKills[enemyId] = ((!TotalMonstersKills.TryGetValue(enemyId, out var value)) ? 1 : (value + 1));
TotalCardsKills[cardId] = ((!TotalCardsKills.TryGetValue(cardId, out var value2)) ? 1 : (value2 + 1));
TotalMonstersKilledCount++;
FloorsData[CurrentFloorIndex].MonsterKilled(cardId, enemyId);
}
public void CardCracked(CardCrackState state)
{
//IL_0012: Unknown result type (might be due to invalid IL or missing references)
//IL_0014: Invalid comparison between Unknown and I4
BreakingCardCount++;
if ((int)state == 2)
{
FullyBrokenCardCount++;
}
}
public void RunEnded(bool isCompleted, double runDuration, int diffRating, int level, List<int> arcanas)
{
if (CurrentFloorIndex != 0)
{
FloorsData[CurrentFloorIndex].OnFloorFinished();
}
Plugin.Instance.Log.LogInfo((object)JsonSerializer.Serialize(FloorsData));
int duration = (int)Math.Round(runDuration);
long num = DateTimeOffset.UtcNow.ToUnixTimeSeconds();
long num2 = 0L;
Dictionary<int, long> dictionary = new Dictionary<int, long>(TotalCardsDamages.Count);
foreach (KeyValuePair<int, double> totalCardsDamage in TotalCardsDamages)
{
num2 += (long)totalCardsDamage.Value;
dictionary[totalCardsDamage.Key] = (long)totalCardsDamage.Value;
}
Dictionary<int, long> dictionary2 = new Dictionary<int, long>(TotalMonstersDamages.Count);
foreach (KeyValuePair<int, double> totalMonstersDamage in TotalMonstersDamages)
{
dictionary2[totalMonstersDamage.Key] = (long)totalMonstersDamage.Value;
}
Destructibles.TryGetValue((DestructibleType)3, out var value);
Destructibles.TryGetValue((DestructibleType)0, out var value2);
object obj = new
{
Duration = duration,
CharacterId = GetCrawlerId(),
DungeonId = GetDungeonId(),
TotalCardsPlayedCount = TotalCardsPlayedCount,
CardsPlayedDict = TotalCardsPlayed,
DamagesDict = dictionary,
TotalDamagesDealt = num2,
IsWin = isCompleted,
DiffRating = diffRating,
TotalDamagesTaken = TotalDamagesTaken,
TotalDamagesTanked = TotalDamagesTanked,
Level = level,
Arcanas = arcanas,
TotalMonstersKills = TotalMonstersKills,
TotalMonstersKilledCount = TotalMonstersKilledCount,
MonstersDamages = dictionary2,
TotalCardsKills = TotalCardsKills,
ChestsOpened = value,
CandlesDestroyed = value2,
TotalBestDamageCardId = TotalBestDamageCardId,
TotalBestDamageCardDamages = TotalBestDamageCardDamages,
TotalCardsInComboCount = TotalCardsInComboCount,
MaxComboReached = MaxComboReached,
FloorsData = FloorsData,
TotalEncountersDefeatedCount = TotalEncountersDefeatedCount,
Timeline = Timeline,
TotalGemsInserted = TotalGemsInserted
};
Plugin.Instance.LogToStatsly(JsonSerializer.Serialize(obj));
var value3 = new
{
Event = "runEnd",
Data = obj
};
Plugin.Instance.LogToStatsly(JsonSerializer.Serialize(value3));
clear();
}
private (List<Plugin.CardDataStatsly> gameCards, List<Plugin.CardDataStatsly> floorCards) GetCardsForUpdate()
{
List<Plugin.CardDataStatsly> list = new List<Plugin.CardDataStatsly>();
foreach (KeyValuePair<int, int> item in TotalCardsPlayed)
{
int key = item.Key;
TotalCardsDamages.TryGetValue(key, out var value);
TotalCardsKills.TryGetValue(key, out var value2);
list.Add(new Plugin.CardDataStatsly
{
Id = item.Key,
PlayedCount = item.Value,
Damages = (long)value,
Kills = value2,
DamagesPerUse = Math.Round(value / (double)item.Value)
});
}
return (list, FloorsData[CurrentFloorIndex].GetCardsForUpdate());
}
private int GetDungeonId()
{
PlayerRunSettings playerRunSettings = Globals.PlayerRunSettings;
DungeonConfig val = playerRunSettings.CurrentDungeonSetting();
return Dicts.GetOrCreateId(val.AssetId, Dicts.DungeonDevNameToId);
}
private int GetCrawlerId()
{
//IL_0090: Unknown result type (might be due to invalid IL or missing references)
//IL_0097: Expected O, but got Unknown
PlayerRunSettings playerRunSettings = Globals.PlayerRunSettings;
FccConfig mainFcc = playerRunSettings.MainFcc;
if ((Object)(object)mainFcc != (Object)null)
{
string assetId = ((CardConfig)mainFcc).AssetId;
return Dicts.GetOrCreateId(assetId, Dicts.CardDevNameToId);
}
List<DeckCardItem> startingDeck = Globals.PlayerRunSettings._startingDeck;
string value = string.Empty;
Enumerator<DeckCardItem> enumerator = startingDeck.GetEnumerator();
bool flag = default(bool);
while (enumerator.MoveNext())
{
DeckCardItem current = enumerator.Current;
string assetId2 = current.cardConfig.AssetId;
if (assetId2.Contains("FCC"))
{
ManualLogSource log = Plugin.Instance.Log;
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(0, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(assetId2);
}
log.LogInfo(val);
value = assetId2;
break;
}
}
return Dicts.GetOrCreateId(value, Dicts.CardDevNameToId);
}
private static string GetFilePath()
{
string folderPath = Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData);
string path = Path.Combine(folderPath, "Statly");
return Path.Combine(path, "vampireCrawlersCurrentRun.txt");
}
private void SaveCurrentRun()
{
//IL_00fa: Unknown result type (might be due to invalid IL or missing references)
//IL_0101: Expected O, but got Unknown
try
{
var value = new
{
PreviousComboCount, TotalDamagesDealt, TotalDamagesTaken, TotalDamagesTanked, TotalEncountersDefeatedCount, CurrentFloorIndex, FloorsData, TotalMovementsCount, TotalTilesVisited, TotalCardsPlayedCount,
TotalCardsInComboCount, MaxComboReached, TotalCardsPlayed, TotalCardsKills, TotalCardsDamages, TotalBestDamageCardId, TotalBestDamageCardDamages, TotalMonstersKilledCount, TotalMonstersKnockedCount, TotalOverkillDamagesCount,
TotalMonstersDamages, TotalMonstersKills, CrawlerId, DungeonId, BreakingCardCount, FullyBrokenCardCount, EvolutionsCount, Arcanas, Destructibles, Timeline,
TotalGemsInserted
};
string contents = JsonSerializer.Serialize(value);
string filePath = GetFilePath();
Directory.CreateDirectory(Path.GetDirectoryName(filePath));
File.WriteAllText(filePath, contents);
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Instance.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to save current run: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
public bool TryLoadCurrentRun()
{
//IL_04e0: Unknown result type (might be due to invalid IL or missing references)
//IL_04e7: Expected O, but got Unknown
try
{
string filePath = GetFilePath();
if (!File.Exists(filePath))
{
return false;
}
string text = File.ReadAllText(filePath);
if (string.IsNullOrWhiteSpace(text))
{
return false;
}
JsonDocument jsonDocument = JsonDocument.Parse(text);
JsonElement rootElement = jsonDocument.RootElement;
PreviousComboCount = rootElement.GetProperty("PreviousComboCount").GetInt32();
TotalDamagesDealt = rootElement.GetProperty("TotalDamagesDealt").GetDouble();
TotalDamagesTaken = rootElement.GetProperty("TotalDamagesTaken").GetInt32();
TotalDamagesTanked = rootElement.GetProperty("TotalDamagesTanked").GetInt32();
TotalEncountersDefeatedCount = rootElement.GetProperty("TotalEncountersDefeatedCount").GetInt32();
CurrentFloorIndex = rootElement.GetProperty("CurrentFloorIndex").GetInt32();
TotalMovementsCount = rootElement.GetProperty("TotalMovementsCount").GetInt32();
TotalTilesVisited = rootElement.GetProperty("TotalTilesVisited").GetInt32();
TotalCardsPlayedCount = rootElement.GetProperty("TotalCardsPlayedCount").GetInt32();
TotalCardsInComboCount = rootElement.GetProperty("TotalCardsInComboCount").GetInt32();
MaxComboReached = rootElement.GetProperty("MaxComboReached").GetInt32();
TotalBestDamageCardId = rootElement.GetProperty("TotalBestDamageCardId").GetInt32();
TotalBestDamageCardDamages = rootElement.GetProperty("TotalBestDamageCardDamages").GetInt32();
TotalMonstersKilledCount = rootElement.GetProperty("TotalMonstersKilledCount").GetInt32();
TotalMonstersKnockedCount = rootElement.GetProperty("TotalMonstersKnockedCount").GetInt32();
TotalOverkillDamagesCount = rootElement.GetProperty("TotalOverkillDamagesCount").GetDouble();
CrawlerId = ((rootElement.GetProperty("CrawlerId").ValueKind == JsonValueKind.Null) ? null : new int?(rootElement.GetProperty("CrawlerId").GetInt32()));
DungeonId = ((rootElement.GetProperty("DungeonId").ValueKind == JsonValueKind.Null) ? null : new int?(rootElement.GetProperty("DungeonId").GetInt32()));
BreakingCardCount = rootElement.GetProperty("BreakingCardCount").GetInt32();
FullyBrokenCardCount = rootElement.GetProperty("FullyBrokenCardCount").GetInt32();
EvolutionsCount = rootElement.GetProperty("EvolutionsCount").GetInt32();
TotalGemsInserted = rootElement.GetProperty("TotalGemsInserted").GetInt32();
TotalCardsPlayed = JsonSerializer.Deserialize<Dictionary<int, int>>(rootElement.GetProperty("TotalCardsPlayed").GetRawText()) ?? new Dictionary<int, int>();
TotalCardsKills = JsonSerializer.Deserialize<Dictionary<int, int>>(rootElement.GetProperty("TotalCardsKills").GetRawText()) ?? new Dictionary<int, int>();
TotalCardsDamages = JsonSerializer.Deserialize<Dictionary<int, double>>(rootElement.GetProperty("TotalCardsDamages").GetRawText()) ?? new Dictionary<int, double>();
TotalMonstersDamages = JsonSerializer.Deserialize<Dictionary<int, double>>(rootElement.GetProperty("TotalMonstersDamages").GetRawText()) ?? new Dictionary<int, double>();
TotalMonstersKills = JsonSerializer.Deserialize<Dictionary<int, int>>(rootElement.GetProperty("TotalMonstersKills").GetRawText()) ?? new Dictionary<int, int>();
Arcanas = JsonSerializer.Deserialize<List<int>>(rootElement.GetProperty("Arcanas").GetRawText()) ?? new List<int>();
Destructibles = JsonSerializer.Deserialize<Dictionary<DestructibleType, int>>(rootElement.GetProperty("Destructibles").GetRawText()) ?? new Dictionary<DestructibleType, int>();
FloorsData = JsonSerializer.Deserialize<Dictionary<int, FloorData>>(rootElement.GetProperty("FloorsData").GetRawText()) ?? new Dictionary<int, FloorData>();
Timeline = JsonSerializer.Deserialize<List<TimelineEvent>>(rootElement.GetProperty("Timeline").GetRawText()) ?? new List<TimelineEvent>();
Plugin.Instance.Log.LogInfo((object)"Resumed run from saved file.");
(List<Plugin.CardDataStatsly>, List<Plugin.CardDataStatsly>) cardsForUpdate = GetCardsForUpdate();
Sender.SendUpdate(cardsForUpdate.Item2, cardsForUpdate.Item1, forceUpdate: true);
return true;
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Instance.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(28, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to load current run: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
return false;
}
}
public void ClearCurrentRunFile()
{
//IL_002e: Unknown result type (might be due to invalid IL or missing references)
//IL_0035: Expected O, but got Unknown
try
{
string filePath = GetFilePath();
if (File.Exists(filePath))
{
File.Delete(filePath);
}
}
catch (Exception ex)
{
ManualLogSource log = Plugin.Instance.Log;
bool flag = default(bool);
BepInExErrorLogInterpolatedStringHandler val = new BepInExErrorLogInterpolatedStringHandler(34, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("Failed to clear current run file: ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<string>(ex.Message);
}
log.LogError(val);
}
}
}
public class FloorData
{
public long TotalDamagesDealt { get; set; } = 0L;
public int DamagesTaken { get; set; } = 0;
public int DamagesTanked { get; set; } = 0;
public int EncountersDefeatedCount { get; set; } = 0;
[JsonIgnore]
public HashSet<Vector2Int> TilesVisited { get; set; } = new HashSet<Vector2Int>();
public int FloorTilesCount { get; set; } = 0;
public int TotalTilesVisited { get; set; } = 0;
public int MovementsCount { get; set; } = 0;
public int CardsPlayedCount { get; set; } = 0;
public int CardsInComboCount { get; set; } = 0;
public int MaxComboReached { get; set; } = 0;
public Dictionary<int, int> CardsPlayed { get; set; } = new Dictionary<int, int>();
public Dictionary<int, int> CardsKills { get; set; } = new Dictionary<int, int>();
public Dictionary<int, double> CardsDamagesRaw { get; set; } = new Dictionary<int, double>();
public Dictionary<int, long> CardsDamages { get; set; } = new Dictionary<int, long>();
public int BestDamageCardId { get; set; } = 0;
public int BestDamageCardDamages { get; set; } = 0;
public int MonstersKilledCount { get; set; } = 0;
public int MonstersKnockedCount { get; set; } = 0;
public double OverkillDamagesCountRaw { get; set; } = 0.0;
public long OverkillDamagesCount { get; set; } = 0L;
public Dictionary<int, double> MonstersDamagesRaw { get; set; } = new Dictionary<int, double>();
public Dictionary<int, long> MonstersDamages { get; set; } = new Dictionary<int, long>();
public Dictionary<int, int> MonstersKills { get; set; } = new Dictionary<int, int>();
public Dictionary<DestructibleType, int> Destructibles { get; set; } = new Dictionary<DestructibleType, int>();
public int ChestsOpened { get; set; } = 0;
public int CandlesDestroyed { get; set; } = 0;
public int GemsInserted { get; set; } = 0;
public void OnFloorFinished()
{
TotalTilesVisited = TilesVisited.Count;
Destructibles.TryGetValue((DestructibleType)3, out var value);
Destructibles.TryGetValue((DestructibleType)0, out var value2);
ChestsOpened = value;
CandlesDestroyed = value2;
foreach (KeyValuePair<int, double> item in CardsDamagesRaw)
{
TotalDamagesDealt += (long)item.Value;
CardsDamages[item.Key] = (int)item.Value;
}
foreach (KeyValuePair<int, double> item2 in MonstersDamagesRaw)
{
MonstersDamages[item2.Key] = (int)item2.Value;
}
OverkillDamagesCount = (long)OverkillDamagesCountRaw;
}
public void CardPlayed(int id, bool isCardInCombo, int comboCount)
{
//IL_0045: Unknown result type (might be due to invalid IL or missing references)
//IL_004b: Expected O, but got Unknown
CardsPlayed[id] = ((!CardsPlayed.TryGetValue(id, out var value)) ? 1 : (value + 1));
CardsPlayedCount++;
ManualLogSource log = Plugin.Instance.Log;
bool flag = default(bool);
BepInExInfoLogInterpolatedStringHandler val = new BepInExInfoLogInterpolatedStringHandler(18, 1, ref flag);
if (flag)
{
((BepInExLogInterpolatedStringHandler)val).AppendLiteral("played ");
((BepInExLogInterpolatedStringHandler)val).AppendFormatted<int>(CardsPlayedCount);
((BepInExLogInterpolatedStringHandler)val).AppendLiteral(" this floor");
}
log.LogInfo(val);
if (isCardInCombo)
{
CardsInComboCount++;
}
if (comboCount > MaxComboReached)
{
MaxComboReached = comboCount;
}
}
public void PlayerDealDamages(int cardId, double damages)
{
CardsDamagesRaw[cardId] = (CardsDamagesRaw.TryGetValue(cardId, out var value) ? (value + damages) : damages);
if (damages > (double)BestDamageCardDamages)
{
BestDamageCardDamages = (int)damages;
BestDamageCardId = cardId;
}
}
public void MonsterReceivesDamages(int monsterId, double damages, double overKillDamages)
{
OverkillDamagesCountRaw += overKillDamages;
MonstersDamagesRaw[monsterId] = (MonstersDamagesRaw.TryGetValue(monsterId, out var value) ? (value + damages) : damages);
}
public void MonsterKilled(int cardId, int enemyId)
{
MonstersKills[enemyId] = ((!MonstersKills.TryGetValue(enemyId, out var value)) ? 1 : (value + 1));
CardsKills[cardId] = ((!CardsKills.TryGetValue(cardId, out var value2)) ? 1 : (value2 + 1));
MonstersKilledCount++;
}
public void OnGemInserted()
{
GemsInserted++;
}
public void AddDestructible(DestructibleType type)
{
//IL_0007: Unknown result type (might be due to invalid IL or missing references)
//IL_0038: Unknown result type (might be due to invalid IL or missing references)
//IL_001a: Unknown result type (might be due to invalid IL or missing references)
//IL_001b: Unknown result type (might be due to invalid IL or missing references)
//IL_001d: Unknown result type (might be due to invalid IL or missing references)
//IL_0024: Unknown result type (might be due to invalid IL or missing references)
if (Destructibles.TryGetValue(type, out var _))
{
Destructibles[type]++;
}
else
{
Destructibles[type] = 1;
}
}
public List<Plugin.CardDataStatsly> GetCardsForUpdate()
{
List<Plugin.CardDataStatsly> list = new List<Plugin.CardDataStatsly>();
foreach (KeyValuePair<int, int> item in CardsPlayed)
{
int key = item.Key;
CardsDamagesRaw.TryGetValue(key, out var value);
CardsKills.TryGetValue(key, out var value2);
list.Add(new Plugin.CardDataStatsly
{
Id = item.Key,
PlayedCount = item.Value,
Damages = (long)value,
DamagesPerUse = Math.Round(value / (double)item.Value),
Kills = value2
});
}
return list;
}
}
public class TimelineEvent
{
public int Timestamp { get; set; }
public int EventId { get; set; }
}
public static class MyPluginInfo
{
public const string PLUGIN_GUID = "VampireMod";
public const string PLUGIN_NAME = "My first plugin";
public const string PLUGIN_VERSION = "1.0.0";
}
}