Some mods target the Mono version of the game, which is available by opting into the Steam beta branch "alternate"
Decompiled source of Silkroad Main Version v1.0.2
mods/Silkroad.dll
Decompiled a day 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.Versioning; using HarmonyLib; using Il2CppInterop.Runtime; using Il2CppInterop.Runtime.InteropTypes; using Il2CppInterop.Runtime.InteropTypes.Arrays; using Il2CppScheduleOne; using Il2CppScheduleOne.DevUtilities; using Il2CppScheduleOne.Economy; using Il2CppScheduleOne.GameTime; using Il2CppScheduleOne.Interaction; using Il2CppScheduleOne.ItemFramework; using Il2CppScheduleOne.Levelling; using Il2CppScheduleOne.Map; using Il2CppScheduleOne.Messaging; using Il2CppScheduleOne.NPCs; using Il2CppScheduleOne.NPCs.Relation; using Il2CppScheduleOne.NPCs.Responses; using Il2CppScheduleOne.Noise; using Il2CppScheduleOne.Persistence.Datas; using Il2CppScheduleOne.Persistence.Loaders; using Il2CppScheduleOne.PlayerScripts; using Il2CppScheduleOne.Product; using Il2CppScheduleOne.Product.Packaging; using Il2CppScheduleOne.Quests; using Il2CppScheduleOne.Storage; using Il2CppScheduleOne.UI.WorldspacePopup; using Il2CppScheduleOne.Variables; using Il2CppScheduleOne.Vehicles; using Il2CppScheduleOne.Vision; using Il2CppSystem; using Il2CppSystem.Collections; using Il2CppSystem.Collections.Generic; using MelonLoader; using MelonLoader.Utils; using Microsoft.CodeAnalysis; using Newtonsoft.Json; using S1API.DeadDrops; using S1API.GameTime; using S1API.Internal.Abstraction; using S1API.Internal.Utils; using S1API.Items; using S1API.Money; using S1API.NPCs; using S1API.Products; using S1API.Quests; using S1API.S1API.Internal.Utils; using S1API.Saveables; using S1API.Storages; using SOE; using SilkRoad.Quests; using UnityEngine; using UnityEngine.EventSystems; 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: MelonInfo(typeof(MyMod), "Silk Road App", "1.0.1", "Akermi", null)] [assembly: MelonGame("TVGS", "Schedule I")] [assembly: TargetFramework(".NETStandard,Version=v2.1", FrameworkDisplayName = ".NET Standard 2.1")] [assembly: AssemblyCompany("S1API")] [assembly: AssemblyConfiguration("Il2Cpp")] [assembly: AssemblyFileVersion("1.0.0.0")] [assembly: AssemblyInformationalVersion("1.0.0+d36dbe161e3172166297fe6432827bbd7680021a")] [assembly: AssemblyProduct("S1API")] [assembly: AssemblyTitle("S1API")] [assembly: AssemblyVersion("1.0.0.0")] namespace Microsoft.CodeAnalysis { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] internal sealed class EmbeddedAttribute : Attribute { } } namespace System.Runtime.CompilerServices { [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Property | AttributeTargets.Field | AttributeTargets.Event | AttributeTargets.Parameter | AttributeTargets.ReturnValue | AttributeTargets.GenericParameter, AllowMultiple = false, Inherited = false)] internal sealed class NullableAttribute : Attribute { public readonly byte[] NullableFlags; public NullableAttribute(byte P_0) { NullableFlags = new byte[1] { P_0 }; } public NullableAttribute(byte[] P_0) { NullableFlags = P_0; } } [CompilerGenerated] [Microsoft.CodeAnalysis.Embedded] [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct | AttributeTargets.Method | AttributeTargets.Interface | AttributeTargets.Delegate, AllowMultiple = false, Inherited = false)] internal sealed class NullableContextAttribute : Attribute { public readonly byte Flag; public NullableContextAttribute(byte P_0) { Flag = P_0; } } } [Serializable] public class DeliverySaveData { public string ProductID; public uint RequiredAmount; public int Reward; public string DeliveryDropGUID; public string RewardDropGUID; public bool Initialized; [JsonConstructor] public DeliverySaveData() { } } [Serializable] public class QuestDataSave { public string DataType; public string GUID; } public static class UIFactory { public static GameObject Panel(string name, Transform parent, Color bgColor, Vector2? anchorMin = null, Vector2? anchorMax = null, bool fullAnchor = false) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0025: Unknown result type (might be due to invalid IL or missing references) //IL_0031: Unknown result type (might be due to invalid IL or missing references) //IL_003d: Unknown result type (might be due to invalid IL or missing references) //IL_0049: Unknown result type (might be due to invalid IL or missing references) //IL_006e: 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_00bc: Unknown result type (might be due to invalid IL or missing references) //IL_0090: 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_009c: Unknown result type (might be due to invalid IL or missing references) //IL_00a8: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent<RectTransform>(); if (fullAnchor) { val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; } else { val2.anchorMin = (Vector2)(((??)anchorMin) ?? Vector2.zero); val2.anchorMax = (Vector2)(((??)anchorMax) ?? Vector2.one); val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; } Image val3 = val.AddComponent<Image>(); ((Graphic)val3).color = bgColor; return val; } public static Text Text(string name, string content, Transform parent, int fontSize = 16, TextAnchor anchor = 0, FontStyle style = 0) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_005c: 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_006e: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(0f, 30f); Text val3 = val.AddComponent<Text>(); val3.text = content; val3.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); val3.fontSize = fontSize; val3.alignment = anchor; val3.fontStyle = style; ((Graphic)val3).color = Color.white; return val3; } public static GameObject Button(string name, string label, Transform parent, Color color) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_0028: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Unknown result type (might be due to invalid IL or missing references) //IL_0056: Unknown result type (might be due to invalid IL or missing references) //IL_005d: Expected O, but got Unknown //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_00cd: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00e7: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.sizeDelta = new Vector2(0f, 40f); Image val3 = val.AddComponent<Image>(); ((Graphic)val3).color = color; Button val4 = val.AddComponent<Button>(); ((Selectable)val4).targetGraphic = (Graphic)(object)val3; GameObject val5 = new GameObject("Text"); val5.transform.SetParent(val.transform, false); Text val6 = val5.AddComponent<Text>(); val6.text = label; val6.font = Resources.GetBuiltinResource<Font>("Arial.ttf"); val6.fontSize = 18; val6.alignment = (TextAnchor)4; ((Graphic)val6).color = Color.white; RectTransform component = val5.GetComponent<RectTransform>(); component.anchorMin = Vector2.zero; component.anchorMax = Vector2.one; component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; return val; } public static RectTransform ScrollableVerticalList(string name, Transform parent, out VerticalLayoutGroup layoutGroup) { //IL_0002: Unknown result type (might be due to invalid IL or missing references) //IL_0008: Expected O, but got Unknown //IL_001e: Unknown result type (might be due to invalid IL or missing references) //IL_002a: Unknown result type (might be due to invalid IL or missing references) //IL_0036: Unknown result type (might be due to invalid IL or missing references) //IL_0042: 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_00be: Unknown result type (might be due to invalid IL or missing references) //IL_00c5: Expected O, but got Unknown //IL_00ee: Unknown result type (might be due to invalid IL or missing references) //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_011c: Unknown result type (might be due to invalid IL or missing references) //IL_0129: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject(name); val.transform.SetParent(parent, false); RectTransform val2 = val.AddComponent<RectTransform>(); val2.anchorMin = Vector2.zero; val2.anchorMax = Vector2.one; val2.offsetMin = Vector2.zero; val2.offsetMax = Vector2.zero; ScrollRect val3 = val.AddComponent<ScrollRect>(); val3.horizontal = false; GameObject val4 = Panel("Viewport", val.transform, new Color(0f, 0f, 0f, 0.05f)); Mask val5 = val4.AddComponent<Mask>(); val5.showMaskGraphic = false; val3.viewport = val4.GetComponent<RectTransform>(); GameObject val6 = new GameObject("Content"); val6.transform.SetParent(val4.transform, false); RectTransform val7 = val6.AddComponent<RectTransform>(); val7.anchorMin = new Vector2(0f, 1f); val7.anchorMax = new Vector2(1f, 1f); val7.pivot = new Vector2(0.5f, 1f); val7.anchoredPosition = Vector2.zero; layoutGroup = val6.AddComponent<VerticalLayoutGroup>(); ((LayoutGroup)layoutGroup).childAlignment = (TextAnchor)1; ((HorizontalOrVerticalLayoutGroup)layoutGroup).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)layoutGroup).childForceExpandHeight = false; ContentSizeFitter val8 = val6.AddComponent<ContentSizeFitter>(); val8.verticalFit = (FitMode)2; val3.content = val7; return val2; } } namespace Silkroad { public abstract class PhoneApp { [CompilerGenerated] private sealed class <DelayedInit>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Instance logger; public PhoneApp <>4__this; private GameObject <appsCanvas>5__1; private Transform <existingApp>5__2; private Transform <templateApp>5__3; private Transform <containerTransform>5__4; private GameObject <container>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedInit>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <appsCanvas>5__1 = null; <existingApp>5__2 = null; <templateApp>5__3 = null; <containerTransform>5__4 = null; <container>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.Player = GameObject.Find("Player_Local"); if ((Object)(object)<>4__this.Player == (Object)null) { logger.Error("Player_Local not found."); return false; } <appsCanvas>5__1 = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas"); if ((Object)(object)<appsCanvas>5__1 == (Object)null) { logger.Error("AppsCanvas not found."); return false; } <existingApp>5__2 = <appsCanvas>5__1.transform.Find(<>4__this.AppName); if ((Object)(object)<existingApp>5__2 != (Object)null) { <>4__this.AppPanel = ((Component)<existingApp>5__2).gameObject; <>4__this.SetupExistingAppPanel(<>4__this.AppPanel, logger); } else { <templateApp>5__3 = <appsCanvas>5__1.transform.Find("ProductManagerApp"); if ((Object)(object)<templateApp>5__3 == (Object)null) { logger.Error("Template ProductManagerApp not found."); return false; } <>4__this.AppPanel = Object.Instantiate<GameObject>(((Component)<templateApp>5__3).gameObject, <appsCanvas>5__1.transform); ((Object)<>4__this.AppPanel).name = <>4__this.AppName; <containerTransform>5__4 = <>4__this.AppPanel.transform.Find("Container"); if ((Object)(object)<containerTransform>5__4 != (Object)null) { <container>5__5 = ((Component)<containerTransform>5__4).gameObject; <>4__this.ClearContainer(<container>5__5); <>4__this.BuildUI(<container>5__5); <container>5__5 = null; } <>4__this.AppCreated = true; <templateApp>5__3 = null; <containerTransform>5__4 = null; } <>4__this.AppPanel.SetActive(false); if (!<>4__this.IconModified) { <>4__this.IconModified = <>4__this.ModifyAppIcon(<>4__this.IconLabel, <>4__this.IconFileName, logger); if (<>4__this.IconModified) { logger.Msg("Icon modified."); } } 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(); } } protected GameObject Player; protected GameObject AppPanel; protected bool AppCreated; protected bool IconModified; protected bool InitializationStarted; protected abstract string AppName { get; } protected abstract string AppTitle { get; } protected abstract string IconLabel { get; } protected abstract string IconFileName { get; } protected abstract void BuildUI(GameObject container); public void Init(Instance logger) { MelonCoroutines.Start(DelayedInit(logger)); } [IteratorStateMachine(typeof(<DelayedInit>d__15))] private IEnumerator DelayedInit(Instance logger) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedInit>d__15(0) { <>4__this = this, logger = logger }; } private void SetupExistingAppPanel(GameObject panel, Instance logger) { Transform val = panel.transform.Find("Container"); if ((Object)(object)val != (Object)null) { GameObject gameObject = ((Component)val).gameObject; if (gameObject.transform.childCount < 2) { ClearContainer(gameObject); BuildUI(gameObject); } } AppCreated = true; } private void ClearContainer(GameObject container) { for (int num = container.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)container.transform.GetChild(num)).gameObject); } } private bool ModifyAppIcon(string labelText, string fileName, Instance logger) { GameObject val = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons/"); if ((Object)(object)val == (Object)null) { if (logger != null) { logger.Error("AppIcons not found."); } return false; } Transform val2 = ((val.transform.childCount > 0) ? val.transform.GetChild(val.transform.childCount - 1) : null); if ((Object)(object)val2 == (Object)null) { if (logger != null) { logger.Error("No icon found to clone."); } return false; } GameObject gameObject = ((Component)val2).gameObject; ((Object)gameObject).name = AppName; Transform val3 = gameObject.transform.Find("Label"); Text val4 = ((val3 != null) ? ((Component)val3).GetComponent<Text>() : null); if ((Object)(object)val4 != (Object)null) { val4.text = labelText; } return ChangeAppIconImage(gameObject, fileName, logger); } private bool ChangeAppIconImage(GameObject iconObj, string filename, Instance logger) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) Transform val = iconObj.transform.Find("Mask/Image"); Image val2 = ((val != null) ? ((Component)val).GetComponent<Image>() : null); if ((Object)(object)val2 == (Object)null) { if (logger != null) { logger.Error("Image component not found in icon."); } return false; } string text = Path.Combine(MelonEnvironment.UserDataDirectory, filename); if (!File.Exists(text)) { if (logger != null) { logger.Error("Icon file not found: " + text); } return false; } try { byte[] array = File.ReadAllBytes(text); Texture2D val3 = new Texture2D(2, 2); if (ImageConversion.LoadImage(val3, Il2CppStructArray<byte>.op_Implicit(array))) { val2.sprite = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f)); return true; } Object.Destroy((Object)(object)val3); } catch (Exception ex) { if (logger != null) { logger.Error("Failed to load image: " + ex.Message); } } return false; } } } namespace S1API.Storages { public class StorageInstance { internal readonly StorageEntity S1Storage; public ItemSlotInstance[] Slots => ((IEnumerable<ItemSlot>)S1Storage.ItemSlots.ToArray()).Select((ItemSlot itemSlot) => new ItemSlotInstance(itemSlot)).ToArray(); public event Action OnOpened { add { S1Storage.onOpened.AddListener(UnityAction.op_Implicit((Action)value.Invoke)); } remove { S1Storage.onOpened.RemoveListener(UnityAction.op_Implicit((Action)value.Invoke)); } } public event Action OnClosed { add { S1Storage.onClosed.AddListener(UnityAction.op_Implicit((Action)value.Invoke)); } remove { S1Storage.onClosed.RemoveListener(UnityAction.op_Implicit((Action)value.Invoke)); } } internal StorageInstance(StorageEntity storage) { S1Storage = storage; } public bool CanItemFit(ItemInstance itemInstance, int quantity = 1) { return S1Storage.CanItemFit(itemInstance.S1ItemInstance, quantity); } public void AddItem(ItemInstance itemInstance) { S1Storage.InsertItem(itemInstance.S1ItemInstance, true); } } } namespace S1API.Saveables { public abstract class Saveable { internal virtual void InitializeInternal(GameObject gameObject, string guid = "") { } internal virtual void StartInternal() { OnStarted(); } internal virtual void LoadInternal(string folderPath) { FieldInfo[] fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { SaveableField customAttribute = fieldInfo.GetCustomAttribute<SaveableField>(); if (customAttribute != null) { string path = (customAttribute.SaveName.EndsWith(".json") ? customAttribute.SaveName : (customAttribute.SaveName + ".json")); string path2 = Path.Combine(folderPath, path); if (File.Exists(path2)) { string text = File.ReadAllText(path2); Type fieldType = fieldInfo.FieldType; object value = JsonConvert.DeserializeObject(text, fieldType); fieldInfo.SetValue(this, value); } } } OnLoaded(); } internal virtual void SaveInternal(string path, ref List<string> extraSaveables) { FieldInfo[] fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { SaveableField customAttribute = fieldInfo.GetCustomAttribute<SaveableField>(); if (customAttribute != null) { string text = (customAttribute.SaveName.EndsWith(".json") ? customAttribute.SaveName : (customAttribute.SaveName + ".json")); string path2 = Path.Combine(path, text); object value = fieldInfo.GetValue(this); if (value == null) { File.Delete(path2); continue; } extraSaveables.Add(text); string contents = JsonConvert.SerializeObject(value, (Formatting)1); File.WriteAllText(path2, contents); } } OnSaved(); } protected virtual void OnStarted() { } protected virtual void OnLoaded() { } protected virtual void OnSaved() { } } [AttributeUsage(AttributeTargets.Field)] public class SaveableField : Attribute { internal string SaveName { get; } public SaveableField(string saveName) { SaveName = saveName; } } public abstract class SaveData { public string DataType = string.Empty; } } namespace S1API.Quests { public abstract class Quest : global::S1API.Internal.Abstraction.Saveable { protected readonly QuestEntry[] QuestEntries = Array.Empty<QuestEntry>(); [SaveableField("QuestData")] private readonly QuestData _questData; internal readonly Quest S1Quest; private readonly GameObject _gameObject; protected abstract string Title { get; } protected abstract string Description { get; } protected virtual bool AutoBegin => true; internal string? SaveFolder => S1Quest.SaveFolderName; public Quest() { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0039: Expected O, but got Unknown //IL_0061: Unknown result type (might be due to invalid IL or missing references) //IL_006b: Expected O, but got Unknown //IL_0072: Unknown result type (might be due to invalid IL or missing references) //IL_007c: Expected O, but got Unknown //IL_0083: Unknown result type (might be due to invalid IL or missing references) //IL_008d: Expected O, but got Unknown //IL_0094: Unknown result type (might be due to invalid IL or missing references) //IL_009e: Expected O, but got Unknown //IL_010b: Unknown result type (might be due to invalid IL or missing references) //IL_0111: Expected O, but got Unknown //IL_017f: Unknown result type (might be due to invalid IL or missing references) //IL_0185: Expected O, but got Unknown //IL_01bf: Unknown result type (might be due to invalid IL or missing references) //IL_01c6: Expected O, but got Unknown //IL_01fc: Unknown result type (might be due to invalid IL or missing references) //IL_0203: Expected O, but got Unknown //IL_024a: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0261: Expected O, but got Unknown _questData = new QuestData(GetType().Name); _gameObject = new GameObject("Quest"); S1Quest = _gameObject.AddComponent<Quest>(); S1Quest.StaticGUID = string.Empty; S1Quest.onActiveState = new UnityEvent(); S1Quest.onComplete = new UnityEvent(); S1Quest.onInitialComplete = new UnityEvent(); S1Quest.onQuestBegin = new UnityEvent(); S1Quest.onQuestEnd = new UnityEvent<EQuestState>(); S1Quest.onTrackChange = new UnityEvent<bool>(); S1Quest.TrackOnBegin = true; S1Quest.AutoCompleteOnAllEntriesComplete = true; S1Quest.autoInitialize = false; GameObject val = new GameObject("IconPrefab", (Type[])(object)new Type[3] { CrossType.Of<RectTransform>(), CrossType.Of<CanvasRenderer>(), CrossType.Of<Image>() }); val.transform.SetParent(_gameObject.transform); Sprite sprite = ImageUtils.LoadImage("SilkRoadIcon_quest.png"); Image component = val.GetComponent<Image>(); component.sprite = sprite; S1Quest.IconPrefab = val.GetComponent<RectTransform>(); GameObject val2 = new GameObject("PoIUIPrefab", (Type[])(object)new Type[4] { CrossType.Of<RectTransform>(), CrossType.Of<CanvasRenderer>(), CrossType.Of<EventTrigger>(), CrossType.Of<Button>() }); val2.transform.SetParent(_gameObject.transform); GameObject val3 = new GameObject("MainLabel", (Type[])(object)new Type[3] { CrossType.Of<RectTransform>(), CrossType.Of<CanvasRenderer>(), CrossType.Of<Text>() }); val3.transform.SetParent(val2.transform); GameObject val4 = new GameObject("IconContainer", (Type[])(object)new Type[3] { CrossType.Of<RectTransform>(), CrossType.Of<CanvasRenderer>(), CrossType.Of<Image>() }); val4.transform.SetParent(val2.transform); Image component2 = val4.GetComponent<Image>(); Sprite sprite2 = ImageUtils.LoadImage("SilkRoadIcon_quest.png"); component2.sprite = sprite2; RectTransform component3 = ((Component)component2).GetComponent<RectTransform>(); component3.sizeDelta = new Vector2(25f, 25f); GameObject val5 = new GameObject("POIPrefab"); val5.SetActive(false); val5.transform.SetParent(_gameObject.transform); POI val6 = val5.AddComponent<POI>(); val6.DefaultMainText = "Did it work?"; val6.UIPrefab = val2; S1Quest.PoIPrefab = val5; } internal override void CreateInternal() { base.CreateInternal(); Quest s1Quest = S1Quest; string title = Title; string description = Description; Il2CppReferenceArray<QuestEntryData> obj = Il2CppReferenceArray<QuestEntryData>.op_Implicit(Array.Empty<QuestEntryData>()); Quest s1Quest2 = S1Quest; s1Quest.InitializeQuest(title, description, obj, (s1Quest2 != null) ? s1Quest2.StaticGUID : null); if (AutoBegin) { Quest s1Quest3 = S1Quest; if (s1Quest3 != null) { s1Quest3.Begin(true); } } } internal override void SaveInternal(string folderPath, ref List<string> extraSaveables) { string text = Path.Combine(folderPath, S1Quest.SaveFolderName); if (!Directory.Exists(text)) { Directory.CreateDirectory(text); } base.SaveInternal(text, ref extraSaveables); } protected QuestEntry AddEntry(string title, Vector3? poiPosition = null) { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000c: Expected O, but got Unknown //IL_0073: Unknown result type (might be due to invalid IL or missing references) //IL_006a: Unknown result type (might be due to invalid IL or missing references) GameObject val = new GameObject("QuestEntry"); Transform transform = val.transform; GameObject gameObject = _gameObject; transform.SetParent((gameObject != null) ? gameObject.transform : null); QuestEntry val2 = val.AddComponent<QuestEntry>(); val2.PoILocation = val.transform; S1Quest.Entries.Add(val2); QuestEntry questEntry = new QuestEntry(val2) { Title = title, POIPosition = (Vector3)(((??)poiPosition) ?? Vector3.zero) }; CollectionExtensions.AddItem<QuestEntry>((IEnumerable<QuestEntry>)QuestEntries, questEntry); return questEntry; } public void Begin() { Quest s1Quest = S1Quest; if (s1Quest != null) { s1Quest.Begin(true); } } public void Cancel() { Quest s1Quest = S1Quest; if (s1Quest != null) { s1Quest.Cancel(true); } } public void Expire() { Quest s1Quest = S1Quest; if (s1Quest != null) { s1Quest.Expire(true); } } public void Fail() { Quest s1Quest = S1Quest; if (s1Quest != null) { s1Quest.Fail(true); } } public void Complete() { Quest s1Quest = S1Quest; if (s1Quest != null) { s1Quest.Complete(true); } } public void End() { Quest s1Quest = S1Quest; if (s1Quest != null) { s1Quest.End(); } } } public class QuestData { public readonly string ClassName; public QuestData(string className) { ClassName = className; } } public class QuestEntry { internal readonly QuestEntry S1QuestEntry; public string Title { get { return S1QuestEntry.Title; } set { S1QuestEntry.SetEntryTitle(value); } } public Vector3 POIPosition { get { //IL_000b: Unknown result type (might be due to invalid IL or missing references) return S1QuestEntry.PoILocation.position; } set { //IL_000b: Unknown result type (might be due to invalid IL or missing references) S1QuestEntry.PoILocation.position = value; } } public QuestState State => (QuestState)S1QuestEntry.State; public event Action OnComplete { add { S1QuestEntry.onComplete.AddListener(UnityAction.op_Implicit((Action)value.Invoke)); } remove { S1QuestEntry.onComplete.RemoveListener(UnityAction.op_Implicit((Action)value.Invoke)); } } internal QuestEntry(QuestEntry questEntry) { S1QuestEntry = questEntry; } public void Begin() { S1QuestEntry.Begin(); } public void Complete() { S1QuestEntry.Complete(); } public void SetState(QuestState questState) { S1QuestEntry.SetState((EQuestState)questState, true); } } public static class QuestManager { internal static readonly List<Quest> Quests = new List<Quest>(); public static Quest CreateQuest<T>(string? guid = null) where T : Quest { return CreateQuest(typeof(T), guid); } public static Quest CreateQuest(Type questType, string? guid = null) { Quest quest = (Quest)Activator.CreateInstance(questType); Quests.Add(quest); return quest; } } public enum QuestState { Inactive, Active, Completed, Failed, Expired, Cancelled } } namespace S1API.Products { public class PackagingDefinition : ItemDefinition { internal PackagingDefinition S1PackagingDefinition => CrossType.As<PackagingDefinition>((object)S1ItemDefinition); public int Quantity => S1PackagingDefinition.Quantity; internal PackagingDefinition(ItemDefinition s1ItemDefinition) : base(s1ItemDefinition) { } } public class ProductDefinition : ItemDefinition { internal ProductDefinition S1ProductDefinition => CrossType.As<ProductDefinition>((object)S1ItemDefinition); public float Price => S1ProductDefinition.Price; internal ProductDefinition(ProductDefinition productDefinition) : base((ItemDefinition)(object)productDefinition) { } public override ItemInstance CreateInstance(int quantity = 1) { return new ProductInstance(CrossType.As<ProductItemInstance>((object)((ItemDefinition)S1ProductDefinition).GetDefaultInstance(quantity))); } } public class ProductInstance : ItemInstance { internal ProductItemInstance S1ProductInstance => CrossType.As<ProductItemInstance>((object)S1ItemInstance); public bool IsPackaged => Object.op_Implicit((Object)(object)S1ProductInstance.AppliedPackaging); public PackagingDefinition AppliedPackaging => new PackagingDefinition((ItemDefinition)(object)S1ProductInstance.AppliedPackaging); internal ProductInstance(ProductItemInstance productInstance) : base((ItemInstance)(object)productInstance) { } } public static class ProductManager { public static ProductDefinition[] DiscoveredProducts => ((IEnumerable<ProductDefinition>)ProductManager.DiscoveredProducts.ToArray()).Select((ProductDefinition productDefinition) => new ProductDefinition(productDefinition)).ToArray(); } } namespace S1API.NPCs { public abstract class NPC : global::S1API.Internal.Abstraction.Saveable { protected readonly List<Response> Responses = new List<Response>(); internal readonly NPC S1NPC; private readonly GameObject _gameObject; public NPC(string guid, string firstName, string lastName) { //IL_0019: Unknown result type (might be due to invalid IL or missing references) //IL_0023: Expected O, but got Unknown //IL_00ef: Unknown result type (might be due to invalid IL or missing references) //IL_00f9: Expected O, but got Unknown //IL_0105: Unknown result type (might be due to invalid IL or missing references) //IL_010f: Expected O, but got Unknown //IL_013d: Unknown result type (might be due to invalid IL or missing references) //IL_0143: Expected O, but got Unknown //IL_0245: Unknown result type (might be due to invalid IL or missing references) //IL_024b: Expected O, but got Unknown //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_028c: Expected O, but got Unknown //IL_0302: Unknown result type (might be due to invalid IL or missing references) //IL_030c: Expected O, but got Unknown _gameObject = new GameObject("NPC"); _gameObject.SetActive(false); S1NPC = _gameObject.AddComponent<NPC>(); S1NPC.FirstName = firstName; S1NPC.LastName = lastName; S1NPC.ID = guid; S1NPC.BakedGUID = Guid.NewGuid().ToString(); S1NPC.MugshotSprite = ImageUtils.LoadImage("SilkRoadIcon.png"); S1NPC.ConversationCategories = new List<EConversationCategory>(); S1NPC.ConversationCategories.Add((EConversationCategory)0); S1NPC.CreateMessageConversation(); S1NPC.Health = _gameObject.GetComponent<NPCHealth>(); S1NPC.Health.onDie = new UnityEvent(); S1NPC.Health.onKnockedOut = new UnityEvent(); S1NPC.Health.Invincible = true; S1NPC.Health.MaxHealth = 100f; GameObject val = new GameObject("NPCAwareness"); val.SetActive(false); val.transform.SetParent(_gameObject.transform); S1NPC.awareness = val.AddComponent<NPCAwareness>(); S1NPC.awareness.onExplosionHeard = new UnityEvent<NoiseEvent>(); S1NPC.awareness.onGunshotHeard = new UnityEvent<NoiseEvent>(); S1NPC.awareness.onHitByCar = new UnityEvent<LandVehicle>(); S1NPC.awareness.onNoticedDrugDealing = new UnityEvent<Player>(); S1NPC.awareness.onNoticedGeneralCrime = new UnityEvent<Player>(); S1NPC.awareness.onNoticedPettyCrime = new UnityEvent<Player>(); S1NPC.awareness.onNoticedPlayerViolatingCurfew = new UnityEvent<Player>(); S1NPC.awareness.onNoticedSuspiciousPlayer = new UnityEvent<Player>(); S1NPC.awareness.Listener = _gameObject.AddComponent<Listener>(); GameObject val2 = new GameObject("NPCResponses"); val2.SetActive(false); val2.transform.SetParent(_gameObject.transform); S1NPC.awareness.Responses = (NPCResponses)(object)val2.AddComponent<NPCResponses_Civilian>(); GameObject val3 = new GameObject("VisionCone"); val3.SetActive(false); val3.transform.SetParent(_gameObject.transform); VisionCone visionCone = val3.AddComponent<VisionCone>(); S1NPC.awareness.VisionCone = visionCone; S1NPC.awareness.VisionCone.QuestionMarkPopup = _gameObject.AddComponent<WorldspacePopup>(); S1NPC.intObj = _gameObject.AddComponent<InteractableObject>(); S1NPC.RelationData = new NPCRelationData(); NPCRelationData relationData = S1NPC.RelationData; relationData.onUnlocked += Action<EUnlockType, bool>.op_Implicit((Action<EUnlockType, bool>)OnUnlockAction); NPCInventory val4 = _gameObject.AddComponent<NPCInventory>(); val4.PickpocketIntObj = _gameObject.AddComponent<InteractableObject>(); S1NPC.Avatar = Player.Local.Avatar; NPCManager.NPCRegistry.Add(S1NPC); _gameObject.SetActive(true); val3.SetActive(true); val2.SetActive(true); val.SetActive(true); void OnUnlockAction(EUnlockType unlockType, bool notify) { if (!string.IsNullOrEmpty(S1NPC.NPCUnlockedVariable)) { NetworkSingleton<VariableDatabase>.Instance.SetVariableValue(S1NPC.NPCUnlockedVariable, true.ToString(), true); } } } internal override void CreateInternal() { Enumerator<Response> enumerator = S1NPC.MSGConversation.currentResponses.GetEnumerator(); while (enumerator.MoveNext()) { Response current = enumerator.Current; Response response = new Response(current) { Label = current.label, Text = current.text }; Responses.Add(response); OnResponseLoaded(response); } base.CreateInternal(); } internal override void SaveInternal(string folderPath, ref List<string> extraSaveables) { string folderPath2 = Path.Combine(folderPath, S1NPC.SaveFolderName); base.SaveInternal(folderPath2, ref extraSaveables); } public void SendTextMessage(string message, Response[]? responses = null, float responseDelay = 1f, bool network = true) { S1NPC.SendTextMessage(message); S1NPC.MSGConversation.ClearResponses(false); if (responses != null && responses.Length != 0) { Responses.Clear(); List<Response> val = new List<Response>(); foreach (Response response in responses) { Responses.Add(response); val.Add(response.S1Response); } S1NPC.MSGConversation.ShowResponses(val, responseDelay, network); } } protected virtual void OnResponseLoaded(Response response) { } } public class NPCInstance { } public class NPCManager { } public class Response { internal readonly Response S1Response; public Action? OnTriggered { get { return ((Delegate)(object)S1Response.callback == (Delegate)null) ? null : ((Action)delegate { S1Response.callback.Invoke(); }); } set { S1Response.callback = Action.op_Implicit(value); } } public string Label { get { return S1Response.label; } set { S1Response.label = value; } } public string Text { get { return S1Response.text; } set { S1Response.text = value; } } public Response() { //IL_0008: Unknown result type (might be due to invalid IL or missing references) //IL_0012: Expected O, but got Unknown S1Response = new Response(); } internal Response(Response response) { S1Response = response; } } } namespace S1API.Money { public class CashDefinition : ItemDefinition { internal CashDefinition S1CashDefinition => CrossType.As<CashDefinition>((object)S1ItemDefinition); internal CashDefinition(CashDefinition s1ItemDefinition) : base((ItemDefinition)(object)s1ItemDefinition) { } public override ItemInstance CreateInstance(int quantity = 1) { return new CashInstance(((ItemDefinition)S1CashDefinition).GetDefaultInstance(quantity)); } } public class CashInstance : ItemInstance { internal CashInstance S1CashInstance => CrossType.As<CashInstance>((object)S1ItemInstance); internal CashInstance(ItemInstance itemInstance) : base(itemInstance) { } public void AddQuantity(float amount) { S1CashInstance.SetBalance(Mathf.Clamp(S1CashInstance.Balance + amount, 0f, float.MaxValue), false); } public void SetQuantity(float newQuantity) { S1CashInstance.SetBalance(newQuantity, false); } } } namespace S1API.Leveling { public static class LevelManager { public static Rank Rank = (Rank)NetworkSingleton<LevelManager>.Instance.Rank; } public enum Rank { StreetRat, Hoodlum, Peddler, Hustler, Bagman, Enforcer, ShotCaller, BlockBoss, Underlord, Baron, Kingpin } } namespace S1API.Items { public enum ItemCategory { Product, Packaging, Growing, Tools, Furniture, Lighting, Cash, Consumable, Equipment, Ingredient, Decoration, Clothing } public class ItemDefinition : IGUIDReference { internal readonly ItemDefinition S1ItemDefinition; public virtual string GUID => S1ItemDefinition.ID; public string ID => S1ItemDefinition.ID; public string Name => S1ItemDefinition.Name; public string Description => S1ItemDefinition.Description; public ItemCategory Category => (ItemCategory)S1ItemDefinition.Category; public int StackLimit => S1ItemDefinition.StackLimit; internal ItemDefinition(ItemDefinition s1ItemDefinition) { S1ItemDefinition = s1ItemDefinition; } internal static ItemDefinition GetFromGUID(string guid) { return ItemManager.GetItemDefinition(guid); } public override bool Equals(object? obj) { return obj is ItemDefinition itemDefinition && (Object)(object)S1ItemDefinition == (Object)(object)itemDefinition.S1ItemDefinition; } public override int GetHashCode() { ItemDefinition s1ItemDefinition = S1ItemDefinition; return (s1ItemDefinition != null) ? ((Object)s1ItemDefinition).GetHashCode() : 0; } public static bool operator ==(ItemDefinition? left, ItemDefinition? right) { if ((object)left == right) { return true; } return (Object)(object)left?.S1ItemDefinition == (Object)(object)right?.S1ItemDefinition; } public static bool operator !=(ItemDefinition left, ItemDefinition right) { return !(left == right); } public virtual ItemInstance CreateInstance(int quantity = 1) { return new ItemInstance(S1ItemDefinition.GetDefaultInstance(quantity)); } } public class ItemInstance { internal readonly ItemInstance S1ItemInstance; public ItemDefinition Definition => new ItemDefinition(S1ItemInstance.Definition); internal ItemInstance(ItemInstance itemInstance) { S1ItemInstance = itemInstance; } } public static class ItemManager { public static ItemDefinition GetItemDefinition(string itemID) { ItemDefinition item = Registry.GetItem(itemID); if (CrossType.Is<ProductDefinition>((object)item, out ProductDefinition result)) { return new ProductDefinition(result); } if (CrossType.Is<CashDefinition>((object)item, out CashDefinition result2)) { return new CashDefinition(result2); } return new ItemDefinition(item); } } public class ItemSlotInstance { internal readonly ItemSlot S1ItemSlot; public int Quantity => S1ItemSlot.Quantity; public ItemInstance? ItemInstance { get { if (CrossType.Is<ProductItemInstance>((object)S1ItemSlot.ItemInstance, out ProductItemInstance result)) { return new ProductInstance(result); } if (CrossType.Is<CashInstance>((object)S1ItemSlot.ItemInstance, out CashInstance result2)) { return new CashInstance((ItemInstance)(object)result2); } if (CrossType.Is<ItemInstance>((object)S1ItemSlot.ItemInstance, out ItemInstance result3)) { return new ItemInstance(result3); } return null; } } internal ItemSlotInstance(ItemSlot itemSlot) { S1ItemSlot = itemSlot; } public void AddQuantity(int amount) { S1ItemSlot.ChangeQuantity(amount, false); } } } namespace S1API.S1API.Internal.Utils { internal class ImageUtils { public static Sprite LoadImage(string fileName) { //IL_0034: Unknown result type (might be due to invalid IL or missing references) //IL_003b: Expected O, but got Unknown //IL_006b: Unknown result type (might be due to invalid IL or missing references) //IL_007a: Unknown result type (might be due to invalid IL or missing references) string path = Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), fileName); if (!File.Exists(path)) { return null; } try { byte[] array = File.ReadAllBytes(path); Texture2D val = new Texture2D(2, 2); if (ImageConversion.LoadImage(val, Il2CppStructArray<byte>.op_Implicit(array))) { return Sprite.Create(val, new Rect(0f, 0f, (float)((Texture)val).width, (float)((Texture)val).height), new Vector2(0.5f, 0.5f)); } } catch (Exception) { } return null; } } } namespace S1API.Internal.Utils { internal static class CrossType { internal static Type Of<T>() { return Il2CppType.Of<T>(); } internal static bool Is<T>(object obj, out T result) where T : Il2CppObjectBase { Object val = (Object)((obj is Object) ? obj : null); if (val != null) { Type val2 = Il2CppType.Of<T>(); if (val2.IsAssignableFrom(val.GetIl2CppType())) { result = ((Il2CppObjectBase)val).TryCast<T>(); return true; } } result = default(T); return false; } internal static T As<T>(object obj) where T : Il2CppObjectBase { Object val = (Object)((obj is Object) ? obj : null); return (val != null) ? ((Il2CppObjectBase)val).Cast<T>() : default(T); } } internal static class ReflectionUtils { internal static List<Type> GetDerivedClasses<TBaseClass>() { List<Type> list = new List<Type>(); Assembly[] array = (from assembly in AppDomain.CurrentDomain.GetAssemblies() where !assembly.FullName.StartsWith("System") && !assembly.FullName.StartsWith("Unity") && !assembly.FullName.StartsWith("Il2Cpp") && !assembly.FullName.StartsWith("mscorlib") && !assembly.FullName.StartsWith("Mono.") && !assembly.FullName.StartsWith("netstandard") select assembly).ToArray(); Assembly[] array2 = array; foreach (Assembly assembly2 in array2) { list.AddRange(from type in assembly2.GetTypes() where typeof(TBaseClass).IsAssignableFrom(type) && type != typeof(TBaseClass) && !type.IsAbstract select type); } return list; } internal static Type? GetTypeByName(string typeName) { string typeName2 = typeName; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); Assembly[] array = assemblies; foreach (Assembly assembly in array) { Type type2 = assembly.GetTypes().FirstOrDefault((Type type) => type.Name == typeName2); if (!(type2 == null)) { return type2; } } return null; } internal static FieldInfo[] GetAllFields(Type? type, BindingFlags bindingFlags) { List<FieldInfo> list = new List<FieldInfo>(); while (type != null && type != typeof(object)) { list.AddRange(type.GetFields(bindingFlags)); type = type.BaseType; } return list.ToArray(); } public static MethodInfo? GetMethod(Type? type, string methodName, BindingFlags bindingFlags) { while (type != null && type != typeof(object)) { MethodInfo method = type.GetMethod(methodName, bindingFlags); if (method != null) { return method; } type = type.BaseType; } return null; } } } namespace S1API.Internal.Patches { [HarmonyPatch] internal class NPCPatches { private static readonly List<NPC> NPCs = new List<NPC>(); [HarmonyPatch(typeof(NPCsLoader), "Load")] [HarmonyPrefix] private static void NPCsLoadersLoad(NPCsLoader __instance, string mainPath) { foreach (Type derivedClass in ReflectionUtils.GetDerivedClasses<NPC>()) { NPC nPC = (NPC)Activator.CreateInstance(derivedClass); NPCs.Add(nPC); string folderPath = Path.Combine(mainPath, nPC.S1NPC.SaveFolderName); nPC.LoadInternal(folderPath); } } [HarmonyPatch(typeof(NPC), "Start")] [HarmonyPostfix] private static void NPCStart(NPC __instance) { NPC __instance2 = __instance; NPCs.FirstOrDefault((NPC npc) => (Object)(object)npc.S1NPC == (Object)(object)__instance2)?.CreateInternal(); } [HarmonyPatch(typeof(NPC), "WriteData")] [HarmonyPostfix] private static void NPCWriteData(NPC __instance, string parentFolderPath, ref List<string> __result) { NPC __instance2 = __instance; NPCs.FirstOrDefault((NPC npc) => (Object)(object)npc.S1NPC == (Object)(object)__instance2)?.SaveInternal(parentFolderPath, ref __result); } [HarmonyPatch(typeof(NPC), "OnDestroy")] [HarmonyPostfix] private static void NPCOnDestroy(NPC __instance) { NPC __instance2 = __instance; NPCs.RemoveAll((NPC npc) => (Object)(object)npc.S1NPC == (Object)(object)__instance2); NPC nPC = NPCs.FirstOrDefault((NPC npc) => (Object)(object)npc.S1NPC == (Object)(object)__instance2); if (nPC != null) { NPCs.Remove(nPC); } } } [HarmonyPatch] internal class QuestPatches { [HarmonyPatch(typeof(QuestManager), "WriteData")] [HarmonyPostfix] private static void QuestManagerWriteData(QuestManager __instance, string parentFolderPath, ref List<string> __result) { string folderPath = Path.Combine(parentFolderPath, "Quests"); foreach (Quest quest in QuestManager.Quests) { quest.SaveInternal(folderPath, ref __result); } } [HarmonyPatch(typeof(QuestsLoader), "Load")] [HarmonyPostfix] private static void QuestsLoaderLoad(QuestsLoader __instance, string mainPath) { string[] array = (from directory in Directory.GetDirectories(mainPath).Select(Path.GetFileName) where directory.StartsWith("Quest_") select directory).ToArray(); string[] array2 = array; string text2 = default(string); string text5 = default(string); foreach (string path in array2) { string text = Path.Combine(mainPath, path); ((Loader)__instance).TryLoadFile(text, ref text2, true); if (text2 == null) { continue; } QuestData val = JsonUtility.FromJson<QuestData>(text2); string text3 = Path.Combine(mainPath, path); string text4 = Path.Combine(text3, "QuestData"); if (!((Loader)__instance).TryLoadFile(text4, ref text5, true)) { continue; } global::S1API.Quests.QuestData questData = JsonConvert.DeserializeObject<global::S1API.Quests.QuestData>(text5, ISaveable.SerializerSettings); if (questData?.ClassName != null) { Type typeByName = ReflectionUtils.GetTypeByName(questData.ClassName); if (!(typeByName == null) && typeof(Quest).IsAssignableFrom(typeByName)) { Quest quest = QuestManager.CreateQuest(typeByName, (val != null) ? val.GUID : null); quest.LoadInternal(text3); } } } } [HarmonyPatch(typeof(QuestManager), "DeleteUnapprovedFiles")] [HarmonyPostfix] private static void QuestManagerDeleteUnapprovedFiles(QuestManager __instance, string parentFolderPath) { string path = Path.Combine(parentFolderPath, "Quests"); string?[] existingQuests = QuestManager.Quests.Select((Quest quest) => quest.SaveFolder).ToArray(); string[] array = (from directory in Directory.GetDirectories(path) where directory.StartsWith("Quest_") && !existingQuests.Contains<string>(directory) select directory).ToArray(); string[] array2 = array; foreach (string path2 in array2) { Directory.Delete(path2, recursive: true); } } [HarmonyPatch(typeof(Quest), "Start")] [HarmonyPrefix] private static void QuestStart(Quest __instance) { Quest __instance2 = __instance; QuestManager.Quests.FirstOrDefault((Quest quest) => (Object)(object)quest.S1Quest == (Object)(object)__instance2)?.CreateInternal(); } } [HarmonyPatch] internal class TimePatches { [HarmonyPatch(typeof(TimeManager), "Awake")] [HarmonyPostfix] private static void TimeManagerAwake(TimeManager __instance) { __instance.onDayPass += Action.op_Implicit((Action)DayPass); static void DayPass() { TimeManager.OnDayPass(); } } } } namespace S1API.Internal.Abstraction { internal class GUIDReferenceConverter : JsonConverter { public override bool CanRead => true; public override bool CanConvert(Type objectType) { return typeof(IGUIDReference).IsAssignableFrom(objectType); } public override void WriteJson(JsonWriter writer, object? value, JsonSerializer serializer) { if (value is IGUIDReference iGUIDReference) { writer.WriteValue(iGUIDReference.GUID); } else { writer.WriteNull(); } } public override object? ReadJson(JsonReader reader, Type objectType, object? existingValue, JsonSerializer serializer) { string text = reader.Value?.ToString(); if (string.IsNullOrEmpty(text)) { return null; } MethodInfo method = ReflectionUtils.GetMethod(objectType, "GetFromGUID", BindingFlags.Static | BindingFlags.NonPublic); if (method == null) { throw new Exception("The type " + objectType.Name + " does not have a valid implementation of the GetFromGUID(string guid) method!"); } return method.Invoke(null, new object[1] { text }); } } internal interface IGUIDReference { string GUID { get; } } internal interface IRegisterable { void CreateInternal(); void DestroyInternal(); void OnCreated(); void OnDestroyed(); } internal interface ISaveable : IRegisterable { internal static JsonSerializerSettings SerializerSettings => new JsonSerializerSettings { ReferenceLoopHandling = (ReferenceLoopHandling)1, Converters = new List<JsonConverter> { (JsonConverter)(object)new GUIDReferenceConverter() } }; void SaveInternal(string path, ref List<string> extraSaveables); void LoadInternal(string folderPath); void OnSaved(); void OnLoaded(); } public abstract class Registerable : IRegisterable { void IRegisterable.CreateInternal() { CreateInternal(); } internal virtual void CreateInternal() { OnCreated(); } void IRegisterable.DestroyInternal() { DestroyInternal(); } internal virtual void DestroyInternal() { OnDestroyed(); } void IRegisterable.OnCreated() { OnCreated(); } protected virtual void OnCreated() { } void IRegisterable.OnDestroyed() { OnDestroyed(); } protected virtual void OnDestroyed() { } } public abstract class Saveable : Registerable, ISaveable, IRegisterable { void ISaveable.LoadInternal(string folderPath) { LoadInternal(folderPath); } internal virtual void LoadInternal(string folderPath) { FieldInfo[] fields = GetType().GetFields(BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] array = fields; foreach (FieldInfo fieldInfo in array) { SaveableField customAttribute = fieldInfo.GetCustomAttribute<SaveableField>(); if (customAttribute != null) { string path = (customAttribute.SaveName.EndsWith(".json") ? customAttribute.SaveName : (customAttribute.SaveName + ".json")); string path2 = Path.Combine(folderPath, path); if (File.Exists(path2)) { string text = File.ReadAllText(path2); Type fieldType = fieldInfo.FieldType; object value = JsonConvert.DeserializeObject(text, fieldType, ISaveable.SerializerSettings); fieldInfo.SetValue(this, value); } } } OnLoaded(); } void ISaveable.SaveInternal(string folderPath, ref List<string> extraSaveables) { SaveInternal(folderPath, ref extraSaveables); } internal virtual void SaveInternal(string folderPath, ref List<string> extraSaveables) { FieldInfo[] allFields = ReflectionUtils.GetAllFields(GetType(), BindingFlags.Instance | BindingFlags.Public | BindingFlags.NonPublic); FieldInfo[] array = allFields; foreach (FieldInfo fieldInfo in array) { SaveableField customAttribute = fieldInfo.GetCustomAttribute<SaveableField>(); if (customAttribute != null) { string text = (customAttribute.SaveName.EndsWith(".json") ? customAttribute.SaveName : (customAttribute.SaveName + ".json")); string path = Path.Combine(folderPath, text); object value = fieldInfo.GetValue(this); if (value == null) { File.Delete(path); continue; } extraSaveables.Add(text); string contents = JsonConvert.SerializeObject(value, (Formatting)1, ISaveable.SerializerSettings); File.WriteAllText(path, contents); } } OnSaved(); } void ISaveable.OnLoaded() { OnLoaded(); } protected virtual void OnLoaded() { } void ISaveable.OnSaved() { OnSaved(); } protected virtual void OnSaved() { } } } namespace S1API.GameTime { public enum Day { Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday } public static class TimeManager { public static Action OnDayPass = delegate { }; public static Day CurrentDay => (Day)NetworkSingleton<TimeManager>.Instance.CurrentDay; } } namespace S1API.DeadDrops { public class DeadDropInstance : IGUIDReference { internal readonly DeadDrop S1DeadDrop; private StorageInstance? _cachedStorage; public string GUID { get { //IL_0006: Unknown result type (might be due to invalid IL or missing references) //IL_000b: Unknown result type (might be due to invalid IL or missing references) Guid gUID = S1DeadDrop.GUID; return ((object)(Guid)(ref gUID)).ToString(); } } public StorageInstance Storage => _cachedStorage ?? (_cachedStorage = new StorageInstance(S1DeadDrop.Storage)); public Vector3 Position => ((Component)S1DeadDrop).transform.position; public string name => ((Object)S1DeadDrop).name; internal DeadDropInstance(DeadDrop deadDrop) { S1DeadDrop = deadDrop; } internal static DeadDropInstance? GetFromGUID(string guid) { string guid2 = guid; return DeadDropManager.All.FirstOrDefault((DeadDropInstance deadDrop) => deadDrop.GUID == guid2); } } public class DeadDropManager { public static DeadDropInstance[] All => ((IEnumerable<DeadDrop>)DeadDrop.DeadDrops.ToArray()).Select((DeadDrop deadDrop) => new DeadDropInstance(deadDrop)).ToArray(); } } namespace S1API.API { [Serializable] public class DeadDropData : SaveData { public string deliverDeadDropGUID; public string collectDeadDropGUID; public DeadDrop DeliveryDeadDrop { get { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(deliverDeadDropGUID)) { return null; } for (int i = 0; i < DeadDrop.DeadDrops.Count; i++) { DeadDrop val = DeadDrop.DeadDrops[i]; if ((Object)(object)val != (Object)null) { Guid gUID = val.GUID; if (((object)(Guid)(ref gUID)).ToString() == deliverDeadDropGUID) { return val; } } } return null; } } public DeadDrop CollectDeadDrop { get { //IL_002f: Unknown result type (might be due to invalid IL or missing references) //IL_0034: Unknown result type (might be due to invalid IL or missing references) if (string.IsNullOrEmpty(collectDeadDropGUID)) { return null; } for (int i = 0; i < DeadDrop.DeadDrops.Count; i++) { DeadDrop val = DeadDrop.DeadDrops[i]; if ((Object)(object)val != (Object)null) { Guid gUID = val.GUID; if (((object)(Guid)(ref gUID)).ToString() == collectDeadDropGUID) { return val; } } } return null; } } } } namespace SOE { public abstract class DeadDropCheckerBase { protected DeadDrop drop; protected string itemID; protected string packaging; protected int requiredAmount; public DeadDropCheckerBase(DeadDrop drop, string itemID, string packaging = "brick", int requiredAmount = 1) { this.drop = drop; this.itemID = itemID; this.packaging = packaging; this.requiredAmount = requiredAmount; } protected void PrintStorageContents() { DeadDrop obj = drop; object obj2; if (obj == null) { obj2 = null; } else { StorageEntity storage = obj.Storage; obj2 = ((storage != null) ? storage.ItemSlots : null); } if (obj2 == null) { return; } List<ItemSlot> itemSlots = drop.Storage.ItemSlots; if (itemSlots.Count == 0) { return; } for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val = itemSlots[i]; ItemInstance val2 = ((val != null) ? val.ItemInstance : null); if (val2 == null) { continue; } int quantity = val.Quantity; string name = val2.Name; ProductItemInstance val3 = ((Il2CppObjectBase)val2).TryCast<ProductItemInstance>(); if (val3 != null) { ItemDefinition definition = ((ItemInstance)val3).Definition; string text = ((definition != null) ? ((Object)definition).name : null) ?? "(null)"; string text2 = val3.PackagingID ?? "?"; name = text + " [" + text2 + "]"; } else { CashInstance val4 = ((Il2CppObjectBase)val2).TryCast<CashInstance>(); if (val4 != null) { name = $"Cash: ${val4.Balance}"; } } } } public bool CheckIfItemDelivered() { DeadDrop obj = drop; object obj2; if (obj == null) { obj2 = null; } else { StorageEntity storage = obj.Storage; obj2 = ((storage != null) ? storage.ItemSlots : null); } if (obj2 == null) { return false; } int num = 0; List<ItemSlot> itemSlots = drop.Storage.ItemSlots; for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val = itemSlots[i]; object obj3; if (val == null) { obj3 = null; } else { ItemInstance itemInstance = val.ItemInstance; obj3 = ((itemInstance != null) ? ((Il2CppObjectBase)itemInstance).TryCast<ProductItemInstance>() : null); } ProductItemInstance val2 = (ProductItemInstance)obj3; if (val2 != null && (((ItemInstance)val2).Name?.Replace(" ", "").ToLowerInvariant() ?? "") == itemID.Replace(" ", "").ToLowerInvariant()) { num += val.Quantity; } } return num >= requiredAmount; } protected void RemoveMatchingItemsFromStorage(int amount) { DeadDrop obj = drop; object obj2; if (obj == null) { obj2 = null; } else { StorageEntity storage = obj.Storage; obj2 = ((storage != null) ? storage.ItemSlots : null); } if (obj2 == null) { return; } int num = amount; List<ItemSlot> itemSlots = drop.Storage.ItemSlots; for (int i = 0; i < itemSlots.Count; i++) { ItemSlot val = itemSlots[i]; object obj3; if (val == null) { obj3 = null; } else { ItemInstance itemInstance = val.ItemInstance; obj3 = ((itemInstance != null) ? ((Il2CppObjectBase)itemInstance).TryCast<ProductItemInstance>() : null); } ProductItemInstance val2 = (ProductItemInstance)obj3; if (val2 == null) { continue; } bool flag = (((ItemInstance)val2).Name?.Replace(" ", "").ToLowerInvariant() ?? "") == itemID.Replace(" ", "").ToLowerInvariant(); bool flag2 = (val2.PackagingID?.ToLowerInvariant() ?? "") == packaging.ToLowerInvariant(); if (flag && flag2) { int num2 = Mathf.Min(num, val.Quantity); val.ChangeQuantity(-num2, false); num -= num2; if (num <= 0) { break; } } } if (num <= 0) { } } } public class DeadDropRewardHandler { private DeadDrop rewardDrop; private int rewardAmount; private bool rewardGiven; private QuestEntry questStep; public DeadDropRewardHandler(DeadDrop drop, int amount) { rewardDrop = drop; rewardAmount = amount; rewardGiven = false; } public void Update() { if (!rewardGiven && !((Object)(object)rewardDrop == (Object)null) && !((Object)(object)rewardDrop.Storage == (Object)null) && rewardDrop.Storage.IsOpened) { InsertReward(); } } private void InsertReward() { if ((Object)(object)PlayerSingleton<PlayerInventory>.Instance == (Object)null) { return; } CashInstance cashInstance = PlayerSingleton<PlayerInventory>.Instance.cashInstance; if (cashInstance == null) { return; } CashInstance val = ((Il2CppObjectBase)((ItemInstance)cashInstance).GetCopy(-1)).Cast<CashInstance>(); if (val == null || (Object)(object)rewardDrop == (Object)null || (Object)(object)rewardDrop.Storage == (Object)null) { return; } val.SetBalance((float)rewardAmount, false); if (rewardDrop.Storage.CanItemFit((ItemInstance)(object)val, 1)) { rewardDrop.Storage.InsertItem((ItemInstance)(object)val, true); if ((Object)(object)questStep != (Object)null) { questStep.Complete(); } rewardGiven = true; } } } public abstract class PhoneApp { [CompilerGenerated] private sealed class <DelayedInit>d__15 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public Instance logger; public PhoneApp <>4__this; private GameObject <appsCanvas>5__1; private Transform <existingApp>5__2; private Transform <templateApp>5__3; private Transform <containerTransform>5__4; private GameObject <container>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedInit>d__15(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <appsCanvas>5__1 = null; <existingApp>5__2 = null; <templateApp>5__3 = null; <containerTransform>5__4 = null; <container>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0026: Unknown result type (might be due to invalid IL or missing references) //IL_0030: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <>2__current = (object)new WaitForSeconds(5f); <>1__state = 1; return true; case 1: <>1__state = -1; <>4__this.Player = GameObject.Find("Player_Local"); if ((Object)(object)<>4__this.Player == (Object)null) { logger.Error("Player_Local not found."); return false; } <appsCanvas>5__1 = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/AppsCanvas"); if ((Object)(object)<appsCanvas>5__1 == (Object)null) { logger.Error("AppsCanvas not found."); return false; } <existingApp>5__2 = <appsCanvas>5__1.transform.Find(<>4__this.AppName); if ((Object)(object)<existingApp>5__2 != (Object)null) { <>4__this.AppPanel = ((Component)<existingApp>5__2).gameObject; <>4__this.SetupExistingAppPanel(<>4__this.AppPanel, logger); } else { <templateApp>5__3 = <appsCanvas>5__1.transform.Find("ProductManagerApp"); if ((Object)(object)<templateApp>5__3 == (Object)null) { logger.Error("Template ProductManagerApp not found."); return false; } <>4__this.AppPanel = Object.Instantiate<GameObject>(((Component)<templateApp>5__3).gameObject, <appsCanvas>5__1.transform); ((Object)<>4__this.AppPanel).name = <>4__this.AppName; <containerTransform>5__4 = <>4__this.AppPanel.transform.Find("Container"); if ((Object)(object)<containerTransform>5__4 != (Object)null) { <container>5__5 = ((Component)<containerTransform>5__4).gameObject; <>4__this.ClearContainer(<container>5__5); <>4__this.BuildUI(<container>5__5); <container>5__5 = null; } <>4__this.AppCreated = true; <templateApp>5__3 = null; <containerTransform>5__4 = null; } <>4__this.AppPanel.SetActive(false); if (!<>4__this.IconModified) { <>4__this.IconModified = <>4__this.ModifyAppIcon(<>4__this.IconLabel, <>4__this.IconFileName, logger); if (<>4__this.IconModified) { logger.Msg("Icon modified."); } } 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(); } } protected GameObject Player; protected GameObject AppPanel; protected bool AppCreated; protected bool IconModified; protected bool InitializationStarted; protected abstract string AppName { get; } protected abstract string AppTitle { get; } protected abstract string IconLabel { get; } protected abstract string IconFileName { get; } protected abstract void BuildUI(GameObject container); public void Init(Instance logger) { MelonCoroutines.Start(DelayedInit(logger)); } [IteratorStateMachine(typeof(<DelayedInit>d__15))] private IEnumerator DelayedInit(Instance logger) { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedInit>d__15(0) { <>4__this = this, logger = logger }; } private void SetupExistingAppPanel(GameObject panel, Instance logger) { Transform val = panel.transform.Find("Container"); if ((Object)(object)val != (Object)null) { GameObject gameObject = ((Component)val).gameObject; if (gameObject.transform.childCount < 2) { ClearContainer(gameObject); BuildUI(gameObject); } } AppCreated = true; } private void ClearContainer(GameObject container) { for (int num = container.transform.childCount - 1; num >= 0; num--) { Object.Destroy((Object)(object)((Component)container.transform.GetChild(num)).gameObject); } } private bool ModifyAppIcon(string labelText, string fileName, Instance logger) { GameObject val = GameObject.Find("Player_Local/CameraContainer/Camera/OverlayCamera/GameplayMenu/Phone/phone/HomeScreen/AppIcons/"); if ((Object)(object)val == (Object)null) { if (logger != null) { logger.Error("AppIcons not found."); } return false; } Transform val2 = ((val.transform.childCount > 0) ? val.transform.GetChild(val.transform.childCount - 1) : null); if ((Object)(object)val2 == (Object)null) { if (logger != null) { logger.Error("No icon found to clone."); } return false; } GameObject gameObject = ((Component)val2).gameObject; ((Object)gameObject).name = AppName; Transform val3 = gameObject.transform.Find("Label"); Text val4 = ((val3 != null) ? ((Component)val3).GetComponent<Text>() : null); if ((Object)(object)val4 != (Object)null) { val4.text = labelText; } return ChangeAppIconImage(gameObject, fileName, logger); } private bool ChangeAppIconImage(GameObject iconObj, string filename, Instance logger) { //IL_008b: Unknown result type (might be due to invalid IL or missing references) //IL_0092: Expected O, but got Unknown //IL_00c4: Unknown result type (might be due to invalid IL or missing references) //IL_00d3: Unknown result type (might be due to invalid IL or missing references) Transform val = iconObj.transform.Find("Mask/Image"); Image val2 = ((val != null) ? ((Component)val).GetComponent<Image>() : null); if ((Object)(object)val2 == (Object)null) { if (logger != null) { logger.Error("Image component not found in icon."); } return false; } string text = Path.Combine(MelonEnvironment.UserDataDirectory, filename); if (!File.Exists(text)) { if (logger != null) { logger.Error("Icon file not found: " + text); } return false; } try { byte[] array = File.ReadAllBytes(text); Texture2D val3 = new Texture2D(2, 2); if (ImageConversion.LoadImage(val3, Il2CppStructArray<byte>.op_Implicit(array))) { val2.sprite = Sprite.Create(val3, new Rect(0f, 0f, (float)((Texture)val3).width, (float)((Texture)val3).height), new Vector2(0.5f, 0.5f)); return true; } Object.Destroy((Object)(object)val3); } catch (Exception ex) { if (logger != null) { logger.Error("Failed to load image: " + ex.Message); } } return false; } } public class MyMod : MelonMod { private bool _isInGame; private MyApp _app; public override void OnSceneWasInitialized(int buildIndex, string sceneName) { bool flag = sceneName?.Contains("Main") ?? false; if (!_isInGame && flag) { ((MelonBase)this).LoggerInstance.Msg("Entering game scene: " + sceneName); _app = new MyApp(); _app.Init(((MelonBase)this).LoggerInstance); } else if (_isInGame && !flag) { ((MelonBase)this).LoggerInstance.Msg("Exiting game scene."); _app = null; } _isInGame = flag; } } public class MyApp : PhoneApp { private List<QuestData> quests; private RectTransform questListContainer; private Text questTitle; private Text questTask; private Text questReward; private Text deliveryStatus; private Button acceptButton; private GameObject containerRoot; private bool hasRefreshedOnOpen = false; protected override string AppName => "Silkroad"; protected override string AppTitle => "Silkroad"; protected override string IconLabel => "Silkroad"; protected override string IconFileName => "SilkroadIcon.png"; protected override void BuildUI(GameObject container) { //IL_0015: Unknown result type (might be due to invalid IL or missing references) //IL_004f: 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_0072: 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) //IL_00c6: Unknown result type (might be due to invalid IL or missing references) //IL_00da: Unknown result type (might be due to invalid IL or missing references) //IL_00f0: Unknown result type (might be due to invalid IL or missing references) //IL_00f7: Expected O, but got Unknown //IL_0116: Unknown result type (might be due to invalid IL or missing references) //IL_0123: Unknown result type (might be due to invalid IL or missing references) //IL_0130: 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_015f: Unknown result type (might be due to invalid IL or missing references) //IL_0166: Expected O, but got Unknown //IL_0186: Unknown result type (might be due to invalid IL or missing references) //IL_0193: Unknown result type (might be due to invalid IL or missing references) //IL_01a0: 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_01d3: Unknown result type (might be due to invalid IL or missing references) //IL_01fb: Unknown result type (might be due to invalid IL or missing references) //IL_0202: Expected O, but got Unknown //IL_022c: Unknown result type (might be due to invalid IL or missing references) //IL_0243: Unknown result type (might be due to invalid IL or missing references) //IL_025a: Unknown result type (might be due to invalid IL or missing references) //IL_0267: Unknown result type (might be due to invalid IL or missing references) //IL_0292: Unknown result type (might be due to invalid IL or missing references) //IL_029c: Expected O, but got Unknown //IL_02ed: Unknown result type (might be due to invalid IL or missing references) //IL_02fc: Unknown result type (might be due to invalid IL or missing references) //IL_0310: Unknown result type (might be due to invalid IL or missing references) //IL_0342: Unknown result type (might be due to invalid IL or missing references) //IL_034c: Expected O, but got Unknown //IL_03ed: Unknown result type (might be due to invalid IL or missing references) containerRoot = container; Transform transform = container.transform; GameObject val = UIFactory.Panel("SilkRoad_Background", transform, Color.black, null, null, fullAnchor: true); GameObject val2 = UIFactory.Panel("TopBar", val.transform, new Color(0.15f, 0.15f, 0.15f), (Vector2?)new Vector2(0f, 0.93f), (Vector2?)new Vector2(1f, 1f), fullAnchor: false); UIFactory.Text("AppTitle", "Silk Road", val2.transform, 26, (TextAnchor)4, (FontStyle)1); GameObject val3 = UIFactory.Panel("QuestListPanel", val.transform, new Color(0.1f, 0.1f, 0.1f), (Vector2?)new Vector2(0f, 0f), (Vector2?)new Vector2(0.5f, 0.93f), fullAnchor: false); GameObject val4 = new GameObject("ScrollView"); val4.transform.SetParent(val3.transform, false); RectTransform val5 = val4.AddComponent<RectTransform>(); val5.anchorMin = Vector2.zero; val5.anchorMax = Vector2.one; val5.offsetMin = Vector2.zero; val5.offsetMax = Vector2.zero; ScrollRect val6 = val4.AddComponent<ScrollRect>(); val6.horizontal = false; GameObject val7 = new GameObject("Viewport"); val7.transform.SetParent(val4.transform, false); RectTransform val8 = val7.AddComponent<RectTransform>(); val8.anchorMin = Vector2.zero; val8.anchorMax = Vector2.one; val8.offsetMin = Vector2.zero; val8.offsetMax = Vector2.zero; ((Graphic)val7.AddComponent<Image>()).color = new Color(0f, 0f, 0f, 0.02f); val7.AddComponent<Mask>().showMaskGraphic = false; val6.viewport = val8; GameObject val9 = new GameObject("QuestListContent"); val9.transform.SetParent(val7.transform, false); RectTransform val10 = val9.AddComponent<RectTransform>(); val10.anchorMin = new Vector2(0f, 1f); val10.anchorMax = new Vector2(1f, 1f); val10.pivot = new Vector2(0.5f, 1f); val10.anchoredPosition = Vector2.zero; VerticalLayoutGroup val11 = val9.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val11).spacing = 10f; ((LayoutGroup)val11).padding = new RectOffset(10, 10, 10, 10); ((HorizontalOrVerticalLayoutGroup)val11).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val11).childForceExpandHeight = false; ContentSizeFitter val12 = val9.AddComponent<ContentSizeFitter>(); val12.verticalFit = (FitMode)2; val6.content = val10; questListContainer = val10; GameObject val13 = UIFactory.Panel("QuestDetailPanel", val.transform, new Color(0.12f, 0.12f, 0.12f), (Vector2?)new Vector2(0.5f, 0f), (Vector2?)new Vector2(1f, 0.93f), fullAnchor: false); VerticalLayoutGroup val14 = val13.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val14).spacing = 12f; ((LayoutGroup)val14).padding = new RectOffset(10, 10, 10, 10); questTitle = UIFactory.Text("QuestTitle", "Select a quest", val13.transform, 22, (TextAnchor)0, (FontStyle)1); questTask = UIFactory.Text("QuestTask", "Task: --", val13.transform, 18, (TextAnchor)0, (FontStyle)0); questReward = UIFactory.Text("QuestReward", "Reward: --", val13.transform, 18, (TextAnchor)0, (FontStyle)0); deliveryStatus = UIFactory.Text("DeliveryStatus", "", val13.transform, 16, (TextAnchor)0, (FontStyle)0); GameObject val15 = UIFactory.Button("AcceptButton", "Accept Delivery", val13.transform, new Color(0.2f, 0.6f, 0.2f)); acceptButton = val15.GetComponent<Button>(); QuestDelivery.OnQuestCompleted += OnDeliveryQuestFinished; LoadQuests(); } private void OnDeliveryQuestFinished() { RefreshQuestList(); } private void OnDestroy() { QuestDelivery.OnQuestCompleted -= OnDeliveryQuestFinished; } public void LoadQuests() { if (quests == null) { quests = new List<QuestData>(); } quests.Clear(); Random random = new Random(); List<ProductDefinition> allProducts = NetworkSingleton<ProductManager>.Instance.AllProducts; List<ProductDefinition> list = new List<ProductDefinition>(); for (int i = 0; i < allProducts.Count; i++) { ProductDefinition val = allProducts[i]; if ((Object)(object)val != (Object)null && !string.IsNullOrEmpty(((Object)val).name) && val.Price > 0f) { list.Add(val); } } List<ProductDefinition> list2 = new List<ProductDefinition>(); int num = Mathf.Min(list.Count, 8); while (list2.Count < num) { int index = random.Next(0, list.Count); ProductDefinition item = list[index]; if (!list2.Contains(item)) { list2.Add(item); } } foreach (ProductDefinition item2 in list2) { int num2 = random.Next(20, 100); int num3 = Mathf.RoundToInt(item2.Price * 20f * (float)num2); int num4 = Random.Range(50, 201) * num2; int reward = num3 + num4; quests.Add(new QuestData { Title = ((ItemDefinition)item2).Name + " Delivery", Task = $"Deliver {num2}x {((ItemDefinition)item2).Name} Bricks to the stash.", Reward = reward, ProductID = ((Object)item2).name, AmountRequired = (uint)num2, TargetObjectName = "GreenTent" }); } RefreshQuestList(); } private void RefreshQuestList() { //IL_002c: Unknown result type (might be due to invalid IL or missing references) //IL_0032: Expected O, but got Unknown //IL_0155: Unknown result type (might be due to invalid IL or missing references) //IL_015c: Expected O, but got Unknown //IL_017e: Unknown result type (might be due to invalid IL or missing references) //IL_01d6: Unknown result type (might be due to invalid IL or missing references) //IL_01e0: Expected O, but got Unknown //IL_0230: Unknown result type (might be due to invalid IL or missing references) //IL_0237: Expected O, but got Unknown //IL_0261: Unknown result type (might be due to invalid IL or missing references) //IL_0286: Unknown result type (might be due to invalid IL or missing references) //IL_02e1: Unknown result type (might be due to invalid IL or missing references) //IL_02e8: Expected O, but got Unknown //IL_0322: Unknown result type (might be due to invalid IL or missing references) //IL_0339: Unknown result type (might be due to invalid IL or missing references) //IL_0346: Unknown result type (might be due to invalid IL or missing references) //IL_0353: Unknown result type (might be due to invalid IL or missing references) //IL_037c: Unknown result type (might be due to invalid IL or missing references) //IL_03a6: Unknown result type (might be due to invalid IL or missing references) //IL_03bd: Unknown result type (might be due to invalid IL or missing references) //IL_0420: Unknown result type (might be due to invalid IL or missing references) //IL_0427: Expected O, but got Unknown //IL_0459: Unknown result type (might be due to invalid IL or missing references) if ((Object)(object)questListContainer == (Object)null) { return; } IEnumerator enumerator = ((Transform)questListContainer).GetEnumerator(); try { while (enumerator.MoveNext()) { Transform val = (Transform)enumerator.Current; Object.Destroy((Object)(object)((Component)val).gameObject); } } finally { if (enumerator is IDisposable disposable) { disposable.Dispose(); } } for (int i = 0; i < quests.Count; i++) { QuestData questData = quests[i]; ProductDefinition val2 = null; List<ProductDefinition> allProducts = NetworkSingleton<ProductManager>.Instance.AllProducts; for (int j = 0; j < allProducts.Count; j++) { ProductDefinition val3 = allProducts[j]; if ((Object)(object)val3 != (Object)null && ((Object)val3).name == questData.ProductID) { val2 = val3; break; } } if ((Object)(object)val2 == (Object)null) { continue; } Sprite icon = ((ItemDefinition)val2).Icon; QuestData clickedQuest; if (!((Object)(object)icon == (Object)null)) { string item = $"{questData.ProductID}_{questData.AmountRequired}"; bool flag = QuestDelivery.CompletedQuestKeys.Contains(item); GameObject val4 = new GameObject("QuestRow_" + questData.Title); val4.AddComponent<RectTransform>(); Image val5 = val4.AddComponent<Image>(); ((Graphic)val5).color = new Color(0.1f, 0.1f, 0.1f); val5.sprite = Resources.GetBuiltinResource<Sprite>("UI/Skin/Background.psd"); val5.type = (Type)1; val4.transform.SetParent((Transform)(object)questListContainer, false); HorizontalLayoutGroup val6 = val4.AddComponent<HorizontalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val6).spacing = 10f; ((LayoutGroup)val6).padding = new RectOffset(50, 10, 5, 5); ((LayoutGroup)val6).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandHeight = false; ((HorizontalOrVerticalLayoutGroup)val6).childForceExpandWidth = false; LayoutElement val7 = val4.AddComponent<LayoutElement>(); val7.preferredHeight = 90f; val7.minHeight = 90f; GameObject val8 = new GameObject("QuestIcon_" + questData.Title); val8.transform.SetParent(val4.transform, false); RectTransform val9 = val8.AddComponent<RectTransform>(); val9.sizeDelta = new Vector2(90f, 90f); Image val10 = val8.AddComponent<Image>(); ((Graphic)val10).color = new Color(0.15f, 0.15f, 0.15f); val10.sprite = Resources.GetBuiltinResource<Sprite>("UI/Skin/Background.psd"); val10.type = (Type)1; LayoutElement val11 = val8.AddComponent<LayoutElement>(); val11.preferredHeight = 90f; val11.minHeight = 90f; val11.preferredWidth = 90f; GameObject val12 = new GameObject("Icon"); val12.AddComponent<RectTransform>(); val12.AddComponent<Image>(); val12.transform.SetParent(val8.transform, false); RectTransform component = val12.GetComponent<RectTransform>(); component.anchorMin = new Vector2(0.15f, 0.15f); component.anchorMax = new Vector2(0.85f, 0.85f); component.offsetMin = Vector2.zero; component.offsetMax = Vector2.zero; Image component2 = val12.GetComponent<Image>(); component2.sprite = icon; component2.preserveAspect = true; ((Graphic)component2).color = Color.white; Outline val13 = val12.AddComponent<Outline>(); ((Shadow)val13).effectColor = new Color(1f, 1f, 1f, 0.15f); ((Shadow)val13).effectDistance = new Vector2(1.5f, -1.5f); Button val14 = val8.AddComponent<Button>(); ((Selectable)val14).targetGraphic = (Graphic)(object)val10; clickedQuest = questData; ((UnityEvent)val14.onClick).AddListener(UnityAction.op_Implicit((Action)Select)); ((Selectable)val14).interactable = !flag && !QuestDelivery.QuestActive; GameObject val15 = new GameObject("QuestText"); val15.AddComponent<RectTransform>(); val15.transform.SetParent(val4.transform, false); RectTransform component3 = val15.GetComponent<RectTransform>(); component3.sizeDelta = new Vector2(280f, 90f); VerticalLayoutGroup val16 = val15.AddComponent<VerticalLayoutGroup>(); ((HorizontalOrVerticalLayoutGroup)val16).spacing = 4f; ((LayoutGroup)val16).childAlignment = (TextAnchor)3; ((HorizontalOrVerticalLayoutGroup)val16).childControlHeight = true; ((HorizontalOrVerticalLayoutGroup)val16).childControlWidth = true; ((HorizontalOrVerticalLayoutGroup)val16).childForceExpandWidth = false; LayoutElement val17 = val15.AddComponent<LayoutElement>(); val17.minWidth = 200f; val17.flexibleWidth = 1f; UIFactory.Text("QuestTitle", questData.Title, val15.transform, 16, (TextAnchor)3, (FontStyle)1); string content = "Client: Unknown"; string fullName = ((Object)val2).GetIl2CppType().FullName; if (fullName.Contains("WeedDefinition")) { content = "Client: German Mafia"; } else if (fullName.Contains("CocaineDefinition")) { content = "Client: Canadian Mafia"; } else if (fullName.Contains("MethDefinition")) { content = "Client: Russian Mafia"; } UIFactory.Text("QuestClient", content, val15.transform, 14, (TextAnchor)0, (FontStyle)0); if (flag) { UIFactory.Text("CompletedLabel", "<color=#888888><i>Already Delivered</i></color>", val15.transform, 12, (TextAnchor)0, (FontStyle)0); } } void Select() { OnSelectQuest(clickedQuest); } } } private void OnSelectQuest(QuestData quest) { QuestData quest2 = quest; questTitle.text = quest2.Title; questTask.text = "Task: " + quest2.Task; questReward.text = $"Reward: ${quest2.Reward}"; ((Component)acceptButton).GetComponentInChildren<Text>().text = "Accept Delivery"; ((UnityEventBase)acceptButton.onClick).RemoveAllListeners(); ((Selectable)acceptButton).interactable = true; ((UnityEvent)acceptButton.onClick).AddListener(UnityAction.op_Implicit((Action)OnClick)); void OnClick() { AcceptQuest(quest2); } } private void AcceptQuest(QuestData quest) { string item = $"{quest.ProductID}_{quest.AmountRequired}"; if (QuestDelivery.QuestActive) { deliveryStatus.text = "⚠\ufe0f Finish your current job first!"; return; } if (QuestDelivery.CompletedQuestKeys.Contains(item)) { deliveryStatus.text = "⛔ Already delivered this shipment."; ((Selectable)acceptButton).interactable = false; return; } Quest quest2 = QuestManager.CreateQuest<QuestDelivery>(); if (quest2 is QuestDelivery questDelivery) { questDelivery.Data.ProductID = quest.ProductID; questDelivery.Data.RequiredAmount = quest.AmountRequired; questDelivery.Data.Reward = quest.Reward; } deliveryStatus.text = "\ud83d\udce6 Delivery started!"; ((Selectable)acceptButton).interactable = false; } private void Update() { if ((Object)(object)containerRoot != (Object)null && containerRoot.activeInHierarchy && !hasRefreshedOnOpen) { if (quests == null || quests.Count == 0) { LoadQuests(); } RefreshQuestList(); hasRefreshedOnOpen = true; } if ((Object)(object)containerRoot != (Object)null && !containerRoot.activeInHierarchy) { hasRefreshedOnOpen = false; } } } public class QuestData { public string Title; public string Task; public int Reward; public string ProductID; public uint AmountRequired; public string TargetObjectName; } } namespace SilkRoad.Quests { public class BlackmarketBuyer : NPC { private static readonly string[] DeliveryAcceptedTexts = new string[5] { "We’ve heard of your product. {amount} bricks of {product}. Impress us.", "Your name reached our ears. {amount} bricks of {product}. Discreet drop. No attention.", "Quality like yours doesn't go unnoticed. Deliver {amount} bricks of {product}. Same location.", "We're watching, and we’re interested. {amount} bricks of {product}. Clean work only.", "Consider this a test. {amount} bricks of {product}. Don’t disappoint." }; private static readonly string[] DeliverySuccessTexts = new string[5] { "The stash was verified. Your reward will be with you shortly.", "Everything checked out. Sit tight — payment's on the way.", "Impressive. Clean drop. Expect your cash soon.", "The cargo's in place. Funds are being processed.", "Solid work. Your reward is en route. Stay alert." }; private static readonly string[] InstantRewardTexts = new string[5] { "Payment’s been sent. You did good — we notice things like that.", "Cash is in your account. You pulled your weight, and that matters.", "Transfer complete. Always good doing business with someone dependable.", "Funds delivered. You handled it right — that earns respect.", "You’ve been paid. Stick with us, and there’s more where that came from." }; public BlackmarketBuyer() : base("blackmarket_buyer", "Blackmarket", "Buyer") { } internal override void CreateInternal() { base.CreateInternal(); Contacts.Buyer = this; } public void SendDeliveryAccepted(string product, int amount) { string text = DeliveryAcceptedTexts[Random.Range(0, DeliveryAcceptedTexts.Length)]; string message = text.Replace("{product}", "<color=#34AD33>" + product + "</color>").Replace("{amount}", $"<color=#FF0004>{amount}x</color>"); SendTextMessage(message); } public void SendDeliverySuccess(string product) { string message = DeliverySuccessTexts[Random.Range(0, DeliverySuccessTexts.Length)]; SendTextMessage(message); } public void SendRewardDropped() { string message = InstantRewardTexts[Random.Range(0, InstantRewardTexts.Length)]; SendTextMessage(message); } } public static class Contacts { public static BlackmarketBuyer Buyer { get; internal set; } } public class QuestDelivery : Quest { [CompilerGenerated] private sealed class <DelayedReward>d__12 : IEnumerator<object>, IEnumerator, IDisposable { private int <>1__state; private object <>2__current; public QuestDelivery <>4__this; private float <delaySeconds>5__1; private int <rewardAmount>5__2; private ChangeCashCommand <consoleCommand>5__3; private List<string> <args>5__4; private string <key>5__5; object IEnumerator<object>.Current { [DebuggerHidden] get { return <>2__current; } } object IEnumerator.Current { [DebuggerHidden] get { return <>2__current; } } [DebuggerHidden] public <DelayedReward>d__12(int <>1__state) { this.<>1__state = <>1__state; } [DebuggerHidden] void IDisposable.Dispose() { <consoleCommand>5__3 = null; <args>5__4 = null; <key>5__5 = null; <>1__state = -2; } private bool MoveNext() { //IL_0032: Unknown result type (might be due to invalid IL or missing references) //IL_003c: Expected O, but got Unknown //IL_0077: Unknown result type (might be due to invalid IL or missing references) //IL_0081: Expected O, but got Unknown switch (<>1__state) { default: return false; case 0: <>1__state = -1; <delaySeconds>5__1 = 600f; <>2__current = (object)new WaitForSeconds(<delaySeconds>5__1); <>1__state = 1; return true; case 1: <>1__state = -1; if (<>4__this.deliveryEntry == null) { return false; } <rewardAmount>5__2 = <>4__this.Data.Reward; <consoleCommand>5__3 = new ChangeCashCommand(); <args>5__4 = new List<string>(); <args>5__4.Add(<rewardAmount>5__2.ToString()); ((ConsoleCommand)<consoleCommand>5__3).Execute(<args>5__4); QuestActive = false; <key>5__5 = $"{<>4__this.Data.ProductID}_{<>4__this.Data.RequiredAmount}"; CompletedQuestKeys.Add(<key>5__5); Contacts.Buyer?.SendRewardDropped(); <>4__this.rewardEntry?.Complete(); <>4__this.Complete(); QuestManager.Quests.Remove(<>4__this); QuestDelivery.OnQuestCompleted?.Invoke(); 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(); } } [SaveableField("DeliveryData")] public DeliverySaveData Data = new DeliverySaveData(); private DeadDropInstance deliveryDrop; private DeadDropInstance rewardDrop; public static HashSet<string> CompletedQuestKeys = new HashSet<string>(); private QuestEntry deliveryEntry; private QuestEntry rewardEntry; public static bool QuestActive = false; protected override string Title => (Data?.ProductID != null) ? ("Deliver " + Data.ProductID) : "Silkroad Delivery"; protected override string Description => (Data?.ProductID != null && Data.RequiredAmount != 0) ? $"Deliver {Data.RequiredAmount}x bricks of {Data.ProductID} to the drop point." : "Deliver the assigned product to the stash location."; public static event Action OnQuestCompleted; internal override void CreateInternal() { //IL_0212: Unknown result type (might be due to invalid IL or missing references) //IL_0250: Unknown result type (might be due to invalid IL or missing references) base.CreateInternal(); QuestActive = true; if (Data == null) { Data = new DeliverySaveData(); } if (!Data.Initialized) { List<DeadDropInstance> list = DeadDropManager.All?.ToList(); if (list == null || list.Count < 6) { return; } deliveryDrop = list[Random.Range(0, DeadDrop.DeadDrops.Count)]; rewardDrop = list[Random.Range(0, DeadDrop.DeadDrops.Count)]; Data.DeliveryDropGUID = deliveryDrop.GUID; Data.RewardDropGUID = rewardDrop.GUID; Data.Initialized = true; } else { deliveryDrop = DeadDropManager.All.FirstOrDefault((DeadDropInstance d) => d.GUID == Data.DeliveryDropGUID); rewardDrop = DeadDropManager.All.FirstOrDefault((DeadDropInstance d) => d.GUID == Data.RewardDropGUID); if (deliveryDrop == null || rewardDrop == null) { List<DeadDropInstance> list2 = DeadDropManager.All.ToList(); if (list2.Count < 2) { return; } deliveryDrop = list2[0]; rewardDrop = list2[1]; Data.DeliveryDropGUID = deliveryDrop.GUID; Data.RewardDropGUID = rewardDrop.GUID; UnityEvent onQuestBegin = S1Quest.onQuestBegin; if (onQuestBegin != null) { onQuestBegin.Invoke(); } } } deliveryEntry = AddEntry($"Deliver {Data.RequiredAmount}x bricks of {Data.ProductID} to {deliveryDrop.name}"); deliveryEntry.POIPosition = deliveryDrop.Position; deliveryEntry.Begin(); rewardEntry = AddEntry("Wait for the payement to arrive."); rewardEntry.POIPosition = rewardDrop.Position; rewardEntry.SetState(QuestState.Inactive); deliveryDrop.Storage.OnClosed += CheckDelivery; Contacts.Buyer?.SendDeliveryAccepted(Data.ProductID, (int)Data.RequiredAmount); } private void CheckDelivery() { int num = deliveryDrop.Storage.Slots.Where((ItemSlotInstance slot) => slot.ItemInstance is ProductInstance productInstance2 && ((ItemDefinition)productInstance2.AppliedPackaging.S1PackagingDefinition).ID == "brick" && productInstance2.Definition.Name == Data.ProductID).Sum((ItemSlotInstance slot) => slot.Quantity); if (num < Data.RequiredAmount) { return; } uint num2 = Data.RequiredAmount; ItemSlotInstance[] slots = deliveryDrop.Storage.Slots; foreach (ItemSlotInstance itemSlotInstance in slots) { if (itemSlotInstance.ItemInstance is ProductInstance productInstance && ((ItemDefinition)productInstance.AppliedPackaging.S1PackagingDefinition).ID == "brick" && productInstance.Definition.Name == Data.ProductID) { int num3 = (int)Mathf.Min((float)itemSlotInstance.Quantity, (float)num2); itemSlotInstance.AddQuantity(-num3); num2 -= (uint)num3; if (num2 == 0) { break; } } } deliveryEntry.Complete(); rewardEntry.SetState(QuestState.Active); MelonCoroutines.Start(DelayedReward()); Contacts.Buyer?.SendDeliverySuccess(Data.ProductID); } [IteratorStateMachine(typeof(<DelayedReward>d__12))] private IEnumerator DelayedReward() { //yield-return decompiler failed: Unexpected instruction in Iterator.Dispose() return new <DelayedReward>d__12(0) { <>4__this = this }; } } }