public static FObjectExport ReadEntry(IOMemoryStream ms, UassetFile f) { //Read in FObjectExport g = new FObjectExport(); g.entryLocation = ms.position; g.id = ms.ReadInt(); g.unknown1 = ms.ReadInt(); g.unknown2 = ms.ReadInt(); g.unknown3 = ms.ReadInt(); g.type = ms.ReadNameTableEntry(f); g.unknown4 = ms.ReadInt(); g.unknown5 = ms.ReadInt(); g.LengthOffset = (int)ms.position; g.dataLength = ms.ReadInt(); g.dataLocation = ms.ReadInt(); g.unknown6 = ms.ReadInt(); g.unknown7 = ms.ReadInt(); g.unknown8 = ms.ReadInt(); g.unknown9 = ms.ReadInt(); g.unknown10 = ms.ReadInt(); g.unknown11 = ms.ReadInt(); g.unknown12 = ms.ReadInt(); g.unknown13 = ms.ReadInt(); g.unknown14 = ms.ReadInt(); g.unknown15 = ms.ReadInt(); g.unknown16 = ms.ReadInt(); g.unknown17 = ms.ReadInt(); g.unknown18 = ms.ReadInt(); g.unknown19 = ms.ReadInt(); g.unknown20 = ms.ReadInt(); g.unknown21 = ms.ReadInt(); g.unknown22 = ms.ReadInt(); long lastPos = ms.position; ms.position = g.dataLocation; g.data = ms.ReadBytes(g.dataLength); ms.position = lastPos; g.uassetFile = f; return(g); }
public DotArkEmbededBinaryData(IOMemoryStream ms) { //First, read the path. path = ms.ReadUEString(); //Now, read the parts. This seems to be split up into part -> blob -> inner blob int parts = ms.ReadInt(); data = new byte[parts][][]; //Loop through each of the parts for (int i = 0; i < parts; i++) { int blobs = ms.ReadInt(); byte[][] partData = new byte[blobs][]; for (int j = 0; j < blobs; j++) { int blobSize = ms.ReadInt() * 4; //Array of 32 bit integers. partData[j] = ms.ReadBytes(blobSize); } data[i] = partData; } }
public static void ProcessImages(List <string> readErrors, DeltaExportPatch patch) { //Clean up any old and bad paths Console.WriteLine("Cleaning up old image conversions..."); if (Directory.Exists("./Lib/UModel/in_temp/")) { Directory.Delete("./Lib/UModel/in_temp/", true); } if (Directory.Exists("./Lib/UModel/out_temp/")) { Directory.Delete("./Lib/UModel/out_temp/", true); } //Make structre Directory.CreateDirectory("./Lib/UModel/in_temp/"); Directory.CreateDirectory("./Lib/UModel/out_temp/"); //Get the queue var queue = patch.queued_images; //First, we copy all packages to a temporary path with their index Console.WriteLine($"Now copying {queue.Count} images..."); for (int i = 0; i < queue.Count; i++) { string source = queue[i].pathname; File.Copy(source, $"./Lib/UModel/in_temp/{i}.uasset"); } //Now, run the conversion Console.WriteLine("Now converting images using UModel..."); Process p = Process.Start(new ProcessStartInfo { Arguments = "", FileName = "go.bat", WorkingDirectory = "Lib\\UModel\\", UseShellExecute = true }); p.WaitForExit(); //Now, load and process these images int ok = 0; Console.WriteLine($"Now processing {queue.Count} images..."); for (int i = 0; i < queue.Count; i += 1) { QueuedImage q = queue[i]; bool status = false; try { //Get the directory. It's a little janky, as files are stored in subdirs string[] results = Directory.GetFiles($"./Lib/UModel/out_temp/{i}/"); if (results.Length != 1) { throw new Exception("None or too many results found for image."); } //Open FileStream on this using (FileStream imgStream = new FileStream(results[0], FileMode.Open, FileAccess.Read)) { //Now, begin reading the TGA data https://en.wikipedia.org/wiki/Truevision_TGA IOMemoryStream imgReader = new IOMemoryStream(imgStream, true); imgReader.position += 3 + 5; //Skip intro, it will always be known imgReader.ReadShort(); //Will always be 0 imgReader.ReadShort(); //Will aways be 0 short width = imgReader.ReadShort(); short height = imgReader.ReadShort(); byte colorDepth = imgReader.ReadByte(); imgReader.ReadByte(); //Now, we can begin reading image data //This appears to be bugged for non-square images right now. using (Image <Rgba32> img = new Image <Rgba32>(width, height)) { //Read file byte[] channels; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { if (colorDepth == 32) { //Read four channels channels = imgReader.ReadBytes(4); //Set pixel img[x, width - y - 1] = new Rgba32(channels[2], channels[1], channels[0], channels[3]); } else if (colorDepth == 24) { //Read three channels channels = imgReader.ReadBytes(3); //Set pixel img[x, width - y - 1] = new Rgba32(channels[2], channels[1], channels[0]); } } } //Apply mods if (q.mods == ImageModifications.White) { ApplyWhiteMod(img); } //Save original image using (MemoryStream ms = new MemoryStream()) { img.SaveAsPng(ms); ms.Position = 0; patch.asset_manager.Upload(Program.config.GetProfile().upload_images + q.hiId + FORMAT_TYPE, ms); } //Now, downscale img.Mutate(x => x.Resize(64, 64)); //Save thumbnail using (MemoryStream ms = new MemoryStream()) { img.SaveAsPng(ms, new PngEncoder { CompressionLevel = 9 }); ms.Position = 0; patch.asset_manager.Upload(Program.config.GetProfile().upload_images + q.loId + FORMAT_TYPE, ms); } status = true; ok++; } } } catch (Exception ex) { Console.WriteLine($"Failed to process image {q.classname} with error {ex.Message}"); readErrors.Add($"Failed to process image {q.classname} with error {ex.Message} {ex.StackTrace}"); } //Now, add to persistent storage patch.persist.external_assets.Add(new DeltaExportBranchExternalAsset { name = q.name, patch = patch.tag, sha1 = q.sha1, time = DateTime.UtcNow, id_hires = q.hiId, id_lores = q.loId, ok = status }); } Log.WriteSuccess("ImageTool", $"Processed and uploading {ok}/{queue.Count} images."); queue.Clear(); //Clean up any old and bad paths Console.WriteLine("Cleaning up..."); if (Directory.Exists("./Lib/UModel/in_temp/")) { Directory.Delete("./Lib/UModel/in_temp/", true); } if (Directory.Exists("./Lib/UModel/out_temp/")) { Directory.Delete("./Lib/UModel/out_temp/", true); } }
public UassetFile(byte[] data, string fullPath) { Fullpath = fullPath; Filename = Path.GetFileNameWithoutExtension(Fullpath); //Create a stream stream = new IOMemoryStream(new MemoryStream(data), true); stream.position = 0; var signature = stream.ReadUInt(); // Check for the file's signature. if (signature != UNREAL_ASSET_MAGIC) { TKContext.LogError("The file provided is not a valid uasset file."); return; } Version = stream.ReadUInt(); stream.ReadBytes(0x10); UnkOffset = stream.ReadInt(); stream.ReadInt(); PackageGroup = Encoding.ASCII.GetString(stream.ReadBytes(0x4)); stream.ReadBytes(0x1); PackageFlags = stream.ReadUInt(); NamesCount = stream.ReadInt(); NamesOffset = stream.ReadInt(); stream.ReadBytes(0x8); ExportsCount = stream.ReadInt(); ExportsOffset = stream.ReadInt(); ImportsCount = stream.ReadInt(); ImportsOffset = stream.ReadInt(); stream.ReadBytes(0x8); UnkOffset2 = stream.ReadInt(); stream.ReadBytes(0x1C); NamesCount2 = stream.ReadInt(); stream.ReadBytes(0x2C); UnkOffset3 = stream.ReadInt(); EndOfFileOffset = stream.ReadInt(); stream.ReadBytes(0x10); UnkOffset4 = stream.ReadInt(); stream.position = NamesOffset; NamesTable = stream.ReadFNameEntries(NamesCount, UE4Version.UE4__4_14); for (int i = 0; i < NamesCount; i++) { TKContext.DebugLog("UassetFile", $"Name Table Entry {i}", NamesTable[i].Name, ConsoleColor.Yellow); } TKContext.LogInner("INFO", $"Uasset names count is {NamesCount}"); //Starts directly after the name table. Assume we're already there ImportsTable = new FObjectImport[ImportsCount]; for (int i = 0; i < ImportsCount; i++) { FObjectImport h = FObjectImport.ReadEntry(stream, this); ImportsTable[i] = h; DebugDump($"FObjectImport {i} @ {h.startPos}", ConsoleColor.Blue, "cType", h.coreType, "u1", h.unknown1.ToString(), "oType", h.objectType, "u2", h.unknown2.ToString(), "i", h.index.ToString(), "name", h.name, "u4", h.unknown4.ToString()); } TKContext.LogInner("INFO", $"Uasset import table size is {ImportsCount}"); //Starts directly after the referenced GameObject table. Assume we're already there ExportsTable = new FObjectExport[ExportsCount]; for (int i = 0; i < ExportsCount; i++) { ExportsTable[i] = FObjectExport.ReadEntry(stream, this); DebugDump($"FObjectExport {i} @ {ExportsTable[i].entryLocation}", ConsoleColor.Magenta, "id", ExportsTable[i].id.ToString(), "u2", ExportsTable[i].unknown2.ToString(), "u3", ExportsTable[i].unknown3.ToString(), "type", ExportsTable[i].type, "u4", ExportsTable[i].unknown4.ToString(), "u5", ExportsTable[i].unknown5.ToString(), "length", ExportsTable[i].dataLength.ToString(), "location", ExportsTable[i].dataLocation.ToString(), "u6", ExportsTable[i].unknown6.ToString(), "u7", ExportsTable[i].unknown7.ToString(), "u8", ExportsTable[i].unknown8.ToString(), "u9", ExportsTable[i].unknown9.ToString(), "u10", ExportsTable[i].unknown10.ToString(), "u11", ExportsTable[i].unknown11.ToString(), "u12", ExportsTable[i].unknown12.ToString(), "u13", ExportsTable[i].unknown13.ToString(), "u14", ExportsTable[i].unknown14.ToString(), "u15", ExportsTable[i].unknown15.ToString(), "u16", ExportsTable[i].unknown16.ToString(), "u17", ExportsTable[i].unknown17.ToString(), "u18", ExportsTable[i].unknown18.ToString(), "u19", ExportsTable[i].unknown19.ToString(), "u20", ExportsTable[i].unknown20.ToString(), "u21", ExportsTable[i].unknown21.ToString(), "u22", ExportsTable[i].unknown22.ToString()); } TKContext.LogInner("INFO", $"Uasset export table size is {ExportsCount}"); using (MemoryStream ms = new MemoryStream()) { stream.position = 0; stream.ms.CopyTo(ms); stream.Close(); FileData = ms.ToArray(); } }
public override void Read(IOMemoryStream ms, UAssetFile f) { //Not really sure how this works....this is just what my original program written 6 months ago does data = Convert.ToBase64String(ms.ReadBytes(length)); }
public byte[] GetSerializedData(IOMemoryStream ms) { ms.position = dataLocation; return(ms.ReadBytes(dataLength)); }