internal static void ExtendedCardLoad(ChaFile file)
            {
                Sideloader.Logger.LogDebug($"Loading card [{file.charaFileName}]");

                var extData = ExtendedSave.GetExtendedDataById(file, UARExtIDOld) ?? ExtendedSave.GetExtendedDataById(file, UARExtID);
                List <ResolveInfo> extInfo;

                if (extData == null || !extData.data.ContainsKey("info"))
                {
                    Sideloader.Logger.LogDebug("No sideloader marker found");
                    extInfo = null;
                }
                else
                {
                    var tmpExtInfo = (object[])extData.data["info"];
                    extInfo = tmpExtInfo.Select(x => ResolveInfo.Deserialize((byte[])x)).ToList();

                    Sideloader.Logger.LogDebug($"Sideloader marker found, external info count: {extInfo.Count}");

                    if (Sideloader.DebugLogging.Value)
                    {
                        foreach (ResolveInfo info in extInfo)
                        {
                            Sideloader.Logger.LogDebug($"External info: {info.GUID} : {info.Property} : {info.Slot}");
                        }
                    }
                }

                IterateCardPrefixes(ResolveStructure, file, extInfo);
            }
 internal static void XMLReadPostfix(Control __instance)
 {
     foreach (Data data in __instance.Datas)
     {
         if (data is Config.EtceteraSystem etceteraSystem)
         {
             if (etceteraSystem.rampId >= BaseSlotID) //Saved with a resolved ID, reset it to default
             {
                 etceteraSystem.rampId = 1;
             }
             else
             {
                 var    xmlDoc   = XDocument.Load("UserData/config/system.xml");
                 string rampGUID = xmlDoc.Element("System").Element("Etc").Element("rampGUID")?.Value;
                 if (!rampGUID.IsNullOrWhiteSpace())
                 {
                     ResolveInfo RampResolveInfo = LoadedResolutionInfo.FirstOrDefault(x => x.Property == "Ramp" && x.GUID == rampGUID && x.Slot == etceteraSystem.rampId);
                     if (RampResolveInfo == null) //Missing mod, reset ID to default
                     {
                         etceteraSystem.rampId = 1;
                     }
                     else //Restore the resolved ID
                     {
                         etceteraSystem.rampId = RampResolveInfo.LocalSlot;
                     }
                 }
             }
         }
     }
 }
Example #3
0
        private static void ExtendedCardLoad(ChaFile file)
        {
            Logger.Log(LogLevel.Debug, $"Loading card [{file.charaFileName}]");

            var extData = ExtendedSave.GetExtendedDataById(file, UniversalAutoResolver.UARExtID);
            List <ResolveInfo> extInfo;

            if (extData == null || !extData.data.ContainsKey("info"))
            {
                Logger.Log(LogLevel.Debug, "No sideloader marker found");
                extInfo = null;
            }
            else
            {
                var tmpExtInfo = (object[])extData.data["info"];
                extInfo = tmpExtInfo.Select(x => ResolveInfo.Unserialize((byte[])x)).ToList();

                Logger.Log(LogLevel.Debug, "Sideloader marker found");
                Logger.Log(LogLevel.Debug, $"External info count: {extInfo.Count}");
                foreach (ResolveInfo info in extInfo)
                {
                    Logger.Log(LogLevel.Debug, $"External info: {info.GUID} : {info.Property} : {info.Slot}");
                }
            }

            IterateCardPrefixes(UniversalAutoResolver.ResolveStructure, file, extInfo);
        }
 internal static void XMLWritePrefix(Control __instance, ref int __state)
 {
     __state = -1;
     foreach (Data data in __instance.Datas)
     {
         if (data is Config.EtceteraSystem etceteraSystem)
         {
             if (etceteraSystem.rampId >= BaseSlotID)
             {
                 ResolveInfo RampResolveInfo = LoadedResolutionInfo.FirstOrDefault(x => x.Property == "Ramp" && x.LocalSlot == etceteraSystem.rampId);
                 if (RampResolveInfo == null)
                 {
                     //ID is a sideloader ID but no resolve info found, set it to the default
                     __state = 1;
                     etceteraSystem.rampId = 1;
                 }
                 else
                 {
                     //Switch out the resolved ID for the original
                     __state = etceteraSystem.rampId;
                     etceteraSystem.rampId = RampResolveInfo.Slot;
                 }
             }
         }
     }
 }
