Beispiel #1
0
        public static void TestChunked()
        {
            // reaper eternal rest:
            //using (Stream chunkedStream = IO.OpenFile(0x710000000000E54)) {
            //    teChunkedData chunked = new teChunkedData(chunkedStream);
            //}

            // model:
            //using (Stream chunkedStream = OpenFile(0xD00000000004286)) {
            //    teChunkedData chunked = new teChunkedData(chunkedStream);
            //}
            using (Stream chunkedStream = OpenFile(0xD000000000053AF)) {  // orisa nyxl
                teChunkedData chunked = new teChunkedData(chunkedStream);
            }

            //var sw = new Stopwatch();
            //const long count = 100;
            //
            //using (Stream chunkedStream = OpenFile(0xD00000000004286)) {
            //    {
            //        // setup static
            //        teChunkedData chunked = new teChunkedData(chunkedStream, true);
            //        chunkedStream.Position = 0;
            //    }
            //    sw.Start();
            //    for (int i = 0; i < count; i++) {
            //        teChunkedData chunked = new teChunkedData(chunkedStream, true);
            //        chunkedStream.Position = 0;
            //    }
            //    sw.Stop();
            //}
            //Console.Out.WriteLine(sw.Elapsed);
        }
Beispiel #2
0
        public static void Save(ICLIFlags flags, string directory, DataModels.Unlock unlock, VoiceSet voiceSet)
        {
            if (voiceSet == null)
            {
                return;
            }

            if (!(unlock.STU is STUUnlock_VoiceLine vl))
            {
                return;
            }

            HashSet <ulong> voiceLines = new HashSet <ulong>();

            using (Stream vlStream = IO.OpenFile(vl.m_F57B051E)) {
                teChunkedData chunkedData = new teChunkedData(vlStream);

                foreach (teEffectComponentVoiceStimulus voiceStimulus in chunkedData.GetChunks <teEffectComponentVoiceStimulus>())
                {
                    if (voiceSet.Stimuli.TryGetValue(voiceStimulus.Header.VoiceStimulus, out var stimuliLines))
                    {
                        foreach (var voiceLine in stimuliLines)
                        {
                            voiceLines.Add(voiceLine);
                        }
                    }
                }
            }

            SaveVoiceLines(flags, voiceLines, voiceSet, directory);
        }
Beispiel #3
0
        public void Parse(ICLIFlags toolFlags)
        {
            var flags     = toolFlags as ExtractFlags;
            var testGuids = flags?.Positionals.Skip(3).Select(x => uint.Parse(x, System.Globalization.NumberStyles.HexNumber));

            teChunkedData.Manager.ChunkTypes.Clear();
            foreach (var guid in Program.TrackedFiles[0xC])
            {
                if (!(testGuids ?? throw new InvalidDataException()).Contains(teResourceGUID.Index(guid)))
                {
                    continue;
                }
                var path = Path.Combine(flags.OutputPath, "teModelChunk", teResourceGUID.Index(guid).ToString("X"));
                if (!Directory.Exists(path))
                {
                    Directory.CreateDirectory(path);
                }
                using (Stream file = IO.OpenFile(guid))
                    using (BinaryReader reader = new BinaryReader(file)) {
                        teChunkedData chunk = new teChunkedData(reader);
                        for (int i = 0; i < chunk.Chunks.Length; ++i)
                        {
                            if (!(chunk.Chunks[i] is teDataChunk_Dummy dummy))
                            {
                                continue;
                            }
                            var filename = Path.Combine(path, chunk.ChunkTags[i]);
                            using (Stream target = File.OpenWrite(filename)) {
                                dummy.Data.CopyTo(target);
                            }
                        }
                    }
            }
        }
