Beispiel #1
0
        private static IEnumerator DoubleTapInterval()
        {
            yield return(new WaitForSeconds(interval));

            clicks = 0;
            BepInLogger.Log("Double-click expired", true);
        }
Beispiel #2
0
        protected void LoadAllUnityArchives(ZipFile arc)
        {
            foreach (ZipEntry entry in arc)
            {
                if (entry.Name.EndsWith(".unity3d"))
                {
                    string assetBundlePath = entry.Name;

                    if (assetBundlePath.Contains('/'))
                    {
                        assetBundlePath = assetBundlePath.Remove(0, assetBundlePath.IndexOf('/') + 1);
                    }

                    Func <AssetBundle> getBundleFunc = () =>
                    {
                        var stream = arc.GetInputStream(entry);

                        byte[] buffer = new byte[entry.Size];

                        stream.Read(buffer, 0, (int)entry.Size);

                        BundleManager.RandomizeCAB(buffer);

                        return(AssetBundle.LoadFromMemory(buffer));
                    };

                    BundleManager.AddBundleLoader(getBundleFunc, assetBundlePath, out string warning);

                    if (!string.IsNullOrEmpty(warning))
                    {
                        BepInLogger.Log($"[SIDELOADER] WARNING! {warning}");
                    }
                }
            }
        }
Beispiel #3
0
        private void OnDroppedFiles(List <string> aFiles, POINT aPos)
        {
            if (aFiles.Count == 0)
            {
                return;
            }
            var path = aFiles[0];

            if (path == null)
            {
                return;
            }

            if (Singleton <CustomBase> .IsInstance())
            {
                try
                {
                    LoadCharacter(path);
                    Utils.Sound.Play(SystemSE.ok_s);
                }
                catch (Exception ex)
                {
                    BepInLogger.Log("Character load failed", true);
                    BepInLogger.Log(ex.ToString());
                    Utils.Sound.Play(SystemSE.ok_l);
                }
            }
        }
Beispiel #4
0
        private void LoadCharacter(string path)
        {
            if (path == null)
            {
                throw new ArgumentNullException(nameof(path));
            }

            var chaCtrl = Singleton <CustomBase> .Instance.chaCtrl;
            var chaFile = chaCtrl.chaFile;

            var originalSex = chaCtrl.sex;

            if (!chaFile.LoadCharaFile(path, chaCtrl.sex))
            {
                throw new IOException();
            }
            if (chaFile.parameter.sex != originalSex)
            {
                chaFile.parameter.sex = originalSex;
                BepInLogger.Log("Warning: The character's sex has been altered to match the editor mode.", true);
            }
            chaCtrl.ChangeCoordinateType(true);
            chaCtrl.Reload();
            Singleton <CustomBase> .Instance.updateCustomUI = true;
            Singleton <CustomHistory> .Instance.Add5(chaCtrl, chaCtrl.Reload, false, false, false, false);
        }
Beispiel #5
0
        private static void Postfix(DownloadScene __instance)
        {
            //BepInLogger.Log("DownloadScene Update", true);
            if (!Input.GetMouseButtonDown(0))
            {
                return;
            }

            clicks++;
            if (clicks == 1)
            {
                BepInLogger.Log("Single-clicked", true);
                doubleTapCoroutine = __instance.StartCoroutine(DoubleTapInterval());
            }
            else if (clicks > 1)
            {
                // IDEA: should it set to 0 or a lower number like -3 and don't StopCoroutine, that way rapid clicks
                // don't double click more than once but if it reset it still works fine..
                clicks = 0;
                __instance.StopCoroutine(doubleTapCoroutine);
                if (__instance.btnDownload.interactable)
                {
                    BepInLogger.Log("Double-clicked, DLing", true);
                    __instance.btnDownload.OnPointerClick(new PointerEventData(null));
                }
                else
                {
                    BepInLogger.Log("Double-clicked, but there is nothing to download", true);
                }
            }
        }
Beispiel #6
0
        public static bool HandleAsset(string assetBundleName, string assetName, Type type, string manifestAssetBundleName, out AssetBundleLoadAssetOperation result)
        {
            if (assetName.StartsWith("bgm") && assetName.Length > 4)
            {
                string path;

                switch ((BGM)int.Parse(assetName.Remove(0, 4)))
                {
                case BGM.Title:
                default:
                    path = $"{BepInEx.Common.Utility.PluginsDirectory}\\title.wav";
                    break;

                case BGM.Custom:
                    path = $"{BepInEx.Common.Utility.PluginsDirectory}\\custom.wav";
                    break;
                }

                if (File.Exists(path))
                {
                    BepInLogger.Log($"Loading {path}");

                    result = new AssetBundleLoadAssetOperationSimulation(AssetLoader.LoadAudioClip(path, AudioType.WAV));

                    return(true);
                }
            }

            result = null;
            return(false);
        }
Beispiel #7
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;
                }

                if (LoadedManifests.Any(x => x.GUID == manifest.GUID))
                {
                    BepInLogger.Log($"[SIDELOADER] Skipping {Path.GetFileName(archivePath)} due to duplicate GUID \"{manifest.GUID}\".");
                    continue;
                }

                string name = !string.IsNullOrEmpty(manifest.Name.Trim())
                    ? manifest.Name
                    : Path.GetFileName(archivePath);

                BepInLogger.Log($"[SIDELOADER] Loaded {name} {manifest.Version ?? ""}");

                Archives.Add(archive);
                LoadedManifests.Add(manifest);

                LoadAllUnityArchives(archive);

                LoadAllLists(archive, manifest);
            }
        }
Beispiel #8
0
        void Start()
        {
            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);
        }
 void Update()
 {
     if (UnityEngine.Input.GetKeyDown(UnityEngine.KeyCode.F10))
     {
         Dump();
         BepInLogger.Log($"Text dumped to \"{Path.GetFullPath("dumped-tl.txt")}\"", true);
     }
 }
Beispiel #10
0
 public static void InstallHooks()
 {
     try
     {
         var harmony = HarmonyInstance.Create("info.jbcs.koikatsu.demosaic");
         harmony.PatchAll(typeof(Hooks));
     }
     catch (Exception e)
     {
         BepInLogger.Log(e.ToString(), false);
     }
 }
Beispiel #11
0
 void Update()
 {
     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);
     }
 }
        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 { }
            }

            //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}");

                    return(new AssetBundleLoadAssetOperationSimulation(AssetLoader.LoadTexture(path)));
                }
                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)));
                }
            }

            //otherwise return normal asset
            return(__result);
        }
Beispiel #13
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 #14
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 #15
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 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 #17
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
                }
            }
        }
        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
                    }
                }
            }
        }