Beispiel #1
0
        public Sideloader()
        {
            //ilmerge
            AppDomain.CurrentDomain.AssemblyResolve += (sender, args) =>
            {
                if (args.Name == "I18N, Version=2.0.0.0, Culture=neutral, PublicKeyToken=0738eb9f132ed756" ||
                    args.Name == "I18N.West, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null")
                {
                    return(Assembly.GetExecutingAssembly());
                }

                return(null);
            };

            //install hooks
            Hooks.InstallHooks();
            AutoResolver.Hooks.InstallHooks();
            ResourceRedirector.ResourceRedirector.AssetResolvers.Add(RedirectHook);

            //check mods directory
            string modDirectory = Path.Combine(Utility.ExecutingDirectory, "mods");

            if (!Directory.Exists(modDirectory))
            {
                return;
            }


            //load zips
            foreach (string archivePath in Directory.GetFiles(modDirectory, "*.zip"))
            {
                var archive = new ZipFile(archivePath);

                if (!Manifest.TryLoadFromZip(archive, out Manifest manifest))
                {
                    BepInLogger.Log($"[SIDELOADER] Cannot load {Path.GetFileName(archivePath)} due to missing/invalid manifest.");
                    continue;
                }

                string name = manifest.Name ?? Path.GetFileName(archivePath);
                BepInLogger.Log($"[SIDELOADER] Loaded {name} {manifest.Version ?? ""}");

                Archives.Add(archive);

                LoadAllUnityArchives(archive);

                LoadAllLists(archive, manifest);
            }
        }
Beispiel #2
0
 void Update()
 {
     if (Event.current == null)
     {
         return;
     }
     if (UnityEngine.Event.current.Equals(ReloadTranslationsKeyEvent))
     {
         Retranslate();
         BepInLogger.Log($"Translation reloaded.", true);
     }
     if (UnityEngine.Event.current.Equals(DumpUntranslatedTextKeyEvent))
     {
         Dump();
         BepInLogger.Log($"Text dumped to \"{Path.GetFullPath("dumped-tl.txt")}\"", true);
     }
 }
Beispiel #3
0
        public static void ResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, ChaFile save)
        {
            //BepInLogger.Log($"Tried to resolve structure: {structure.GetType().Name}");

            var extData = ExtendedSave.GetExtendedDataById(save, UARExtID);

            if (extData == null || !extData.data.ContainsKey("info"))
            {
                //BepInLogger.Log($"No info to load!");
                return;
            }

            var tmpExtInfo = (object[])extData.data["info"];
            var extInfo    = tmpExtInfo.Select(x => ResolveInfo.Unserialize((byte[])x));

            //BepInLogger.Log($"Internal info count: {LoadedResolutionInfo.Count}");
            //foreach (ResolveInfo info in LoadedResolutionInfo)
            //    BepInLogger.Log($"Internal info: {info.ModID} : {info.Property} : {info.Slot}");

            //BepInLogger.Log($"External info count: {extInfo.Count()}");
            //foreach (ResolveInfo info in extInfo)
            //    BepInLogger.Log($"External info: {info.ModID} : {info.Property} : {info.Slot}");


            foreach (var kv in propertyDict)
            {
                var extResolve = extInfo.FirstOrDefault(x => x.Property == kv.Key.ToString());

                if (extResolve != null)
                {
                    var intResolve = LoadedResolutionInfo.FirstOrDefault(x => x.CanResolve(extResolve));

                    if (intResolve != null)
                    {
                        BepInLogger.Log($"[UAR] Resolving {extResolve.ModID}:{extResolve.Property} from slot {extResolve.Slot} to slot {intResolve.LocalSlot}");

                        kv.Value.SetMethod(structure, intResolve.LocalSlot);
                    }
                }
            }
        }
Beispiel #4
0
        void UntranslateAll()
        {
            Hooks.TranslationHooksEnabled = false;

            int i = 0;

            foreach (var kv in originalTranslations)
            {
                if (kv.Key.IsAlive)
                {
                    i++;

                    if (kv.Key.Target is TMP_Text)
                    {
                        TMP_Text tmtext = (TMP_Text)kv.Key.Target;

                        tmtext.text = kv.Value;
                    }
                    else if (kv.Key.Target is TextMeshProUGUI)
                    {
                        TextMeshProUGUI tmtext = (TextMeshProUGUI)kv.Key.Target;

                        tmtext.text = kv.Value;
                    }
                    else if (kv.Key.Target is UnityEngine.UI.Text)
                    {
                        UnityEngine.UI.Text tmtext = (UnityEngine.UI.Text)kv.Key.Target;

                        tmtext.text = kv.Value;
                    }
                }
            }

            BepInLogger.Log($"{i} translations reloaded.");

            Hooks.TranslationHooksEnabled = true;
        }
