public static bool IsSupported(UrlDir.UrlFile file) { switch (file.fileExtension.ToUpper()) { /* * KSPs own file format... got a custom loader */ case "MBM": // God bless http://www.codeproject.com/Articles/31702/NET-Targa-Image-Reader for doing the heavy lifting, // though i would have prefered KSP to never support TGAs case "TGA": /* * For legacy files do we use Image.FromStream, that should recognize pretty much every thing in system.drawing.imaging.imageformat * ( http://msdn.microsoft.com/en-us/library/system.drawing.imaging.imageformat%28v=vs.110%29.aspx ) * * Lets add a few extensions for now... hope they work */ case "PNG": case "BMP": case "EMF": case "GIF": case "ICO": case "JPEG": case "JPG": case "TIFF": case "TIF": case "WMF": return(true); default: ("LOD Unsupported Texture: " + file.fullPath).Log(); return(false); } }
// Load the model file requested from file and return it as a GameObject. public static GameObject LoadModelFile(UrlDir.UrlFile modelFile) { GameObject loadedObject = null; GameDatabase db = GameDatabase.Instance; /* * // Method 1: Access the internal PartReader.Read method by reflection to read it. * loadedObject = (GameObject)RunMethod( * "KSP_x64_Data/Managed/Assembly-CSharp.dll", * "PartReader", * "Read", * new object[] { modelFile }); * * // Method 2: Alternative reference implementation of PartReader for being able to add debug messages * loadedObject = ChronoReader.Read(urlFile); */ // Method 3: Use the database loader instead of the part reader directly DatabaseLoaderModel_MU databaseLoader = new DatabaseLoaderModel_MU(); db.StartCoroutine(databaseLoader.Load(modelFile, null)); loadedObject = databaseLoader.obj; if (loadedObject == null) { Debug.LogError("Chrononaut:LoadModelFile(): Failed to read file: " + modelFile.name); return(null); } return(loadedObject); }
public static TextureInfoWrapper DDSToTexture(UrlDir.UrlFile file, TexInfo Texture, bool mipmaps, bool isCompressed, bool hasAlpha) { TextureConverter.InitImageBuffer(); FileStream imgStream = new FileStream(Texture.filename, FileMode.Open, FileAccess.Read); imgStream.Position = 0; imgStream.Read(imageBuffer, 0, MAX_IMAGE_SIZE); imgStream.Close(); TextureFormat format = TextureFormat.DXT1; if (hasAlpha && isCompressed) { format = TextureFormat.DXT5; } else if (hasAlpha) { format = TextureFormat.RGBA32; } else if (!isCompressed) { format = TextureFormat.RGB24; } Texture2D newTex = new Texture2D(Texture.width, Texture.height, format, mipmaps); newTex.LoadRawTextureData(imageBuffer); newTex.Apply(false, Texture.makeNotReadable); newTex.name = Texture.name; TextureInfoWrapper newTexInfo = new TextureInfoWrapper(file, newTex, Texture.isNormalMap, !Texture.makeNotReadable, isCompressed); newTexInfo.name = Texture.name; return(newTexInfo); }
public ProtoUrlConfig(UrlDir.UrlFile urlFile, ConfigNode node) { UrlFile = urlFile ?? throw new ArgumentNullException(nameof(urlFile)); Node = node ?? throw new ArgumentNullException(nameof(node)); FileUrl = UrlFile.url + '.' + urlFile.fileExtension; FullUrl = FileUrl + '/' + Node.name; }
private void Start() { HashSet <UrlDir.UrlFile> blacklist = new HashSet <UrlDir.UrlFile>(); HashSet <UrlDir.UrlFile> whitelist = new HashSet <UrlDir.UrlFile>(); UrlDir gameData = GameDatabase.Instance.root.children.Find(dir => dir.type == UrlDir.DirectoryType.GameData); foreach (UrlDir.UrlFile file in GameDatabase.Instance.root.AllFiles) { if (file.fileExtension == "restockblacklist") { Debug.Log($"[Restock] Reading blacklist {file.url}.{file.fileExtension}"); foreach (string line in File.ReadAllLines(file.fullPath)) { string lineBeforeComment = line.Split(commentSep, 2, StringSplitOptions.None)[0].Trim(); if (lineBeforeComment == string.Empty) { continue; } foreach (UrlDir.UrlFile blacklistFile in FindFiles(lineBeforeComment, gameData)) { blacklist.Add(blacklistFile); } } } else if (file.fileExtension == "restockwhitelist") { Debug.Log($"[Restock] Reading whitelist {file.url}.{file.fileExtension}"); foreach (string line in File.ReadAllLines(file.fullPath)) { string lineBeforeComment = line.Split(commentSep, 2, StringSplitOptions.None)[0].Trim(); if (lineBeforeComment == string.Empty) { continue; } foreach (UrlDir.UrlFile whitelistFile in FindFiles(lineBeforeComment, gameData)) { whitelist.Add(whitelistFile); } } } } Debug.Log("[Restock] Removing blacklisted assets"); foreach (UrlDir.UrlFile file in blacklist) { if (whitelist.Contains(file)) { continue; } Debug.Log($"[Restock] Removing {file.url}.{file.fileExtension}"); UrlDir.UrlFile newFile2 = new UrlDir.UrlFile(file.parent, new FileInfo(file.fullPath + ".disabled")); file.parent.files[file.parent.files.IndexOf(file)] = newFile2; } Destroy(gameObject); }
public TextureData(GameDatabase.TextureInfo info, UrlDir.UrlFile file) { File = file; Info = info; Info.texture = CreateEmptyThumbnailTexture(); Info.texture.name = Info.name = file.url; }
// Makes lod taking over control over an already loaded texture. public static void ForceManage(GameDatabase.TextureInfo info) { // this one is experimental for now. // it tries to resolve the source file by the textures name (yea, kinda stupid) // it unloads the currently laoded texture // it places an unloaded "dummy" // warning, this might not work with derived TextureInfos! Or think about this replacing TextureInfo in the first place if (iManagedTextures.ContainsKey(info)) { "Texture already managed!".Log(); return; } UrlDir.UrlFile file = Stuff.ResolveTextureInfo(info); // Todo: Resolve file... if (file == null) { throw new NotSupportedException("Could not find a source file for this texture. This kinda textures are not currently supported."); } if (info.texture != null) { UnityEngine.Resources.UnloadAsset(info.texture); } var data = new TextureData(info, file); if (!DelayLoading) { SetupNative(data); // Todo14: See above } "ForceManage, Adding texture".Log(); iManagedTextures.Add(data.Info, data); }
public void TestCreateFile__Url__AlreadyExists() { UrlDir root = UrlBuilder.CreateRoot(); UrlDir.UrlFile file1 = UrlBuilder.CreateFile("abc/def.txt", root); UrlDir.UrlFile file2 = UrlBuilder.CreateFile("abc/def.txt", root); Assert.Same(file1, file2); Assert.Equal("def", file1.name); Assert.Equal("txt", file1.fileExtension); Assert.Equal(UrlDir.FileType.Unknown, file1.fileType); Assert.Equal("abc/def", file1.url); UrlDir parent1 = file1.parent; Assert.NotNull(parent1); Assert.Equal("abc", parent1.name); Assert.Contains(file1, parent1.files); Assert.Same(root, file1.root); Assert.Same(root, parent1.root); Assert.Contains(file1, root.AllFiles); }
public ImageConfigItem(string cacheKey, UrlDir.UrlFile fromFile) { ImageSettings = new ImageSettings(); CacheKey = cacheKey; FileUrl = fromFile.url + "." + fromFile.fileExtension; updateVerificationData(fromFile); }
public PatchExtractorTest() { root = UrlBuilder.CreateRoot(); file = UrlBuilder.CreateFile("abc/def.cfg", root); progress = Substitute.For <IPatchProgress>(); }
public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo fileInfo) { if (_fallbackFont == null) { _fallbackFont = Resources.FindObjectsOfTypeAll <TMP_FontAsset>().First(o => o.name == FallbackName); if (_fallbackFont == null) { Logging.LogError($"Could not find fallback font '{FallbackName}'"); } } Logging.Log($"Loading font file '{urlFile.fullPath}'"); var bundle = AssetBundle.LoadFromFile(urlFile.fullPath); if (!bundle) { Logging.Log($"Could not load font asset {urlFile.fullPath}"); } else { var loadedFonts = bundle.LoadAllAssets <TMP_FontAsset>(); foreach (var font in loadedFonts) { Logging.Log($"Adding font {font.name}"); font.fallbackFontAssets.Add(_fallbackFont); } } yield break; }
public static void Init() { // log version Lib.Log("version " + Lib.Version()); // parse settings Settings.Parse(); // parse profile Profile.Parse(); // detect features Features.Detect(); // get configs from DB UrlDir.UrlFile root = null; foreach (UrlDir.UrlConfig url in GameDatabase.Instance.root.AllConfigs) { root = url.parent; break; } // inject MM patches on-the-fly, so that profile/features can be queried with NEEDS[] Inject(root, "Profile", Lib.UppercaseFirst(Settings.Profile)); if (Features.Reliability) Inject(root, "Feature", "Reliability"); if (Features.Deploy) Inject(root, "Feature", "Deploy"); if (Features.SpaceWeather) Inject(root, "Feature", "SpaceWeather"); if (Features.Automation) Inject(root, "Feature", "Automation"); if (Features.Science) Inject(root, "Feature", "Science"); if (Features.Radiation) Inject(root, "Feature", "Radiation"); if (Features.Shielding) Inject(root, "Feature", "Shielding"); if (Features.LivingSpace) Inject(root, "Feature", "LivingSpace"); if (Features.Comfort) Inject(root, "Feature", "Comfort"); if (Features.Poisoning) Inject(root, "Feature", "Poisoning"); if (Features.Pressure) Inject(root, "Feature", "Pressure"); if (Features.Humidity) Inject(root, "Feature", "Humidity"); if (Features.Habitat) Inject(root, "Feature", "Habitat"); if (Features.Supplies) Inject(root, "Feature", "Supplies"); }
public void TestUrlFile() { UrlDir.UrlFile urlFile = UrlBuilder.CreateFile("abc/def.cfg"); ProtoUrlConfig protoUrlConfig = new ProtoUrlConfig(urlFile, new ConfigNode()); Assert.Same(urlFile, protoUrlConfig.UrlFile); }
// Get the model file name for a part by reading the cfg file contents UrlDir.UrlFile GetModelFile(Part part) { AvailablePart availablePart = part.partInfo; /* * TESTS * Debug.Log("AvailPart: " + availablePart.name); * Debug.Log("mesh: " + availablePart.partConfig.GetValue("mesh")); * Debug.Log("MODEL: " + * (availablePart.partConfig.GetNode("MODEL") != null ? * availablePart.partConfig.GetNode("MODEL").GetValue("model") : * "none")); */ // Check for an entry in either the PART.model property or the PART.MODEL.model value string modelName = availablePart.partConfig.GetValue("mesh"); if (modelName != null) { // The "url" is on the firmat "Parts/<PartType>/<ConfigFileName>/<PartName> // We need to strip away the ConfigFileName and PartName to get the real path string[] urlParts = availablePart.partUrl.Split('/'); string url = ""; for (int i = 0; i < urlParts.Count() - 2; i++) { url += urlParts[i] + "/"; } modelName = url + modelName; } else { modelName = availablePart.partConfig.GetNode("MODEL").GetValue("model") + ".mu"; } // Calculate the proper URLs for the file string directory = Path.GetDirectoryName(modelName); FileInfo file = new FileInfo("GameData/" + modelName); // Generate the root directory UrlDir root = UrlBuilder.CreateDir(directory); UrlDir.UrlFile modelFile = new UrlDir.UrlFile(root, file); // Apperently, if the file is name "model.mu" the reader is supposed to just // pick the first file in the folder... =S if (!File.Exists("GameData/" + modelName)) { IEnumerable <UrlDir.UrlFile> modelFiles = root.GetFiles(UrlDir.FileType.Model); foreach (UrlDir.UrlFile mFile in modelFiles) { Debug.Log("modelFiles: " + mFile.name); } } // Create the full path and name of the model file return(modelFile); }
public void TestFind__DirectChild() { UrlDir urlDir = UrlBuilder.CreateDir("abc"); UrlDir.UrlFile urlFile = UrlBuilder.CreateFile("def.cfg", urlDir); Assert.Equal(urlFile, urlDir.Find("def")); }
public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo file) { GameDatabase.TextureInfo texInfo = TexRefCnt.Load(urlFile); obj = texInfo; successful = true; yield return(null); }
internal static GameDatabase.TextureInfo Load(UrlDir.UrlFile urlFile) { UrlDir.UrlFile file = urlFile; string hash = TexRefCnt.GetMD5String(file.fullPath); string urlReplace = TexPatchLoader.GetReplacement(file.url); if (urlReplace != null) { // file = getReplacementFile(urlReplace); // hash = TexRefCnt.GetMD5String(file.fullPath); GameDatabase.TextureInfo dummy = new GameDatabase.TextureInfo(file, new Texture2D(2, 2), false, false, false); dummy.name = file.url; dummy.texture.name = dummy.name; return(dummy); } GameDatabase.TextureInfo texInfo = new GameDatabase.TextureInfo(file, null, false, false, false); bool hasMipmaps = updateToStockSettings(texInfo); string cached = Directory.GetParent(Assembly.GetExecutingAssembly().Location) + "/ScaledTexCache/" + Path.GetFileName(file.url) + "_hash_" + hash; Loader.Log("hash: " + hash); if (texHashDictionary.ContainsKey(hash)) { Loader.Log("Loaded From hash"); texInfo.texture = texHashDictionary[hash]; } else if (File.Exists(cached)) { Loader.Log("Loaded From cache @" + cached); byte[] cache = System.IO.File.ReadAllBytes(cached); TextureFormat format = texInfo.isCompressed ? TextureFormat.DXT5 : TextureFormat.ARGB32; texInfo.texture = new Texture2D(32, 32, format, hasMipmaps); if (texInfo.file.fileExtension == "dds") { //texInfo.isReadable = true; } texInfo.texture.Apply(hasMipmaps, !texInfo.isReadable); texInfo.texture.LoadImage(cache); texHashDictionary[hash] = texInfo.texture; //add texture reference. TexRefCnt texRef = new TexRefCnt(texInfo, hash, true); texInfo.texture.name = file.url; } else { TextureConverter.Reload(texInfo, false, default(Vector2), null, hasMipmaps); texHashDictionary[hash] = texInfo.texture; TexRefCnt texRef = new TexRefCnt(texInfo, hash, false); texInfo.texture.name = file.url; } Loader.Log(texInfo.file.fileExtension + " c: " + texInfo.isCompressed + " n: " + texInfo.isNormalMap + " r: " + texInfo.isReadable + " m: " + (texInfo.texture.mipmapCount > 1)); texInfo.name = urlFile.url; Loader.Log(texInfo.name + " -> " + texInfo.texture.name); return(texInfo); }
public PatchApplierTest() { logger = Substitute.For <IBasicLogger>(); progress = Substitute.For <IPatchProgress>(); databaseRoot = UrlBuilder.CreateRoot(); file = UrlBuilder.CreateFile("abc/def.cfg", databaseRoot); patchList = new PatchList(modList); patchApplier = new PatchApplier(patchList, databaseRoot, progress, logger); }
public NeedsCheckerTest() { root = UrlBuilder.CreateRoot(); gameData = UrlBuilder.CreateGameData(root); file = UrlBuilder.CreateFile("abc/def.cfg", gameData); progress = Substitute.For <IPatchProgress>(); logger = Substitute.For <IBasicLogger>(); }
public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo file) { TexInfo t = new TexInfo(urlFile.url); GameDatabase.TextureInfo texture = UpdateTexture(t); obj = texture; successful = true; yield return(null); }
public void TestFind__Extension() { UrlDir urlDir = UrlBuilder.CreateDir("abc"); UrlBuilder.CreateFile("def/ghi.yyy", urlDir); UrlDir.UrlFile urlFile = UrlBuilder.CreateFile("def/ghi.cfg", urlDir); UrlBuilder.CreateFile("def/ghi.zzz", urlDir); Assert.Equal(urlFile, urlDir.Find("def/ghi.cfg")); }
ImageConfigItem addFileToCache(string key, UrlDir.UrlFile file) { var item = new ImageConfigItem(key, file); item.clearCache(GetCacheDirectory()); CachedDataPerKey.Add(key, item); CachedDataPerResUrl.Add(item.FileUrl, item); IsDirty = true; return(item); }
public TexInfo(UrlDir.UrlFile file) { this.file = file; this.name = file.url; this.isNormalMap = DatabaseLoaderTexture_ATM.IsNormal(name); this.width = 1; this.height = 1; loadOriginalFirst = false; needsResize = false; makeNotReadable = true; }
public static UrlDir.UrlConfig CreateConfig(string url, ConfigNode node, UrlDir parent = null) { if (Path.GetExtension(url) != ".cfg") { url += ".cfg"; } UrlDir.UrlFile file = CreateFile(url, parent); return(CreateConfig(node, file)); }
public override IEnumerator Load(UrlDir.UrlFile urlFile, FileInfo file) { GameDatabase.TextureInfo texInfo = Load(urlFile); if (texInfo != null) { obj = texInfo; successful = true; } yield return(null); }
// Convert the settings defined by the user into MM :FOR[] nodes public IEnumerable <String> ModuleManagerAddToModList() { if (_settingsApplied) { return(null); } _settingsApplied = true; UrlDir.UrlFile file = GameDatabase.Instance.GetConfigs("InterstellarConsortium")[0].parent; return(ConvertToTags(InterstellarSettings.Instance.Settings, "IC")); }
// inject an MM patch on-the-fly, so that NEEDS[TypeId] can be used in MM patches static void Inject(UrlDir.UrlFile root, string type, string id) { Lib.Log(Lib.BuildString("Injecting ", type, id)); if (ModuleManager.MM_major >= 4) { MM40Injector.AddInjector(type, id); } else { root.configs.Add(new UrlDir.UrlConfig(root, new ConfigNode(Lib.BuildString("@Kerbalism:FOR[", type, id, "]")))); } }
public void Start() { PartResourceLibrary.Instance.LoadDefinitions(); ConfigNode paramsNode = null; foreach (ConfigNode n in GameDatabase.Instance.GetConfigNodes("LRTRCONFIG")) { paramsNode = n; } if (paramsNode == null) { Debug.LogError("[LRTRCONFIG] Could not find LRTRCONFIG node."); return; } // get configs from DB UrlDir.UrlFile root = null; foreach (UrlDir.UrlConfig url in GameDatabase.Instance.root.AllConfigs) { root = url.parent; break; } // get mod directories UrlDir gameData = GameDatabase.Instance.root.children.First(dir => dir.type == UrlDir.DirectoryType.GameData); foreach (ConfigNode feature in paramsNode.GetNodes()) { bool enableFeature = false; if (feature.GetValue("enabled") != null) { enableFeature = feature.GetValue("enabled").ToLower() == "true"; } string[] disabledBy = feature.GetValues("disabledBy"); foreach (string modName in disabledBy) { foreach (UrlDir subDir in gameData.children) { if (String.Compare(modName, subDir.name, true) == 0) { enableFeature = false; Debug.Log("[LRTRCONFIG] " + feature.name + " disabled by " + modName); } } } if (enableFeature) { Inject(root, "LRTR", feature.name); } } }
public ProtoUrlConfig(UrlDir.UrlFile urlFile, ConfigNode node) { UrlFile = urlFile ?? throw new ArgumentNullException(nameof(urlFile)); Node = node ?? throw new ArgumentNullException(nameof(node)); FileUrl = UrlFile.url + '.' + urlFile.fileExtension; FullUrl = FileUrl + '/' + Node.name; if (node.GetValue("name") is string nameValue) { FullUrl += '[' + nameValue + ']'; } }
// inject an MM patch on-the-fly, so that NEEDS[TypeId] can be used in MM patches static void Inject(UrlDir.UrlFile root, string type, string id) { Debug.Log("[LRTRCONFIG] " + id + " enabled"); if (ModuleManager.MM_major >= 4) { MM40Injector.AddInjector(type, id); } else { root.configs.Add(new UrlDir.UrlConfig(root, new ConfigNode("@LRTR:FOR[" + type + id + "]"))); } }
private void LoadCache() { // Clear the config DB foreach (UrlDir.UrlFile files in GameDatabase.Instance.root.AllConfigFiles) { files.configs.Clear(); } // And then load all the cached configs ConfigNode cache = ConfigNode.Load(cachePath); if (cache.HasValue("patchedNodeCount")) int.TryParse(cache.GetValue("patchedNodeCount"), out patchedNodeCount); if (cache.HasValue("catEatenCount")) int.TryParse(cache.GetValue("catEatenCount"), out catEatenCount); // Create the fake file where we load the physic config cache UrlDir gameDataDir = GameDatabase.Instance.root.AllDirectories.First(d => d.path.EndsWith("GameData") && d.name == "" && d.url == ""); // need to use a file with a cfg extension to get the right fileType or you can't AddConfig on it physicsUrlFile = new UrlDir.UrlFile(gameDataDir, new FileInfo(defaultPhysicsPath)); gameDataDir.files.Add(physicsUrlFile); foreach (ConfigNode node in cache.nodes) { string name = node.GetValue("name"); string type = node.GetValue("type"); string parentUrl = node.GetValue("parentUrl"); string url = node.GetValue("url"); UrlDir.UrlFile parent = GameDatabase.Instance.root.AllConfigFiles.FirstOrDefault(f => f.url == parentUrl); if (parent != null) { parent.AddConfig(node.nodes[0]); } else { log("Parent null for " + parentUrl); } } log("Cache Loaded"); }
private void LoadPhysicsConfig() { log("Loading Physics.cfg"); UrlDir gameDataDir = GameDatabase.Instance.root.AllDirectories.First(d => d.path.EndsWith("GameData") && d.name == "" && d.url == ""); // need to use a file with a cfg extenssion to get the right fileType or you can't AddConfig on it physicsUrlFile = new UrlDir.UrlFile(gameDataDir, new FileInfo(defaultPhysicsPath)); // Since it loaded the default config badly (sub node only) we clear it first physicsUrlFile.configs.Clear(); // And reload it properly ConfigNode physicsContent = ConfigNode.Load(defaultPhysicsPath); physicsContent.name = "PHYSICSGLOBALS"; physicsUrlFile.AddConfig(physicsContent); gameDataDir.files.Add(physicsUrlFile); }