Decompiled source of RtDQuestForge v0.1.3

RtDQuestForge.dll

Decompiled 15 hours ago
using 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.Versioning;
using System.Text;
using BepInEx;
using BepInEx.Bootstrap;
using BepInEx.Configuration;
using BepInEx.Logging;
using HarmonyLib;
using Jotunn;
using Jotunn.Entities;
using Jotunn.Managers;
using Jotunn.Utils;
using Microsoft.CodeAnalysis;
using Newtonsoft.Json;
using RtDQuestForge.UI;
using UnityEngine;
using UnityEngine.Events;
using UnityEngine.SceneManagement;
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: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")]
[assembly: AssemblyCompany("RtDQuestForge")]
[assembly: AssemblyConfiguration("Debug")]
[assembly: AssemblyFileVersion("1.0.0.0")]
[assembly: AssemblyInformationalVersion("1.0.0+ed86fa6ae4e635401aec7ec7505b20ec6695e301")]
[assembly: AssemblyProduct("RtDQuestForge")]
[assembly: AssemblyTitle("RtDQuestForge")]
[assembly: AssemblyVersion("1.0.0.0")]
[module: RefSafetyRules(11)]
namespace Microsoft.CodeAnalysis
{
	[CompilerGenerated]
	[Embedded]
	internal sealed class EmbeddedAttribute : Attribute
	{
	}
}
namespace System.Runtime.CompilerServices
{
	[CompilerGenerated]
	[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 RtDQuestForge
{
	public static class QuestConfigLoader
	{
		private const string DefaultFileName = "quests_default.json";

		public static QuestList LoadAll(string configDir, ManualLogSource logger)
		{
			Directory.CreateDirectory(configDir);
			EnsureDefaultFileExists(configDir, logger);
			string[] array = (from f in Directory.GetFiles(configDir, "*.json")
				where !Path.GetFileName(f).StartsWith("progress_", StringComparison.OrdinalIgnoreCase)
				select f).OrderBy<string, string>(Path.GetFileName, StringComparer.OrdinalIgnoreCase).ToArray();
			QuestList questList = new QuestList();
			HashSet<string> seenIds = new HashSet<string>(StringComparer.OrdinalIgnoreCase);
			string[] array2 = array;
			foreach (string file in array2)
			{
				MergeFile(file, questList, seenIds, logger);
			}
			logger.LogMessage((object)("Loaded " + questList.Quests.Count + " quest(s) from " + array.Length + " file(s)."));
			return questList;
		}

		private static void MergeFile(string file, QuestList combined, HashSet<string> seenIds, ManualLogSource logger)
		{
			//IL_003b: Expected O, but got Unknown
			string fileName = Path.GetFileName(file);
			string text;
			try
			{
				text = File.ReadAllText(file);
			}
			catch (IOException arg)
			{
				logger.LogWarning((object)$"Exception caught while reading {fileName}: {arg}");
				return;
			}
			QuestList questList;
			try
			{
				questList = JsonConvert.DeserializeObject<QuestList>(text);
			}
			catch (JsonException ex)
			{
				JsonException arg2 = ex;
				logger.LogWarning((object)$"Exception caught while parsing {fileName}, file was skipped: {arg2}");
				return;
			}
			if (questList == null || questList.Quests == null)
			{
				return;
			}
			foreach (QuestConfig quest in questList.Quests)
			{
				if (string.IsNullOrWhiteSpace(quest.ID))
				{
					logger.LogWarning((object)("Skipped a quest with no ID in " + fileName + " ('" + quest.Title + "')."));
				}
				else if (!seenIds.Add(quest.ID))
				{
					logger.LogWarning((object)("Duplicate quest ID '" + quest.ID + "' in " + fileName + " was skipped, already loaded from another file."));
				}
				else
				{
					quest.SourceFile = Path.GetFileNameWithoutExtension(file);
					combined.Quests.Add(quest);
				}
			}
		}

		private static void EnsureDefaultFileExists(string configDir, ManualLogSource logger)
		{
			try
			{
				string text = Path.Combine(configDir, "quests_default.json");
				if (!File.Exists(text))
				{
					QuestConfig questConfig = new QuestConfig();
					questConfig.ID = "example_kill_quest";
					questConfig.Title = "Thin the Herd";
					questConfig.Goal = "A few deer kills to get your bearings with the quest journal.";
					questConfig.Rarity = "Common";
					questConfig.KillReqs = new List<ObjectiveEntry>
					{
						new ObjectiveEntry
						{
							Prefab = "Deer",
							Amount = 3
						}
					};
					questConfig.RewardItems = new List<RewardEntry>
					{
						new RewardEntry
						{
							Prefab = "Coins",
							Amount = 20
						}
					};
					QuestConfig questConfig2 = new QuestConfig();
					questConfig2.ID = "example_gather_quest";
					questConfig2.Title = "Supply Run";
					questConfig2.Goal = "Gather wood and stone for the settlement.";
					questConfig2.Rarity = "Common";
					questConfig2.GatherReqs = new List<ObjectiveEntry>
					{
						new ObjectiveEntry
						{
							Prefab = "Wood",
							Amount = 10
						},
						new ObjectiveEntry
						{
							Prefab = "Stone",
							Amount = 5
						}
					};
					questConfig2.RewardItems = new List<RewardEntry>
					{
						new RewardEntry
						{
							Prefab = "Coins",
							Amount = 15
						},
						new RewardEntry
						{
							Prefab = "Resin",
							Amount = 5
						}
					};
					QuestConfig questConfig3 = new QuestConfig();
					questConfig3.ID = "example_skill_quest";
					questConfig3.PreReqID = "example_kill_quest";
					questConfig3.Title = "Seasoned Hunter";
					questConfig3.Goal = "Prove yourself against the boars and bring back their leather.";
					questConfig3.Rarity = "Uncommon";
					questConfig3.KillReqs = new List<ObjectiveEntry>
					{
						new ObjectiveEntry
						{
							Prefab = "Boar",
							Amount = 5
						}
					};
					questConfig3.GatherReqs = new List<ObjectiveEntry>
					{
						new ObjectiveEntry
						{
							Prefab = "LeatherScraps",
							Amount = 5
						}
					};
					questConfig3.RewardItems = new List<RewardEntry>
					{
						new RewardEntry
						{
							Prefab = "Coins",
							Amount = 40
						}
					};
					questConfig3.SkillRewards = new List<SkillRewardEntry>
					{
						new SkillRewardEntry
						{
							Skill = "Bows",
							Amount = 10f
						},
						new SkillRewardEntry
						{
							Skill = "Run",
							Amount = 5f
						}
					};
					QuestConfig questConfig4 = new QuestConfig();
					questConfig4.ID = "example_mmo_quest";
					questConfig4.Title = "Greydwarf Purge";
					questConfig4.Goal = "Clear out the greydwarves lurking at the forest's edge.";
					questConfig4.Rarity = "Common";
					questConfig4.KillReqs = new List<ObjectiveEntry>
					{
						new ObjectiveEntry
						{
							Prefab = "Greydwarf",
							Amount = 5
						}
					};
					questConfig4.RewardItems = new List<RewardEntry>
					{
						new RewardEntry
						{
							Prefab = "Coins",
							Amount = 25
						}
					};
					questConfig4.ExpReward = 150;
					QuestList questList = new QuestList();
					questList.Quests = new List<QuestConfig> { questConfig, questConfig2, questConfig3, questConfig4 };
					File.WriteAllText(text, JsonConvert.SerializeObject((object)questList, (Formatting)1));
					logger.LogMessage((object)("Created starter quest file at " + text));
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while creating the default quest file: {arg}");
			}
		}
	}
	[BepInPlugin("soloredis.rtdquestforge", "RtDQuestForge", "0.1.3")]
	[NetworkCompatibility(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	[BepInDependency(/*Could not decode attribute arguments.*/)]
	internal class QuestForgePlugin : BaseUnityPlugin
	{
		public const string PluginGUID = "soloredis.rtdquestforge";

		public const string PluginName = "RtDQuestForge";

		public const string PluginVersion = "0.1.3";

		public static QuestManager Manager;

		private static ManualLogSource StaticLogger;

		private static ConfigEntry<bool> LoggingEnable;

		private ConfigEntry<KeyboardShortcut> JournalHotkey;

		private Harmony HarmonyInstance;

		private QuestJournalPanel Journal;

		public static bool VerboseLogging => LoggingEnable != null && LoggingEnable.Value;

		private void Awake()
		{
			StaticLogger = ((BaseUnityPlugin)this).Logger;
			CreateConfigs();
			JSONSupport();
			LoadQuests();
			PatchGame();
			QuestSync.Init(((BaseUnityPlugin)this).Logger);
			SceneManager.sceneLoaded += OnSceneLoaded;
		}

		private void CreateConfigs()
		{
			//IL_002e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0033: Unknown result type (might be due to invalid IL or missing references)
			//IL_003c: Expected O, but got Unknown
			//IL_003c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0046: Expected O, but got Unknown
			//IL_0063: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Expected O, but got Unknown
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_008e: Expected O, but got Unknown
			try
			{
				((BaseUnityPlugin)this).Config.SaveOnConfigSet = true;
				LoggingEnable = ((BaseUnityPlugin)this).Config.Bind<bool>("Logging", "Enable", false, new ConfigDescription("Enables verbose diagnostic logging.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = false
				} }));
				JournalHotkey = ((BaseUnityPlugin)this).Config.Bind<KeyboardShortcut>("General", "JournalHotkey", new KeyboardShortcut((KeyCode)108, Array.Empty<KeyCode>()), new ConfigDescription("Key to open the quest journal.", (AcceptableValueBase)null, new object[1] { (object)new ConfigurationManagerAttributes
				{
					IsAdminOnly = false
				} }));
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while adding configuration values: {arg}");
			}
		}

		private void JSONSupport()
		{
			try
			{
				string text = Path.Combine(Paths.ConfigPath, "RtDQuestForge", "translations");
				Directory.CreateDirectory(text);
				string text2 = Path.Combine(text, "English.json");
				if (!File.Exists(text2))
				{
					File.WriteAllText(text2, "{\n  \"rtdqf_journal_title\": \"Quest Journal\",\n  \"rtdqf_active\": \"Active\",\n  \"rtdqf_completed\": \"Completed\",\n  \"rtdqf_page\": \"Page\",\n  \"rtdqf_accept\": \"Accept\",\n  \"rtdqf_abandon\": \"Abandon\",\n  \"rtdqf_slay\": \"Slay\",\n  \"rtdqf_gather\": \"Gather\",\n  \"rtdqf_reward\": \"Reward\",\n  \"rtdqf_requires\": \"Requires\",\n  \"rtdqf_mmo_exp\": \"MMO EXP\",\n  \"rtdqf_quest_complete\": \"Quest Complete\"\n}\n");
					((BaseUnityPlugin)this).Logger.LogMessage((object)("Created default translation file at " + text2));
				}
				CustomLocalization localization = LocalizationManager.Instance.GetLocalization();
				string[] files = Directory.GetFiles(text, "*.json");
				foreach (string path in files)
				{
					string fileNameWithoutExtension = Path.GetFileNameWithoutExtension(path);
					localization.AddJsonFile(fileNameWithoutExtension, File.ReadAllText(path));
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while loading localization files: {arg}");
			}
		}

		private void LoadQuests()
		{
			try
			{
				string configDir = Path.Combine(Paths.ConfigPath, "RtDQuestForge");
				Manager = new QuestManager(configDir, ((BaseUnityPlugin)this).Logger);
				Manager.LoadQuestDefinitions();
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while loading quest definitions: {arg}");
			}
		}

		private void PatchGame()
		{
			//IL_0008: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			try
			{
				HarmonyInstance = new Harmony("soloredis.rtdquestforge");
				HarmonyInstance.PatchAll();
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while applying Harmony patches: {arg}");
			}
		}

		private void OnSceneLoaded(Scene scene, LoadSceneMode mode)
		{
			if (!(((Scene)(ref scene)).name != "main"))
			{
				BuildUI();
			}
		}

		private void BuildUI()
		{
			//IL_0018: Unknown result type (might be due to invalid IL or missing references)
			//IL_001e: Expected O, but got Unknown
			try
			{
				if ((Object)(object)Journal == (Object)null)
				{
					GameObject val = new GameObject("QuestForge_JournalHost");
					Object.DontDestroyOnLoad((Object)(object)val);
					Journal = val.AddComponent<QuestJournalPanel>();
					Journal.Init(Manager, ((BaseUnityPlugin)this).Logger);
				}
			}
			catch (Exception arg)
			{
				((BaseUnityPlugin)this).Logger.LogWarning((object)$"Exception caught while building UI: {arg}");
			}
		}

		private void Update()
		{
			//IL_004c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0051: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b7: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)Player.m_localPlayer == (Object)null || (Object)(object)Journal == (Object)null)
			{
				return;
			}
			KeyboardShortcut value;
			if (Journal.IsOpen)
			{
				if (!Input.GetKeyDown((KeyCode)27) && !Menu.IsVisible())
				{
					value = JournalHotkey.Value;
					if (!((KeyboardShortcut)(ref value)).IsDown())
					{
						return;
					}
				}
				Journal.Hide();
			}
			else if ((!((Object)(object)Chat.instance != (Object)null) || !Chat.instance.HasFocus()) && !Console.IsVisible() && !TextInput.IsVisible())
			{
				value = JournalHotkey.Value;
				if (((KeyboardShortcut)(ref value)).IsDown())
				{
					Journal.Toggle();
				}
			}
		}

		public static void HandleQuestCompleted(QuestConfig quest)
		{
			try
			{
				RewardGranter.GrantRewards(quest, StaticLogger);
				if ((Object)(object)Player.m_localPlayer != (Object)null)
				{
					string text = ((Localization.instance != null) ? Localization.instance.Localize("$rtdqf_quest_complete") : "Quest Complete");
					((Character)Player.m_localPlayer).Message((MessageType)2, text + ": " + quest.Title, 0, (Sprite)null);
				}
			}
			catch (Exception arg)
			{
				ManualLogSource staticLogger = StaticLogger;
				if (staticLogger != null)
				{
					staticLogger.LogWarning((object)$"Exception caught while granting quest rewards: {arg}");
				}
			}
		}
	}
	public class QuestManager
	{
		public QuestList AllQuests;

		public QuestProgressData Progress;

		private readonly string ConfigDir;

		private readonly ManualLogSource Logger;

		private string ProgressFilePath;

		public event Action<QuestConfig> OnQuestCompleted;

		public event Action<QuestConfig, string, int, int> OnObjectiveProgress;

		public QuestManager(string configDir, ManualLogSource logger)
		{
			ConfigDir = configDir;
			Logger = logger;
			AllQuests = new QuestList();
			Progress = new QuestProgressData();
		}

		public void LoadQuestDefinitions()
		{
			try
			{
				AllQuests = QuestConfigLoader.LoadAll(ConfigDir, Logger);
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while loading quest definitions: {arg}");
			}
		}

		public void ApplyServerQuestList(QuestList list)
		{
			AllQuests = ((list != null) ? list : new QuestList());
		}

		public void LoadProgress(string characterName)
		{
			try
			{
				ProgressFilePath = Path.Combine(ConfigDir, "progress_" + SanitizeFileName(characterName) + ".json");
				if (File.Exists(ProgressFilePath))
				{
					Progress = JsonConvert.DeserializeObject<QuestProgressData>(File.ReadAllText(ProgressFilePath));
					if (Progress == null)
					{
						Progress = new QuestProgressData();
					}
				}
				else
				{
					Progress = new QuestProgressData();
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while loading progress file, starting fresh: {arg}");
				Progress = new QuestProgressData();
			}
		}

		public void SaveProgress()
		{
			try
			{
				if (!string.IsNullOrEmpty(ProgressFilePath))
				{
					File.WriteAllText(ProgressFilePath, JsonConvert.SerializeObject((object)Progress, (Formatting)1));
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while saving progress file: {arg}");
			}
		}

		public IEnumerable<QuestConfig> GetAvailableQuests()
		{
			return AllQuests.Quests.Where((QuestConfig q) => !Progress.CompletedQuestIDs.Contains(q.ID) && (string.IsNullOrEmpty(q.PreReqID) || Progress.CompletedQuestIDs.Contains(q.PreReqID)));
		}

		public void AcceptQuest(QuestConfig quest)
		{
			Progress.AcceptedQuestIDs.Add(quest.ID);
			Progress.TrackedQuestIDs.Add(quest.ID);
			SaveProgress();
		}

		public void AbandonQuest(QuestConfig quest)
		{
			Progress.AcceptedQuestIDs.Remove(quest.ID);
			Progress.TrackedQuestIDs.Remove(quest.ID);
			foreach (ObjectiveEntry killReq in quest.KillReqs)
			{
				Progress.KillCounts.Remove(quest.ID + ":" + killReq.Prefab);
			}
			foreach (ObjectiveEntry gatherReq in quest.GatherReqs)
			{
				Progress.GatherCounts.Remove(quest.ID + ":" + gatherReq.Prefab);
			}
			SaveProgress();
		}

		public void RegisterKill(string prefabName)
		{
			RegisterObjective(prefabName, (QuestConfig q) => q.KillReqs, Progress.KillCounts, 1);
		}

		public void RegisterGather(string prefabName, int amountAdded)
		{
			RegisterObjective(prefabName, (QuestConfig q) => q.GatherReqs, Progress.GatherCounts, amountAdded);
		}

		private void RegisterObjective(string prefabName, Func<QuestConfig, List<ObjectiveEntry>> selector, Dictionary<string, int> counters, int amount)
		{
			try
			{
				bool flag = false;
				foreach (QuestConfig item in (from q in GetAvailableQuests()
					where Progress.AcceptedQuestIDs.Contains(q.ID)
					select q).ToList())
				{
					List<ObjectiveEntry> list = selector(item);
					if (list == null)
					{
						continue;
					}
					ObjectiveEntry objectiveEntry = list.FirstOrDefault((ObjectiveEntry o) => string.Equals(o.Prefab, prefabName, StringComparison.OrdinalIgnoreCase));
					if (objectiveEntry != null)
					{
						string key = item.ID + ":" + prefabName;
						counters.TryGetValue(key, out var value);
						value = (counters[key] = Math.Min(value + amount, objectiveEntry.Amount));
						flag = true;
						if (this.OnObjectiveProgress != null)
						{
							this.OnObjectiveProgress(item, prefabName, value, objectiveEntry.Amount);
						}
						if (IsQuestComplete(item))
						{
							CompleteQuest(item);
						}
					}
				}
				if (flag)
				{
					SaveProgress();
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while registering objective progress for {prefabName}: {arg}");
			}
		}

		private bool IsQuestComplete(QuestConfig quest)
		{
			int value;
			bool flag = quest.KillReqs.All((ObjectiveEntry o) => Progress.KillCounts.TryGetValue(quest.ID + ":" + o.Prefab, out value) && value >= o.Amount);
			bool flag2 = quest.GatherReqs.All((ObjectiveEntry o) => Progress.GatherCounts.TryGetValue(quest.ID + ":" + o.Prefab, out value) && value >= o.Amount);
			return flag && flag2;
		}

		private void CompleteQuest(QuestConfig quest)
		{
			Progress.CompletedQuestIDs.Add(quest.ID);
			Progress.TrackedQuestIDs.Remove(quest.ID);
			Progress.AcceptedQuestIDs.Remove(quest.ID);
			if (this.OnQuestCompleted != null)
			{
				this.OnQuestCompleted(quest);
			}
		}

		private static string SanitizeFileName(string name)
		{
			char[] invalidFileNameChars = Path.GetInvalidFileNameChars();
			foreach (char oldChar in invalidFileNameChars)
			{
				name = name.Replace(oldChar, '_');
			}
			return name;
		}
	}
	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 = "Common";

		public string PreReqID;

		public List<ObjectiveEntry> KillReqs = new List<ObjectiveEntry>();

		public List<ObjectiveEntry> GatherReqs = new List<ObjectiveEntry>();

		public List<RewardEntry> RewardItems = new List<RewardEntry>();

		public List<SkillRewardEntry> SkillRewards = new List<SkillRewardEntry>();

		public int ExpReward;

		public string SourceFile;
	}
	public class ObjectiveEntry
	{
		public string Prefab;

		public int Amount;
	}
	public class RewardEntry
	{
		public string Prefab;

		public int Amount = 1;
	}
	public class SkillRewardEntry
	{
		public string Skill;

		public float Amount;
	}
	public class QuestProgressData
	{
		public HashSet<string> CompletedQuestIDs = new HashSet<string>();

		public HashSet<string> AcceptedQuestIDs = new HashSet<string>();

		public HashSet<string> TrackedQuestIDs = new HashSet<string>();

		public Dictionary<string, int> KillCounts = new Dictionary<string, int>();

		public Dictionary<string, int> GatherCounts = new Dictionary<string, int>();
	}
	public static class QuestSync
	{
		[CompilerGenerated]
		private static class <>O
		{
			public static CoroutineHandler <0>__OnServerReceive;

			public static CoroutineHandler <1>__OnClientReceive;

			public static CoroutineHandler <2>__OnKillServerReceive;

			public static CoroutineHandler <3>__OnKillClientReceive;
		}

		private static CustomRPC SyncRpc;

		private static CustomRPC KillRpc;

		private static ManualLogSource Logger;

		public static void Init(ManualLogSource logger)
		{
			//IL_0022: Unknown result type (might be due to invalid IL or missing references)
			//IL_0027: Unknown result type (might be due to invalid IL or missing references)
			//IL_002d: Expected O, but got Unknown
			//IL_003d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			//IL_0048: Expected O, but got Unknown
			//IL_006c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0077: Expected O, but got Unknown
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_008c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Expected O, but got Unknown
			try
			{
				Logger = logger;
				NetworkManager instance = NetworkManager.Instance;
				object obj = <>O.<0>__OnServerReceive;
				if (obj == null)
				{
					CoroutineHandler val = OnServerReceive;
					<>O.<0>__OnServerReceive = val;
					obj = (object)val;
				}
				object obj2 = <>O.<1>__OnClientReceive;
				if (obj2 == null)
				{
					CoroutineHandler val2 = OnClientReceive;
					<>O.<1>__OnClientReceive = val2;
					obj2 = (object)val2;
				}
				SyncRpc = instance.AddRPC("rtdqf_questsync", (CoroutineHandler)obj, (CoroutineHandler)obj2);
				NetworkManager instance2 = NetworkManager.Instance;
				object obj3 = <>O.<2>__OnKillServerReceive;
				if (obj3 == null)
				{
					CoroutineHandler val3 = OnKillServerReceive;
					<>O.<2>__OnKillServerReceive = val3;
					obj3 = (object)val3;
				}
				object obj4 = <>O.<3>__OnKillClientReceive;
				if (obj4 == null)
				{
					CoroutineHandler val4 = OnKillClientReceive;
					<>O.<3>__OnKillClientReceive = val4;
					obj4 = (object)val4;
				}
				KillRpc = instance2.AddRPC("rtdqf_killcredit", (CoroutineHandler)obj3, (CoroutineHandler)obj4);
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while registering the quest sync RPCs: {arg}");
			}
		}

		public static void RequestFromServer()
		{
			//IL_0050: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			try
			{
				if (!((Object)(object)ZNet.instance == (Object)null) && !ZNet.instance.IsServer() && SyncRpc != null)
				{
					ZNetPeer serverPeer = ZNet.instance.GetServerPeer();
					if (serverPeer != null)
					{
						SyncRpc.SendPackage(serverPeer.m_uid, new ZPackage());
						Logger.LogMessage((object)"Requested quest list from the server.");
					}
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while requesting quest sync: {arg}");
			}
		}

		public static void SendKillCredit(string killerPlayerName, string prefabName)
		{
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_005a: Expected O, but got Unknown
			try
			{
				if (KillRpc != null)
				{
					if (QuestForgePlugin.VerboseLogging)
					{
						Logger.LogMessage((object)("Broadcasting kill credit package for " + killerPlayerName + " (" + prefabName + ")."));
					}
					ZPackage val = new ZPackage();
					val.Write(killerPlayerName);
					val.Write(prefabName);
					KillRpc.SendPackage(ZRoutedRpc.Everybody, val);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while sending kill credit for {prefabName}: {arg}");
			}
		}

		private static IEnumerator OnServerReceive(long sender, ZPackage package)
		{
			try
			{
				string json = JsonConvert.SerializeObject((object)QuestForgePlugin.Manager.AllQuests);
				ZPackage response = new ZPackage();
				response.Write(json);
				SyncRpc.SendPackage(sender, response);
				Logger.LogMessage((object)("Sent quest list to peer " + sender + "."));
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while sending quest sync to peer {sender}: {ex2}");
			}
			yield break;
		}

		private static IEnumerator OnClientReceive(long sender, ZPackage package)
		{
			try
			{
				string json = package.ReadString();
				QuestList serverList = JsonConvert.DeserializeObject<QuestList>(json);
				if (serverList != null && serverList.Quests != null)
				{
					QuestForgePlugin.Manager.ApplyServerQuestList(serverList);
					Logger.LogMessage((object)("Applied " + serverList.Quests.Count + " quest(s) from the server."));
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while applying quest sync from the server: {ex2}");
			}
			yield break;
		}

		private static IEnumerator OnKillServerReceive(long sender, ZPackage package)
		{
			try
			{
				string killerPlayerName = package.ReadString();
				string prefabName = package.ReadString();
				if (QuestForgePlugin.VerboseLogging)
				{
					Logger.LogMessage((object)("Server forwarding kill credit for " + killerPlayerName + " (" + prefabName + ") to all peers."));
				}
				foreach (ZNetPeer peer in ZNet.instance.GetPeers())
				{
					ZPackage forward = new ZPackage();
					forward.Write(killerPlayerName);
					forward.Write(prefabName);
					KillRpc.SendPackage(peer.m_uid, forward);
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while forwarding kill credit: {ex2}");
			}
			yield break;
		}

		private static IEnumerator OnKillClientReceive(long sender, ZPackage package)
		{
			try
			{
				if (QuestForgePlugin.VerboseLogging)
				{
					Logger.LogMessage((object)("Kill credit package received from peer " + sender + "."));
				}
				string killerPlayerName = package.ReadString();
				string prefabName = package.ReadString();
				if ((Object)(object)Player.m_localPlayer != (Object)null && Player.m_localPlayer.GetPlayerName() == killerPlayerName && QuestForgePlugin.Manager != null)
				{
					if (QuestForgePlugin.VerboseLogging)
					{
						Logger.LogMessage((object)("Kill credit matched local player, registering " + prefabName + "."));
					}
					QuestForgePlugin.Manager.RegisterKill(prefabName);
				}
			}
			catch (Exception ex)
			{
				Exception ex2 = ex;
				Logger.LogWarning((object)$"Exception caught while applying kill credit: {ex2}");
			}
			yield break;
		}
	}
	public static class RewardGranter
	{
		private const string EpicMmoGuid = "WackyMole.EpicMMOSystem";

		public static void GrantRewards(QuestConfig quest, ManualLogSource logger)
		{
			if (!((Object)(object)Player.m_localPlayer == (Object)null))
			{
				GrantItems(quest, logger);
				GrantSkillXP(quest, logger);
				GrantEpicMmoXP(quest, logger);
			}
		}

		private static void GrantItems(QuestConfig quest, ManualLogSource logger)
		{
			try
			{
				foreach (RewardEntry rewardItem in quest.RewardItems)
				{
					GameObject prefab = ZNetScene.instance.GetPrefab(rewardItem.Prefab);
					if ((Object)(object)prefab == (Object)null)
					{
						logger.LogWarning((object)("Reward prefab '" + rewardItem.Prefab + "' on quest '" + quest.ID + "' does not exist and was skipped."));
						continue;
					}
					ItemDrop component = prefab.GetComponent<ItemDrop>();
					if ((Object)(object)component == (Object)null)
					{
						logger.LogWarning((object)("Prefab '" + rewardItem.Prefab + "' on quest '" + quest.ID + "' has no ItemDrop component."));
					}
					else
					{
						ItemData val = component.m_itemData.Clone();
						val.m_stack = rewardItem.Amount;
						Inventory inventory = ((Humanoid)Player.m_localPlayer).GetInventory();
						if (!inventory.AddItem(val))
						{
							((Humanoid)Player.m_localPlayer).DropItem(inventory, val, val.m_stack);
						}
					}
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while granting item rewards for quest '{quest.ID}': {arg}");
			}
		}

		private static void GrantSkillXP(QuestConfig quest, ManualLogSource logger)
		{
			//IL_0073: Unknown result type (might be due to invalid IL or missing references)
			try
			{
				foreach (SkillRewardEntry skillReward in quest.SkillRewards)
				{
					if (!Enum.TryParse<SkillType>(skillReward.Skill, ignoreCase: true, out SkillType result))
					{
						logger.LogWarning((object)("Unknown skill '" + skillReward.Skill + "' on quest '" + quest.ID + "'."));
					}
					else
					{
						((Character)Player.m_localPlayer).RaiseSkill(result, skillReward.Amount);
					}
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while granting skill XP for quest '{quest.ID}': {arg}");
			}
		}

		private static void GrantEpicMmoXP(QuestConfig quest, ManualLogSource logger)
		{
			if (quest.ExpReward <= 0 || !Chainloader.PluginInfos.ContainsKey("WackyMole.EpicMMOSystem"))
			{
				return;
			}
			try
			{
				object instance = Chainloader.PluginInfos["WackyMole.EpicMMOSystem"].Instance;
				Type type = instance.GetType().Assembly.GetType("EpicMMOSystem.LevelSystem");
				if (type == null)
				{
					return;
				}
				PropertyInfo property = type.GetProperty("Instance", BindingFlags.Static | BindingFlags.Public);
				object obj = ((property != null) ? property.GetValue(null) : 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 == 1)
					{
						object obj2 = Convert.ChangeType(quest.ExpReward, parameters[0].ParameterType);
						method.Invoke(obj, new object[1] { obj2 });
					}
					else if (parameters.Length == 2)
					{
						object obj3 = ((parameters[0].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(quest.ExpReward, parameters[0].ParameterType));
						object obj4 = ((parameters[1].ParameterType == typeof(Player)) ? Player.m_localPlayer : Convert.ChangeType(quest.ExpReward, parameters[1].ParameterType));
						method.Invoke(obj, new object[2] { obj3, obj4 });
					}
				}
			}
			catch (Exception arg)
			{
				logger.LogWarning((object)$"Exception caught while granting EpicMMO XP for quest '{quest.ID}': {arg}");
			}
		}
	}
}
namespace RtDQuestForge.UI
{
	public class QuestJournalPanel : MonoBehaviour
	{
		private QuestManager Manager;

		private ManualLogSource Logger;

		private GameObject RootPanel;

		private RectTransform ActiveListContainer;

		private RectTransform CompletedListContainer;

		private readonly List<GameObject> EntryPool = new List<GameObject>();

		private int CurrentPageIndex;

		private List<string> SourceFiles = new List<string>();

		private GameObject PagerRoot;

		private Text PagerLabel;

		public bool IsOpen => (Object)(object)RootPanel != (Object)null && RootPanel.activeSelf;

		private static string L(string token)
		{
			return (Localization.instance != null) ? Localization.instance.Localize(token) : token;
		}

		public void Init(QuestManager manager, ManualLogSource logger)
		{
			Manager = manager;
			Logger = logger;
			BuildUI();
			Hide();
		}

		public void Toggle()
		{
			if (IsOpen)
			{
				Hide();
			}
			else
			{
				Show();
			}
		}

		public void Show()
		{
			RootPanel.SetActive(true);
			Refresh();
			GUIManager.BlockInput(true);
		}

		public void Hide()
		{
			RootPanel.SetActive(false);
			GUIManager.BlockInput(false);
		}

		public void Refresh()
		{
			try
			{
				foreach (GameObject item in EntryPool)
				{
					Object.Destroy((Object)(object)item);
				}
				EntryPool.Clear();
				if (Manager != null)
				{
					SourceFiles = Manager.AllQuests.Quests.Select((QuestConfig q) => string.IsNullOrEmpty(q.SourceFile) ? "Quests" : q.SourceFile).Distinct().OrderBy<string, string>((string name) => name, StringComparer.OrdinalIgnoreCase)
						.ToList();
					if (SourceFiles.Count == 0)
					{
						SourceFiles.Add("Quests");
					}
					if (CurrentPageIndex >= SourceFiles.Count)
					{
						CurrentPageIndex = 0;
					}
					string currentFile = SourceFiles[CurrentPageIndex];
					PagerRoot.SetActive(SourceFiles.Count > 1);
					PagerLabel.text = L("$rtdqf_page") + " " + (CurrentPageIndex + 1) + "/" + SourceFiles.Count;
					List<QuestConfig> pageQuests = Manager.AllQuests.Quests.Where((QuestConfig q) => (string.IsNullOrEmpty(q.SourceFile) ? "Quests" : q.SourceFile) == currentFile).ToList();
					List<QuestConfig> first = (from q in Manager.GetAvailableQuests()
						where pageQuests.Contains(q)
						select q).ToList();
					List<QuestConfig> second = pageQuests.Where((QuestConfig q) => !Manager.Progress.CompletedQuestIDs.Contains(q.ID) && !string.IsNullOrEmpty(q.PreReqID) && !Manager.Progress.CompletedQuestIDs.Contains(q.PreReqID)).ToList();
					List<QuestConfig> quests = pageQuests.Where((QuestConfig q) => Manager.Progress.CompletedQuestIDs.Contains(q.ID)).ToList();
					FillColumn(ActiveListContainer, first.Concat(second).ToList());
					FillColumn(CompletedListContainer, quests);
				}
			}
			catch (Exception arg)
			{
				Logger.LogWarning((object)$"Exception caught while refreshing the quest journal: {arg}");
			}
		}

		private void ChangePage(int direction)
		{
			if (SourceFiles.Count > 1)
			{
				CurrentPageIndex += direction;
				if (CurrentPageIndex < 0)
				{
					CurrentPageIndex = SourceFiles.Count - 1;
				}
				if (CurrentPageIndex >= SourceFiles.Count)
				{
					CurrentPageIndex = 0;
				}
				Refresh();
			}
		}

		private void FillColumn(RectTransform container, List<QuestConfig> quests)
		{
			//IL_006a: Unknown result type (might be due to invalid IL or missing references)
			float num = 0f;
			float num2 = 150f;
			foreach (QuestConfig quest in quests)
			{
				GameObject item = BuildEntry(container, quest, num);
				EntryPool.Add(item);
				num -= num2;
			}
			container.sizeDelta = new Vector2(0f, Mathf.Abs(num) + 20f);
		}

		private void BuildUI()
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0054: Unknown result type (might be due to invalid IL or missing references)
			//IL_0078: Unknown result type (might be due to invalid IL or missing references)
			//IL_0082: Expected O, but got Unknown
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c7: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e9: Unknown result type (might be due to invalid IL or missing references)
			//IL_0165: Unknown result type (might be due to invalid IL or missing references)
			//IL_0140: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ad: Unknown result type (might be due to invalid IL or missing references)
			//IL_01c4: 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_01f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0209: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("QuestForge_JournalCanvas");
			val.transform.SetParent(((Component)this).transform, false);
			Canvas val2 = val.AddComponent<Canvas>();
			val2.renderMode = (RenderMode)0;
			val2.sortingOrder = 200;
			CanvasScaler val3 = val.AddComponent<CanvasScaler>();
			val3.uiScaleMode = (ScaleMode)1;
			val3.referenceResolution = new Vector2(1920f, 1080f);
			val3.matchWidthOrHeight = 0.5f;
			val.AddComponent<GraphicRaycaster>();
			RootPanel = new GameObject("Panel");
			RootPanel.transform.SetParent(val.transform, false);
			RectTransform val4 = RootPanel.AddComponent<RectTransform>();
			val4.sizeDelta = new Vector2(920f, 560f);
			val4.anchorMin = new Vector2(0.5f, 0.5f);
			val4.anchorMax = new Vector2(0.5f, 0.5f);
			val4.anchoredPosition = Vector2.zero;
			Image val5 = RootPanel.AddComponent<Image>();
			Sprite val6 = ((GUIManager.Instance != null) ? GUIManager.Instance.GetSprite("woodpanel_trophys") : null);
			if ((Object)(object)val6 != (Object)null)
			{
				val5.sprite = val6;
				val5.type = (Type)1;
				((Graphic)val5).color = Color.white;
			}
			else
			{
				((Graphic)val5).color = new Color(0.05f, 0.05f, 0.05f, 0.92f);
			}
			Text val7 = CreateText(RootPanel.transform, L("$rtdqf_journal_title"), 26, (TextAnchor)4);
			ApplyValheimHeaderStyle(val7);
			RectTransform component = ((Component)val7).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.sizeDelta = new Vector2(0f, 40f);
			component.anchoredPosition = new Vector2(0f, -18f);
			BuildPager();
			ActiveListContainer = BuildColumn(L("$rtdqf_active"), 0f, 0.5f);
			CompletedListContainer = BuildColumn(L("$rtdqf_completed"), 0.5f, 1f);
		}

		private void BuildPager()
		{
			//IL_0007: Unknown result type (might be due to invalid IL or missing references)
			//IL_0011: Expected O, but got Unknown
			//IL_0045: Unknown result type (might be due to invalid IL or missing references)
			//IL_005b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_0087: Unknown result type (might be due to invalid IL or missing references)
			//IL_009d: Unknown result type (might be due to invalid IL or missing references)
			//IL_00bf: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c9: Expected O, but got Unknown
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f2: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_011e: Unknown result type (might be due to invalid IL or missing references)
			//IL_012a: 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_0156: Expected O, but got Unknown
			//IL_016b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0182: Unknown result type (might be due to invalid IL or missing references)
			//IL_0199: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b0: Unknown result type (might be due to invalid IL or missing references)
			//IL_01bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_01ff: Unknown result type (might be due to invalid IL or missing references)
			//IL_0216: Unknown result type (might be due to invalid IL or missing references)
			//IL_022d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0244: Unknown result type (might be due to invalid IL or missing references)
			PagerRoot = new GameObject("Pager");
			PagerRoot.transform.SetParent(RootPanel.transform, false);
			RectTransform val = PagerRoot.AddComponent<RectTransform>();
			val.anchorMin = new Vector2(1f, 1f);
			val.anchorMax = new Vector2(1f, 1f);
			val.pivot = new Vector2(1f, 1f);
			val.sizeDelta = new Vector2(260f, 28f);
			val.anchoredPosition = new Vector2(-22f, -20f);
			Button val2 = CreateButton(PagerRoot.transform, "<", (UnityAction)delegate
			{
				ChangePage(-1);
			});
			RectTransform component = ((Component)val2).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 0f);
			component.anchorMax = new Vector2(0f, 1f);
			component.pivot = new Vector2(0f, 0.5f);
			component.sizeDelta = new Vector2(28f, 0f);
			component.anchoredPosition = Vector2.zero;
			Button val3 = CreateButton(PagerRoot.transform, ">", (UnityAction)delegate
			{
				ChangePage(1);
			});
			RectTransform component2 = ((Component)val3).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(1f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.pivot = new Vector2(1f, 0.5f);
			component2.sizeDelta = new Vector2(28f, 0f);
			component2.anchoredPosition = Vector2.zero;
			PagerLabel = CreateText(PagerRoot.transform, "", 12, (TextAnchor)4);
			RectTransform component3 = ((Component)PagerLabel).GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 1f);
			component3.offsetMin = new Vector2(32f, 0f);
			component3.offsetMax = new Vector2(-32f, 0f);
		}

		private RectTransform BuildColumn(string header, float anchorLeft, float anchorRight)
		{
			//IL_000c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0012: Expected O, but got Unknown
			//IL_0038: Unknown result type (might be due to invalid IL or missing references)
			//IL_004a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0060: Unknown result type (might be due to invalid IL or missing references)
			//IL_0076: Unknown result type (might be due to invalid IL or missing references)
			//IL_00aa: Unknown result type (might be due to invalid IL or missing references)
			//IL_00c0: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d6: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_00f8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0108: Unknown result type (might be due to invalid IL or missing references)
			//IL_010f: Expected O, but got Unknown
			//IL_0141: Unknown result type (might be due to invalid IL or missing references)
			//IL_0158: Unknown result type (might be due to invalid IL or missing references)
			//IL_016f: Unknown result type (might be due to invalid IL or missing references)
			//IL_0186: Unknown result type (might be due to invalid IL or missing references)
			//IL_0196: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Expected O, but got Unknown
			//IL_01bd: 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_01d7: Unknown result type (might be due to invalid IL or missing references)
			//IL_01e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_020a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0228: Unknown result type (might be due to invalid IL or missing references)
			//IL_022f: Expected O, but got Unknown
			//IL_0259: Unknown result type (might be due to invalid IL or missing references)
			//IL_0270: Unknown result type (might be due to invalid IL or missing references)
			//IL_0287: Unknown result type (might be due to invalid IL or missing references)
			//IL_0294: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ab: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Column_" + header);
			val.transform.SetParent(RootPanel.transform, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(anchorLeft, 0f);
			val2.anchorMax = new Vector2(anchorRight, 1f);
			val2.offsetMin = new Vector2(18f, 22f);
			val2.offsetMax = new Vector2(-18f, -62f);
			Text val3 = CreateText(val.transform, header, 18, (TextAnchor)4);
			ApplyValheimHeaderStyle(val3);
			RectTransform component = ((Component)val3).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0.5f, 1f);
			component.sizeDelta = new Vector2(0f, 26f);
			component.anchoredPosition = Vector2.zero;
			GameObject val4 = new GameObject("ScrollView");
			val4.transform.SetParent(val.transform, false);
			ScrollRect val5 = val4.AddComponent<ScrollRect>();
			RectTransform component2 = val4.GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.offsetMin = new Vector2(0f, 0f);
			component2.offsetMax = new Vector2(0f, -30f);
			GameObject val6 = new GameObject("Viewport");
			val6.transform.SetParent(val4.transform, false);
			RectTransform val7 = val6.AddComponent<RectTransform>();
			val7.anchorMin = Vector2.zero;
			val7.anchorMax = Vector2.one;
			val7.offsetMin = Vector2.zero;
			val7.offsetMax = Vector2.zero;
			((Graphic)val6.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.01f);
			val6.AddComponent<Mask>().showMaskGraphic = false;
			GameObject val8 = new GameObject("Content");
			val8.transform.SetParent(val6.transform, false);
			RectTransform val9 = val8.AddComponent<RectTransform>();
			val9.anchorMin = new Vector2(0f, 1f);
			val9.anchorMax = new Vector2(1f, 1f);
			val9.pivot = new Vector2(0.5f, 1f);
			val9.anchoredPosition = Vector2.zero;
			val9.sizeDelta = new Vector2(0f, 0f);
			val5.viewport = val7;
			val5.content = val9;
			val5.horizontal = false;
			val5.vertical = true;
			val5.viewport = val7;
			val5.content = val9;
			val5.horizontal = false;
			val5.vertical = true;
			val5.scrollSensitivity = 500f;
			return val9;
		}

		private GameObject BuildEntry(RectTransform parent, QuestConfig quest, float y)
		{
			//IL_002a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0030: Expected O, but got Unknown
			//IL_0050: 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_007c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0092: Unknown result type (might be due to invalid IL or missing references)
			//IL_00a4: Unknown result type (might be due to invalid IL or missing references)
			//IL_015a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0144: Unknown result type (might be due to invalid IL or missing references)
			//IL_016a: Unknown result type (might be due to invalid IL or missing references)
			//IL_0171: Expected O, but got Unknown
			//IL_0190: Unknown result type (might be due to invalid IL or missing references)
			//IL_019d: Unknown result type (might be due to invalid IL or missing references)
			//IL_01b4: Unknown result type (might be due to invalid IL or missing references)
			//IL_01cb: Unknown result type (might be due to invalid IL or missing references)
			//IL_02ec: Unknown result type (might be due to invalid IL or missing references)
			//IL_02d1: Unknown result type (might be due to invalid IL or missing references)
			//IL_023d: Unknown result type (might be due to invalid IL or missing references)
			//IL_026a: Unknown result type (might be due to invalid IL or missing references)
			//IL_032e: Unknown result type (might be due to invalid IL or missing references)
			//IL_0345: Unknown result type (might be due to invalid IL or missing references)
			//IL_035c: Unknown result type (might be due to invalid IL or missing references)
			//IL_0373: Unknown result type (might be due to invalid IL or missing references)
			//IL_038a: 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_03e2: Unknown result type (might be due to invalid IL or missing references)
			//IL_03f9: Unknown result type (might be due to invalid IL or missing references)
			//IL_02a8: Unknown result type (might be due to invalid IL or missing references)
			//IL_0297: Unknown result type (might be due to invalid IL or missing references)
			//IL_0418: Unknown result type (might be due to invalid IL or missing references)
			//IL_04bd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04dd: Unknown result type (might be due to invalid IL or missing references)
			//IL_04f4: Unknown result type (might be due to invalid IL or missing references)
			//IL_050b: Unknown result type (might be due to invalid IL or missing references)
			//IL_0522: Unknown result type (might be due to invalid IL or missing references)
			//IL_0539: Unknown result type (might be due to invalid IL or missing references)
			//IL_0581: Unknown result type (might be due to invalid IL or missing references)
			//IL_058b: Expected O, but got Unknown
			//IL_05a2: Unknown result type (might be due to invalid IL or missing references)
			//IL_05b9: Unknown result type (might be due to invalid IL or missing references)
			//IL_05d0: Unknown result type (might be due to invalid IL or missing references)
			//IL_05e7: Unknown result type (might be due to invalid IL or missing references)
			//IL_05fe: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Quest_" + quest.ID);
			val.transform.SetParent((Transform)(object)parent, false);
			RectTransform val2 = val.AddComponent<RectTransform>();
			val2.anchorMin = new Vector2(0f, 1f);
			val2.anchorMax = new Vector2(1f, 1f);
			val2.pivot = new Vector2(0.5f, 1f);
			val2.sizeDelta = new Vector2(0f, 140f);
			val2.anchoredPosition = new Vector2(0f, y);
			bool flag = Manager.Progress.CompletedQuestIDs.Contains(quest.ID);
			bool flag2 = Manager.Progress.AcceptedQuestIDs.Contains(quest.ID);
			bool flag3 = !flag && !string.IsNullOrEmpty(quest.PreReqID) && !Manager.Progress.CompletedQuestIDs.Contains(quest.PreReqID);
			((Graphic)val.AddComponent<Image>()).color = (Color)(flag3 ? new Color(0.35f, 0.35f, 0.35f) : QuestUIStyles.RarityColor(quest.Rarity));
			GameObject val3 = new GameObject("Inner");
			val3.transform.SetParent(val.transform, false);
			RectTransform val4 = val3.AddComponent<RectTransform>();
			val4.anchorMin = Vector2.zero;
			val4.anchorMax = Vector2.one;
			val4.offsetMin = new Vector2(3f, 3f);
			val4.offsetMax = new Vector2(-3f, -3f);
			Image val5 = val3.AddComponent<Image>();
			Sprite val6 = ((GUIManager.Instance != null) ? GUIManager.Instance.GetSprite("woodpanel_trophys") : null);
			if ((Object)(object)val6 != (Object)null)
			{
				val5.sprite = val6;
				val5.type = (Type)1;
				if (flag)
				{
					((Graphic)val5).color = new Color(0.55f, 0.75f, 0.55f, 1f);
				}
				else if (flag3)
				{
					((Graphic)val5).color = new Color(0.45f, 0.45f, 0.45f, 1f);
				}
				else if (flag2)
				{
					((Graphic)val5).color = new Color(1f, 0.92f, 0.75f, 1f);
				}
				else
				{
					((Graphic)val5).color = Color.white;
				}
			}
			else
			{
				((Graphic)val5).color = (flag ? new Color(0.08f, 0.14f, 0.08f, 0.95f) : new Color(0.1f, 0.1f, 0.1f, 0.95f));
			}
			Text val7 = CreateText(val3.transform, L(quest.Title), 16, (TextAnchor)0);
			RectTransform component = ((Component)val7).GetComponent<RectTransform>();
			component.anchorMin = new Vector2(0f, 1f);
			component.anchorMax = new Vector2(1f, 1f);
			component.pivot = new Vector2(0f, 1f);
			component.sizeDelta = new Vector2(-16f, 20f);
			component.anchoredPosition = new Vector2(10f, -8f);
			Text val8 = CreateText(val3.transform, L(quest.Goal), 12, (TextAnchor)0);
			RectTransform component2 = ((Component)val8).GetComponent<RectTransform>();
			component2.anchorMin = new Vector2(0f, 0f);
			component2.anchorMax = new Vector2(1f, 1f);
			component2.offsetMin = new Vector2(10f, 62f);
			component2.offsetMax = new Vector2((float)((flag || flag3) ? (-10) : (-92)), -30f);
			string content;
			if (flag3)
			{
				QuestConfig questConfig = Manager.AllQuests.Quests.FirstOrDefault((QuestConfig q) => q.ID == quest.PreReqID);
				string text = ((questConfig != null) ? L(questConfig.Title) : quest.PreReqID);
				content = L("$rtdqf_requires") + ": " + text;
			}
			else
			{
				content = BuildDetailLine(quest);
			}
			Text val9 = CreateText(val3.transform, content, 11, (TextAnchor)6);
			((Graphic)val9).color = new Color(0.8f, 0.8f, 0.1f);
			RectTransform component3 = ((Component)val9).GetComponent<RectTransform>();
			component3.anchorMin = new Vector2(0f, 0f);
			component3.anchorMax = new Vector2(1f, 0f);
			component3.pivot = new Vector2(0.5f, 0f);
			component3.sizeDelta = new Vector2(-20f, 40f);
			component3.anchoredPosition = new Vector2(0f, 16f);
			if (!flag && !flag3)
			{
				Button val10 = CreateButton(val3.transform, flag2 ? L("$rtdqf_abandon") : L("$rtdqf_accept"), (UnityAction)delegate
				{
					if (Manager.Progress.AcceptedQuestIDs.Contains(quest.ID))
					{
						Manager.AbandonQuest(quest);
					}
					else
					{
						Manager.AcceptQuest(quest);
					}
					Refresh();
				});
				RectTransform component4 = ((Component)val10).GetComponent<RectTransform>();
				component4.anchorMin = new Vector2(1f, 1f);
				component4.anchorMax = new Vector2(1f, 1f);
				component4.pivot = new Vector2(1f, 1f);
				component4.sizeDelta = new Vector2(78f, 24f);
				component4.anchoredPosition = new Vector2(-8f, -8f);
			}
			return val;
		}

		private string BuildDetailLine(QuestConfig quest)
		{
			StringBuilder stringBuilder = new StringBuilder();
			foreach (ObjectiveEntry killReq in quest.KillReqs)
			{
				Manager.Progress.KillCounts.TryGetValue(quest.ID + ":" + killReq.Prefab, out var value);
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("   ");
				}
				stringBuilder.Append(L("$rtdqf_slay") + " " + killReq.Prefab + ": " + value + "/" + killReq.Amount);
			}
			foreach (ObjectiveEntry gatherReq in quest.GatherReqs)
			{
				Manager.Progress.GatherCounts.TryGetValue(quest.ID + ":" + gatherReq.Prefab, out var value2);
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("   ");
				}
				stringBuilder.Append(L("$rtdqf_gather") + " " + gatherReq.Prefab + ": " + value2 + "/" + gatherReq.Amount);
			}
			StringBuilder stringBuilder2 = new StringBuilder();
			foreach (RewardEntry rewardItem in quest.RewardItems)
			{
				if (stringBuilder2.Length > 0)
				{
					stringBuilder2.Append(", ");
				}
				stringBuilder2.Append(rewardItem.Amount + " " + rewardItem.Prefab);
			}
			foreach (SkillRewardEntry skillReward in quest.SkillRewards)
			{
				if (stringBuilder2.Length > 0)
				{
					stringBuilder2.Append(", ");
				}
				stringBuilder2.Append("+" + skillReward.Amount + " " + skillReward.Skill + " XP");
			}
			if (quest.ExpReward > 0 && Chainloader.PluginInfos.ContainsKey("WackyMole.EpicMMOSystem"))
			{
				if (stringBuilder2.Length > 0)
				{
					stringBuilder2.Append(", ");
				}
				stringBuilder2.Append(quest.ExpReward + " " + L("$rtdqf_mmo_exp"));
			}
			if (stringBuilder2.Length > 0)
			{
				if (stringBuilder.Length > 0)
				{
					stringBuilder.Append("\n");
				}
				stringBuilder.Append(L("$rtdqf_reward") + ": " + stringBuilder2);
			}
			return stringBuilder.ToString();
		}

		private static Text CreateText(Transform parent, string content, int fontSize, TextAnchor anchor)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_0032: Unknown result type (might be due to invalid IL or missing references)
			//IL_007b: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Text");
			val.transform.SetParent(parent, false);
			Text val2 = val.AddComponent<Text>();
			val2.text = content;
			val2.fontSize = fontSize;
			val2.alignment = anchor;
			Font val3 = ((GUIManager.Instance != null) ? GUIManager.Instance.AveriaSerif : null);
			val2.font = (((Object)(object)val3 != (Object)null) ? val3 : Resources.GetBuiltinResource<Font>("LegacyRuntime.ttf"));
			((Graphic)val2).color = new Color(0.15f, 0.09f, 0.05f);
			val2.horizontalOverflow = (HorizontalWrapMode)0;
			val2.verticalOverflow = (VerticalWrapMode)0;
			return val2;
		}

		private static void ApplyValheimHeaderStyle(Text text)
		{
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			if (GUIManager.Instance != null)
			{
				Font averiaSerifBold = GUIManager.Instance.AveriaSerifBold;
				if ((Object)(object)averiaSerifBold != (Object)null)
				{
					text.font = averiaSerifBold;
				}
				((Graphic)text).color = GUIManager.Instance.ValheimOrange;
			}
		}

		private static Button CreateButton(Transform parent, string label, UnityAction onClick)
		{
			//IL_0006: Unknown result type (might be due to invalid IL or missing references)
			//IL_000c: Expected O, but got Unknown
			//IL_004d: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_0065: Unknown result type (might be due to invalid IL or missing references)
			//IL_0071: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b2: Unknown result type (might be due to invalid IL or missing references)
			GameObject val = new GameObject("Button");
			val.transform.SetParent(parent, false);
			val.AddComponent<Image>();
			Button val2 = val.AddComponent<Button>();
			((UnityEvent)val2.onClick).AddListener(onClick);
			Text val3 = CreateText(val.transform, label, 12, (TextAnchor)4);
			RectTransform component = ((Component)val3).GetComponent<RectTransform>();
			component.anchorMin = Vector2.zero;
			component.anchorMax = Vector2.one;
			component.offsetMin = Vector2.zero;
			component.offsetMax = Vector2.zero;
			if (GUIManager.Instance != null)
			{
				GUIManager.Instance.ApplyButtonStyle(val2, 16);
			}
			else
			{
				((Graphic)val.GetComponent<Image>()).color = new Color(0.2f, 0.2f, 0.2f);
			}
			return val2;
		}
	}
	internal static class QuestUIStyles
	{
		public static Color RarityColor(string rarity)
		{
			//IL_0030: Unknown result type (might be due to invalid IL or missing references)
			//IL_0035: Unknown result type (might be due to invalid IL or missing references)
			//IL_0059: Unknown result type (might be due to invalid IL or missing references)
			//IL_005e: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e4: Unknown result type (might be due to invalid IL or missing references)
			//IL_0084: Unknown result type (might be due to invalid IL or missing references)
			//IL_0089: Unknown result type (might be due to invalid IL or missing references)
			//IL_00ac: Unknown result type (might be due to invalid IL or missing references)
			//IL_00b1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00dc: Unknown result type (might be due to invalid IL or missing references)
			//IL_00e1: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d4: Unknown result type (might be due to invalid IL or missing references)
			//IL_00d9: Unknown result type (might be due to invalid IL or missing references)
			return (Color)(((rarity != null) ? rarity.ToLowerInvariant() : "") switch
			{
				"common" => new Color(0.75f, 0.75f, 0.75f), 
				"uncommon" => new Color(0.3f, 0.8f, 0.3f), 
				"rare" => new Color(0.3f, 0.55f, 1f), 
				"epic" => new Color(0.65f, 0.3f, 0.9f), 
				"legendary" => new Color(1f, 0.65f, 0.1f), 
				_ => Color.white, 
			});
		}
	}
}
namespace RtDQuestForge.Patches
{
	[HarmonyPatch(typeof(Character), "OnDeath")]
	internal static class Patch_Character_OnDeath_KillTracking
	{
		private static readonly FieldInfo LastHitField = AccessTools.Field(typeof(Character), "m_lastHit");

		private static void Postfix(Character __instance)
		{
			//IL_0042: Unknown result type (might be due to invalid IL or missing references)
			if ((Object)(object)__instance == (Object)null || __instance is Player)
			{
				return;
			}
			HitData val = ((!(LastHitField != null)) ? ((HitData)null) : ((HitData)LastHitField.GetValue(__instance)));
			if (val == null)
			{
				return;
			}
			Character attacker = val.GetAttacker();
			Player val2 = (Player)(object)((attacker is Player) ? attacker : null);
			if ((Object)(object)val2 == (Object)null)
			{
				return;
			}
			string prefabName = Utils.GetPrefabName(((Component)__instance).gameObject);
			if ((Object)(object)Player.m_localPlayer != (Object)null && (Object)(object)val2 == (Object)(object)Player.m_localPlayer)
			{
				if (QuestForgePlugin.Manager != null)
				{
					QuestForgePlugin.Manager.RegisterKill(prefabName);
				}
			}
			else
			{
				Logger.LogMessage((object)("Routing kill credit: " + val2.GetPlayerName() + " killed " + prefabName));
				QuestSync.SendKillCredit(val2.GetPlayerName(), prefabName);
			}
		}
	}
	[HarmonyPatch(typeof(Inventory), "AddItem", new Type[] { typeof(ItemData) })]
	internal static class Patch_Inventory_AddItem_GatherTracking
	{
		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() && QuestForgePlugin.Manager != null)
			{
				QuestForgePlugin.Manager.RegisterGather(((Object)item.m_dropPrefab).name, item.m_stack);
			}
		}
	}
	[HarmonyPatch(typeof(Player), "OnSpawned")]
	internal static class Patch_Player_OnSpawned_LoadProgress
	{
		private static bool EventsWired;

		private static void Postfix(Player __instance)
		{
			if (!((Object)(object)__instance != (Object)(object)Player.m_localPlayer) && QuestForgePlugin.Manager != null)
			{
				QuestForgePlugin.Manager.LoadProgress(__instance.GetPlayerName());
				QuestSync.RequestFromServer();
				if (!EventsWired)
				{
					EventsWired = true;
					QuestForgePlugin.Manager.OnQuestCompleted += QuestForgePlugin.HandleQuestCompleted;
				}
			}
		}
	}
}