示例#1
0
        public string ReadTextureEntry(ResourceEntry entry, XmlWriter resourceXML, string name)
        {
            TextureResource resource = new TextureResource();

            using (MemoryStream stream = new MemoryStream(entry.Data))
            {
                resource.Deserialize(entry.Version, stream, Endian);
            }

            string FetchedName = "";

            if (_TextureNames.ContainsKey(resource.NameHash))
            {
                FetchedName = _TextureNames[resource.NameHash];

                if (!string.IsNullOrEmpty(FetchedName))
                {
                    name = FetchedName;
                }
            }

            resourceXML.WriteElementString("File", name);

            // We lack the file hash in M3 and M1: DE. So we have to add it to the file.
            var game = GameStorage.Instance.GetSelectedGame();

            if (game.GameType == GamesEnumerator.MafiaI_DE || game.GameType == GamesEnumerator.MafiaIII)
            {
                resourceXML.WriteElementString("FileHash", resource.NameHash.ToString());
            }

            resourceXML.WriteElementString("HasMIP", resource.HasMIP.ToString());
            entry.Data = resource.Data;
            return(name);
        }
示例#2
0
        public ResourceEntry ReadTextureEntry(ResourceEntry entry, XmlWriter resourceXML, string name)
        {
            TextureResource resource = new TextureResource();

            resource.Deserialize(entry.Version, new MemoryStream(entry.Data), Endian.Little);
            resourceXML.WriteElementString("File", name);
            resourceXML.WriteElementString("HasMIP", resource.HasMIP.ToString());
            entry.Data = resource.Data;
            return(entry);
        }
示例#3
0
        public void ExtractPatch(FileInfo file)
        {
            XmlWriterSettings settings = new XmlWriterSettings();

            settings.Indent             = true;
            settings.IndentChars        = ("\t");
            settings.OmitXmlDeclaration = true;

            string extractedPath = Path.Combine(file.Directory.FullName, "extracted");

            if (!Directory.Exists(extractedPath))
            {
                Directory.CreateDirectory(extractedPath);
            }

            string finalPath = Path.Combine(extractedPath, file.Name);

            Directory.CreateDirectory(finalPath);

            Log.WriteLine("Begin unpacking and saving files..");

            XmlWriter resourceXML = XmlWriter.Create(finalPath + "/SDSContent.xml", settings);

            resourceXML.WriteStartElement("SDSResource");

            PatchFile patchFile = null;

            using (var input = File.OpenRead(file.FullName))
            {
                using (Stream data = ArchiveEncryption.Unwrap(input))
                {
                    patchFile      = new PatchFile();
                    patchFile.file = new FileInfo(file.FullName + ".patch");
                    patchFile.Deserialize(data ?? input, Endian.Little);
                }
            }
            Dictionary <string, Dictionary <int, string> >         sortedResources   = new Dictionary <string, Dictionary <int, string> >();
            Dictionary <string, List <KeyValuePair <int, bool> > > resPatchAvailable = new Dictionary <string, List <KeyValuePair <int, bool> > >();

            for (int i = 0; i < ResourceTypes.Count; i++)
            {
                sortedResources.Add(ResourceTypes[i].Name, new Dictionary <int, string>());
                resPatchAvailable.Add(ResourceTypes[i].Name, new List <KeyValuePair <int, bool> >());
            }

            for (int i = 0; i < ResourceEntries.Count; i++)
            {
                var type = ResourceTypes[_ResourceEntries[i].TypeId].Name;
                var name = (type == "Mipmap" ? ResourceNames[i].Remove(0, 4) : ResourceNames[i]);

                if (sortedResources.ContainsKey(type))
                {
                    sortedResources[type].Add(i, name);

                    if (patchFile.UnkInts1.Contains(i))
                    {
                        resPatchAvailable[type].Add(new KeyValuePair <int, bool>(i, false));
                    }
                }
            }

            for (int i = 0; i < patchFile.resources.Length; i++)
            {
                var entry = patchFile.resources[i];

                string type = "";
                if (entry.TypeId < ResourceTypes.Count)
                {
                    type = ResourceTypes[entry.TypeId].Name;
                }
                else
                {
                    // NB: M2DE's midtown.sds.patch seems to have a bogus type. I think its a MipMap, but
                    // I've had to implement a huge-ass fallback hack just to accomodate this bogus entry.
                    type = "Unknown";
                }

                string name = string.Format("{0}_{1}", type, i);
                if (resPatchAvailable.ContainsKey(type))
                {
                    for (int z = 0; z < resPatchAvailable[type].Count; z++)
                    {
                        var res = resPatchAvailable[type][z];
                        if (type == "Texture" || type == "Mipmap")
                        {
                            TextureResource tRes = new TextureResource();
                            tRes.Deserialize(entry.Version, new MemoryStream(entry.Data), Endian.Little);
                            var resName = sortedResources[type][res.Key];
                            var hash    = FNV64.Hash(resName);
                            if (tRes.NameHash == hash)
                            {
                                Console.WriteLine("Detected possible candidate: {0}", resName);
                                name = resName;
                                break;
                            }
                        }
                        else
                        {
                            if (!res.Value)
                            {
                                string StoredName = sortedResources[type][res.Key];
                                if (!StoredName.Equals("not available"))
                                {
                                    name = StoredName;
                                }

                                resPatchAvailable[type][z] = new KeyValuePair <int, bool>(res.Key, true);
                                break;
                            }
                        }
                    }
                }

                bool bContainsDDS = (name.Contains(".dds"));
                var  saveName     = "";
                resourceXML.WriteStartElement("ResourceEntry");
                resourceXML.WriteElementString("Type", type);
                switch (type)
                {
                case "Texture":
                    var textureName = (!bContainsDDS) ? name + ".dds" : name;
                    ReadTextureEntry(entry, resourceXML, name);
                    saveName = textureName;
                    break;

                case "Mipmap":
                    var mipName = (!bContainsDDS) ? "MIP_ " + name + ".dds" : "MIP_ " + name;
                    ReadMipmapEntry(entry, resourceXML, name);
                    saveName = mipName;
                    break;

                case "IndexBufferPool":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "VertexBufferPool":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "AnimalTrafficPaths":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "FrameResource":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "Translokator":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "Effects":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "FrameNameTable":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "EntityDataStorage":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "PREFAB":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "ItemDesc":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "Actors":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "Collisions":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "Animation2":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "NAV_AIWORLD_DATA":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "NAV_OBJ_DATA":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "NAV_HPD_DATA":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "FxAnimSet":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "FxActor":
                    saveName = ReadBasicEntry(resourceXML, name);
                    break;

                case "Sound":
                    ReadSoundEntry(entry, resourceXML, name, finalPath);
                    saveName = name + ".fsb";
                    break;

                case "Script":
                    ReadScriptEntry(entry, resourceXML, finalPath);
                    continue;

                case "AudioSectors":
                    ReadAudioSectorEntry(entry, resourceXML, name, finalPath);
                    saveName = name;
                    break;

                default:
                    saveName = name;
                    Console.WriteLine("Unhandled Resource Type {0}", type);
                    break;
                }
                resourceXML.WriteElementString("Version", entry.Version.ToString());
                File.WriteAllBytes(finalPath + "/" + saveName, entry.Data);
                resourceXML.WriteEndElement();
            }
            resourceXML.WriteEndElement();
            resourceXML.Flush();
            resourceXML.Dispose();
        }