Example #5
0
        internal static void ResolveStudioRamp(ExtensibleSaveFormat.PluginData extData, ResolveType resolveType)
        {
#if KK
            //Set ramp ID to the resolved ID
            int rampID = Studio.Studio.Instance.sceneInfo.rampG;

            if (extData != null && extData.data.ContainsKey("rampInfoGUID"))
            {
                string rampGUID = (string)extData.data["rampInfoGUID"];

                ResolveInfo intResolve = LoadedResolutionInfo.FirstOrDefault(x => x.Property == "Ramp" && x.GUID == rampGUID && x.Slot == rampID);
                if (intResolve != null)
                {
                    if (resolveType == ResolveType.Load && Sideloader.DebugLogging.Value)
                    {
                        Sideloader.Logger.LogDebug($"Resolving (Studio Ramp) [{rampID}] {rampID}->{intResolve.LocalSlot}");
                    }

                    Studio.Studio.Instance.sceneInfo.rampG = intResolve.LocalSlot;
                }
                else
                {
                    ShowGUIDError(rampGUID);
                }
            }
            else if (resolveType == ResolveType.Load)
            {
                if (!Lists.InternalDataList[ChaListDefine.CategoryNo.mt_ramp].ContainsKey(rampID))
                {
                    //Ramp ID saved to the scene doesn't exist in the items list, try compatibility resolving
                    ResolveInfo intResolve = LoadedResolutionInfo.FirstOrDefault(x => x.Property == "Ramp" && x.Slot == rampID);
                    if (intResolve != null)
                    {
                        //Found a matching sideloader mod
                        if (Sideloader.DebugLogging.Value)
                        {
                            Sideloader.Logger.LogDebug($"Compatibility resolving (Studio Ramp) {rampID}->{intResolve.LocalSlot}");
                        }
                        Studio.Studio.Instance.sceneInfo.rampG = intResolve.LocalSlot;
                    }
                    else
                    {
                        Sideloader.Logger.Log(BepInEx.Logging.LogLevel.Warning | BepInEx.Logging.LogLevel.Message, $"[UAR] Compatibility resolving (Studio Ramp) failed, no match found for ID {rampID}");
                    }
                }
            }
#endif
        }