Beispiel #4
0
        public void Parse(ICLIFlags toolFlags)
        {
            var flags     = toolFlags as ExtractFlags;
            var testGuids = flags?.Positionals.Skip(3).Select(x => uint.Parse(x, System.Globalization.NumberStyles.HexNumber));

            foreach (var guid in Program.TrackedFiles[0xC])
            {
                if (!(testGuids ?? throw new InvalidDataException()).Contains(teResourceGUID.Index(guid)))
                {
                    continue;
                }
                using (Stream file = IO.OpenFile(guid))
                    using (BinaryReader reader = new BinaryReader(file)) {
                        teChunkedData    chunk    = new teChunkedData(reader);
                        teModelChunk_STU stuChunk = chunk.GetChunk <teModelChunk_STU>();

                        var hitboxes = stuChunk.StructuredData.m_CB4D298D;
                        var complex  = hitboxes.Select(x => x.m_B7C8314A).OfType <STU_B3800E70>().First();
                        var lines    = new List <string> {
                            "ply",
                            "format ascii 1.0",
                            $"element vertex {complex.m_88FCECD7.Length}",
                            "property float x",
                            "property float y",
                            "property float z",
                            "end_header"
                        };
                        lines.AddRange(complex.m_88FCECD7.Select(x => $"{x.X} {x.Y} {x.Z}")); // vertex

                        File.WriteAllText(@"F:\Test.ply", string.Join("\n", lines));
                    }
            }
        }
Beispiel #5
0
 public RefPoseSkeleton(teChunkedData chunkedData)
 {
     ChunkedData = chunkedData;
     if (_culture != null)
     {
         return;
     }
     _culture = (CultureInfo)CultureInfo.InvariantCulture.Clone();
     _culture.NumberFormat.NumberDecimalSeparator = ".";
 }
Beispiel #6
0
        private void SaveEffect(string dir, ulong guid)
        {
            using (Stream stream = OpenFile(guid)) {
                teChunkedData chunkedData = new teChunkedData(stream);

                ulong lastModel = 0;

                foreach (IChunk chunk in chunkedData.Chunks)
                {
                    if (chunk is teEffectChunkShaderSetup shaderSetup)
                    {
                        //if (teResourceGUID.Index(lastModel) != 0x296B) continue;  // the circle

                        ExtractDebugShaders.SaveMaterial(dir, shaderSetup.Header.Material, GetFileName(guid));
                    }

                    if (chunk is teEffectComponentParticle particle)
                    {
                        lastModel = particle.Header.Model;
                    }
                    else
                    {
                        lastModel = 0;
                    }
                }

                foreach (teEffectComponentEntityControl entityControl in chunkedData.GetChunks <teEffectComponentEntityControl>())
                {
                    if (entityControl.Header.Animation == 0)
                    {
                        continue;
                    }

                    SaveAnimation(dir, entityControl.Header.Animation);
                }

                foreach (teEffectComponentModel model in chunkedData.GetChunks <teEffectComponentModel>())
                {
                    if (model.Header.Animation == 0)
                    {
                        continue;
                    }

                    SaveAnimation(dir, model.Header.Animation);
                }
            }
        }
Beispiel #7
0
        public static void SaveModel(ICLIFlags flags, string path, FindLogic.Combo.ComboInfo info, ulong modelGUID)
        {
            bool convertModels = true;
            bool doRefpose     = false;
            byte lod           = 1;

            if (flags is ExtractFlags extractFlags)
            {
                convertModels = extractFlags.ConvertModels && !extractFlags.Raw;
                doRefpose     = extractFlags.ExtractRefpose;
                lod           = extractFlags.LOD;
                if (extractFlags.SkipModels)
                {
                    return;
                }
            }

            FindLogic.Combo.ModelInfoNew modelInfo = info.Models[modelGUID];
            string modelDirectory = Path.Combine(path, "Models", modelInfo.GetName());

            if (convertModels)
            {
                string modelPath = Path.Combine(modelDirectory, $"{modelInfo.GetNameIndex()}.owmdl");
                CreateDirectoryFromFile(modelPath);

                using (Stream modelStream = OpenFile(modelInfo.GUID)) {
                    teChunkedData chunkedData = new teChunkedData(modelStream);

                    OverwatchModel model = new OverwatchModel(chunkedData, modelInfo.GUID, (sbyte)lod);
                    if (modelInfo.ModelLooks.Count > 0)
                    {
                        FindLogic.Combo.ModelLookInfo modelLookInfo = info.ModelLooks[modelInfo.ModelLooks.First()];
                        model.ModelLookFileName = Path.Combine("ModelLooks",
                                                               modelLookInfo.GetNameIndex() + ".owmat");
                    }
                    using (Stream fileStream = File.OpenWrite(modelPath)) {
                        fileStream.SetLength(0);
                        model.Write(fileStream);
                    }

                    if (doRefpose)
                    {
                        string refposePath = Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".smd");

                        using (Stream fileStream = File.OpenWrite(refposePath)) {
                            fileStream.SetLength(0);
                            var refpose = new RefPoseSkeleton(chunkedData);
                            refpose.Write(fileStream);
                        }
                    }
                }
            }
            else
            {
                using (Stream modelStream = OpenFile(modelInfo.GUID)) {
                    WriteFile(modelStream, Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".00C"));
                }
            }

            foreach (ulong modelModelLook in modelInfo.ModelLooks)
            {
                SaveModelLook(flags, modelDirectory, info, modelModelLook);
            }

            foreach (ulong looseMaterial in modelInfo.LooseMaterials)
            {
                SaveMaterial(flags, modelDirectory, info, looseMaterial);
            }

            foreach (ulong modelAnimation in modelInfo.Animations)
            {
                SaveAnimation(flags, modelDirectory, info, modelAnimation, modelGUID);
            }
        }