Beispiel #5
0
        void Start()
        {
            string managedDir = Path.Combine(Utility.ExecutingDirectory,
                                             $@"{System.Diagnostics.Process.GetCurrentProcess().ProcessName}_Data\Managed");

            if (File.Exists(Path.Combine(managedDir, "IllusionPlugin.dll")))
            {
                BepInLogger.Log("WARNING: IPA has been detected to be installed! IPALoader may not function correctly!", true, ConsoleColor.Red);
            }


            if (!Directory.Exists(IPAPluginDir))
            {
                BepInLogger.Log("No IPA plugin directory, skipping load");
                return;
            }

            if (IPAManagerObject != null)
            {
                Destroy(IPAManagerObject);
            }

            IPAManagerObject = new GameObject("IPA_Manager");

            DontDestroyOnLoad(IPAManagerObject);
            IPAManagerObject.SetActive(false);

            BepInLogger.Log("Loading IPA plugins");

            foreach (string path in Directory.GetFiles(IPAPluginDir, "*.dll"))
            {
                try
                {
                    var assembly = Assembly.LoadFile(path);

                    foreach (Type t in assembly.GetTypes())
                    {
                        if (t.IsAbstract || t.IsInterface)
                        {
                            continue;
                        }

                        if (t.Name == "CompositePlugin")
                        {
                            continue;
                        }

                        if (typeof(IPlugin).IsAssignableFrom(t))
                        {
                            pluginToLoad = (IPlugin)Activator.CreateInstance(t);

                            Component c = Chainloader.ManagerObject.AddComponent <IPAPlugin>();

                            BepInLogger.Log($"Loaded IPA plugin [{pluginToLoad.Name}]");

                            pluginToLoad = null;
                        }
                    }
                }
                catch (Exception ex)
                {
                    BepInLogger.Log($"Error loading IPA plugin {Path.GetFileName(path)}");
                    BepInLogger.Log(ex.ToString());
                }
            }

            IPAManagerObject.SetActive(true);
        }
        public static void ResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, ChaFile save, string propertyPrefix = "")
        {
            //BepInLogger.Log($"Tried to resolve structure: {structure.GetType().Name}");

            var extData = ExtendedSave.GetExtendedDataById(save, UARExtID);

            IEnumerable <ResolveInfo> extInfo;

            if (extData == null || !extData.data.ContainsKey("info"))
            {
                extInfo = null;
                //BepInLogger.Log("Nothing to load!");
            }
            else
            {
                var tmpExtInfo = (object[])extData.data["info"];
                extInfo = tmpExtInfo.Select(x => ResolveInfo.Unserialize((byte[])x));
            }

            //BepInLogger.Log($"Internal info count: {LoadedResolutionInfo.Count}");
            //foreach (ResolveInfo info in LoadedResolutionInfo)
            //    BepInLogger.Log($"Internal info: {info.ModID} : {info.Property} : {info.Slot}");

            //if (extInfo.Any())
            //{
            //    BepInLogger.Log($"External info count: {extInfo.Count()}");
            //    foreach (ResolveInfo info in extInfo)
            //        BepInLogger.Log($"External info: {info.ModID} : {info.Property} : {info.Slot}");
            //}

            foreach (var kv in propertyDict)
            {
                if (extInfo != null)
                {
                    var extResolve = extInfo.FirstOrDefault(x => x.Property == $"{propertyPrefix}{kv.Key.ToString()}");

                    if (extResolve != null)
                    {
                        //the property has external slot information
                        var intResolve = LoadedResolutionInfo.FirstOrDefault(x =>
                                                                             x.AppendPropertyPrefix(propertyPrefix).CanResolve(extResolve));

                        if (intResolve != null)
                        {
                            //found a match to a corrosponding internal mod
                            BepInLogger.Log(
                                $"[UAR] Resolving {extResolve.ModID}:{extResolve.Property} from slot {extResolve.Slot} to slot {intResolve.LocalSlot}");

                            kv.Value.SetMethod(structure, intResolve.LocalSlot);
                        }
                        else
                        {
                            //did not find a match, we don't have the mod
                            BepInLogger.Log($"[UAR] WARNING! Missing mod detected! [{extResolve.ModID}]", true,
                                            ConsoleColor.Yellow);

                            kv.Value.SetMethod(structure, 999999); //set to an invalid ID
                        }
                    }
                }
                else
                {
                    //check if it's a vanilla item
                    if (!ResourceRedirector.ListLoader.InternalDataList[kv.Key.Category]
                        .ContainsKey(kv.Value.GetMethod(structure)))
                    {
                        //the property does not have external slot information
                        //check if we have a corrosponding item for backwards compatbility
                        var intResolve = LoadedResolutionInfo.FirstOrDefault(x => x.Property == kv.Key.ToString() &&
                                                                             x.Slot == kv.Value.GetMethod(structure));

                        if (intResolve != null)
                        {
                            //found a match
                            BepInLogger.Log($"[UAR] Compatibility resolving {intResolve.Property} from slot {kv.Value.GetMethod(structure)} to slot {intResolve.LocalSlot}");

                            kv.Value.SetMethod(structure, intResolve.LocalSlot);
                        }
                        //otherwise ignore if not found
                    }
                    else
                    {
                        //not resolving since we prioritize vanilla items over modded items
                        //BepInLogger.Log($"[UAR] Not resolving item due to vanilla ID range");
                        //log commented out because it causes too much spam
                    }
                }
            }
        }
        public static AssetBundleLoadAssetOperation HandleAsset(string assetBundleName, string assetName, Type type, string manifestAssetBundleName, ref AssetBundleLoadAssetOperation __result)
        {
            foreach (var handler in AssetResolvers)
            {
                try
                {
                    if (handler.Invoke(assetBundleName, assetName, type, manifestAssetBundleName, out AssetBundleLoadAssetOperation result))
                    {
                        return(result);
                    }
                }
                catch (Exception ex)
                {
                    BepInLogger.Log(ex.ToString());
                }
            }

            //emulate asset load
            string dir = Path.Combine(EmulatedDir, assetBundleName.Replace('/', '\\').Replace(".unity3d", ""));

            if (Directory.Exists(dir))
            {
                if (type == typeof(Texture2D))
                {
                    string path = Path.Combine(dir, $"{assetName}.png");

                    if (!File.Exists(path))
                    {
                        return(__result);
                    }

                    BepInLogger.Log($"Loading emulated asset {path}");

                    var tex = AssetLoader.LoadTexture(path);

                    if (path.Contains("clamp"))
                    {
                        tex.wrapMode = TextureWrapMode.Clamp;
                    }
                    else if (path.Contains("repeat"))
                    {
                        tex.wrapMode = TextureWrapMode.Repeat;
                    }


                    return(new AssetBundleLoadAssetOperationSimulation(tex));
                }
                else if (type == typeof(AudioClip))
                {
                    string path = Path.Combine(dir, $"{assetName}.wav");

                    if (!File.Exists(path))
                    {
                        return(__result);
                    }

                    BepInLogger.Log($"Loading emulated asset {path}");

                    return(new AssetBundleLoadAssetOperationSimulation(AssetLoader.LoadAudioClip(path, AudioType.WAV)));
                }
            }

            string emulatedPath = Path.Combine(EmulatedDir, assetBundleName.Replace('/', '\\'));

            if (File.Exists(emulatedPath))
            {
                if (!EmulatedAssetBundles.TryGetValue(emulatedPath, out AssetBundle bundle))
                {
                    bundle = AssetBundle.LoadFromFile(emulatedPath);

                    EmulatedAssetBundles[emulatedPath] = bundle;
                }

                return(new AssetBundleLoadAssetOperationSimulation(bundle.LoadAsset(assetName)));
            }

            //otherwise return normal asset
            return(__result);
        }