Example #6
0
            internal static void ExtendedCardLoad(ChaFile file)
            {
                string cardName = file.charaFileName;

                if (cardName.IsNullOrEmpty())
                {
                    cardName = file.parameter?.fullname?.Trim();
                }
                Sideloader.Logger.LogDebug($"Loading card [{cardName}]");

                var extData = ExtendedSave.GetExtendedDataById(file, UARExtIDOld) ?? ExtendedSave.GetExtendedDataById(file, UARExtID);
                List <ResolveInfo> extInfo;

                if (extData == null || !extData.data.ContainsKey("info"))
                {
                    Sideloader.Logger.LogDebug("No sideloader marker found");
                    extInfo = null;
                }
                else
                {
                    var tmpExtInfo = (object[])extData.data["info"];
                    extInfo = tmpExtInfo.Select(x => ResolveInfo.Deserialize((byte[])x)).ToList();

                    Sideloader.Logger.LogDebug($"Sideloader marker found, external info count: {extInfo.Count}");

                    if (Sideloader.DebugLogging.Value)
                    {
                        foreach (ResolveInfo info in extInfo)
                        {
                            Sideloader.Logger.LogDebug($"External info: {info.GUID} : {info.Property} : {info.Slot}");
                        }
                    }
                }

                IterateCardPrefixes(ResolveStructure, file, extInfo);

#if AI || HS2
                //Resolve the bundleID to the same ID as the hair
                foreach (var hairPart in file.custom.hair.parts)
                {
                    if (hairPart.id > BaseSlotID)
                    {
                        hairPart.bundleId = hairPart.id;
                    }
                }
#endif
            }
            internal static void SceneInfoInit(SceneInfo __instance)
            {
                var    xmlDoc    = XDocument.Load("UserData/config/system.xml");
                string rampGUID  = xmlDoc.Element("System").Element("Etc").Element("rampGUID")?.Value;
                string rampIDXML = xmlDoc.Element("System").Element("Etc").Element("rampId")?.Value;

                if (!rampGUID.IsNullOrWhiteSpace() && !rampIDXML.IsNullOrWhiteSpace() && int.TryParse(rampIDXML, out int rampID))
                {
                    ResolveInfo RampResolveInfo = LoadedResolutionInfo.FirstOrDefault(x => x.Property == "Ramp" && x.GUID == rampGUID && x.Slot == rampID);
                    if (RampResolveInfo == null) //Missing mod, reset ID to default
                    {
                        __instance.rampG = 1;
                    }
                    else //Restore the resolved ID
                    {
                        __instance.rampG = RampResolveInfo.LocalSlot;
                    }
                }
            }
Example #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)
                {
                    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);
                    }
                }
            }
        }
            internal static void XMLWritePostfix(Control __instance, ref int __state)
            {
                int rampId = __state;

                if (rampId >= BaseSlotID)
                {
                    foreach (Data data in __instance.Datas)
                    {
                        if (data is Config.EtceteraSystem etceteraSystem)
                        {
                            ResolveInfo RampResolveInfo = LoadedResolutionInfo.FirstOrDefault(x => x.Property == "Ramp" && x.LocalSlot == rampId);
                            if (RampResolveInfo != null)
                            {
                                //Restore the resolved ID
                                etceteraSystem.rampId = RampResolveInfo.LocalSlot;

                                var xmlDoc = XDocument.Load("UserData/config/system.xml");
                                xmlDoc.Element("System").Element("Etc").Element("rampId").AddAfterSelf(new XElement("rampGUID", RampResolveInfo.GUID));
                                xmlDoc.Save("UserData/config/system.xml");
                            }
                        }
                    }
                }
            }
Example #10
0
        internal static void MigrateData(ResolveInfo extResolve, ChaListDefine.CategoryNo categoryNo)
        {
            if (extResolve.GUID.IsNullOrWhiteSpace())
            {
                return;
            }

            var migrationInfoList = GetMigrationInfo(extResolve.GUID);

            if (migrationInfoList.Any(x => x.MigrationType == MigrationType.StripAll))
            {
                extResolve.GUID = "";
                return;
            }

            foreach (var migrationInfo in migrationInfoList.Where(x => x.MigrationType == MigrationType.MigrateAll))
            {
                if (Sideloader.GetManifest(migrationInfo.GUIDNew) != null)
                {
                    Sideloader.Logger.LogInfo($"Migrating GUID {migrationInfo.GUIDOld} -> {migrationInfo.GUIDNew}");
                    extResolve.GUID = migrationInfo.GUIDNew;
                    return;
                }
            }

            foreach (var migrationInfo in migrationInfoList.Where(x => x.IDOld == extResolve.Slot && categoryNo == extResolve.CategoryNo))
            {
                if (Sideloader.GetManifest(migrationInfo.GUIDNew) != null)
                {
                    Sideloader.Logger.LogInfo($"Migrating {migrationInfo.GUIDOld}:{migrationInfo.IDOld} -> {migrationInfo.GUIDNew}:{migrationInfo.IDNew}");
                    extResolve.GUID = migrationInfo.GUIDNew;
                    extResolve.Slot = migrationInfo.IDNew;
                    return;
                }
            }
        }