Beispiel #8
0
        public void Process(EffectInfo effectInfo, KeyValuePair <ChunkPlaybackInfo, IChunk> chunk, Dictionary <ulong, ulong> replacements)
        {
            // todo: STUVoiceStimulus has f3099f20/m_volume
            // probably more stuff too


            // hey have some notes about particles:
            // 000000003CEC.006 - 000000001D3D.08F = ana - guardian:
            //     one RPCE, 61 chunks
            //     seems to be at correct position with rpce at rot: x=90

            // 000000003796.006 - 000000001A31.08F = genji - warrior's salute:
            //     one RPCE, 64 chunks.

            // VCCE might be a texture/material transform
            // A B C D = R G B A
            // see 'extract-debug-vcce'


            if (effectInfo == null)
            {
                return;
            }
            if (chunk.Value == null)
            {
                return;
            }
            if (replacements == null)
            {
                replacements = new Dictionary <ulong, ulong>();
            }

            // if (chunk.Value.GetType() == typeof(TCFE)) {
            //     TCFE tcfe = chunk.Value as TCFE;
            //     if (tcfe == null) return;
            //     effectInfo.EffectLength = tcfe.Data.EndTime1;
            // } else

            if (chunk.Value is teEffectComponentModel model)
            {
                AddDMCE(effectInfo, model, chunk.Key, replacements);
            }

            if (chunk.Value is teEffectComponentEntityControl control)
            {
                AddCECE(effectInfo, control, chunk.Key, replacements);
            }

            if (chunk.Value is teEffectComponentSound sound)
            {
                AddOSCE(effectInfo, sound, chunk.Key, replacements);
            }
            else if (chunk.Value is teEffectComponentEffect effectComponentEffect)
            {
                EffectInfo feceInfo   = null;
                ulong      effectGuid = effectComponentEffect.Header.Effect;
                if (replacements.ContainsKey(effectGuid))
                {
                    effectGuid = replacements[effectGuid];
                }
                using (Stream effectStream = IO.OpenFile(effectGuid)) {
                    if (effectStream != null)
                    {
                        teChunkedData subChunked = new teChunkedData(effectStream);
                        EffectParser  sub        = new EffectParser(subChunked, effectGuid);
                        feceInfo = sub.ProcessAll(replacements);
                    }
                }

                AddFECE(effectInfo, effectGuid, feceInfo, chunk.Key, replacements);
            }
            else if (chunk.Value is teEffectComponentEntity entity)
            {
                AddNECE(effectInfo, entity, chunk.Key, replacements);
            }
            else if (chunk.Value is teEffectComponentVoiceStimulus voiceStimulus)
            {
                AddSVCE(effectInfo, voiceStimulus, chunk.Key, replacements);
            }

            // if (chunk.Value.GetType() == typeof(RPCE)) {
            //     RPCE rpce = chunk.Value as RPCE;
            //     if (rpce == null) return;
            //     AddRPCE(effectInfo, rpce, chunk.Key, replacements);
            // }
            // if (chunk.Value.GetType() == typeof(SSCE)) {
            //     SSCE ssce = chunk.Value as SSCE;
            //     if (ssce == null) return;
            //
            //     AddSSCE(effectInfo, ssce, chunk.Key.PreviousChunk?.GetType(), replacements);
            // }
        }
