Please disclose if any significant portion of your mod was created using AI tools by adding the 'AI Generated' category. Failing to do so may result in the mod being removed from Thunderstore.
Decompiled source of SimpleQuest v4.9.1
plugins/SimpleQuest/SimpleQuest.dll
Decompiled 3 weeks agousing System; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; using System.Runtime.Versioning; using BepInEx; using BepInEx.Bootstrap; using BepInEx.Configuration; using HarmonyLib; using Jotunn.Entities; using Jotunn.Managers; using Newtonsoft.Json; using UnityEngine; using UnityEngine.Events; using UnityEngine.UI; [assembly: CompilationRelaxations(8)] [assembly: RuntimeCompatibility(WrapNonExceptionThrows = true)] [assembly: Debuggable(DebuggableAttribute.DebuggingModes.Default | DebuggableAttribute.DebuggingModes.DisableOptimizations | DebuggableAttribute.DebuggingModes.IgnoreSymbolStoreSequencePoints | DebuggableAttribute.DebuggingModes.EnableEditAndContinue)] [assembly: AssemblyTitle("SimpleQuest")] [assembly: AssemblyDescription("")] [assembly: AssemblyConfiguration("")] [assembly: AssemblyCompany("")] [assembly: AssemblyProduct("SimpleQuest")] [assembly: AssemblyCopyright("Copyright © 2026")] [assembly: AssemblyTrademark("")] [assembly: ComVisible(false)] [assembly: Guid("526f6350-8ad0-4fd8-8066-5806b070f058")] [assembly: AssemblyFileVersion("4.8.8.0")] [assembly: TargetFramework(".NETFramework,Version=v4.7.2", FrameworkDisplayName = ".NET Framework 4.7.2")] [assembly: AssemblyVersion("4.8.8.0")] namespace SimpleQuest; [HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })] public static class ItemCollectionPatch { private static void Postfix(Inventory __instance, ItemData item, bool __result) { if (!__result || item == null || (Object)(object)item.m_dropPrefab == (Object)null || (Object)(object)Player.m_localPlayer == (Object)null || __instance != ((Humanoid)Player.m_localPlayer).GetInventory()) { return; } if ((Object)(object)SimpleQuestPro.Instance != (Object)null) { string name = ((Object)item.m_dropPrefab).name; List<QuestConfig> list = SimpleQuestPro.Instance.serverQuests.Quests.Where((QuestConfig q) => string.IsNullOrEmpty(q.PreReqID) || SimpleQuestPro.Instance.completedQuests.Contains(q.PreReqID)).ToList(); foreach (QuestConfig item2 in list) { if (!SimpleQuestPro.Instance.completedQuests.Contains(item2.ID)) { QuestRequirement questRequirement = item2.Reqs?.FirstOrDefault((QuestRequirement r) => r.Prefab.Trim().Equals(name, StringComparison.OrdinalIgnoreCase)); if (questRequirement != null) { int itemCount = QuestUtils.GetItemCount(name); string itemName = QuestUtils.GetItemName(name); ((Character)Player.m_localPlayer).Message((MessageType)1, $"<b><color=#FFD700>{itemName}: {itemCount} / {questRequirement.Amount}</color></b>", 0, (Sprite)null); } } } if (SimpleQuestPro.Instance.IsWindowActive()) { QuestUI.UpdateUI(); } } QuestUI.UpdateHUD(); } } [HarmonyPatch(typeof(Character), "ApplyDamage")] public static class UniversalKillPatch { private static void Postfix(Character __instance, HitData hit) { if ((Object)(object)__instance == (Object)null || __instance.IsPlayer() || !(__instance.GetHealth() <= 0f)) { return; } string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject).Trim(); if (!SimpleQuestPro.playerKills.ContainsKey(prefabName)) { SimpleQuestPro.playerKills[prefabName] = 0; } SimpleQuestPro.playerKills[prefabName]++; if ((Object)(object)SimpleQuestPro.Instance != (Object)null) { foreach (QuestConfig quest in SimpleQuestPro.Instance.serverQuests.Quests) { if (SimpleQuestPro.Instance.completedQuests.Contains(quest.ID)) { continue; } QuestRequirement questRequirement = quest.KillReqs?.FirstOrDefault((QuestRequirement k) => k.Prefab.Trim().Equals(prefabName, StringComparison.OrdinalIgnoreCase)); if (questRequirement != null) { int num = SimpleQuestPro.playerKills[prefabName]; string arg = Localization.instance.Localize("$" + prefabName); Player localPlayer = Player.m_localPlayer; if (localPlayer != null) { ((Character)localPlayer).Message((MessageType)1, $"<b><color=#FFD700>{arg}: {num} / {questRequirement.Amount}</color></b>", 0, (Sprite)null); } } } if (SimpleQuestPro.Instance.IsWindowActive()) { QuestUI.UpdateUI(); } } QuestUI.UpdateHUD(); } } [HarmonyPatch] public static class PlantWatcher { [HarmonyPatch(typeof(Player), "ConsumeResources")] [HarmonyPrefix] private static void Prefix(Requirement[] requirements, int itemQuality) { if (requirements == null || (Object)(object)Player.m_localPlayer == (Object)null) { return; } foreach (Requirement val in requirements) { if (val == null || (Object)(object)val.m_resItem == (Object)null) { continue; } string name = ((Object)val.m_resItem).name; string questName = ""; if (name.Contains("CarrotSeeds")) { questName = "Carrot"; } else if (name.Contains("TurnipSeeds")) { questName = "Turnip"; } else if (name.Contains("OnionSeeds")) { questName = "Onion"; } else if (name.Contains("Seed")) { questName = name.Replace("Seeds", "").Replace("Seed", ""); } if (string.IsNullOrEmpty(questName)) { continue; } if ((Object)(object)SimpleQuestPro.Instance != (Object)null) { List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests(); foreach (QuestConfig item in visibleQuests) { if (SimpleQuestPro.Instance.completedQuests.Contains(item.ID)) { continue; } QuestRequirement questRequirement = item.KillReqs?.FirstOrDefault((QuestRequirement k) => string.Equals(k.Prefab.Trim(), questName, StringComparison.OrdinalIgnoreCase)); if (questRequirement != null) { if (!SimpleQuestPro.playerKills.ContainsKey(questName)) { SimpleQuestPro.playerKills[questName] = 0; } SimpleQuestPro.playerKills[questName]++; int num = SimpleQuestPro.playerKills[questName]; string itemName = QuestUtils.GetItemName(questName); ((Character)Player.m_localPlayer).Message((MessageType)1, $"<b><color=#FFD700>{itemName}: {num} / {questRequirement.Amount}</color></b>", 0, (Sprite)null); } } if (SimpleQuestPro.Instance.IsWindowActive()) { QuestUI.UpdateUI(); } } QuestUI.UpdateHUD(); } } } public static class QuestUI { [Serializable] [CompilerGenerated] private sealed class <>c { public static readonly <>c <>9 = new <>c(); public static UnityAction <>9__17_0; public static UnityAction <>9__17_1; public static UnityAction <>9__17_2; public static UnityAction <>9__17_3; public static Func<KeyValuePair<string, int>, int> <>9__18_2; public static Func<QuestRequirement, string> <>9__18_0; public static Func<KeyValuePair<string, int>, int> <>9__19_2; internal void <CreateUI>b__17_0() { List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests(); if (visibleQuests.Count > 0) { QuestConfig questConfig = visibleQuests[currentIndex]; if (SimpleQuestPro.trackedQuests.Contains(questConfig.ID)) { SimpleQuestPro.trackedQuests.Remove(questConfig.ID); } else { SimpleQuestPro.trackedQuests.Add(questConfig.ID); } UpdateUI(); UpdateHUD(); QuestUtils.PlaySfx("sfx_gui_mouse_over"); } } internal void <CreateUI>b__17_1() { int count = QuestUtils.GetVisibleQuests().Count; if (count > 0) { currentIndex = (currentIndex - 1 + count) % count; currentIconIndex = 0; UpdateUI(); QuestUtils.PlaySfx("sfx_book_page"); } } internal void <CreateUI>b__17_2() { int count = QuestUtils.GetVisibleQuests().Count; if (count > 0) { currentIndex = (currentIndex + 1) % count; currentIconIndex = 0; UpdateUI(); QuestUtils.PlaySfx("sfx_book_page"); } } internal void <CreateUI>b__17_3() { showHistoryMode = !showHistoryMode; currentIndex = 0; UpdateUI(); QuestUtils.PlaySfx("sfx_book_page"); } internal int <UpdateUI>b__18_2(KeyValuePair<string, int> x) { return x.Value; } internal string <UpdateUI>b__18_0(QuestRequirement x) { return $"{QuestUtils.GetItemName(x.Prefab)} x{x.Amount}"; } internal int <UpdateHUD>b__19_2(KeyValuePair<string, int> x) { return x.Value; } } public static GameObject window; public static GameObject hudPanel; public static Text infoText; public static Text pageText; public static Text btnText; public static Text titleText; public static Text historyBtnText; public static Text hudText; public static Text trackBtnText; public static GameObject btnFinish; public static GameObject btnHistory; public static GameObject btnTrack; public static Image rewardIcon; public static int currentIndex; public static int currentIconIndex; public static float iconTimer; public static bool showHistoryMode; public static void CreateUI() { //IL_001a: Unknown result type (might be due to invalid IL or missing references) //IL_0029: Unknown result type (might be due to invalid IL or missing references) //IL_002e: Unknown result type (might be due to invalid IL or missing references) //IL_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00ab: Unknown result type (might be due to invalid IL or missing references) //IL_00ba: Unknown result type (might be due to invalid IL or missing references) //IL_00df: Unknown result type (might be due to invalid IL or missing references) //IL_00e5: Unknown result type (might be due to invalid IL or missing references) //IL_012e: Unknown result type (might be due to invalid IL or missing references) //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_014c: Unknown result type (might be due to invalid IL or missing references) //IL_015d: Unknown result type (might be due to invalid IL or missing references) //IL_0163: Unknown result type (might be due to invalid IL or missing references) //IL_01ac: Unknown result type (might be due to invalid IL or missing references) //IL_01bb: Unknown result type (might be due to invalid IL or missing references) //IL_01ca: Unknown result type (might be due to invalid IL or missing references) //IL_01db: Unknown result type (might be due to invalid IL or missing references) //IL_01e1: Unknown result type (might be due to invalid IL or missing references) //IL_0224: Unknown result type (might be due to invalid IL or missing references) //IL_022a: Expected O, but got Unknown //IL_025e: Unknown result type (might be due to invalid IL or missing references) //IL_0274: Unknown result type (might be due to invalid IL or missing references) //IL_02a5: Unknown result type (might be due to invalid IL or missing references) //IL_02b4: Unknown result type (might be due to invalid IL or missing references) //IL_02c3: Unknown result type (might be due to invalid IL or missing references) //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_033d: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Unknown result type (might be due to invalid IL or missing references) //IL_035b: Unknown result type (might be due to invalid IL or missing references) //IL_030e: Unknown result type (might be due to invalid IL or missing references) //IL_0313: Unknown result type (might be due to invalid IL or missing references) //IL_0319: Expected O, but got Unknown //IL_03bc: Unknown result type (might be due to invalid IL or missing references) //IL_03cb: Unknown result type (might be due to invalid IL or missing references) //IL_03da: Unknown result type (might be due to invalid IL or missing references) //IL_038d: Unknown result type (might be due to invalid IL or missing references) //IL_0392: Unknown result type (might be due to invalid IL or missing references) //IL_0398: Expected O, but got Unknown //IL_043b: Unknown result type (might be due to invalid IL or missing references) //IL_044a: Unknown result type (might be due to invalid IL or missing references) //IL_0459: Unknown result type (might be due to invalid IL or missing references) //IL_040c: Unknown result type (might be due to invalid IL or missing references) //IL_0411: Unknown result type (might be due to invalid IL or missing references) //IL_0417: Expected O, but got Unknown //IL_04d3: Unknown result type (might be due to invalid IL or missing references) //IL_04e2: Unknown result type (might be due to invalid IL or missing references) //IL_04f1: Unknown result type (might be due to invalid IL or missing references) //IL_0533: Unknown result type (might be due to invalid IL or missing references) //IL_053d: Expected O, but got Unknown //IL_055c: Unknown result type (might be due to invalid IL or missing references) //IL_056b: Unknown result type (might be due to invalid IL or missing references) //IL_057a: Unknown result type (might be due to invalid IL or missing references) //IL_058b: Unknown result type (might be due to invalid IL or missing references) //IL_05a5: Unknown result type (might be due to invalid IL or missing references) //IL_04a4: Unknown result type (might be due to invalid IL or missing references) //IL_04a9: Unknown result type (might be due to invalid IL or missing references) //IL_04af: Expected O, but got Unknown window = GUIManager.Instance.CreateWoodpanel(GUIManager.CustomGUIFront.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), Vector2.zero, 600f, 550f, true); Image component = window.GetComponent<Image>(); if ((Object)(object)component != (Object)null) { ((Graphic)component).color = new Color(0.6f, 0.6f, 0.6f, 1f); } titleText = GUIManager.Instance.CreateText("", window.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -20f), GUIManager.Instance.AveriaSerifBold, 18, new Color(1f, 0.84f, 0f, 1f), false, Color.clear, 400f, 30f, false).GetComponent<Text>(); titleText.alignment = (TextAnchor)4; pageText = GUIManager.Instance.CreateText("", window.transform, new Vector2(0.5f, 1f), new Vector2(0.5f, 1f), new Vector2(0f, -40f), GUIManager.Instance.AveriaSerifBold, 14, Color.white, false, Color.clear, 200f, 30f, false).GetComponent<Text>(); pageText.alignment = (TextAnchor)4; infoText = GUIManager.Instance.CreateText("", window.transform, new Vector2(0.5f, 0.5f), new Vector2(0.5f, 0.5f), new Vector2(0f, 60f), GUIManager.Instance.AveriaSerifBold, 17, Color.white, false, Color.clear, 500f, 350f, false).GetComponent<Text>(); infoText.alignment = (TextAnchor)4; GameObject val = new GameObject("RewardIcon", new Type[1] { typeof(Image) }); val.transform.SetParent(window.transform, false); rewardIcon = val.GetComponent<Image>(); RectTransform component2 = val.GetComponent<RectTransform>(); component2.anchoredPosition = new Vector2(0f, -145f); component2.sizeDelta = new Vector2(64f, 64f); val.SetActive(false); btnTrack = GUIManager.Instance.CreateButton("Отслеживать", window.transform, new Vector2(1f, 0f), new Vector2(1f, 0f), new Vector2(-100f, 45f), 130f, 30f); trackBtnText = btnTrack.GetComponentInChildren<Text>(); ButtonClickedEvent onClick = btnTrack.GetComponent<Button>().onClick; object obj = <>c.<>9__17_0; if (obj == null) { UnityAction val2 = delegate { List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests(); if (visibleQuests.Count > 0) { QuestConfig questConfig = visibleQuests[currentIndex]; if (SimpleQuestPro.trackedQuests.Contains(questConfig.ID)) { SimpleQuestPro.trackedQuests.Remove(questConfig.ID); } else { SimpleQuestPro.trackedQuests.Add(questConfig.ID); } UpdateUI(); UpdateHUD(); QuestUtils.PlaySfx("sfx_gui_mouse_over"); } }; <>c.<>9__17_0 = val2; obj = (object)val2; } ((UnityEvent)onClick).AddListener((UnityAction)obj); ButtonClickedEvent onClick2 = GUIManager.Instance.CreateButton("<", window.transform, new Vector2(0f, 0.5f), new Vector2(0f, 0.5f), new Vector2(60f, 0f), 45f, 45f).GetComponent<Button>().onClick; object obj2 = <>c.<>9__17_1; if (obj2 == null) { UnityAction val3 = delegate { int count2 = QuestUtils.GetVisibleQuests().Count; if (count2 > 0) { currentIndex = (currentIndex - 1 + count2) % count2; currentIconIndex = 0; UpdateUI(); QuestUtils.PlaySfx("sfx_book_page"); } }; <>c.<>9__17_1 = val3; obj2 = (object)val3; } ((UnityEvent)onClick2).AddListener((UnityAction)obj2); ButtonClickedEvent onClick3 = GUIManager.Instance.CreateButton(">", window.transform, new Vector2(1f, 0.5f), new Vector2(1f, 0.5f), new Vector2(-60f, 0f), 45f, 45f).GetComponent<Button>().onClick; object obj3 = <>c.<>9__17_2; if (obj3 == null) { UnityAction val4 = delegate { int count = QuestUtils.GetVisibleQuests().Count; if (count > 0) { currentIndex = (currentIndex + 1) % count; currentIconIndex = 0; UpdateUI(); QuestUtils.PlaySfx("sfx_book_page"); } }; <>c.<>9__17_2 = val4; obj3 = (object)val4; } ((UnityEvent)onClick3).AddListener((UnityAction)obj3); btnHistory = GUIManager.Instance.CreateButton("История", window.transform, new Vector2(1f, 1f), new Vector2(1f, 1f), new Vector2(-90f, -40f), 130f, 30f); historyBtnText = btnHistory.GetComponentInChildren<Text>(); ButtonClickedEvent onClick4 = btnHistory.GetComponent<Button>().onClick; object obj4 = <>c.<>9__17_3; if (obj4 == null) { UnityAction val5 = delegate { showHistoryMode = !showHistoryMode; currentIndex = 0; UpdateUI(); QuestUtils.PlaySfx("sfx_book_page"); }; <>c.<>9__17_3 = val5; obj4 = (object)val5; } ((UnityEvent)onClick4).AddListener((UnityAction)obj4); btnFinish = GUIManager.Instance.CreateButton("", window.transform, new Vector2(0.5f, 0f), new Vector2(0.5f, 0f), new Vector2(0f, 45f), 200f, 40f); btnText = btnFinish.GetComponentInChildren<Text>(); ((UnityEvent)btnFinish.GetComponent<Button>().onClick).AddListener(new UnityAction(SimpleQuestPro.Instance.CompleteQuest)); hudPanel = GUIManager.Instance.CreateText("", GUIManager.CustomGUIFront.transform, new Vector2(1f, 0.63f), new Vector2(1f, 0.63f), new Vector2(-165f, 0f), GUIManager.Instance.AveriaSerifBold, 16, Color.white, true, new Color(0f, 0f, 0f, 0.5f), 400f, 300f, false); hudText = hudPanel.GetComponent<Text>(); hudText.horizontalOverflow = (HorizontalWrapMode)1; hudText.verticalOverflow = (VerticalWrapMode)1; hudText.alignment = (TextAnchor)1; hudPanel.SetActive(false); window.SetActive(false); } public static void UpdateUI() { List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests(); titleText.text = (showHistoryMode ? "<color=#FFD700><b>ИСТОРИЯ ГЕРОЯ</b></color>" : ("<color=#FFD700><b>" + Localization.instance.Localize("$sq_journal") + "</b></color>")); historyBtnText.text = (showHistoryMode ? "Назад" : "История героя"); if (visibleQuests.Count == 0) { infoText.text = (showHistoryMode ? "\n\nПодвигов пока нет." : "\n\nНет доступных заданий."); pageText.text = "0 / 0"; btnFinish.SetActive(false); btnTrack.SetActive(false); Image obj = rewardIcon; if (obj != null) { ((Component)obj).gameObject.SetActive(false); } return; } btnFinish.SetActive(!showHistoryMode); btnTrack.SetActive(!showHistoryMode); if (currentIndex >= visibleQuests.Count) { currentIndex = 0; } QuestConfig questConfig = visibleQuests[currentIndex]; trackBtnText.text = (SimpleQuestPro.trackedQuests.Contains(questConfig.ID) ? "<color=#FF4500>Не отслеживать</color>" : "Отслеживать"); bool flag = SimpleQuestPro.Instance.completedQuests.Contains(questConfig.ID); bool flag2 = true; string rarityColor = QuestUtils.GetRarityColor(questConfig.Rarity); string text = (showHistoryMode ? "\n<color=#00FF00><b>[ ВЫПОЛНЕНО ]</b></color>\n" : ""); string text2 = "\n<color=" + rarityColor + ">━━━━━━━━━━━━━━━━━━</color>\n"; if (questConfig.Reqs != null) { foreach (QuestRequirement req in questConfig.Reqs) { int num = (flag ? req.Amount : QuestUtils.GetItemCount(req.Prefab)); text2 += string.Format("• {0}: <color={1}><b>{2}</b> / {3}</color>\n", QuestUtils.GetItemName(req.Prefab), (num >= req.Amount) ? "#00FF00" : "#FF4500", num, req.Amount); if (!flag && num < req.Amount) { flag2 = false; } } } if (questConfig.KillReqs != null) { foreach (QuestRequirement i in questConfig.KillReqs) { int num2 = (flag ? i.Amount : SimpleQuestPro.playerKills.Where((KeyValuePair<string, int> x) => x.Key.Equals(i.Prefab.Trim(), StringComparison.OrdinalIgnoreCase)).Sum((KeyValuePair<string, int> x) => x.Value)); text2 += string.Format("• {0}: <color={1}><b>{2}</b> / {3}</color>\n", Localization.instance.Localize("$" + i.Prefab.Trim()), (num2 >= i.Amount) ? "#00FF00" : "#FF4500", num2, i.Amount); if (!flag && num2 < i.Amount) { flag2 = false; } } } int num3 = ((questConfig.RewardItems == null) ? 1 : questConfig.RewardItems.Count); bool flag3 = ((Humanoid)Player.m_localPlayer).GetInventory().GetEmptySlots() >= num3; if (flag) { btnText.text = "Выполнено"; ((Selectable)btnFinish.GetComponent<Button>()).interactable = false; } else { btnText.text = ((!flag2) ? "Недостаточно" : ((!flag3) ? "Нет места" : "<b>Завершить</b>")); ((Selectable)btnFinish.GetComponent<Button>()).interactable = flag2 && flag3; } pageText.text = $"{currentIndex + 1} / {visibleQuests.Count}"; SetRewardIcon((questConfig.RewardItems != null && questConfig.RewardItems.Count > 0) ? questConfig.RewardItems[currentIconIndex % questConfig.RewardItems.Count].Prefab : questConfig.RewardItem); string text3 = ((questConfig.RewardItems != null && questConfig.RewardItems.Count > 0) ? string.Join(", ", questConfig.RewardItems.Select((QuestRequirement x) => $"{QuestUtils.GetItemName(x.Prefab)} x{x.Amount}")) : $"{QuestUtils.GetItemName(questConfig.RewardItem)} x{questConfig.RewardAmount}"); if (questConfig.ExpReward > 0) { text3 += $" | <color=#00BFFF>+{questConfig.ExpReward} XP</color>"; } infoText.text = "<size=26><color=" + rarityColor + "><b>" + questConfig.Title + "</b></color></size>\n" + text + "<i>" + questConfig.Goal + "</i>\n" + text2 + "\n<color=#FFD700><b>Награда:</b></color> " + text3; UpdateHUD(); } public static void UpdateHUD() { if ((Object)(object)hudPanel == (Object)null) { return; } if (SimpleQuestPro.trackedQuests == null || SimpleQuestPro.trackedQuests.Count == 0 || (Object)(object)Player.m_localPlayer == (Object)null) { hudPanel.SetActive(false); return; } string text = ""; foreach (string id in SimpleQuestPro.trackedQuests.ToList()) { QuestConfig questConfig = SimpleQuestPro.Instance.serverQuests.Quests.FirstOrDefault((QuestConfig x) => x.ID.Equals(id, StringComparison.OrdinalIgnoreCase)); if (questConfig == null) { continue; } if (SimpleQuestPro.Instance.completedQuests.Contains(questConfig.ID)) { SimpleQuestPro.trackedQuests.Remove(id); continue; } text = text + "<b><color=#FFD700>" + questConfig.Title + "</color></b>\n"; if (questConfig.Reqs != null) { foreach (QuestRequirement req in questConfig.Reqs) { int itemCount = QuestUtils.GetItemCount(req.Prefab); string text2 = ((itemCount >= req.Amount) ? "#00FF00" : "white"); text += $"<b> • {QuestUtils.GetItemName(req.Prefab)}: <color={text2}>{itemCount}/{req.Amount}</color></b>\n"; } } if (questConfig.KillReqs != null) { foreach (QuestRequirement i in questConfig.KillReqs) { int num = SimpleQuestPro.playerKills.Where((KeyValuePair<string, int> x) => x.Key.Equals(i.Prefab.Trim(), StringComparison.OrdinalIgnoreCase)).Sum((KeyValuePair<string, int> x) => x.Value); string text3 = ((num >= i.Amount) ? "#00FF00" : "white"); text += string.Format("<b> • {0}: <color={1}>{2}/{3}</color></b>\n", Localization.instance.Localize("$" + i.Prefab.Trim()), text3, num, i.Amount); } } text += "\n"; } if (!string.IsNullOrEmpty(text)) { hudText.text = text; hudPanel.SetActive(true); } else { hudPanel.SetActive(false); } } public static void SetRewardIcon(string prefabName) { if (!((Object)(object)rewardIcon == (Object)null) && !string.IsNullOrEmpty(prefabName)) { ZNetScene instance = ZNetScene.instance; object obj; if (instance == null) { obj = null; } else { GameObject prefab = instance.GetPrefab(prefabName); obj = ((prefab != null) ? prefab.GetComponent<ItemDrop>() : null); } ItemDrop val = (ItemDrop)obj; if ((Object)(object)val != (Object)null) { rewardIcon.sprite = val.m_itemData.GetIcon(); ((Component)rewardIcon).gameObject.SetActive(true); } else { ((Component)rewardIcon).gameObject.SetActive(false); } } } } public static class QuestUtils { public static List<QuestConfig> GetVisibleQuests() { if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)SimpleQuestPro.Instance == (Object)null) { return new List<QuestConfig>(); } if (QuestUI.showHistoryMode) { return SimpleQuestPro.Instance.serverQuests.Quests.Where((QuestConfig q) => SimpleQuestPro.Instance.completedQuests.Contains(q.ID)).ToList(); } return SimpleQuestPro.Instance.serverQuests.Quests.Where((QuestConfig q) => (string.IsNullOrEmpty(q.PreReqID) || SimpleQuestPro.Instance.completedQuests.Contains(q.PreReqID)) && !SimpleQuestPro.Instance.completedQuests.Contains(q.ID)).ToList(); } public static string GetRarityColor(string rarity) { if (string.IsNullOrEmpty(rarity)) { return "#4d2600"; } return rarity.ToLower() switch { "common" => "#696969", "rare" => "#1E90FF", "epic" => "#9400D3", "legendary" => "#FFD700", "mythic" => "#FF4500", _ => "#4d2600", }; } public static int GetItemCount(string prefab) { Player localPlayer = Player.m_localPlayer; return (localPlayer != null) ? (from x in ((Humanoid)localPlayer).GetInventory().GetAllItems() where (Object)(object)x.m_dropPrefab != (Object)null && string.Equals(((Object)x.m_dropPrefab).name, prefab, StringComparison.OrdinalIgnoreCase) select x).Sum((ItemData x) => x.m_stack) : 0; } public static string GetItemName(string prefab) { if (string.IsNullOrEmpty(prefab)) { return ""; } string[] array = new string[3] { "$item_" + prefab.ToLower(), "$" + prefab, "$" + prefab.ToLower() }; string[] array2 = array; foreach (string text in array2) { string text2 = Localization.instance.Localize(text); if (!text2.StartsWith("$")) { return text2; } } return prefab; } public static void PlaySfx(string sfxName) { //IL_0062: Unknown result type (might be due to invalid IL or missing references) //IL_0067: Unknown result type (might be due to invalid IL or missing references) if (!((Object)(object)ZNetScene.instance == (Object)null) && !((Object)(object)Player.m_localPlayer == (Object)null)) { GameObject prefab = ZNetScene.instance.GetPrefab(sfxName); if ((Object)(object)prefab == (Object)null) { prefab = ZNetScene.instance.GetPrefab("sfx_gui_click"); } if ((Object)(object)prefab != (Object)null) { Object.Instantiate<GameObject>(prefab, ((Component)Utils.GetMainCamera()).transform.position, Quaternion.identity); } } } public static void AddExp(int amount) { if ((Object)(object)Player.m_localPlayer == (Object)null) { return; } try { if (!Chainloader.PluginInfos.ContainsKey("WackyMole.EpicMMOSystem")) { return; } PluginInfo val = Chainloader.PluginInfos["WackyMole.EpicMMOSystem"]; Assembly assembly = ((object)val.Instance).GetType().Assembly; Type type = assembly.GetType("EpicMMOSystem.LevelSystem"); if (type == null) { return; } object obj = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public)?.GetValue(null); if (obj == null) { return; } MethodInfo method = type.GetMethod("AddExp", BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); if (method != null) { ParameterInfo[] parameters = method.GetParameters(); if (parameters.Length == 2) { object obj2 = ((parameters[0].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(amount, parameters[0].ParameterType)); object obj3 = ((parameters[1].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(amount, parameters[1].ParameterType)); method.Invoke(obj, new object[2] { obj2, obj3 }); } else if (parameters.Length == 1) { object obj4 = Convert.ChangeType(amount, parameters[0].ParameterType); method.Invoke(obj, new object[1] { obj4 }); } } } catch { } } } [BepInPlugin("com.RonmaruMori.simplequest", "Simple Quest Pro", "4.9.1")] [BepInDependency(/*Could not decode attribute arguments.*/)] public class SimpleQuestPro : BaseUnityPlugin { [CompilerGenerated] private sealed class <OnClientQuestRequest>d__20 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public long sender; public ZPackage package; public SimpleQuestPro <>4__this; private ZPackage <pkg>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnClientQuestRequest>d__20(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <pkg>5__1 = null; <>1__state = -2; } private bool MoveNext() { //IL_0030: Unknown result type (might be due to invalid IL or missing references) //IL_003a: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; if (ZNet.instance.IsServer()) { <pkg>5__1 = new ZPackage(); <pkg>5__1.Write(RawServerJson); <>4__this.questSyncRPC.SendPackage(sender, <pkg>5__1); <pkg>5__1 = null; } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } [CompilerGenerated] private sealed class <OnServerQuestReceived>d__21 : IEnumerator<object>, IDisposable, IEnumerator { private int <>1__state; private object <>2__current; public long sender; public ZPackage package; public SimpleQuestPro <>4__this; private string <json>5__1; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <OnServerQuestReceived>d__21(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <json>5__1 = null; <>1__state = -2; } private bool MoveNext() { switch (<>1__state) { default: return false; case 0: <>1__state = -1; <json>5__1 = package.ReadString(); if (!string.IsNullOrEmpty(<json>5__1)) { <>4__this.serverQuests = JsonConvert.DeserializeObject<QuestList>(<json>5__1) ?? <>4__this.serverQuests; if (<>4__this.IsWindowActive()) { QuestUI.UpdateUI(); } } <>2__current = null; <>1__state = 1; return true; case 1: <>1__state = -1; return false; } } bool IEnumerator.MoveNext() { //ILSpy generated this explicit interface implementation from .override directive in MoveNext return this.MoveNext(); } [DebuggerHidden] void IEnumerator.Reset() { throw new NotSupportedException(); } } public const string ModGUID = "com.RonmaruMori.simplequest"; public const string ModName = "Simple Quest Pro"; public const string ModVersion = "4.9.1"; public static SimpleQuestPro Instance; private ConfigEntry<KeyCode> questKey; public QuestList serverQuests = new QuestList(); public HashSet<string> completedQuests = new HashSet<string>(); public static Dictionary<string, int> playerKills = new Dictionary<string, int>(); public static HashSet<string> trackedQuests = new HashSet<string>(); private CustomRPC questSyncRPC; private static string RawServerJson = string.Empty; private bool isFirstSpawn = true; public bool IsWindowActive() { return (Object)(object)QuestUI.window != (Object)null && QuestUI.window.activeSelf; } private void Awake() { //IL_000c: Unknown result type (might be due to invalid IL or missing references) //IL_007e: Unknown result type (might be due to invalid IL or missing references) //IL_008a: Unknown result type (might be due to invalid IL or missing references) //IL_0094: Expected O, but got Unknown //IL_0094: Expected O, but got Unknown Instance = this; new Harmony("com.RonmaruMori.simplequest").PatchAll(); LoadLocalization(); questKey = ((BaseUnityPlugin)this).Config.Bind<KeyCode>("General", "QuestKey", (KeyCode)108, "Клавиша журнала"); string text = Path.Combine(Paths.ConfigPath, "SimpleQuest"); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } LoadQuestsLocal(text); questSyncRPC = NetworkManager.Instance.AddRPC("QuestSync", new CoroutineHandler(OnClientQuestRequest), new CoroutineHandler(OnServerQuestReceived)); ((BaseUnityPlugin)this).Logger.LogInfo((object)"Simple Quest Pro v4.9.1 готова."); } private void Update() { //IL_0082: Unknown result type (might be due to invalid IL or missing references) //IL_008c: Expected O, but got Unknown //IL_01d1: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)Player.m_localPlayer == (Object)null) { isFirstSpawn = true; return; } if (isFirstSpawn) { isFirstSpawn = false; LoadProgress(); LoadQuestsLocal(Path.Combine(Paths.ConfigPath, "SimpleQuest")); if ((Object)(object)ZNet.instance != (Object)null && !ZNet.instance.IsServer()) { questSyncRPC.SendPackage(ZNet.instance.GetServerPeer().m_uid, new ZPackage()); } } if (IsWindowActive()) { if (Input.GetKeyDown((KeyCode)9) || Input.GetKeyDown((KeyCode)27)) { ToggleUI(); return; } UpdateIconSlideshow(); float axis = Input.GetAxis("Mouse ScrollWheel"); if (axis != 0f) { int count = QuestUtils.GetVisibleQuests().Count; if (count > 0) { if (axis > 0f) { QuestUI.currentIndex = (QuestUI.currentIndex - 1 + count) % count; } else { QuestUI.currentIndex = (QuestUI.currentIndex + 1) % count; } QuestUI.currentIconIndex = 0; QuestUI.UpdateUI(); QuestUtils.PlaySfx("sfx_book_page"); } } } if ((Object)(object)QuestUI.hudPanel != (Object)null) { bool flag = InventoryGui.IsVisible() || Menu.IsVisible() || StoreGui.IsVisible() || TextInput.IsVisible() || Chat.instance.HasFocus(); QuestUI.hudPanel.SetActive(!flag && !IsWindowActive() && !QuestUI.showHistoryMode && trackedQuests.Count > 0); } if (!Chat.instance.HasFocus() && !InventoryGui.IsVisible() && Input.GetKeyDown(questKey.Value)) { ToggleUI(); } } private void UpdateIconSlideshow() { List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests(); if (visibleQuests.Count == 0) { return; } QuestConfig questConfig = visibleQuests[Math.Min(QuestUI.currentIndex, visibleQuests.Count - 1)]; if (questConfig.RewardItems != null && questConfig.RewardItems.Count > 1) { QuestUI.iconTimer += Time.deltaTime; if (QuestUI.iconTimer >= 2f) { QuestUI.iconTimer = 0f; QuestUI.currentIconIndex = (QuestUI.currentIconIndex + 1) % questConfig.RewardItems.Count; QuestUI.SetRewardIcon(questConfig.RewardItems[QuestUI.currentIconIndex].Prefab); } } } public void ToggleUI() { if ((Object)(object)QuestUI.window == (Object)null) { QuestUI.CreateUI(); } bool flag = !QuestUI.window.activeSelf; if (flag) { QuestUI.showHistoryMode = false; QuestUI.currentIndex = 0; QuestUI.UpdateUI(); QuestUtils.PlaySfx("sfx_gui_mouse_over"); } else { SaveProgress(); QuestUtils.PlaySfx("sfx_gui_mouse_over"); } QuestUI.window.SetActive(flag); GUIManager.BlockInput(flag); Cursor.visible = flag; Cursor.lockState = (CursorLockMode)((!flag) ? 1 : 0); } public void CompleteQuest() { List<QuestConfig> visibleQuests = QuestUtils.GetVisibleQuests(); if (visibleQuests.Count == 0) { return; } QuestConfig questConfig = visibleQuests[QuestUI.currentIndex]; if (completedQuests.Contains(questConfig.ID)) { return; } Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory(); if (questConfig.Reqs != null) { foreach (QuestRequirement req in questConfig.Reqs) { if (QuestUtils.GetItemCount(req.Prefab) < req.Amount) { return; } } } if (questConfig.KillReqs != null) { foreach (QuestRequirement i in questConfig.KillReqs) { int num = playerKills.Where((KeyValuePair<string, int> x) => x.Key.Equals(i.Prefab.Trim(), StringComparison.OrdinalIgnoreCase)).Sum((KeyValuePair<string, int> x) => x.Value); if (num < i.Amount) { return; } } } if (questConfig.Reqs != null) { foreach (QuestRequirement req2 in questConfig.Reqs) { int num2 = req2.Amount; List<ItemData> list = inventory.GetAllItems().ToList(); for (int num3 = list.Count - 1; num3 >= 0; num3--) { if ((Object)(object)list[num3].m_dropPrefab != (Object)null && string.Equals(((Object)list[num3].m_dropPrefab).name, req2.Prefab, StringComparison.OrdinalIgnoreCase)) { int num4 = Math.Min(list[num3].m_stack, num2); ItemData obj = list[num3]; obj.m_stack -= num4; num2 -= num4; if (list[num3].m_stack <= 0) { inventory.RemoveItem(list[num3]); } if (num2 <= 0) { break; } } } } } if (questConfig.RewardItems != null && questConfig.RewardItems.Count > 0) { foreach (QuestRequirement rewardItem in questConfig.RewardItems) { inventory.AddItem(rewardItem.Prefab, rewardItem.Amount, 1, 0, 0L, "", false); } } else if (!string.IsNullOrEmpty(questConfig.RewardItem)) { inventory.AddItem(questConfig.RewardItem, questConfig.RewardAmount, 1, 0, 0L, "", false); } if (questConfig.ExpReward > 0) { QuestUtils.AddExp(questConfig.ExpReward); } completedQuests.Add(questConfig.ID); SaveProgress(); QuestUI.UpdateUI(); QuestUtils.PlaySfx("sfx_coins_up"); ((Character)Player.m_localPlayer).Message((MessageType)2, Localization.instance.Localize("$sq_success"), 0, (Sprite)null); } private void LoadLocalization() { try { string path = Path.Combine(Path.GetDirectoryName(((BaseUnityPlugin)this).Info.Location), "translations"); string path2 = Path.Combine(path, Localization.instance.GetSelectedLanguage() + ".json"); if (!File.Exists(path2)) { path2 = Path.Combine(path, "English.json"); } if (!File.Exists(path2)) { return; } Dictionary<string, string> dictionary = JsonConvert.DeserializeObject<Dictionary<string, string>>(File.ReadAllText(path2)); foreach (KeyValuePair<string, string> item in dictionary) { LocalizationManager.Instance.AddToken(item.Key, item.Value, false); } } catch { } } private void LoadQuestsLocal(string dir) { string path = Path.Combine(dir, "quests.json"); if (File.Exists(path)) { RawServerJson = File.ReadAllText(path); serverQuests = JsonConvert.DeserializeObject<QuestList>(RawServerJson) ?? new QuestList(); } } [IteratorStateMachine(typeof(<OnClientQuestRequest>d__20))] private IEnumerator OnClientQuestRequest(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnClientQuestRequest>d__20(0) { <>4__this = this, sender = sender, package = package }; } [IteratorStateMachine(typeof(<OnServerQuestReceived>d__21))] private IEnumerator OnServerQuestReceived(long sender, ZPackage package) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <OnServerQuestReceived>d__21(0) { <>4__this = this, sender = sender, package = package }; } private void LoadProgress() { string path = Path.Combine(Paths.ConfigPath, "SimpleQuest", "progress_" + Player.m_localPlayer.GetPlayerName() + ".sav"); if (File.Exists(path)) { string[] source = File.ReadAllLines(path); completedQuests = new HashSet<string>(source.Where((string l) => !l.StartsWith("KILLS:"))); string text = source.FirstOrDefault((string l) => l.StartsWith("KILLS:")); if (text != null) { playerKills = JsonConvert.DeserializeObject<Dictionary<string, int>>(text.Replace("KILLS:", "")) ?? new Dictionary<string, int>(); } } } private void SaveProgress() { string path = Path.Combine(Paths.ConfigPath, "SimpleQuest", "progress_" + Player.m_localPlayer.GetPlayerName() + ".sav"); List<string> list = completedQuests.ToList(); list.Add("KILLS:" + JsonConvert.SerializeObject((object)playerKills)); File.WriteAllLines(path, list); } } public class QuestList { public List<QuestConfig> Quests = new List<QuestConfig>(); } public class QuestConfig { public string ID; public string Title; public string Goal; public string Rarity; public string RewardItem; public string PreReqID; public int RewardAmount; public int ExpReward; public List<QuestRequirement> Reqs; public List<QuestRequirement> KillReqs; public List<QuestRequirement> RewardItems; } public class QuestRequirement { public string Prefab; public int Amount; }