Example #11
0
 public bool CanResolve(ResolveInfo other) => GUID == other.GUID && Property == other.Property && Slot == other.Slot;
Example #12
0
        /// <summary>
        /// Change the ID of items saved to a card to their resolved IDs
        /// </summary>
        internal static void ResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, ICollection <ResolveInfo> extInfo, string propertyPrefix = "")
        {
            foreach (var kv in propertyDict)
            {
                string property = $"{propertyPrefix}{kv.Key}";

                //For accessories, make sure we're checking the appropriate category
                if (kv.Key.Category.ToString().Contains("ao_"))
                {
                    ChaFileAccessory.PartsInfo AccessoryInfo = (ChaFileAccessory.PartsInfo)structure;

                    if ((int)kv.Key.Category != AccessoryInfo.type)
                    {
                        //If the current category does not match the category saved to the card do not attempt resolving
                        continue;
                    }
                }

                ResolveInfo extResolve = extInfo?.FirstOrDefault(x => x.Property == property);
                if (extResolve == null)
                {
                    CompatibilityResolve(kv, structure);
                    continue;
                }

                if (Sideloader.MigrationEnabled.Value)
                {
                    MigrateData(extResolve, kv.Key.Category);
                }

                //If the GUID is blank or has been made blank by migration do compatibility resolve
                if (extResolve.GUID.IsNullOrWhiteSpace())
                {
                    CompatibilityResolve(kv, structure);
                    continue;
                }

                //the property has external slot information
                var intResolve = TryGetResolutionInfo(extResolve.Slot, kv.Key.ToString(), kv.Key.Category, extResolve.GUID);

                if (intResolve != null)
                {
                    //found a match to a corrosponding internal mod
                    if (Sideloader.DebugLogging.Value)
                    {
                        Sideloader.Logger.LogDebug($"Resolving {extResolve.GUID}:{extResolve.Property} from slot {extResolve.Slot} to slot {intResolve.LocalSlot}");
                    }
                    kv.Value.SetMethod(structure, intResolve.LocalSlot);
                }
                else
                {
#if KK || EC
                    if (Lists.InternalDataList[kv.Key.Category].ContainsKey(kv.Value.GetMethod(structure)))
#elif AI || HS2
                    if (Lists.InternalDataList[(int)kv.Key.Category].ContainsKey(kv.Value.GetMethod(structure)))
#endif
                    {
#if KK || EC
                        string mainAB = Lists.InternalDataList[kv.Key.Category][kv.Value.GetMethod(structure)].dictInfo[(int)ChaListDefine.KeyType.MainAB];
#elif AI || HS2
                        string mainAB = Lists.InternalDataList[(int)kv.Key.Category][kv.Value.GetMethod(structure)].dictInfo[(int)ChaListDefine.KeyType.MainAB];
#endif
                        mainAB = mainAB.Replace("chara/", "").Replace(".unity3d", "").Replace(kv.Key.Category.ToString() + "_", "").Replace("/", "");

                        if (int.TryParse(mainAB, out int x))
                        {
                            //ID found but it conflicts with a vanilla item. Change the ID to avoid conflicts.
                            ShowGUIDError(extResolve.GUID);
                            if (kv.Key.Category.ToString().Contains("ao_") && Sideloader.KeepMissingAccessories.Value && GetNowSceneNames().Any(sceneName => sceneName == "CustomScene"))
                            {
                                kv.Value.SetMethod(structure, 1);
                            }
                            else
                            {
                                kv.Value.SetMethod(structure, BaseSlotID - 1);
                            }
                        }
                        else
                        {
                            //ID found and it does not conflict with a vanilla item, likely the user has a hard mod version of the mod installed
                            Sideloader.Logger.LogDebug($"Missing mod detected [{extResolve.GUID}] but matching ID found");
                        }
                    }
                    else
                    {
                        //ID not found. Change the ID to avoid potential future conflicts.
                        ShowGUIDError(extResolve.GUID);
                        if (kv.Key.Category.ToString().Contains("ao_") && Sideloader.KeepMissingAccessories.Value && GetNowSceneNames().Any(sceneName => sceneName == "CustomScene"))
                        {
                            kv.Value.SetMethod(structure, 1);
                        }
                        else
                        {
                            kv.Value.SetMethod(structure, BaseSlotID - 1);
                        }
                    }
                }
            }
        }
