public TryOpen ( string filename, Stream &s ) : bool | ||
filename | string | |
s | Stream | |
return | bool |
public ObjectCreator(Manifest manifest, FileSystem.FileSystem modFiles) { typeCache = new Cache <string, Type>(FindType); ctorCache = new Cache <Type, ConstructorInfo>(GetCtor); // Allow mods to load types from the core Game assembly, and any additional assemblies they specify. var assemblyList = new List <Assembly>() { typeof(Game).Assembly }; foreach (var path in manifest.Assemblies) { var data = modFiles.Open(path).ReadAllBytes(); // .NET doesn't provide any way of querying the metadata of an assembly without either: // (a) loading duplicate data into the application domain, breaking the world. // (b) crashing if the assembly has already been loaded. // We can't check the internal name of the assembly, so we'll work off the data instead var hash = CryptoUtil.SHA1Hash(data); Assembly assembly; if (!ResolvedAssemblies.TryGetValue(hash, out assembly)) { Stream symbolStream = null; var hasSymbols = false; // Mono has its own symbol format. if (isMonoRuntime) { hasSymbols = modFiles.TryOpen(path + ".mdb", out symbolStream); } // .NET uses .pdb files. else { hasSymbols = modFiles.TryOpen(path.Substring(0, path.Length - 4) + ".pdb", out symbolStream); } assembly = hasSymbols ? Assembly.Load(data, symbolStream.ReadAllBytes()) : Assembly.Load(data); ResolvedAssemblies.Add(hash, assembly); } assemblyList.Add(assembly); } AppDomain.CurrentDomain.AssemblyResolve += ResolveAssembly; assemblies = assemblyList.SelectMany(asm => asm.GetNamespaces().Select(ns => Pair.New(asm, ns))).ToArray(); AppDomain.CurrentDomain.AssemblyResolve -= ResolveAssembly; }
public bool TryParsePackage(Stream s, string filename, FS context, out IReadOnlyPackage package) { if (filename.EndsWith(".lpk")) { s = Crypter.Decrypt(s); } var signature = s.ReadASCII(4); s.Position -= 4; if (!signature.Equals("DATA") && !signature.Equals("DAT2")) { package = null; return(false); } Stream lvlLookup; context.TryOpen("LvlLookup.yaml", out lvlLookup); package = new LvlPackage(s, filename, MiniYaml.FromStream(lvlLookup).ToDictionary(x => x.Key, x => x.Value)); return(true); }
bool IPackageLoader.TryParsePackage(Stream s, string filename, FS context, out IReadOnlyPackage package) { if (!filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase)) { package = null; return(false); } // Load the global mix database if (globalFilenames == null) { if (context.TryOpen("global mix database.dat", out var mixDatabase)) { using (var db = new XccGlobalDatabase(mixDatabase)) globalFilenames = db.Entries.Distinct().ToArray(); } } package = new MixFile(s, filename, globalFilenames ?? Array.Empty <string>()); return(true); }
bool IPackageLoader.TryParsePackage(Stream s, string filename, FS context, out IReadOnlyPackage package) { if (!filename.EndsWith(".mix", StringComparison.InvariantCultureIgnoreCase)) { package = null; return(false); } // Load the global mix database var allPossibleFilenames = new HashSet <string>(); if (context.TryOpen("global mix database.dat", out var mixDatabase)) { using (var db = new XccGlobalDatabase(mixDatabase)) foreach (var e in db.Entries) { allPossibleFilenames.Add(e); } } package = new MixFile(s, filename, allPossibleFilenames); return(true); }
public StfFile(Stream stream, string filename, OpenRA.FileSystem.FileSystem filesystem) { this.stream = stream; Name = filename; var container = new StfContainer(stream); index = container.Files; contents.AddRange(index.Keys); Stream remapStream; if (!filesystem.TryOpen(filename + ".yaml", out remapStream)) { return; } var remapYaml = MiniYaml.FromStream(remapStream); var aniLoader = new AniLoader(); foreach (var entry in remapYaml) { var targetAni = entry.Key; var targetFrames = new List <AniLoader.AniSpriteFrame>(); foreach (var set in entry.Value.Value.Split(' ')) { var flipX = set.Contains("x"); var flipY = set.Contains("y"); var sourceParts = set.Replace("x", "").Replace("y", "").Split(':'); ISpriteFrame[] sourceFrames; aniLoader.TryParseSprite(GetStream(sourceParts[0] + ".ani"), out sourceFrames); var targetFramesList = new List <int>(); if (sourceParts[1].Contains("-")) { var rangeParts = sourceParts[1].Split('-'); var from = int.Parse(rangeParts[0]); var to = rangeParts.Length > 1 ? int.Parse(rangeParts[1]) : from; if (from < to) { for (var i = from; i <= to; i++) { targetFramesList.Add(i); } } else { for (var i = from; i >= to; i--) { targetFramesList.Add(i); } } } else { targetFramesList.Add(int.Parse(sourceParts[1])); } foreach (var frameId in targetFramesList) { var sourceFrame = sourceFrames[frameId] as AniLoader.AniSpriteFrame; if (flipX) { var newData = new byte[sourceFrame.Data.Length]; for (var y = 0; y < sourceFrame.Size.Height; y++) { for (var x = 0; x < sourceFrame.Size.Width; x++) { newData[y * sourceFrame.Size.Width + sourceFrame.Size.Width - x - 1] = sourceFrame.Data[y * sourceFrame.Size.Width + x]; } } sourceFrame.Data = newData; sourceFrame.OffsetOrigin = new int2((sourceFrame.Size.Width - sourceFrame.OffsetOrigin.X * 2 - 1) / 2, sourceFrame.OffsetOrigin.Y); } if (flipY) { var newData = new byte[sourceFrame.Data.Length]; for (var y = 0; y < sourceFrame.Size.Height; y++) { for (var x = 0; x < sourceFrame.Size.Width; x++) { newData[(sourceFrame.Size.Height - y - 1) * sourceFrame.Size.Width + x] = sourceFrame.Data[y * sourceFrame.Size.Width + x]; } } sourceFrame.Data = newData; sourceFrame.OffsetOrigin = new int2(sourceFrame.OffsetOrigin.X, sourceFrame.Size.Height - sourceFrame.OffsetOrigin.Y - 1); } targetFrames.Add(sourceFrame); } } var currentFrameOffset = 0; var virtualStream = new MemoryStream(); virtualStream.Write(BitConverter.GetBytes((ushort)targetFrames.Count), 0, 2); virtualStream.Write(targetFrames.Count * 18); virtualStream.Write(0); virtualStream.Write(BitConverter.GetBytes((ushort)0xfefe), 0, 2); foreach (var targetFrame in targetFrames) { virtualStream.Write(targetFrame.OffsetOrigin.X); virtualStream.Write(targetFrame.OffsetOrigin.Y); virtualStream.Write(BitConverter.GetBytes((ushort)targetFrame.Size.Width / 2), 0, 2); virtualStream.Write(BitConverter.GetBytes((ushort)targetFrame.Size.Height), 0, 2); virtualStream.Write(BitConverter.GetBytes((ushort)0), 0, 2); // priority virtualStream.Write(currentFrameOffset); currentFrameOffset += targetFrame.Data.Length / 2; } foreach (var targetFrame in targetFrames) { for (var y = 0; y < targetFrame.Size.Height; y++) { for (var x = 0; x < targetFrame.Size.Width; x += 2) { virtualStream.WriteByte(targetFrame.Data[y * targetFrame.Size.Width + x]); } } } virtualAnis.Add(targetAni + ".ani", virtualStream.ToArray()); } contents.AddRange(virtualAnis.Keys); }
public LvlPackage(Stream s, string filename, FS context) { stream = s; Name = filename; var lvlLookup = new Dictionary <string, string>(); var updateLookup = false; Stream s2; if (context.TryOpen(filename + ".yaml", out s2)) { lvlLookup = MiniYaml.FromStream(s2).ToDictionary(x => x.Key, x => x.Value.Value); } var fileTypeListOffset = s.ReadUInt32(); s.Position = fileTypeListOffset; uint firstFileListOffset = 0; for (var i = 0; s.Position < s.Length; i++) { s.Position = fileTypeListOffset + i * 8; var fileType = s.ReadASCII(4); var fileListOffset = s.ReadUInt32(); // List terminator reached. if (fileListOffset == 0) { break; } // We need this to calculate the last fileLength. if (firstFileListOffset == 0) { firstFileListOffset = fileListOffset; } // To determine when this list ends, check the next entry s.Position += 4; var fileListEndOffset = s.ReadUInt32(); // List terminator reached, so assume the list goes on till the fileTypeList starts. if (fileListEndOffset == 0) { fileListEndOffset = fileTypeListOffset; } s.Position = fileListOffset; for (var j = 0; s.Position < fileListEndOffset; j++) { var fileOffset = s.ReadUInt32(); // Removed file, still increments fileId. if (fileOffset == 0) { continue; } // As the fileLength is nowhere stored, but files always follow in order, calculate the previous fileLength. if (index.Count > 0) { var entry = index.ElementAt(index.Count - 1).Value; entry[1] = fileOffset - entry[0]; } var assetFileName = j + "." + fileType.ToLower(); // Lookup assumed original filename for better readability in yaml files. if (lvlLookup.ContainsKey(assetFileName)) { assetFileName = lvlLookup[assetFileName]; } else { lvlLookup.Add(assetFileName, assetFileName); updateLookup = true; } index.Add(assetFileName, new uint[] { fileOffset, 0 }); } } // Calculate the last fileLength. if (index.Count > 0) { var entry = index.ElementAt(index.Count - 1).Value; entry[1] = firstFileListOffset - entry[0]; } if (updateLookup) { File.WriteAllText(filename + ".yaml", lvlLookup.Select(e => e.Key + ": " + e.Value).JoinWith("\n") + "\n"); } /*if (!Directory.Exists("XTRACT/" + filename)) * Directory.CreateDirectory("XTRACT/" + filename); * * foreach (var entry in index) * { * stream.Position = entry.Value[0]; * File.WriteAllBytes("XTRACT/" + filename + "/" + entry.Key, stream.ReadBytes((int)entry.Value[1])); * }*/ }