Beispiel #9
0
 public EffectParser(teChunkedData chunked, ulong guid)
 {
     ChunkedData = chunked;
     GUID        = guid;
 }
Beispiel #10
0
        public static void SaveModel(ICLIFlags flags, string path, SaveContext info, ulong modelGUID)
        {
            bool convertModels = true;
            bool doRefpose     = false;
            bool doStu         = false;
            byte lod           = 1;

            if (flags is ExtractFlags extractFlags)
            {
                convertModels = !extractFlags.RawModels && !extractFlags.Raw;
                doRefpose     = extractFlags.ExtractRefpose;
                doStu         = extractFlags.ExtractModelStu;
                lod           = extractFlags.LOD;
                if (extractFlags.SkipModels)
                {
                    return;
                }
            }

            FindLogic.Combo.ModelAsset modelInfo = info.m_info.m_models[modelGUID];
            string modelDirectory = Path.Combine(path, "Models", modelInfo.GetName());

            if (convertModels)
            {
                string modelPath = Path.Combine(modelDirectory, $"{modelInfo.GetNameIndex()}.owmdl");

                using (Stream modelStream = OpenFile(modelInfo.m_GUID)) {
                    if (modelStream == null)
                    {
                        return;
                    }
                    CreateDirectoryFromFile(modelPath);

                    teChunkedData chunkedData = new teChunkedData(modelStream);

                    OverwatchModel model = new OverwatchModel(chunkedData, modelInfo.m_GUID, (sbyte)lod);
                    if (modelInfo.m_modelLooks.Count > 0)
                    {
                        FindLogic.Combo.ModelLookAsset modelLookInfo = info.m_info.m_modelLooks[modelInfo.m_modelLooks.First()];
                        model.ModelLookFileName = Path.Combine("ModelLooks",
                                                               modelLookInfo.GetNameIndex() + ".owmat");
                    }

                    using (Stream fileStream = File.OpenWrite(modelPath)) {
                        fileStream.SetLength(0);
                        model.Write(fileStream);
                    }

                    if (doRefpose)
                    {
                        string refposePath = Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".smd");

                        using (Stream fileStream = File.OpenWrite(refposePath)) {
                            fileStream.SetLength(0);
                            var refpose = new RefPoseSkeleton(chunkedData);
                            refpose.Write(fileStream);
                        }
                    }

                    if (doStu)
                    {
                        var    stu     = chunkedData.GetChunks <teModelChunk_STU>().Select(x => x.StructuredData).ToArray();
                        string stuPath = Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".json");
                        JSONTool.OutputJSONAlt(stu, new ListFlags {
                            Output = stuPath
                        }, false);
                    }
                }
            }
            else
            {
                using (Stream modelStream = OpenFile(modelInfo.m_GUID)) {
                    WriteFile(modelStream, Path.Combine(modelDirectory, modelInfo.GetNameIndex() + ".00C"));
                }
            }

            foreach (ulong modelModelLook in modelInfo.m_modelLooks)
            {
                SaveModelLook(flags, modelDirectory, info, modelModelLook);
            }

            foreach (ulong looseMaterial in modelInfo.m_looseMaterials)
            {
                SaveMaterial(flags, modelDirectory, info, looseMaterial);
            }

            foreach (ulong modelAnimation in modelInfo.n_animations)
            {
                SaveAnimation(flags, modelDirectory, info, modelAnimation, modelGUID);
            }
        }
Beispiel #11
0
 public OverwatchModel(teChunkedData chunkedData, ulong guid, sbyte targetLod = 1)
 {
     _data     = chunkedData;
     GUID      = guid;
     TargetLod = targetLod;
 }