Example #13
0
        private static void ExtendedCoordinateImport(Dictionary <string, PluginData> importedExtendedData)
        {
            if (importedExtendedData.TryGetValue(UniversalAutoResolver.UARExtID, out var pluginData))
            {
                if (pluginData != null && pluginData.data.ContainsKey("info"))
                {
                    var tmpExtInfo = (object[])pluginData.data["info"];
                    var extInfo    = tmpExtInfo.Select(x => ResolveInfo.Deserialize((byte[])x)).ToList();

                    for (int i = 0; i < extInfo.Count;)
                    {
                        Sideloader.Logger.Log(LogLevel.Debug, $"External info: {extInfo[i].GUID} : {extInfo[i].Property} : {extInfo[i].Slot} : {extInfo[i].CategoryNo}");
                        if (extInfo[i].Property.EndsWith("ClothesShoesInner"))
                        {
                            //KK had inner shoes, EC does not
                            extInfo.RemoveAt(i);
                        }
                        else
                        {
                            extInfo[i].Property = extInfo[i].Property.Replace("outfit0", "outfit");

                            //KK originally had only one emblem
                            if (extInfo[i].Property.EndsWith("Emblem"))
                            {
                                extInfo[i].Property += "0";
                            }

                            //KK has multiple shoes slots, convert to one shoes slot
                            extInfo[i].Property = extInfo[i].Property.Replace("ClothesShoesOuter", "ClothesShoes");

                            i++;
                        }
                    }

                    importedExtendedData[UniversalAutoResolver.UARExtID] = new PluginData
                    {
                        data = new Dictionary <string, object>
                        {
                            ["info"] = extInfo.Select(x => x.Serialize()).ToList()
                        }
                    };
                }
            }

            if (Sideloader.DebugLogging.Value && importedExtendedData.TryGetValue(UniversalAutoResolver.UARExtID, out var extData))
            {
                if (extData == null || !extData.data.ContainsKey("info"))
                {
                    Sideloader.Logger.Log(LogLevel.Debug, "Imported coordinate data: No sideloader marker found");
                }
                else
                {
                    var tmpExtInfo = (List <byte[]>)extData.data["info"];
                    var extInfo    = tmpExtInfo.Select(ResolveInfo.Deserialize).ToList();

                    Sideloader.Logger.Log(LogLevel.Debug, $"Imported coordinate data: Sideloader marker found, external info count: {extInfo.Count}");

                    foreach (ResolveInfo info in extInfo)
                    {
                        Sideloader.Logger.Log(LogLevel.Debug, $"External info: {info.GUID} : {info.Property} : {info.Slot} : {info.CategoryNo}");
                    }
                }
            }
        }
        public static void ResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, ChaFile save, string propertyPrefix = "")
        {
            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 != null && extInfo.Any())
            {
                Logger.Log(LogLevel.Debug, $"External info count: {extInfo.Count()}");
                foreach (ResolveInfo info in extInfo)
                {
                    Logger.Log(LogLevel.Debug, $"External info: {info.GUID} : {info.Property} : {info.Slot}");
                }
            }

            void CompatibilityResolve(KeyValuePair <CategoryProperty, StructValue <int> > kv)
            {
                //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
                        Logger.Log(LogLevel.Info, $"[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
                }
            }

            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
                            Logger.Log(LogLevel.Info, $"[UAR] Resolving {extResolve.GUID}:{extResolve.Property} from slot {extResolve.Slot} to slot {intResolve.LocalSlot}");

                            kv.Value.SetMethod(structure, intResolve.LocalSlot);
                        }
                        else
                        {
                            //we didn't find a match, check if we have the same GUID loaded

                            if (LoadedResolutionInfo.Any(x => x.GUID == extResolve.GUID))
                            {
                                //we have the GUID loaded, so the user has an outdated mod
                                Logger.Log(LogLevel.Warning | LogLevel.Message, $"[UAR] WARNING! ({save.parameter.lastname} {save.parameter.firstname}) Outdated mod detected! [{extResolve.GUID}]");
                            }
                            else
                            {
                                //did not find a match, we don't have the mod
                                Logger.Log(LogLevel.Warning | LogLevel.Message, $"[UAR] WARNING! ({save.parameter.lastname} {save.parameter.firstname}) Missing mod detected! [{extResolve.GUID}]");
                            }

                            kv.Value.SetMethod(structure, 999999);     //set to an invalid ID
                        }
                    }
                    else if (UnityEngine.Event.current.alt)
                    {
                        CompatibilityResolve(kv);
                    }
                }
                else
                {
                    CompatibilityResolve(kv);
                }
            }
        }
        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
                    }
                }
            }
        }
