internal static void LoadXML(XDocument manifestDocument, bool isDevelopment) { { var heelDatas = manifestDocument?.Root?.Element("AI_HeelsData")?.Elements("heel"); var guid = manifestDocument?.Root?.Element("guid").Value; if (heelDatas != null) { foreach (var element in heelDatas) { var heelID = int.Parse(element.Attribute("id")?.Value); var resolvedID = UniversalAutoResolver.TryGetResolutionInfo(heelID, "ChaFileClothes.ClothesShoes", guid); if (resolvedID != null) { Util.Logger.Log(string.Format("Found Resolved ID: \"{0}\"=>\"{1}\"", heelID, resolvedID.LocalSlot)); heelID = resolvedID.LocalSlot; } Values.configs.Remove(heelID); } } LoadXML(manifestDocument); } }
internal static bool CheckItemIDHook(int category, int id, ref byte __result) { if (id >= UniversalAutoResolver.BaseSlotID) { { ResolveInfo Info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)category, id); if (CheckItemList.TryGetValue(Info.GUID, out var x)) { if (x.TryGetValue(category, out var y)) { if (y.Contains(Info.Slot)) { __result = 2; //Not new return(false); } } } __result = 1; //New return(false); } } return(true); }
public CustomSelectListCtrlEventArgs(GameObject _gameObject) { CustomSelectInfoComponent _cmp = _gameObject.GetComponent <CustomSelectInfoComponent>(); if (_cmp == null || !_cmp.tgl.interactable) { return; } if (_cmp.info.index >= UniversalAutoResolver.BaseSlotID) { ResolveInfo _info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)_cmp.info.category, _cmp.info.index); if (_info != null) { CategoryNo = (int)_info.CategoryNo; GUID = _info.GUID; ItemID = _info.LocalSlot; LocalItemID = _info.Slot; } } else { CategoryNo = _cmp.info.category; ItemID = _cmp.info.index; LocalItemID = -1; } }
internal void Backup() { int _coordinateIndex = ChaControl.fileStatus.coordinateType; List <ChaFileAccessory.PartsInfo> _parts = MoreAccessoriesSupport.ListPartsInfo(ChaControl, _coordinateIndex); PartsInfo.Clear(); PartsResolveInfo.Clear(); for (int i = 0; i < _parts.Count; i++) { ChaFileAccessory.PartsInfo _part = MoreAccessoriesSupport.GetPartsInfo(ChaControl, _coordinateIndex, i); if (_part.type > 120) { byte[] _byte = MessagePackSerializer.Serialize(_part); PartsInfo[i] = MessagePackSerializer.Deserialize <ChaFileAccessory.PartsInfo>(_byte); PartsResolveInfo[i] = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)_part.type, _part.id); } } foreach (string _name in SupportList) { Traverse.Create(this).Field(_name).Method("Backup").GetValue(); } }
protected void LoadAllLists(ZipFile arc, Manifest manifest) { foreach (ZipEntry entry in arc) { if (entry.Name.StartsWith("abdata/list/characustom", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { var stream = arc.GetInputStream(entry); var chaListData = ListLoader.LoadCSV(stream); SetPossessNew(chaListData); UniversalAutoResolver.GenerateResolutionInfo(manifest, chaListData); IndexList(manifest, chaListData); ListLoader.ExternalDataList.Add(chaListData); if (LoadedData.TryGetValue(manifest, out lists)) { lists.Add(chaListData); } else { LoadedData[manifest] = new List <ChaListData> { chaListData }; } } } }
internal static void CustomSelectListCtrlPostfix(CustomSelectListCtrl __instance, GameObject obj) { if (null == obj) { return; } CustomSelectInfoComponent component = obj.GetComponent <CustomSelectInfoComponent>(); if (null == component) { return; } if (!component.tgl.interactable) { return; } if (__instance.onChangeItemFunc != null) { if (component.info.index >= UniversalAutoResolver.BaseSlotID) { ResolveInfo Info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)component.info.category, component.info.index); if (Info != null) { BepInEx.Logging.Logger.LogWarning($"[CustomSelectListCtrlPostfix][{Info.GUID}][{(int) Info.CategoryNo}][{Info.CategoryNo}][{Info.Slot}][{Info.LocalSlot}]"); } } else { BepInEx.Logging.Logger.LogWarning($"[CustomSelectListCtrlPostfix][hardmod][{(ChaListDefine.CategoryNo) component.info.category}][{component.info.category}][{component.info.index}]"); } } }
public static void Save() { var sceneInfo = Studio.Studio.Instance.sceneInfo; var systemButtonCtrl = Studio.Studio.Instance.systemButtonCtrl; if (sceneInfo != null && systemButtonCtrl != null) { _sceneData.aceNo = sceneInfo.aceNo; _sceneData.aceBlend = sceneInfo.aceBlend; var aceInfo = UniversalAutoResolver.LoadedStudioResolutionInfo.FirstOrDefault(x => x.ResolveItem && x.LocalSlot == sceneInfo.aceNo); if (aceInfo != null) { _sceneData.aceNo = aceInfo.Slot; _sceneData.aceNo_GUID = aceInfo.GUID; } var aoe = Traverse.Create(systemButtonCtrl).Field("amplifyOcculusionEffectInfo").Property("aoe").GetValue <AmplifyOcclusionEffect>(); _sceneData.enableAOE = (bool)aoe.GetType().GetProperty("enabled").GetValue(aoe, null); _sceneData.aoeColor = sceneInfo.aoeColor; _sceneData.aoeRadius = sceneInfo.aoeRadius; _sceneData.enableBloom = sceneInfo.enableBloom; _sceneData.bloomIntensity = sceneInfo.bloomIntensity; _sceneData.bloomThreshold = sceneInfo.bloomThreshold; _sceneData.bloomBlur = sceneInfo.bloomBlur; _sceneData.enableDepth = sceneInfo.enableDepth; _sceneData.depthFocalSize = sceneInfo.depthFocalSize; _sceneData.depthAperture = sceneInfo.depthAperture; _sceneData.enableVignette = sceneInfo.enableVignette; _sceneData.enableFog = sceneInfo.enableFog; _sceneData.fogColor = sceneInfo.fogColor; _sceneData.fogHeight = sceneInfo.fogHeight; _sceneData.fogStartDistance = sceneInfo.fogStartDistance; _sceneData.enableSunShafts = sceneInfo.enableSunShafts; _sceneData.sunThresholdColor = sceneInfo.sunThresholdColor; _sceneData.sunColor = sceneInfo.sunColor; var toggleEnable = Traverse.Create(systemButtonCtrl).Field("selfShadowInfo").Field("toggleEnable").GetValue <Toggle>(); _sceneData.enableShadow = (bool)toggleEnable.GetType().GetProperty("isOn").GetValue(toggleEnable, null); _sceneData.rampG = sceneInfo.rampG; var rampGInfo = UniversalAutoResolver.TryGetResolutionInfo(ChaListDefine.CategoryNo.mt_ramp, sceneInfo.rampG); if (rampGInfo != null) { _sceneData.rampG = rampGInfo.Slot; _sceneData.rampG_GUID = rampGInfo.GUID; } _sceneData.ambientShadowG = sceneInfo.ambientShadowG; _sceneData.lineWidthG = sceneInfo.lineWidthG; _sceneData.lineColorG = sceneInfo.lineColorG; _sceneData.ambientShadow = sceneInfo.ambientShadow; _sceneData.cameraNearClip = Camera.main.nearClipPlane; _sceneData.fov = Studio.Studio.Instance.cameraCtrl.fieldOfView; _sceneData.saved = true; Log.Message("Default scene settings saved"); } }
private static void LoadXML(XDocument manifestDocument, bool isDevelopment) { { var heelData = manifestDocument?.Root?.Element("AI_HeelsData")?.Elements("heel"); var guid = manifestDocument?.Root?.Element("guid")?.Value; if (heelData != null) { foreach (var element in heelData) { var heelID = int.Parse(element.Attribute("id")?.Value ?? string.Empty); var resolvedID = UniversalAutoResolver.TryGetResolutionInfo(heelID, "ChaFileClothes.ClothesShoes", guid); if (resolvedID != null) { Logger.Log($"Found Resolved ID: \"{heelID}\"=>\"{resolvedID.LocalSlot}\""); heelID = resolvedID.LocalSlot; } Values.Configs.Remove(heelID); } } LoadXML(manifestDocument); } }
private void UnblacklistMod(string guid) { List <CustomSelectInfo> lstSelectInfo = (List <CustomSelectInfo>)Traverse.Create(CustomSelectListCtrlInstance).Field("lstSelectInfo").GetValue(); bool changeFilter = false; for (var i = 0; i < lstSelectInfo.Count; i++) { CustomSelectInfo customSelectInfo = lstSelectInfo[i]; if (customSelectInfo.index >= UniversalAutoResolver.BaseSlotID) { ResolveInfo info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)customSelectInfo.category, customSelectInfo.index); if (info != null && info.GUID == guid) { if (!Blacklist.ContainsKey(info.GUID)) { Blacklist[info.GUID] = new Dictionary <int, HashSet <int> >(); } if (!Blacklist[info.GUID].ContainsKey(customSelectInfo.category)) { Blacklist[info.GUID][customSelectInfo.category] = new HashSet <int>(); } Blacklist[info.GUID][customSelectInfo.category].Remove(info.Slot); SaveBlacklist(); var controls = CustomBase.Instance.GetComponentsInChildren <CustomSelectListCtrl>(true); for (var j = 0; j < controls.Length; j++) { var customSelectListCtrl = controls[j]; if (customSelectListCtrl.GetSelectInfoFromIndex(customSelectInfo.index)?.category == customSelectInfo.category) { if (ListVisibility.TryGetValue(customSelectListCtrl, out var visibilityType)) { if (visibilityType == ListVisibilityType.Hidden) { customSelectListCtrl.DisvisibleItem(customSelectInfo.index, true); } } List <CustomSelectInfo> lstSelectInfo2 = (List <CustomSelectInfo>)Traverse.Create(customSelectListCtrl).Field("lstSelectInfo").GetValue(); if (lstSelectInfo2.All(x => x.disvisible)) { changeFilter = true; } } } } } } if (changeFilter) { ChangeListFilter(ListVisibilityType.Filtered); } SetMenuVisibility(false); }
private static void SetSceneInfoValues(SceneInfo sceneInfo) { sceneInfo.aceNo = _sceneData.aceNo; if (!string.IsNullOrEmpty(_sceneData.aceNo_GUID)) { var aceInfo = UniversalAutoResolver.LoadedStudioResolutionInfo.FirstOrDefault(x => x.GUID == _sceneData.aceNo_GUID && x.Slot == _sceneData.aceNo); if (aceInfo != null) { sceneInfo.aceNo = aceInfo.LocalSlot; } } sceneInfo.aceBlend = _sceneData.aceBlend; sceneInfo.enableAOE = _sceneData.enableAOE; sceneInfo.aoeColor = _sceneData.aoeColor; sceneInfo.aoeRadius = _sceneData.aoeRadius; sceneInfo.enableBloom = _sceneData.enableBloom; sceneInfo.bloomIntensity = _sceneData.bloomIntensity; sceneInfo.bloomThreshold = _sceneData.bloomThreshold; sceneInfo.bloomBlur = _sceneData.bloomBlur; sceneInfo.enableDepth = _sceneData.enableDepth; sceneInfo.depthFocalSize = _sceneData.depthFocalSize; sceneInfo.depthAperture = _sceneData.depthAperture; sceneInfo.enableVignette = _sceneData.enableVignette; sceneInfo.enableFog = _sceneData.enableFog; sceneInfo.fogColor = _sceneData.fogColor; sceneInfo.fogHeight = _sceneData.fogHeight; sceneInfo.fogStartDistance = _sceneData.fogStartDistance; sceneInfo.enableSunShafts = _sceneData.enableSunShafts; sceneInfo.sunThresholdColor = _sceneData.sunThresholdColor; sceneInfo.sunColor = _sceneData.sunColor; sceneInfo.enableShadow = _sceneData.enableShadow; sceneInfo.rampG = _sceneData.rampG; if (!string.IsNullOrEmpty(_sceneData.rampG_GUID)) { var rampGInfo = UniversalAutoResolver.TryGetResolutionInfo(_sceneData.rampG, ChaListDefine.CategoryNo.mt_ramp, _sceneData.rampG_GUID); if (rampGInfo != null) { sceneInfo.rampG = rampGInfo.LocalSlot; } } sceneInfo.ambientShadowG = _sceneData.ambientShadowG; sceneInfo.lineWidthG = _sceneData.lineWidthG; sceneInfo.lineColorG = _sceneData.lineColorG; sceneInfo.ambientShadow = _sceneData.ambientShadow; }
public static bool ItemMatchesSearch(CustomSelectInfo data, string searchStr) { var searchIn = ""; switch (HS2_MakerSearch.searchBy.Value) { case SearchBy.Name: searchIn = data.name; if (HS2_MakerSearch.useTranslatedCache.Value) { searchIn = searchNameStrings.TryGetValue(data, out var cachedTranslation) ? cachedTranslation : data.name; } break; case SearchBy.AssetBundle: searchIn = data.assetBundle; break; } if (data.id >= UniversalAutoResolver.BaseSlotID) { ResolveInfo info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)data.category, data.id); if (info != null) { Manifest manifest = Sideloader.Sideloader.GetManifest(info.GUID); if (manifest.Author != null) { searchIn = searchIn + " " + manifest.Author; } } } var rule = StringComparison.Ordinal; if (!HS2_MakerSearch.caseSensitive.Value) { searchStr = searchStr.ToLowerInvariant(); rule = StringComparison.OrdinalIgnoreCase; } var splitSearchStr = searchStr.Split((char[])null, StringSplitOptions.RemoveEmptyEntries); return(splitSearchStr.All(s => searchIn.IndexOf(s, rule) >= 0)); }
private void BlacklistMod(string guid) { for (var i = 0; i < CustomSelectListCtrlInstance.lstSelectInfo.Count; i++) { CustomSelectInfo customSelectInfo = CustomSelectListCtrlInstance.lstSelectInfo[i]; if (customSelectInfo.index >= UniversalAutoResolver.BaseSlotID) { ResolveInfo info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)customSelectInfo.category, customSelectInfo.index); if (info != null && info.GUID == guid) { if (!Blacklist.ContainsKey(info.GUID)) { Blacklist[info.GUID] = new Dictionary <int, HashSet <int> >(); } if (!Blacklist[info.GUID].ContainsKey(customSelectInfo.category)) { Blacklist[info.GUID][customSelectInfo.category] = new HashSet <int>(); } Blacklist[info.GUID][customSelectInfo.category].Add(info.Slot); SaveBlacklist(); var controls = CustomBase.Instance.GetComponentsInChildren <CustomSelectListCtrl>(true); for (var j = 0; j < controls.Length; j++) { var customSelectListCtrl = controls[j]; if (customSelectListCtrl.GetSelectInfoFromIndex(customSelectInfo.index)?.category == customSelectInfo.category) { if (ListVisibility.TryGetValue(customSelectListCtrl, out var visibilityType)) { if (visibilityType == ListVisibilityType.Filtered) { customSelectListCtrl.DisvisibleItem(customSelectInfo.index, true); } } } } } } } SetMenuVisibility(false); }
public static void ChangeListFilter(CustomSelectListCtrl customSelectListCtrl, ListVisibilityType visibilityType) { List <CustomSelectInfo> lstSelectInfo = (List <CustomSelectInfo>)Traverse.Create(customSelectListCtrl).Field("lstSelectInfo").GetValue(); int count = 0; for (var i = 0; i < lstSelectInfo.Count; i++) { CustomSelectInfo customSelectInfo = lstSelectInfo[i]; if (visibilityType == ListVisibilityType.All) { customSelectListCtrl.DisvisibleItem(customSelectInfo.index, false); continue; } bool hide = visibilityType != ListVisibilityType.Filtered; if (customSelectInfo.index >= UniversalAutoResolver.BaseSlotID) { ResolveInfo Info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)customSelectInfo.category, customSelectInfo.index); if (Info != null) { if (CheckBlacklist(Info.GUID, (int)Info.CategoryNo, Info.Slot)) { hide = visibilityType == ListVisibilityType.Filtered; count++; } } } customSelectListCtrl.DisvisibleItem(customSelectInfo.index, hide); } ListVisibility[customSelectListCtrl] = visibilityType; if (count == 0 && visibilityType == ListVisibilityType.Hidden) { Logger.LogMessage("No items are hidden"); ChangeListFilter(customSelectListCtrl, ListVisibilityType.Filtered); } }
internal static bool AddItemIDHook(int category, int id) { if (id >= UniversalAutoResolver.BaseSlotID) { ResolveInfo Info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)category, id); if (!CheckItemList.ContainsKey(Info.GUID)) { CheckItemList[Info.GUID] = new Dictionary <int, HashSet <int> >(); } if (!CheckItemList[Info.GUID].ContainsKey(category)) { CheckItemList[Info.GUID][category] = new HashSet <int>(); } if (!CheckItemList[Info.GUID][category].Contains(Info.Slot)) { CheckItemList[Info.GUID][category].Add(Info.Slot); SaveCheckItemList(); } return(false); } return(true); }
protected void LoadAllLists(ZipFile arc, Manifest manifest) { foreach (ZipEntry entry in arc) { if (entry.Name.StartsWith("abdata/list/characustom", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { try { var stream = arc.GetInputStream(entry); var chaListData = ListLoader.LoadCSV(stream); SetPossessNew(chaListData); UniversalAutoResolver.GenerateResolutionInfo(manifest, chaListData); IndexList(manifest, chaListData); ListLoader.ExternalDataList.Add(chaListData); if (LoadedData.TryGetValue(manifest, out lists)) { lists.Add(chaListData); } else { LoadedData[manifest] = new List <ChaListData> { chaListData }; } } catch (SystemException ex) { Logger.Log(LogLevel.Error, $"[SIDELOADER] Failed to load list file \"{entry.Name}\" from archive \"{arc.Name}\" with error: {ex.Message}"); Logger.Log(LogLevel.Debug, $"[SIDELOADER] Error details: {ex}"); } } } }
internal static void MigrateData(ref ResolveInfo extResolve) { if (extResolve.GUID.IsNullOrWhiteSpace()) { return; } List <MigrationInfo> migrationInfoList = UniversalAutoResolver.GetMigrationInfo(extResolve.GUID); if (migrationInfoList.Any(x => x.MigrationType == MigrationType.StripAll)) { extResolve.GUID = ""; return; } int slot = extResolve.Slot; ChaListDefine.CategoryNo categoryNo = extResolve.CategoryNo; foreach (MigrationInfo migrationInfo in migrationInfoList.Where(x => x.IDOld == slot && x.Category == categoryNo)) { if (Sideloader.Sideloader.GetManifest(migrationInfo.GUIDNew) != null) { extResolve.GUID = migrationInfo.GUIDNew; extResolve.Slot = migrationInfo.IDNew; return; } } foreach (MigrationInfo migrationInfo in migrationInfoList.Where(x => x.MigrationType == MigrationType.MigrateAll)) { if (Sideloader.Sideloader.GetManifest(migrationInfo.GUIDNew) != null) { extResolve.GUID = migrationInfo.GUIDNew; } } }
private void LoadAllLists(ZipFile arc, Manifest manifest) { List <ZipEntry> BoneList = new List <ZipEntry>(); foreach (ZipEntry entry in arc) { if (entry.Name.StartsWith("abdata/list/characustom", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { try { var stream = arc.GetInputStream(entry); var chaListData = Lists.LoadCSV(stream); SetPossessNew(chaListData); UniversalAutoResolver.GenerateResolutionInfo(manifest, chaListData, _gatheredResolutionInfos); Lists.ExternalDataList.Add(chaListData); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } #if KK || AI else if (entry.Name.StartsWith("abdata/studio/info", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { if (Path.GetFileNameWithoutExtension(entry.Name).ToLower().StartsWith("itembonelist_")) { BoneList.Add(entry); } else { try { var stream = arc.GetInputStream(entry); var studioListData = Lists.LoadStudioCSV(stream, entry.Name); UniversalAutoResolver.GenerateStudioResolutionInfo(manifest, studioListData); Lists.ExternalStudioDataList.Add(studioListData); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } } #if KK else if (entry.Name.StartsWith("abdata/map/list/mapinfo/", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { try { var stream = arc.GetInputStream(entry); MapInfo mapListData = Lists.LoadMapCSV(stream); Lists.ExternalMapList.Add(mapListData); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } #endif #endif } #if KK || AI //ItemBoneList data must be resolved after the corresponding item so they can be resolved to the same ID foreach (ZipEntry entry in BoneList) { try { var stream = arc.GetInputStream(entry); var studioListData = Lists.LoadStudioCSV(stream, entry.Name); UniversalAutoResolver.GenerateStudioResolutionInfo(manifest, studioListData); Lists.ExternalStudioDataList.Add(studioListData); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } #endif }
private void PrintInfo(int index) { List <CustomSelectInfo> lstSelectInfo = (List <CustomSelectInfo>)Traverse.Create(CustomSelectListCtrlInstance).Field("lstSelectInfo").GetValue(); var customSelectInfo = lstSelectInfo.First(x => x.index == index); if (index >= UniversalAutoResolver.BaseSlotID) { ResolveInfo info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)customSelectInfo.category, customSelectInfo.index); if (info != null) { Logger.LogMessage($"Item GUID:{info.GUID} Category:{(int)info.CategoryNo}({info.CategoryNo}) ID:{info.Slot}"); Dictionary <int, ListInfoBase> dictionary = Singleton <Character> .Instance.chaListCtrl.GetCategoryInfo(info.CategoryNo); if (dictionary != null && dictionary.TryGetValue(customSelectInfo.index, out ListInfoBase listInfoBase)) { string assetBundle = listInfoBase.GetInfo(ChaListDefine.KeyType.MainAB); if (!assetBundle.IsNullOrEmpty() && assetBundle != "0") { string asset = TryGetMainAsset(listInfoBase); if (asset == null) { Logger.LogMessage($"AssetBundle:{assetBundle}"); } else { Logger.LogMessage($"AssetBundle:{assetBundle} Asset:{asset}"); } } } if (Sideloader.Sideloader.ZipArchives.TryGetValue(info.GUID, out string zipFileName)) { Logger.LogMessage($"Zip File:{Path.GetFileName(zipFileName)}"); } } } else { Logger.LogMessage($"Item Category:{CurrentCustomSelectInfoComponent.info.category}({(ChaListDefine.CategoryNo)CurrentCustomSelectInfoComponent.info.category}) ID:{CurrentCustomSelectInfoComponent.info.index}"); Dictionary <int, ListInfoBase> dictionary = Singleton <Character> .Instance.chaListCtrl.GetCategoryInfo((ChaListDefine.CategoryNo) CurrentCustomSelectInfoComponent.info.category); if (dictionary != null && dictionary.TryGetValue(customSelectInfo.index, out var listInfoBase)) { string assetBundle = listInfoBase.GetInfo(ChaListDefine.KeyType.MainAB); if (!assetBundle.IsNullOrEmpty() && assetBundle != "0") { string asset = TryGetMainAsset(listInfoBase); if (asset == null) { Logger.LogMessage($"AssetBundle:{assetBundle}"); } else { Logger.LogMessage($"AssetBundle:{assetBundle} Asset:{asset}"); } } } } SetMenuVisibility(false); }
internal static void LoadXML(XDocument manifestDocument) { // Load XML and put all Heel Data on plugin's data dictionary. var heelData = manifestDocument?.Root?.Element("AI_HeelsData")?.Elements("heel"); var guid = manifestDocument?.Root?.Element("guid")?.Value; if (heelData == null) { return; } Logger.Log($"Registering Heelz Data for \"{guid}\""); foreach (var element in heelData) { var heelID = int.Parse(element.Attribute("id")?.Value ?? "-1"); Logger.Log($"Registering Heel Config for clothe ID: {heelID}"); if (heelID <= -1) { continue; } Logger.Log("Finding sideloader reference"); var resolvedID = UniversalAutoResolver.TryGetResolutionInfo(heelID, "ChaFileClothes.ClothesShoes", guid); if (resolvedID != null) { Logger.Log($"Found Resolved ID: \"{heelID}\"=>\"{resolvedID.LocalSlot}\""); heelID = resolvedID.LocalSlot; } else { // Due to some limitation, I'm limiting heels registration to the sideloader items. Logger.Log($"Unable to resolve ID: {heelID}."); return; } if (Values.Configs.ContainsKey(heelID)) { Logger.Log($"CONFLICTING HEEL DATA! Shoe ID {heelID} already has heel data."); return; } try { var newConfig = new HeelsConfig(element); if (heelID <= 0) { Logger.Log($"Heelz refused to register heel ID: \"{heelID}\""); } else { Values.Configs.Add(heelID, newConfig); Logger.Log($"Registered new heel ID: \"{heelID}\""); } } catch (Exception e) { Logger.Log(e.ToString()); } } }
private void LoadModsFromDirectories(params string[] modDirectories) { Logger.LogInfo("Scanning the \"mods\" directory..."); var stopWatch = Stopwatch.StartNew(); // Look for mods, load their manifests var allMods = new List <string>(); foreach (var modDirectory in modDirectories) { if (!modDirectory.IsNullOrWhiteSpace() && Directory.Exists(modDirectory)) { allMods.AddRange(GetZipmodsFromDirectory(modDirectory)); } } var archives = new Dictionary <ZipFile, Manifest>(); foreach (var archivePath in allMods) { ZipFile archive = null; try { archive = new ZipFile(archivePath); if (Manifest.TryLoadFromZip(archive, out Manifest manifest)) { if (manifest.Game.IsNullOrWhiteSpace() || GameNameList.Contains(manifest.Game.ToLower().Replace("!", ""))) { archives.Add(archive, manifest); } else { Logger.LogInfo($"Skipping archive \"{GetRelativeArchiveDir(archivePath)}\" because it's meant for {manifest.Game}"); } } } catch (Exception ex) { Logger.LogError($"Failed to load archive \"{GetRelativeArchiveDir(archivePath)}\" with error: {ex}"); archive?.Close(); } } var modLoadInfoSb = new StringBuilder(); // Handle duplicate GUIDs and load unique mods foreach (var modGroup in archives.GroupBy(x => x.Value.GUID)) { // Order by version if available, else use modified dates (less reliable) // If versions match, prefer mods inside folders or with more descriptive names so modpacks are preferred var orderedModsQuery = modGroup.All(x => !string.IsNullOrEmpty(x.Value.Version)) ? modGroup.OrderByDescending(x => x.Value.Version, new ManifestVersionComparer()).ThenByDescending(x => x.Key.Name.Length) : modGroup.OrderByDescending(x => File.GetLastWriteTime(x.Key.Name)); var orderedMods = orderedModsQuery.ToList(); if (orderedMods.Count > 1) { var modList = string.Join(", ", orderedMods.Select(x => '"' + GetRelativeArchiveDir(x.Key.Name) + '"').ToArray()); Logger.LogWarning($"Archives with identical GUIDs detected! Archives: {modList}; Only \"{GetRelativeArchiveDir(orderedMods[0].Key.Name)}\" will be loaded because it's the newest"); // Don't keep the duplicate archives in memory foreach (var dupeMod in orderedMods.Skip(1)) { dupeMod.Key.Close(); } } // Actually load the mods (only one per GUID, the newest one) var archive = orderedMods[0].Key; var manifest = orderedMods[0].Value; try { Archives.Add(archive); Manifests[manifest.GUID] = manifest; LoadAllUnityArchives(archive, archive.Name); LoadAllLists(archive, manifest); BuildPngFolderList(archive); UniversalAutoResolver.GenerateMigrationInfo(manifest, _gatheredMigrationInfos); var trimmedName = manifest.Name?.Trim(); var displayName = !string.IsNullOrEmpty(trimmedName) ? trimmedName : Path.GetFileName(archive.Name); modLoadInfoSb.AppendLine($"Loaded {displayName} {manifest.Version}"); } catch (Exception ex) { Logger.LogError($"Failed to load archive \"{GetRelativeArchiveDir(archive.Name)}\" with error: {ex}"); } } stopWatch.Stop(); if (ModLoadingLogging.Value) { Logger.LogInfo($"List of loaded mods:\n{modLoadInfoSb}"); } Logger.LogInfo($"Successfully loaded {Archives.Count} mods out of {allMods.Count()} archives in {stopWatch.ElapsedMilliseconds}ms"); UniversalAutoResolver.SetResolveInfos(_gatheredResolutionInfos); UniversalAutoResolver.SetMigrationInfos(_gatheredMigrationInfos); BuildPngOnlyFolderList(); #pragma warning disable CS0618 // Type or member is obsolete LoadedManifests = Manifests.Values.AsEnumerable().ToList(); #pragma warning restore CS0618 // Type or member is obsolete }
private void LoadModsFromDirectory(string modDirectory) { string GetRelativeArchiveDir(string archiveDir) { return(archiveDir.Length < modDirectory.Length ? archiveDir : archiveDir.Substring(modDirectory.Length).Trim(' ', '/', '\\')); } Logger.Log(LogLevel.Info, "[SIDELOADER] Scanning the \"mods\" directory..."); // Look for mods, load their manifests var allMods = Directory.GetFiles(modDirectory, "*", SearchOption.AllDirectories) .Where(x => x.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) || x.EndsWith(".zipmod", StringComparison.OrdinalIgnoreCase)); var archives = new Dictionary <ZipFile, Manifest>(); foreach (var archivePath in allMods) { ZipFile archive = null; try { archive = new ZipFile(archivePath); if (Manifest.TryLoadFromZip(archive, out Manifest manifest)) { archives.Add(archive, manifest); } } catch (Exception ex) { Logger.Log(LogLevel.Error, $"[SIDELOADER] Failed to load archive \"{GetRelativeArchiveDir(archivePath)}\" with error: {ex.Message}"); Logger.Log(LogLevel.Debug, $"[SIDELOADER] Error details: {ex}"); archive?.Close(); } } // Handlie duplicate GUIDs and load unique mods foreach (var modGroup in archives.GroupBy(x => x.Value.GUID)) { // Order by version if available, else use modified dates (less reliable) // If versions match, prefer mods inside folders or with more descriptive names so modpacks are preferred var orderedModsQuery = modGroup.All(x => !string.IsNullOrEmpty(x.Value.Version)) ? modGroup.OrderByDescending(x => x.Value.Version, new ManifestVersionComparer()).ThenByDescending(x => x.Key.Name.Length) : modGroup.OrderByDescending(x => File.GetLastWriteTime(x.Key.Name)); var orderedMods = orderedModsQuery.ToList(); if (orderedMods.Count > 1) { var modList = string.Join(", ", orderedMods.Select(x => '"' + GetRelativeArchiveDir(x.Key.Name) + '"').ToArray()); Logger.Log(LogLevel.Warning, $"[SIDELOADER] Archives with identical GUIDs detected! Archives: {modList}"); Logger.Log(LogLevel.Warning, $"[SIDELOADER] Only \"{GetRelativeArchiveDir(orderedMods[0].Key.Name)}\" will be loaded because it's the newest"); // Don't keep the duplicate archives in memory foreach (var dupeMod in orderedMods.Skip(1)) { dupeMod.Key.Close(); } } // Actually load the mods (only one per GUID, the newest one) var archive = orderedMods[0].Key; var manifest = orderedMods[0].Value; try { Archives.Add(archive); LoadedManifests.Add(manifest); LoadAllUnityArchives(archive, archive.Name); LoadAllLists(archive, manifest); BuildPngFolderList(archive); var trimmedName = manifest.Name?.Trim(); var displayName = !string.IsNullOrEmpty(trimmedName) ? trimmedName : Path.GetFileName(archive.Name); Logger.Log(LogLevel.Info, $"[SIDELOADER] Loaded {displayName} {manifest.Version ?? ""}"); } catch (Exception ex) { Logger.Log(LogLevel.Error, $"[SIDELOADER] Failed to load archive \"{GetRelativeArchiveDir(archive.Name)}\" with error: {ex.Message}"); Logger.Log(LogLevel.Debug, $"[SIDELOADER] Error details: {ex}"); } } UniversalAutoResolver.SetResolveInfos(_gatheredResolutionInfos); BuildPngOnlyFolderList(); }
private void LoadModsFromDirectories(params string[] modDirectories) { var stopWatch = Stopwatch.StartNew(); // Look for mods, load their manifests var allMods = new List <string>(); foreach (var modDirectory in modDirectories) { if (!modDirectory.IsNullOrWhiteSpace() && Directory.Exists(modDirectory)) { var prevCount = allMods.Count; allMods.AddRange(Directory.GetFiles(modDirectory, "*", SearchOption.AllDirectories) .Where(x => x.EndsWith(".zip", StringComparison.OrdinalIgnoreCase) || x.EndsWith(".zipmod", StringComparison.OrdinalIgnoreCase))); Logger.LogInfo("Found " + (allMods.Count - prevCount) + " zipmods in directory: " + modDirectory); } } var archives = allMods.RunParallel(archivePath => { ZipFile archive = null; try { archive = new ZipFile(archivePath); if (Manifest.TryLoadFromZip(archive, out Manifest manifest)) { //Skip the mod if it is not for this game if (!manifest.Game.IsNullOrWhiteSpace() && !GameNameList.Contains(manifest.Game.ToLower().Replace("!", ""))) { Logger.LogInfo($"Skipping archive \"{GetRelativeArchiveDir(archivePath)}\" because it's meant for {manifest.Game}"); return(null); } return(new { archive, manifest }); } } catch (Exception ex) { Logger.LogError($"Failed to load archive \"{GetRelativeArchiveDir(archivePath)}\" with error: {ex}"); archive?.Close(); } return(null); }, 3).Where(x => x != null).ToList(); var enableModLoadingLogging = DebugLoggingModLoading.Value; var modLoadInfoSb = enableModLoadingLogging ? new StringBuilder(1000) : null; // Handle duplicate GUIDs and load unique mods foreach (var modGroup in archives.GroupBy(x => x.manifest.GUID).OrderBy(x => x.Key)) { // Order by version if available, else use modified dates (less reliable) // If versions match, prefer mods inside folders or with more descriptive names so modpacks are preferred var orderedModsQuery = modGroup.All(x => !string.IsNullOrEmpty(x.manifest.Version)) ? modGroup.OrderByDescending(x => x.manifest.Version, new ManifestVersionComparer()).ThenByDescending(x => x.archive.Name.Length) : modGroup.OrderByDescending(x => File.GetLastWriteTime(x.archive.Name)); var orderedMods = orderedModsQuery.ToList(); if (orderedMods.Count > 1) { var modList = string.Join(", ", orderedMods.Skip(1).Select(x => '"' + GetRelativeArchiveDir(x.archive.Name) + '"').ToArray()); Logger.LogWarning($"Multiple versions detected, only \"{GetRelativeArchiveDir(orderedMods[0].archive.Name)}\" will be loaded. Skipped versions: {modList}"); // Don't keep the duplicate archives in memory foreach (var dupeMod in orderedMods.Skip(1)) { dupeMod.archive.Close(); } } // Actually load the mods (only one per GUID, the newest one) var archive = orderedMods[0].archive; var manifest = orderedMods[0].manifest; try { Archives.Add(archive); ZipArchives[manifest.GUID] = archive.Name; Manifests[manifest.GUID] = manifest; LoadAllUnityArchives(archive, archive.Name); LoadAllLists(archive, manifest); BuildPngFolderList(archive); UniversalAutoResolver.GenerateMigrationInfo(manifest, _gatheredMigrationInfos); #if AI || HS2 UniversalAutoResolver.GenerateHeadPresetInfo(manifest, _gatheredHeadPresetInfos); UniversalAutoResolver.GenerateFaceSkinInfo(manifest, _gatheredFaceSkinInfos); #endif var trimmedName = manifest.Name?.Trim(); var displayName = !string.IsNullOrEmpty(trimmedName) ? trimmedName : Path.GetFileName(archive.Name); if (enableModLoadingLogging) { modLoadInfoSb.AppendLine($"Loaded {displayName} {manifest.Version}"); } } catch (Exception ex) { Logger.LogError($"Failed to load archive \"{GetRelativeArchiveDir(archive.Name)}\" with error: {ex}"); } } UniversalAutoResolver.SetResolveInfos(_gatheredResolutionInfos); UniversalAutoResolver.SetMigrationInfos(_gatheredMigrationInfos); #if AI || HS2 UniversalAutoResolver.SetHeadPresetInfos(_gatheredHeadPresetInfos); UniversalAutoResolver.SetFaceSkinInfos(_gatheredFaceSkinInfos); UniversalAutoResolver.ResolveFaceSkins(); #endif BuildPngOnlyFolderList(); #pragma warning disable CS0618 // Type or member is obsolete LoadedManifests = Manifests.Values.AsEnumerable().ToList(); #pragma warning restore CS0618 // Type or member is obsolete stopWatch.Stop(); if (enableModLoadingLogging) { Logger.LogInfo($"List of loaded mods:\n{modLoadInfoSb}"); } Logger.LogInfo($"Successfully loaded {Archives.Count} mods out of {allMods.Count} archives in {stopWatch.ElapsedMilliseconds}ms"); var failedPaths = allMods.Except(Archives.Select(x => x.Name)); var failedStrings = failedPaths.Select(GetRelativeArchiveDir).ToArray(); if (failedStrings.Length > 0) { Logger.LogWarning("Could not load " + failedStrings.Length + " mods, see previous warnings for more information. File names of skipped archives:\n" + string.Join(" | ", failedStrings)); } }
protected void LoadAllLists(ZipFile arc, Manifest manifest) { List <ZipEntry> BoneList = new List <ZipEntry>(); foreach (ZipEntry entry in arc) { if (entry.Name.StartsWith("abdata/list/characustom", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { try { var stream = arc.GetInputStream(entry); var chaListData = ListLoader.LoadCSV(stream); SetPossessNew(chaListData); UniversalAutoResolver.GenerateResolutionInfo(manifest, chaListData); ListLoader.ExternalDataList.Add(chaListData); } catch (Exception ex) { Logger.Log(LogLevel.Error, $"[SIDELOADER] Failed to load list file \"{entry.Name}\" from archive \"{arc.Name}\" with error: {ex.Message}"); Logger.Log(LogLevel.Error, $"[SIDELOADER] Error details: {ex}"); } } if (entry.Name.StartsWith("abdata/studio/info", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { if (Path.GetFileNameWithoutExtension(entry.Name).ToLower().StartsWith("itembonelist_")) { BoneList.Add(entry); } else { try { var stream = arc.GetInputStream(entry); var studioListData = ListLoader.LoadStudioCSV(stream, entry.Name); UniversalAutoResolver.GenerateStudioResolutionInfo(manifest, studioListData); ListLoader.ExternalStudioDataList.Add(studioListData); } catch (Exception ex) { Logger.Log(LogLevel.Error, $"[SIDELOADER] Failed to load list file \"{entry.Name}\" from archive \"{arc.Name}\" with error: {ex.Message}"); Logger.Log(LogLevel.Error, $"[SIDELOADER] Error details: {ex}"); } } } } //ItemBoneList data must be resolved after the corresponding item so they can be resolved to the same ID foreach (ZipEntry entry in BoneList) { try { var stream = arc.GetInputStream(entry); var studioListData = ListLoader.LoadStudioCSV(stream, entry.Name); UniversalAutoResolver.GenerateStudioResolutionInfo(manifest, studioListData); ListLoader.ExternalStudioDataList.Add(studioListData); } catch (Exception ex) { Logger.Log(LogLevel.Error, $"[SIDELOADER] Failed to load list file \"{entry.Name}\" from archive \"{arc.Name}\" with error: {ex.Message}"); Logger.Log(LogLevel.Error, $"[SIDELOADER] Error details: {ex}"); } } }
private void ShowMenu() { if (CustomBase.Instance == null) { return; } InitUI(); SetMenuVisibility(false); if (CurrentCustomSelectInfoComponent == null) { return; } if (!MouseIn) { return; } var xPosition = Input.mousePosition.x / Screen.width + 0.01f; var yPosition = Input.mousePosition.y / Screen.height - UIHeight - 0.01f; ContextMenuPanel.transform.SetRect(xPosition, yPosition, UIWidth + xPosition, UIHeight + yPosition); SetMenuVisibility(true); List <CustomSelectInfo> lstSelectInfo = (List <CustomSelectInfo>)Traverse.Create(CustomSelectListCtrlInstance).Field("lstSelectInfo").GetValue(); int index = CurrentCustomSelectInfoComponent.info.index; var customSelectInfo = lstSelectInfo.First(x => x.index == index); string guid = null; int category = customSelectInfo.category; int id = index; if (index >= UniversalAutoResolver.BaseSlotID) { ResolveInfo info = UniversalAutoResolver.TryGetResolutionInfo((ChaListDefine.CategoryNo)customSelectInfo.category, customSelectInfo.index); if (info != null) { guid = info.GUID; id = info.Slot; } } if (ListVisibility.TryGetValue(CustomSelectListCtrlInstance, out var listVisibilityType)) { FilterDropdown.Set((int)listVisibilityType); } BlacklistButton.onClick.RemoveAllListeners(); BlacklistModButton.onClick.RemoveAllListeners(); InfoButton.onClick.RemoveAllListeners(); if (guid == null) { BlacklistButton.enabled = false; BlacklistModButton.enabled = false; } else { BlacklistButton.enabled = true; BlacklistModButton.enabled = true; if (CheckBlacklist(guid, category, id)) { BlacklistButton.GetComponentInChildren <Text>().text = "Unhide this item"; BlacklistButton.onClick.AddListener(() => UnblacklistItem(guid, category, id, index)); BlacklistModButton.GetComponentInChildren <Text>().text = "Unhide all items from this mod"; BlacklistModButton.onClick.AddListener(() => UnblacklistMod(guid)); } else { BlacklistButton.GetComponentInChildren <Text>().text = "Hide this item"; BlacklistButton.onClick.AddListener(() => BlacklistItem(guid, category, id, index)); BlacklistModButton.GetComponentInChildren <Text>().text = "Hide all items from this mod"; BlacklistModButton.onClick.AddListener(() => BlacklistMod(guid)); } } InfoButton.onClick.AddListener(() => PrintInfo(index)); }
/// <summary> /// Look through all the GUIDs, compare it to the MigrationInfoList, and do migration when necessary /// </summary> private static IEnumerable <ResolveInfo> MigrateGUID(IEnumerable <ResolveInfo> extInfo, string characterName = "") { List <ResolveInfo> extInfoNew = new List <ResolveInfo>(); bool DidBlankGUIDMessage = false; try { if (extInfo == null) { return(extInfo); } foreach (ResolveInfo resolveInfo in extInfo) { if (resolveInfo.GUID.IsNullOrEmpty()) { //Don't add empty GUID to the new list, this way CompatibilityResolve will treat it as a hard mod and attempt to find a match if (!DidBlankGUIDMessage) //No need to spam it for every single thing { if (characterName == "") { Logger.Log(LogLevel.Warning | LogLevel.Message, $"Blank GUID detected, attempting Compatibility Resolve"); } else { Logger.Log(LogLevel.Warning | LogLevel.Message, $"[{characterName}] Blank GUID detected, attempting Compatibility Resolve"); } DidBlankGUIDMessage = true; } } else { string propertyWithoutPrefix = resolveInfo.Property; //Remove outfit and accessory prefixes for searching purposes if (propertyWithoutPrefix.StartsWith("outfit")) { propertyWithoutPrefix = propertyWithoutPrefix.Remove(0, propertyWithoutPrefix.IndexOf('.') + 1); } if (propertyWithoutPrefix.Remove(propertyWithoutPrefix.IndexOf('.')).Contains("accessory")) { propertyWithoutPrefix = propertyWithoutPrefix.Remove(0, propertyWithoutPrefix.IndexOf('.') + 1); } MigrationInfo info = MigrationInfoList.Where(x => (x.Property == propertyWithoutPrefix && x.OldID == resolveInfo.Slot && x.OldGUID == resolveInfo.GUID) || (x.Property == "*" && x.OldGUID == resolveInfo.GUID) || (x.Property == "-" && x.OldGUID == resolveInfo.GUID)).FirstOrDefault(); if (info == null) { //This item does not need to be migrated extInfoNew.Add(resolveInfo); } else if (info.Property == "*") //* assumes only the GUID changed while the IDs stayed the same { ResolveInfo GUIDCheckOld = UniversalAutoResolver.LoadedResolutionInfo.FirstOrDefault(x => x.GUID == resolveInfo.GUID); if (GUIDCheckOld == null) { //We do not have the old mod installed, do migration. Whether we have the new mod is irrelevant. //If we don't have the new mod the user will get a missing mod warning for the new mod since they should be using that instead. //If we do it will load correctly. Logger.Log(LogLevel.Info, $"Migrating GUID {info.OldGUID} -> {info.NewGUID}"); ResolveInfo resolveInfoNew = new ResolveInfo(); resolveInfoNew = resolveInfo; resolveInfoNew.GUID = info.NewGUID; extInfoNew.Add(resolveInfoNew); } else { ResolveInfo GUIDCheckNew = UniversalAutoResolver.LoadedResolutionInfo.FirstOrDefault(x => x.GUID == info.NewGUID); if (GUIDCheckNew == null) { //We have the old mod but not the new, do not do migration extInfoNew.Add(resolveInfo); } else { //We have the old mod and the new, do migration so characters save with the new stuff Logger.Log(LogLevel.Info, $"Migrating GUID {info.OldGUID} -> {info.NewGUID}"); ResolveInfo resolveInfoNew = new ResolveInfo(); resolveInfoNew = resolveInfo; resolveInfoNew.GUID = info.NewGUID; extInfoNew.Add(resolveInfoNew); } } } else if (info.Property == "-") //- indicates the entry needs to be stripped of its extended data and loaded as a hard mod { continue; } else { ResolveInfo intResolveOld = UniversalAutoResolver.TryGetResolutionInfo(resolveInfo.Slot, propertyWithoutPrefix, resolveInfo.GUID); if (intResolveOld == null) { //We do not have the old mod installed, do migration. Whether we have the new mod is irrelevant. //If we don't have the new mod the user will get a missing mod warning for the new mod since they should be using that instead. //If we do it will load correctly. Logger.Log(LogLevel.Info, $"Migrating {info.OldGUID}:{info.OldID} -> {info.NewGUID}:{info.NewID}"); ResolveInfo resolveInfoNew = new ResolveInfo(); resolveInfoNew = resolveInfo; resolveInfoNew.GUID = info.NewGUID; resolveInfoNew.Slot = info.NewID; extInfoNew.Add(resolveInfoNew); } else { ResolveInfo intResolveNew = UniversalAutoResolver.TryGetResolutionInfo(info.NewID, propertyWithoutPrefix, info.NewGUID); if (intResolveNew == null) { //We have the old mod but not the new, do not do migration extInfoNew.Add(resolveInfo); } else { //We have the old mod and the new, do migration so characters save with the new stuff Logger.Log(LogLevel.Info, $"Migrating {info.OldGUID}:{info.OldID} -> {info.NewGUID}:{info.NewID}"); ResolveInfo b = new ResolveInfo(); b = resolveInfo; b.GUID = info.NewGUID; b.Slot = info.NewID; extInfoNew.Add(b); } } } } } extInfo = extInfoNew; } catch (Exception ex) { //If something goes horribly wrong, return the original extInfo Logger.Log(LogLevel.Error, $"GUID migration cancelled due to error: {ex}"); return(extInfo); } return(extInfoNew); }
private void LoadAllLists(ZipFile arc, Manifest manifest) { List <ZipEntry> BoneList = new List <ZipEntry>(); foreach (ZipEntry entry in arc) { if (entry.Name.StartsWith("abdata/list/characustom", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { try { var stream = arc.GetInputStream(entry); var chaListData = Lists.LoadCSV(stream); SetPossessNew(chaListData); UniversalAutoResolver.GenerateResolutionInfo(manifest, chaListData, _gatheredResolutionInfos); Lists.ExternalDataList.Add(chaListData); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } #if KK || AI || HS2 else if (entry.Name.StartsWith("abdata/studio/info", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { if (Path.GetFileNameWithoutExtension(entry.Name).ToLower().StartsWith("itembonelist_")) { BoneList.Add(entry); } else { try { var stream = arc.GetInputStream(entry); var studioListData = Lists.LoadStudioCSV(stream, entry.Name, manifest.GUID); UniversalAutoResolver.GenerateStudioResolutionInfo(manifest, studioListData); Lists.ExternalStudioDataList.Add(studioListData); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } } #if AI || HS2 else if (entry.Name.StartsWith("abdata/list/map/", StringComparison.OrdinalIgnoreCase) && entry.Name.EndsWith(".csv", StringComparison.OrdinalIgnoreCase)) { try { string assetBundleName = entry.Name; assetBundleName = assetBundleName.Remove(0, assetBundleName.IndexOf('/') + 1); //Remove "abdata/" assetBundleName = assetBundleName.Remove(assetBundleName.LastIndexOf('/')); //Remove the .csv filename assetBundleName += ".unity3d"; string assetName = entry.Name; assetName = assetName.Remove(0, assetName.LastIndexOf('/') + 1); //Remove all but the filename assetName = assetName.Remove(assetName.LastIndexOf('.')); //Remove the .csv var stream = arc.GetInputStream(entry); Lists.LoadExcelDataCSV(assetBundleName, assetName, stream); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } #endif #endif } #if KK || AI || HS2 //ItemBoneList data must be resolved after the corresponding item so they can be resolved to the same ID foreach (ZipEntry entry in BoneList) { try { var stream = arc.GetInputStream(entry); var studioListData = Lists.LoadStudioCSV(stream, entry.Name, manifest.GUID); UniversalAutoResolver.GenerateStudioResolutionInfo(manifest, studioListData); Lists.ExternalStudioDataList.Add(studioListData); } catch (Exception ex) { Logger.LogError($"Failed to load list file \"{entry.Name}\" from archive \"{GetRelativeArchiveDir(arc.Name)}\" with error: {ex}"); } } #endif }
internal static void LoadXML(XDocument manifestDocument) { // Load XML and put all Heel Data on plugin's data dictionary. var heelDatas = manifestDocument?.Root?.Element("AI_HeelsData")?.Elements("heel"); var guid = manifestDocument?.Root?.Element("guid").Value; if (heelDatas != null) { foreach (var element in heelDatas) { var heelID = int.Parse(element.Attribute("id")?.Value); if (Values.configs.ContainsKey(heelID)) { Util.Logger.Log(string.Format("CONFLITING HEEL DATA! Shoe ID {0} already has heel data.", heelID)); return; } Util.Logger.Log(string.Format("Registering Heel Config for clothe ID: {0}", heelID)); if (heelID > -1) { var newConfig = new HeelConfig(); try { foreach (var partKey in Constant.parts) { var partElement = element.Element(partKey); if (partElement == null) { continue; } // register position values such as roll, move scale. // it will parse vec, min, max. but unfortunately, only "roll" will get the limitation feature. // since we can't just make limit of vector... it's not going to move in most of case var vectors = new Dictionary <string, Vector3>(); foreach (var modKey in Constant.modifiers) { var split = partElement.Element(modKey)?.Attribute("vec")?.Value?.Split(','); if (split != null) { var vector = new Vector3(float.Parse(split[0]), float.Parse(split[1]), float.Parse(split[2])); vectors.Add(modKey, vector); } else { vectors.Add(modKey, modKey == "scale" ? Vector3.one : Vector3.zero); // Yeah.. if there is no scale, don't f**k it up. } Util.Logger.Log(string.Format("\t{0}_{1}: {2}", partKey, modKey, vectors[modKey].ToString())); if (modKey == "roll") { var mins = partElement.Element(modKey)?.Attribute("min")?.Value ?.Split(','); var maxs = partElement.Element(modKey)?.Attribute("max")?.Value ?.Split(','); if (mins != null) { vectors.Add(modKey + "min", new Vector3(float.Parse(mins[0]), float.Parse(mins[1]), float.Parse(mins[2]))); Util.Logger.Log(string.Format("\t{0}_{1}: {2}", partKey, modKey + "min", vectors[modKey + "min"].ToString())); } if (maxs != null) { vectors.Add(modKey + "max", new Vector3(float.Parse(maxs[0]), float.Parse(maxs[1]), float.Parse(maxs[2]))); Util.Logger.Log(string.Format("\t{0}_{1}: {2}", partKey, modKey + "max", vectors[modKey + "max"].ToString())); } } } newConfig.heelVectors.Add(partKey, vectors); // register parent angle derivation. var isFixed = partElement?.Attribute("fixed")?.Value; if (isFixed != null) { newConfig.isFixed.Add(partKey, bool.Parse(isFixed)); Util.Logger.Log(string.Format("\t{0}_isFixed: {1}", partKey, isFixed)); } } var rootSplit = element.Element("root")?.Attribute("vec")?.Value?.Split(','); if (rootSplit != null) { newConfig.rootMove = new Vector3(float.Parse(rootSplit[0]), float.Parse(rootSplit[1]), float.Parse(rootSplit[2])); } else { newConfig.rootMove = Vector3.zero; } newConfig.loaded = true; var resolvedID = UniversalAutoResolver.TryGetResolutionInfo(heelID, "ChaFileClothes.ClothesShoes", guid); if (resolvedID != null) { Util.Logger.Log(string.Format("Found Resolved ID: \"{0}\"=>\"{1}\"", heelID, resolvedID.LocalSlot)); heelID = resolvedID.LocalSlot; } Values.configs.Add(heelID, newConfig); Util.Logger.Log(string.Format("Registered new heel ID: \"{0}\"", heelID)); } catch (Exception e) { Util.Logger.Log(e.ToString()); } } } } }
private static void LoadStudioAnims(Studio.Info __instance, ref IEnumerator __result) { __result = __result.AppendCo(() => { foreach (var keyVal in animationDict) { CreateGroup(0); CreateGroup(1); void CreateGroup(byte sex) { var grp = new Info.GroupInfo { name = $"AL {(sex == 0 ? "M" : "F")} {keyVal.Key}" }; var animGrp = new Dictionary <int, Dictionary <int, Info.AnimeLoadInfo> >(); var grpKey = $"{keyVal.Key}{sex}"; if (!EModeGroups.TryGetValue(grpKey, out var grpId)) { return; } foreach (var swapAnimInfo in keyVal.Value.Where(x => x.StudioId >= 0)) { var path = sex == 0 ? swapAnimInfo.PathMale : swapAnimInfo.PathFemale; var ctrl = sex == 0 ? swapAnimInfo.ControllerMale : swapAnimInfo.ControllerFemale; if (string.IsNullOrEmpty(path) || string.IsNullOrEmpty(ctrl)) { continue; } var controller = AssetBundleManager.LoadAsset(path, ctrl, typeof(RuntimeAnimatorController)).GetAsset <RuntimeAnimatorController>(); if (controller == null) { continue; } var animName = string.IsNullOrEmpty(swapAnimInfo.AnimationName) ? ctrl : swapAnimInfo.AnimationName; grp.dicCategory.Add(swapAnimInfo.StudioId, animName); var animCat = new Dictionary <int, Info.AnimeLoadInfo>(); animGrp.Add(swapAnimInfo.StudioId, animCat); var clips = controller.animationClips; for (int i = 0; i < clips.Length; i++) { var newSlot = UniversalAutoResolver.GetUniqueSlotID(); UniversalAutoResolver.LoadedStudioResolutionInfo.Add(new StudioResolveInfo { GUID = swapAnimInfo.Guid, Slot = i, ResolveItem = true, LocalSlot = newSlot, Group = grpId, Category = swapAnimInfo.StudioId }); animCat.Add(newSlot, new Info.AnimeLoadInfo { name = clips[i].name, bundlePath = path, fileName = ctrl, clip = clips[i].name, }); } } if (animGrp.Count > 0) { __instance.dicAGroupCategory.Add(grpId, grp); __instance.dicAnimeLoadInfo.Add(grpId, animGrp); } } } }); }
protected override void OnReload(GameMode currentGameMode) { TaskUnlock(); PluginData ExtendedData = GetExtendedData(); PartsInfo.Clear(); PartsResolveInfo.Clear(); FunctionEnable = false; AutoCopyToBlank = false; ReferralIndex = RefMax; MaterialEditor.Reset(); if (ExtendedData != null) { if (ExtendedData.data.TryGetValue("MoreAccessoriesExtdata", out object loadedMoreAccessoriesExtdata) && loadedMoreAccessoriesExtdata != null) { PartsInfo = MessagePackSerializer.Deserialize <Dictionary <int, ChaFileAccessory.PartsInfo> >((byte[])loadedMoreAccessoriesExtdata); } if (ExtendedData.data.TryGetValue("ResolutionInfoExtdata", out object loadedResolutionInfoExtdata) && loadedResolutionInfoExtdata != null) { PartsResolveInfo = MessagePackSerializer.Deserialize <Dictionary <int, ResolveInfo> >((byte[])loadedResolutionInfoExtdata); } foreach (string _name in SupportList) { if (ExtendedData.data.TryGetValue($"{_name}Extdata", out object loadedExtdata) && loadedExtdata != null) { if (_name == "HairAccessoryCustomizer") { Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <Dictionary <int, string> >((byte[])loadedExtdata) }).GetValue(); } else if (_name == "AccStateSync") { if (ExtendedData.version < 2) { Traverse.Create(this).Field(_name).Method("Migrate", new object[] { MessagePackSerializer.Deserialize <Dictionary <int, string> >((byte[])loadedExtdata) }).GetValue(); } else { Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <Dictionary <string, string> >((byte[])loadedExtdata) }).GetValue(); } } else if (_name == "MaterialEditor") { Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <Dictionary <string, string> >((byte[])loadedExtdata) }).GetValue(); } else if ((_name == "MaterialRouter") || (_name == "DynamicBoneEditor")) { Traverse.Create(this).Field(_name).Method("Load", new object[] { MessagePackSerializer.Deserialize <List <string> >((byte[])loadedExtdata) }).GetValue(); } } } if (ExtendedData.data.TryGetValue("FunctionEnable", out object loadedFunctionEnable) && loadedFunctionEnable != null) { FunctionEnable = (bool)loadedFunctionEnable; } if (ExtendedData.data.TryGetValue("AutoCopyToBlank", out object loadedAutoCopyToBlank) && loadedAutoCopyToBlank != null) { AutoCopyToBlank = (bool)loadedAutoCopyToBlank; } if (ExtendedData.data.TryGetValue("ReferralIndex", out object loadedReferralIndex) && loadedReferralIndex != null) { SetReferralIndex((int)loadedReferralIndex); } if (ExtendedData.data.TryGetValue("TextureContainer", out object loadedTextureContainer) && loadedTextureContainer != null) { MaterialEditor.TexContainer = MessagePackSerializer.Deserialize <Dictionary <int, byte[]> >((byte[])loadedTextureContainer); } foreach (KeyValuePair <int, ChaFileAccessory.PartsInfo> _part in PartsInfo) { if (!PartsResolveInfo.ContainsKey(_part.Key)) { continue; } if (PartsResolveInfo[_part.Key] == null) { continue; } ResolveInfo _info = PartsResolveInfo[_part.Key]; MigrateData(ref _info); if (_info != null) { if (!_info.GUID.IsNullOrEmpty()) { _info = UniversalAutoResolver.TryGetResolutionInfo(PartsResolveInfo[_part.Key].Slot, PartsResolveInfo[_part.Key].CategoryNo, PartsResolveInfo[_part.Key].GUID); } PartsResolveInfo[_part.Key] = _info.JsonClone() as ResolveInfo; _part.Value.id = _info.LocalSlot; } else { PartsResolveInfo[_part.Key] = null; } } } if (MakerAPI.InsideAndLoaded) { MakerToggleEnable.Value = FunctionEnable; MakerToggleAutoCopyToBlank.Value = AutoCopyToBlank; MakerDropdownRef.Value = ReferralIndex; } IEnumerator OnReloadCoroutine() { DebugMsg(LogLevel.Warning, $"[OnReloadCoroutine][{ChaControl.GetFullname()}] fired"); yield return(new WaitForEndOfFrame()); yield return(new WaitForEndOfFrame()); AutoCopyCheck(); } ChaControl.StartCoroutine(OnReloadCoroutine()); base.OnReload(currentGameMode); }