Beispiel #8
0
        public static void ResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, ChaFile save)
        {
            //BepInLogger.Log($"Tried to resolve structure: {structure.GetType().Name}");

            var extData = ExtendedSave.GetExtendedDataById(save, UARExtID);

            if (extData == null || !extData.data.ContainsKey("info"))
            {
                //BepInLogger.Log($"No info to load!");
                return;
            }

            var tmpExtInfo = (object[])extData.data["info"];
            var extInfo    = tmpExtInfo.Select(x => ResolveInfo.Unserialize((byte[])x));

            //BepInLogger.Log($"Internal info count: {LoadedResolutionInfo.Count}");
            //foreach (ResolveInfo info in LoadedResolutionInfo)
            //    BepInLogger.Log($"Internal info: {info.ModID} : {info.Property} : {info.Slot}");

            //BepInLogger.Log($"External info count: {extInfo.Count()}");
            //foreach (ResolveInfo info in extInfo)
            //    BepInLogger.Log($"External info: {info.ModID} : {info.Property} : {info.Slot}");


            foreach (var kv in propertyDict)
            {
                var extResolve = extInfo.FirstOrDefault(x => x.Property == kv.Key.ToString());

                if (extResolve != null)
                {
                    //the property has external slot information
                    var intResolve = LoadedResolutionInfo.FirstOrDefault(x => x.CanResolve(extResolve));

                    if (intResolve != null)
                    {
                        //found a match to a corrosponding internal mod
                        BepInLogger.Log($"[UAR] Resolving {extResolve.ModID}:{extResolve.Property} from slot {extResolve.Slot} to slot {intResolve.LocalSlot}");

                        kv.Value.SetMethod(structure, intResolve.LocalSlot);
                    }
                    else
                    {
                        //did not find a match, we don't have the mod
                        BepInLogger.Log($"[UAR] WARNING! Missing mod detected! [{extResolve.ModID}]", true);

                        kv.Value.SetMethod(structure, 999999); //set to an invalid ID
                    }
                }
                else
                {
                    //the property does not have external slot information
                    //check if we have a corrosponding item for backwards compatbility
                    var intResolve = LoadedResolutionInfo.FirstOrDefault(x => x.Property == kv.Key.ToString() &&
                                                                         x.Slot == kv.Value.GetMethod(structure));

                    if (intResolve != null)
                    {
                        //found a match
                        BepInLogger.Log($"[UAR] Compatibility resolving {intResolve.Property} from slot {kv.Value.GetMethod(structure)} to slot {intResolve.LocalSlot}");

                        kv.Value.SetMethod(structure, intResolve.LocalSlot);
                    }
                    //otherwise ignore if not found
                }
            }
        }