Example #1
0
            public long AddFile(ArcFileEntry file)
            {
                long ptr = files.Count;

                if (file.id != 0xFFFF)
                {
                    file.id = (ushort)cid;
                }
                cid++;
                files.Add(file);
                return(ptr);
            }
Example #2
0
        public static void Install()
        {
            // get gamepath and Mod folder
            string gamepath  = Path.GetFullPath(".\\");
            string ModFolder = Path.Combine(gamepath, "Mod");


            ArcFileSystem fs = new ArcFileSystem();

            // Iterate through each file in Mod folder and add it to the proxy ARC file
            foreach (string file in Directory.GetFiles(ModFolder, "*.ks", SearchOption.AllDirectories))
            {
                string name = Path.GetFileName(file);

                ArcFileEntry arcFile = !fs.FileExists(file) ? fs.CreateFile(name) : fs.GetFile(file);
                arcFile.Pointer = new WindowsFilePointer(file);
            }

            foreach (string file in Directory.GetFiles(ModFolder, "*.ogg", SearchOption.AllDirectories))
            {
                string name = Path.GetFileName(file);

                ArcFileEntry arcFile = !fs.FileExists(file) ? fs.CreateFile(name) : fs.GetFile(file);
                arcFile.Pointer = new WindowsFilePointer(file);
            }

            // Save the ARC file on disk because the game does not support loading ARC from meory easily
            // the temp ARC is saved in ML_temp folder in game's folder, so as to not get in the way of general mods
            if (!Directory.Exists(Path.Combine(gamepath, "ML_temp")))
            {
                Directory.CreateDirectory(Path.Combine(gamepath, "ML_temp"));
            }

            using (FileStream fStream = File.Create(Path.Combine(gamepath, "ML_temp\\ML_temp.arc")))
            {
                fs.Save(fStream);
            }

            // Get the game's file system and add our custom ARC file
            FileSystemArchive gameFileSystem = GameUty.FileSystem as FileSystemArchive;

            gameFileSystem.AddArchive(Path.Combine(gamepath, "ML_temp\\ML_temp.arc"));

            // load custom arcs, cuz yolo

            foreach (string arc in Directory.GetFiles(ModFolder, "*.arc", SearchOption.AllDirectories))
            {
                gameFileSystem.AddArchive(arc);
            }
        }
Example #3
0
        private static void DumpArcNode(Stream arcstr, ArcHeader head, ArcNode node, string destroot, string nameoverride = null)
        {
            string nodeName = nameoverride;

            arcstr.Seek(node.filenameOffset + head.stringOffset + 0x20, SeekOrigin.Begin);
            if (nodeName == null)
            {
                nodeName = Data.ReadString(arcstr);
            }

            destroot += "\\" + nodeName;
            Directory.CreateDirectory(destroot);

            for (int i = 0; i < node.entryCount; ++i)
            {
                ArcFileEntry curr = new ArcFileEntry(arcstr, head, (int)(node.entryOffset + i));

                if (curr.id == 0xFFFF)                                                                 //subdirectory
                {
                    if (curr.filenameOffset != 0 && curr.filenameOffset != 2)                          //don't go to "." and ".."
                    {
                        ArcNode dirNode = new ArcNode(arcstr, (int)curr.dataOffset);                   //Some arc packing programs have a glitch
                        arcstr.Seek(curr.filenameOffset + head.stringOffset + 0x20, SeekOrigin.Begin); //People use them so just work around it
                        DumpArcNode(arcstr, head, dirNode, destroot, Data.ReadString(arcstr));
                    }
                }
                else //file
                {
                    arcstr.Seek(curr.filenameOffset + head.stringOffset + 0x20, SeekOrigin.Begin);
                    string currName = Data.ReadString(arcstr);

                    FileStream dest = new FileStream(destroot + "\\" + currName, FileMode.Create);

                    int    read = 0;
                    byte[] buff = new byte[1024];
                    arcstr.Seek(curr.dataOffset + head.dataStart + 0x20, SeekOrigin.Begin);
                    while (read < curr.dataSize)
                    {
                        int r = arcstr.Read(buff, 0, (int)Math.Min(1024, curr.dataSize - read));
                        dest.Write(buff, 0, r);
                        read += r;
                    }
                    dest.Close();
                }
            }
        }
