public static byte[] GetObjectData(Version m_version, GPUPlatform m_graphicApi, ShaderSubProgram shaderSubProgram) { var shaderData = shaderSubProgram.ProgramData.ToArray(); int dataOffset = 0; if (IsOffset(m_graphicApi)) { dataOffset = IsOffset5(m_version) ? 5 : 6; uint fourCC = BitConverter.ToUInt32(shaderData, dataOffset); if (fourCC != DXBCFourCC) { throw new Exception("Magic number doesn't match"); } } int length = shaderData.Length - dataOffset; var memoryStream = new MemoryStream(shaderData, dataOffset, length); var outStream = new MemoryStream(); using (var reader = new EndianReader(memoryStream)) using (var writer = new EndianWriter(outStream)) { var magicBytes = reader.ReadBytes(4); var checksum = reader.ReadBytes(16); var unknown0 = reader.ReadUInt32(); var totalSize = reader.ReadUInt32(); var chunkCount = reader.ReadUInt32(); var chunkOffsets = new List <uint>(); for (int i = 0; i < chunkCount; i++) { chunkOffsets.Add(reader.ReadUInt32()); } var offset = (uint)memoryStream.Position + 4; var resourceChunkData = GetResourceChunk(shaderSubProgram); //Adjust for new chunk totalSize += (uint)resourceChunkData.Length; for (int i = 0; i < chunkCount; i++) { chunkOffsets[i] += (uint)resourceChunkData.Length + 4; } chunkOffsets.Insert(0, offset); chunkCount += 1; totalSize += (uint)resourceChunkData.Length; writer.Write(magicBytes); writer.Write(checksum); writer.Write(unknown0); writer.Write(totalSize); writer.Write(chunkCount); foreach (var chunkOffset in chunkOffsets) { writer.Write(chunkOffset); } writer.Write(resourceChunkData); var rest = reader.ReadBytes((int)memoryStream.Length - (int)memoryStream.Position); writer.Write(rest); return(outStream.ToArray()); } }
private static ShaderTextExporter ShaderExporterInstantiator(Version version, ShaderGpuProgramType programType) { if (programType.IsDX()) { return(new ShaderDXExporter(version, programType)); } return(Shader.DefaultShaderExporterInstantiator(version, programType)); }
private static bool IsUseUnityCrunch(Version version, TextureFormat format) { if (version.IsGreaterEqual(2017, 3)) { return(true); } return(format == TextureFormat.ETC_RGB4Crunched || format == TextureFormat.ETC2_RGBA8Crunched); }
public static byte[] RestoreProgramData(BinaryReader reader, Version version, ref ShaderSubProgram shaderSubProgram) { using (MemoryStream dest = new MemoryStream()) { using (BinaryWriter writer = new BinaryWriter(dest)) { uint baseOffset = (uint)reader.BaseStream.Position; byte[] magicBytes = reader.ReadBytes(4); byte[] checksum = reader.ReadBytes(16); uint unknown0 = reader.ReadUInt32(); uint totalSize = reader.ReadUInt32(); uint chunkCount = reader.ReadUInt32(); List <uint> chunkOffsets = new List <uint>(); for (int i = 0; i < chunkCount; i++) { chunkOffsets.Add(reader.ReadUInt32()); } uint bodyOffset = (uint)reader.BaseStream.Position; // Check if shader already has resource chunk foreach (uint chunkOffset in chunkOffsets) { reader.BaseStream.Position = chunkOffset + baseOffset; uint fourCc = reader.ReadUInt32(); if (fourCc == RDEFFourCC) { reader.BaseStream.Position = baseOffset; byte[] original = reader.ReadBytes((int)reader.BaseStream.Length); return(original); } } reader.BaseStream.Position = bodyOffset; byte[] resourceChunkData = GetResourceChunk(version, ref shaderSubProgram); //Adjust for new chunk totalSize += (uint)resourceChunkData.Length; for (int i = 0; i < chunkCount; i++) { chunkOffsets[i] += (uint)resourceChunkData.Length + 4; } chunkOffsets.Insert(0, bodyOffset - baseOffset + 4); chunkCount += 1; totalSize += (uint)resourceChunkData.Length; writer.Write(magicBytes); writer.Write(checksum); writer.Write(unknown0); writer.Write(totalSize); writer.Write(chunkCount); foreach (uint chunkOffset in chunkOffsets) { writer.Write(chunkOffset); } writer.Write(resourceChunkData); byte[] rest = reader.ReadBytes((int)reader.BaseStream.Length - (int)reader.BaseStream.Position); writer.Write(rest); return(dest.ToArray()); } } }
private static ShaderTextExporter DefaultShaderExporterInstantiator(Version version, GPUPlatform graphicApi) { switch (graphicApi) { case GPUPlatform.vulkan: return(new ShaderVulkanExporter()); default: return(Shader.DefaultShaderExporterInstantiator(version, graphicApi)); } }
public static byte[] RestoreProgramData(Version version, GPUPlatform graphicApi, ShaderSubProgram shaderSubProgram) { int dataOffset = GetDataOffset(version, graphicApi, shaderSubProgram); using (MemoryStream src = new MemoryStream(shaderSubProgram.ProgramData, dataOffset, shaderSubProgram.ProgramData.Length - dataOffset)) { using (EndianReader reader = new EndianReader(src)) { using (MemoryStream dest = new MemoryStream()) { using (EndianWriter writer = new EndianWriter(dest)) { byte[] magicBytes = reader.ReadBytes(4); byte[] checksum = reader.ReadBytes(16); uint unknown0 = reader.ReadUInt32(); uint totalSize = reader.ReadUInt32(); uint chunkCount = reader.ReadUInt32(); List <uint> chunkOffsets = new List <uint>(); for (int i = 0; i < chunkCount; i++) { chunkOffsets.Add(reader.ReadUInt32()); } uint offset = (uint)src.Position + 4; byte[] resourceChunkData = GetResourceChunk(shaderSubProgram); //Adjust for new chunk totalSize += (uint)resourceChunkData.Length; for (int i = 0; i < chunkCount; i++) { chunkOffsets[i] += (uint)resourceChunkData.Length + 4; } chunkOffsets.Insert(0, offset); chunkCount += 1; totalSize += (uint)resourceChunkData.Length; writer.Write(magicBytes); writer.Write(checksum); writer.Write(unknown0); writer.Write(totalSize); writer.Write(chunkCount); foreach (uint chunkOffset in chunkOffsets) { writer.Write(chunkOffset); } writer.Write(resourceChunkData); byte[] rest = reader.ReadBytes((int)src.Length - (int)src.Position); writer.Write(rest); return(dest.ToArray()); } } } } }
private static byte[] GetResourceChunk(Version version, ref ShaderSubProgram shaderSubprogram) { using (MemoryStream memoryStream = new MemoryStream()) { using (EndianWriter writer = new EndianWriter(memoryStream, EndianType.LittleEndian)) { ResourceChunk resourceChunk = new ResourceChunk(version, ref shaderSubprogram); resourceChunk.Write(writer); //uint size = resourceChunk.Size; //if (memoryStream.Length != resourceChunk.Size) throw new Exception("Expected size does not match actual size"); return(memoryStream.ToArray()); } } }
public static int GetDataOffset(Version version, GPUPlatform graphicApi, ShaderSubProgram shaderSubProgram) { int dataOffset = 0; if (IsOffset(graphicApi)) { dataOffset = IsOffset5(version) ? 5 : 6; uint fourCC = BitConverter.ToUInt32(shaderSubProgram.ProgramData, dataOffset); if (fourCC != DXBCFourCC) { throw new Exception("Magic number doesn't match"); } } return(dataOffset); }
private ShaderTextExporter AssemblyShaderExporterInstantiator(Version version, GPUPlatform graphicApi) { switch (graphicApi) { case GPUPlatform.d3d9: case GPUPlatform.d3d11_9x: case GPUPlatform.d3d11: return(new AsmExporter(graphicApi)); case GPUPlatform.vulkan: return(new ShaderVulkanExporter()); default: return(Shader.DefaultShaderExporterInstantiator(version, graphicApi)); } }
private static ShaderTextExporter ShaderExporterInstantiator(Version version, GPUPlatform graphicApi) { switch (graphicApi) { case GPUPlatform.unknown: return(new ShaderTextExporter()); case GPUPlatform.openGL: case GPUPlatform.gles: case GPUPlatform.gles3: case GPUPlatform.glcore: return(new ShaderGLESExporter()); case GPUPlatform.metal: return(new ShaderMetalExporter(version)); default: return(new DummyShaderTextExporter()); } }
private static ShaderTextExporter ShaderExporterInstantiator(Version version, GPUPlatform graphicApi) { switch (graphicApi) { case GPUPlatform.d3d9: return(new ShaderDXExporter(graphicApi)); case GPUPlatform.d3d11_9x: case GPUPlatform.d3d11: return(new ShaderDXExporter(graphicApi)); //return new ShaderHLSLccExporter(graphicApi); case GPUPlatform.vulkan: return(new ShaderVulkanExporter()); default: return(Shader.DefaultShaderExporterInstantiator(version, graphicApi)); } }
private ShaderTextExporter HLSLShaderExporterInstantiator(Version version, GPUPlatform graphicApi) { switch (graphicApi) { case GPUPlatform.d3d11: var glLang = settings.ShaderExportMode == ShaderExportMode.Metal ? HLSLccWrapper.WrappedGLLang.LANG_METAL : HLSLccWrapper.WrappedGLLang.LANG_DEFAULT; return(new HLSLccExporter(graphicApi, glLang)); case GPUPlatform.d3d9: case GPUPlatform.d3d11_9x: return(new AsmExporter(graphicApi)); case GPUPlatform.vulkan: return(new ShaderVulkanExporter()); default: return(Shader.DefaultShaderExporterInstantiator(version, graphicApi)); } }
public static bool IsEncoded(Version version) { return(version.IsGreaterEqual(5, 3)); }
public static bool IsSerialized(Version version) { return(version.IsGreaterEqual(5, 5)); }
static bool IsReadLocalKeywords(Version version) { return(version.IsGreaterEqual(2019)); }
/// <summary> /// 5.3.0 /// </summary> private static bool IsOffset5(Version version) => version.IsEqual(5, 3);
public GameStructureExporter(ExportSettings settings, IEnumerable <string> files) { GameDir = settings.GameDir; ExportPath = settings.ExportDir; GameStructure = GameStructure.Load(files); Version version = new Version(2017, 3, 0, VersionType.Final, 3); if (string.IsNullOrEmpty(settings.ExportVersion) || settings.ExportVersion.ToLower() == "detect") { //The version in unity default resources and unity_builtin_extra seem to differ from the game version version = GameStructure.FileCollection.GameFiles.Values.Max(t => t.Version); Logger.Log(LogType.Info, LogCategory.Export, $"Version detected as {version.ToString()}"); } else { version = Version.Parse(settings.ExportVersion); Logger.Log(LogType.Info, LogCategory.Export, $"Version set to {version.ToString()}"); } options = new ExportOptions( version, Platform.NoTarget, TransferInstructionFlags.NoTransferInstructionFlags ); var fileCollection = GameStructure.FileCollection; var textureExporter = new TextureAssetExporter(); var engineExporter = new EngineAssetExporter(); fileCollection.Exporter.OverrideExporter(ClassIDType.Material, engineExporter); fileCollection.Exporter.OverrideExporter(ClassIDType.Mesh, engineExporter); fileCollection.Exporter.OverrideExporter(ClassIDType.Shader, new CustomShaderAssetExporter(settings)); fileCollection.Exporter.OverrideExporter(ClassIDType.TextAsset, new TextAssetExporter()); fileCollection.Exporter.OverrideExporter(ClassIDType.AudioClip, new AudioAssetExporter()); fileCollection.Exporter.OverrideExporter(ClassIDType.Font, new FontAssetExporter()); fileCollection.Exporter.OverrideExporter(ClassIDType.MovieTexture, new MovieTextureAssetExporter()); fileCollection.Exporter.OverrideExporter(ClassIDType.Texture2D, engineExporter); fileCollection.Exporter.OverrideExporter(ClassIDType.Texture2D, textureExporter); fileCollection.Exporter.OverrideExporter(ClassIDType.Cubemap, textureExporter); fileCollection.Exporter.OverrideExporter(ClassIDType.Sprite, engineExporter); //engine or texture exporter? fileCollection.Exporter.EventExportStarted += () => { Logger.Log(LogType.Info, LogCategory.Export, "EventExportStarted"); UpdateTitle($"EventExportStarted"); }; fileCollection.Exporter.EventExportPreparationStarted += () => { Logger.Log(LogType.Info, LogCategory.Export, "EventExportPreparationStarted"); UpdateTitle($"EventExportPreparationStarted"); }; fileCollection.Exporter.EventExportPreparationFinished += () => { Logger.Log(LogType.Info, LogCategory.Export, "EventExportPreparationFinished"); UpdateTitle($"EventExportPreparationFinished"); }; fileCollection.Exporter.EventExportFinished += () => { Logger.Log(LogType.Info, LogCategory.Export, "EventExportFinished"); UpdateTitle($"EventExportFinished"); }; fileCollection.Exporter.EventExportStarted += () => { Logger.Log(LogType.Info, LogCategory.Export, "EventExportStarted"); UpdateTitle($"EventExportStarted"); }; fileCollection.Exporter.EventExportProgressUpdated += (int number, int total) => { UpdateTitle($"Exported {number / (float)total * 100:0.#} - {number} of {total}"); }; if (settings.ScriptByName) { foreach (var asset in fileCollection.FetchAssets()) { if (asset is MonoScript script) { using (MD5 md5 = MD5.Create()) { var data = md5.ComputeHash(Encoding.UTF8.GetBytes($"{script.AssemblyName}.{script.Namespace}.{script.ClassName}")); var newGuid = new Guid(data); Util.SetGUID(script, newGuid); } } } } if (settings.ShaderByName) { foreach (var asset in fileCollection.FetchAssets()) { if (asset is Shader shader) { using (MD5 md5 = MD5.Create()) { var data = md5.ComputeHash(Encoding.UTF8.GetBytes($"{shader.ValidName}")); var newGuid = new Guid(data); var engGuid = new GUID(newGuid); Util.SetGUID(shader, newGuid); Console.WriteLine($"Set shader {shader.ValidName} to Guid {engGuid}"); } } } } }
/// <summary> /// 2.1.0 and greater /// </summary> public static bool AlignStrings(Version version) => version.IsGreaterEqual(2, 1);
private static bool IsOffset5(Version version) { return(version.IsEqual(5, 3)); }
/// <summary> /// 2017.1 and greater /// </summary> public static bool AlignArrays(Version version) => version.IsGreaterEqual(2017);
public virtual void DoExport(string filePath, uTinyRipper.Version version, ref ShaderSubProgram subProgram) { }
public void Load(IReadOnlyList <string> args) { try { if (args?.Any() != true) { return; } PrepareExportDirectory("Ripped"); var gameDir = args[0]; var classes = args .FirstOrDefault(arg => arg.StartsWith("--Types=")) .Substring("--Types=".Length) .Split(',') .Select(cls => { if (Enum.TryParse <ClassIDType>(cls, out var result)) { return(result); } return((ClassIDType)(-1)); }) .Where(v => ((int)(v)) >= 0) .ToArray(); var filename = Path.GetFileName(gameDir); var player = Path.Combine(gameDir, $"{filename}.exe"); var playerInfo = FileVersionInfo.GetVersionInfo(player); var unityVersion = playerInfo.ProductVersion; unityVersion = unityVersion.Substring(0, unityVersion.LastIndexOf('.')); var gameStructure = GameStructure.Load(new[] { gameDir }); var fileCollection = gameStructure.FileCollection; ShutItAllDown(fileCollection.Exporter); fileCollection.Exporter.OverrideExporter(ClassIDType.MonoScript, new NoScriptExporter()); foreach (var cls in classes) { EnableExport(cls, fileCollection.Exporter); } Dictionary <string, Guid> AssemblyHash = new Dictionary <string, Guid>(); Dictionary <string, long> ScriptId = new Dictionary <string, long>(); var unityPlayerVersion = new System.Version(unityVersion); var version = new Version(unityPlayerVersion.Major, unityPlayerVersion.Minor, unityPlayerVersion.Revision, VersionType.Final, 3); var options = new ExportOptions( version, Platform.NoTarget, TransferInstructionFlags.NoTransferInstructionFlags ); var serializedFiles = fileCollection.GameFiles.Values; fileCollection.Exporter.Export("Ripped", fileCollection, serializedFiles, options); Logger.Log(LogType.Info, LogCategory.General, "Finished"); } catch (Exception ex) { Logger.Log(LogType.Error, LogCategory.General, ex.ToString()); } }