Example #16
0
 public bool CanResolve(ResolveInfo other) => GUID == other.GUID && Slot == other.Slot;
Example #17
0
 public bool CanResolve(ResolveInfo other)
 {
     return(GUID == other.GUID && Slot == other.Slot);
 }
Example #18
0
            private static void ChaFileSaveFilePostHook(ChaFile __instance)
            {
                if (DoingImport)
                {
                    return;
                }

                string cardName = __instance.charaFileName;

                if (cardName.IsNullOrEmpty())
                {
                    cardName = __instance.parameter?.fullname?.Trim();
                }
                Sideloader.Logger.LogDebug($"Reloading card [{cardName}]");

                var extData = ExtendedSave.GetExtendedDataById(__instance, UARExtIDOld) ?? ExtendedSave.GetExtendedDataById(__instance, UARExtID);

                // Some old ChaFile cards has object[] for "info"

                List <ResolveInfo> extInfo;

                if (extData.data["info"] is List <byte[]> lstByte)
                {
                    extInfo = lstByte.Select(ResolveInfo.Deserialize).ToList();
                }
                else if (extData.data["info"] is object[] objArray)
                {
                    extInfo = objArray.Select(x => ResolveInfo.Deserialize((byte[])x)).ToList();
                }
                else
                {
                    Sideloader.Logger.LogError("Unknown data type:" + (extData.data["info"]).GetType());
                    return;
                }

                Sideloader.Logger.LogDebug($"External info count: {extInfo.Count}");

                if (Sideloader.DebugLogging.Value)
                {
                    foreach (ResolveInfo info in extInfo)
                    {
                        Sideloader.Logger.LogDebug($"External info: {info.GUID} : {info.Property} : {info.Slot}");
                    }
                }

                void ResetStructResolveStructure(Dictionary <CategoryProperty, StructValue <int> > propertyDict, object structure, IEnumerable <ResolveInfo> extInfo2, string propertyPrefix = "")
                {
                    foreach (var kv in propertyDict)
                    {
                        var extResolve = extInfo.FirstOrDefault(x => x.Property == $"{propertyPrefix}{kv.Key}");

                        if (extResolve != null)
                        {
                            kv.Value.SetMethod(structure, extResolve.LocalSlot);
                        }
                    }
                }

                IterateCardPrefixes(ResetStructResolveStructure, __instance, extInfo);

#if AI || HS2
                //Resolve the bundleID to the same ID as the hair
                foreach (var hairPart in __instance.custom.hair.parts)
                {
                    if (hairPart.id > BaseSlotID)
                    {
                        hairPart.bundleId = hairPart.id;
                    }
                }
#endif
            }
Example #19
0
 public bool CanResolve(ResolveInfo other)
 {
     return(ModID == other.ModID &&
            Property == other.Property &&
            Slot == other.Slot);
 }
Example #20
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
                }
            }
        }