Example #4
0
        private static ArcInfo BuildArcInfo(string dir, string arcdir, long parent, Dictionary <string, ushort> dirStrings, ArcInfo ai)
        {
            DirectoryInfo di = new DirectoryInfo(dir);

            string curdir;

            if (arcdir != "")
            {
                curdir = arcdir + "/" + di.Name;
            }
            else
            {
                curdir = di.Name;
            }

            ArcNode dirNode = new ArcNode();

            if (!dirStrings.ContainsKey(dir))
            {
                dirNode.filenameOffset = (uint)ai.AddString(di.Name);
            }
            else
            {
                dirNode.filenameOffset = dirStrings[dir];
            }
            dirNode.unknown     = GCN.CreateHash(di.Name);
            dirNode.entryOffset = (uint)(ai.files.Count);
            dirNode.entryCount  = 0;
            dirNode.WritePath   = curdir;
            if (ai.nodes.Count == 0)
            {
                dirNode.type = BitConverter.ToUInt32(new byte[4] {
                    (byte)'T', (byte)'O', (byte)'O', (byte)'R'
                }, 0);
            }
            else
            {
                byte[] type = new byte[4];
                for (int i = 0; i < 4; i++)
                {
                    if (i < di.Name.Length)
                    {
                        type[3 - i] = (byte)(di.Name.ToUpper())[i];
                    }
                    else
                    {
                        type[3 - i] = 0x20;
                    }
                }
                dirNode.type = BitConverter.ToUInt32(type, 0);
            }

            long coffset = ai.AddNode(dirNode);

            string[] files = Directory.EnumerateFiles(dir, "*", SearchOption.TopDirectoryOnly).ToArray();
            foreach (string file in files)
            {
                FileInfo     fi     = new FileInfo(file);
                ArcFileEntry fentry = new ArcFileEntry();
                fentry.id = 0;
                if (dirStrings.ContainsKey(file))
                {
                    fentry.filenameOffset = dirStrings[file];
                }
                else
                {
                    fentry.filenameOffset = (ushort)ai.AddString(fi.Name);
                }
                fentry.dataOffset = (uint)ai.CountData(file, out fentry.dataSize);
                fentry.WritePath  = curdir + "/" + fi.Name;
                fentry.unknown    = GCN.CreateHash(fi.Name);
                fentry.unknown2   = 0x1100;
                ai.AddFile(fentry);
                dirNode.entryCount++;
            }

            long fileoff = coffset;

            string[] dirs = Directory.EnumerateDirectories(dir, "*", SearchOption.TopDirectoryOnly).ToArray();

            foreach (string idir in dirs)
            {
                DirectoryInfo idi    = new DirectoryInfo(idir);
                ArcFileEntry  dentry = new ArcFileEntry();
                dentry.id             = 0xFFFF;
                dentry.filenameOffset = (ushort)ai.AddString(idi.Name);
                dirStrings.Add(idir, dentry.filenameOffset);
                dentry.dataOffset = (uint)(++fileoff);
                fileoff          += Directory.EnumerateDirectories(idir, "*", SearchOption.AllDirectories).Count();
                dentry.dataSize   = 16;
                dentry.WritePath  = curdir;
                dentry.unknown    = GCN.CreateHash(idi.Name);
                dentry.unknown2   = 0x0200;
                ai.AddFile(dentry);
                dirNode.entryCount++;
            }

            ArcFileEntry cEntry = new ArcFileEntry();

            cEntry.id             = 0xFFFF;
            cEntry.filenameOffset = 0;
            cEntry.WritePath      = curdir;
            cEntry.dataOffset     = (uint)coffset;
            cEntry.dataSize       = 16;
            cEntry.unknown        = 0x2E;
            cEntry.unknown2       = 0x0200;
            ai.AddFile(cEntry);
            ArcFileEntry pEntry = new ArcFileEntry();

            pEntry.filenameOffset = 2;
            pEntry.id             = 0xFFFF;
            pEntry.WritePath      = arcdir;
            pEntry.dataOffset     = (uint)parent;
            pEntry.dataSize       = 16;
            pEntry.unknown        = 0xB8;
            pEntry.unknown2       = 0x0200;
            ai.AddFile(pEntry);
            dirNode.entryCount += 2;

            ai.nodes[ai.nodes.Count - 1] = dirNode;

            foreach (string idir in dirs)
            {
                ai = BuildArcInfo(idir, curdir, coffset, dirStrings, ai);
            }
            return(ai);
        }