Beispiel #12
0
        public static void TryConvertFile(Stream stream, string convertDir, string md5)
        {
            using (BinaryReader reader = new BinaryReader(stream, Encoding.UTF8, true)) {
                uint magic = reader.ReadUInt32();

                stream.Position = 0;
                if (magic == teChunkedData.Magic)
                {
                    teChunkedData chunkedData = new teChunkedData(reader);
                    if (chunkedData.Header.StringIdentifier == "MODL")
                    {
                        OverwatchModel model = new OverwatchModel(chunkedData, 0);
                        using (Stream file = File.OpenWrite(Path.Combine(convertDir, md5) + ".owmdl")) {
                            file.SetLength(0);
                            model.Write(file);
                        }
                    }
                }
                else if (magic == 0x4D4F5649)      // MOVI
                {
                    stream.Position = 128;
                    using (Stream file = File.OpenWrite(Path.Combine(convertDir, md5) + ".bk2")) {
                        file.SetLength(0);
                        stream.CopyTo(file);
                    }
                }
                else
                {
                    // ok might be a heckin bundle

                    /*int i = 0;
                     * while (reader.BaseStream.Position < reader.BaseStream.Length) {
                     *  try {
                     *      magic = reader.ReadUInt32();
                     *      if (magic != teChunkedData.Magic) {
                     *          reader.BaseStream.Position -= 3;
                     *          continue;
                     *      }
                     *      reader.BaseStream.Position -= 4;
                     *      teChunkedData chunkedData = new teChunkedData(reader);
                     *      if (chunkedData.Header.StringIdentifier == "MODL") {
                     *          OverwatchModel model = new OverwatchModel(chunkedData, 0);
                     *          using (Stream file = File.OpenWrite(Path.Combine(convertDir, md5) + $"-{i}.owmdl")) {
                     *              file.SetLength(0);
                     *              model.Write(file);
                     *          }
                     *      }
                     *
                     *      i++;
                     *  } catch (Exception) {
                     *      // fine
                     *  }
                     * }*/

                    try {
                        //teStructuredData structuredData =new teStructuredData(stream, true);

                        teTexture texture = new teTexture(reader);
                        if (!texture.PayloadRequired && texture.Header.DataSize <= stream.Length &&
                            (texture.Header.Flags == teTexture.Flags.Tex1D ||
                             texture.Header.Flags == teTexture.Flags.Tex2D ||
                             texture.Header.Flags == teTexture.Flags.Tex3D ||
                             texture.Header.Flags == teTexture.Flags.Cube ||
                             texture.Header.Flags == teTexture.Flags.Array ||
                             texture.Header.Flags == teTexture.Flags.Unk16 ||
                             texture.Header.Flags == teTexture.Flags.Unk32 ||
                             texture.Header.Flags == teTexture.Flags.Unk128) &&
                            texture.Header.Height < 10000 && texture.Header.Width < 10000 && texture.Header.DataSize > 68)
                        {
                            using (Stream file = File.OpenWrite(Path.Combine(convertDir, md5) + ".dds")) {
                                file.SetLength(0);
                                texture.SaveToDDS(file, false, texture.Header.MipCount);
                            }
                        }
                    } catch (Exception) {
                        // fine
                    }

                    try {
                        stream.Position = 0;
                        teStructuredData structuredData = new teStructuredData(stream, true);

                        if (structuredData.GetInstance <STUResourceKey>() != null)
                        {
                            var key = structuredData.GetInstance <STUResourceKey>();

                            Console.Out.WriteLine("found key");
                            var longKey        = ulong.Parse(key.m_keyID, NumberStyles.HexNumber);
                            var longRevKey     = BitConverter.ToUInt64(BitConverter.GetBytes(longKey).Reverse().ToArray(), 0);
                            var keyValueString = BitConverter.ToString(key.m_key).Replace("-", string.Empty);
                            var keyNameProper  = longRevKey.ToString("X16");
                            Console.Out.WriteLine("Added Encryption Key {0}, Value: {1}", keyNameProper, keyValueString);
                        }
                        // if (structuredData.GetInstance<STUHero>() != null) {
                        //
                        // }
                    } catch (Exception) {
                        // fine
                    }
                }
            }
        }