public static bool extract(byte[] infile, string outdir) { if (infile[0] != 'S' || infile[1] != 'A' || infile[2] != 'R' || infile[3] != 'C') { lerror = "Not a SARC archive!"; return(false); } int pos = 4; ushort hdr = makeu16(infile[pos], infile[pos + 1]); pos += 2; ushort order = makeu16(infile[pos], infile[pos + 1]); pos += 2; if (order != 65279) { lerror = "Little endian is not supported!"; return(false); } uint size = makeu32(infile[pos], infile[pos + 1], infile[pos + 2], infile[pos + 3]); pos += 4; uint doff = makeu32(infile[pos], infile[pos + 1], infile[pos + 2], infile[pos + 3]); pos += 4; uint unknown = makeu32(infile[pos], infile[pos + 1], infile[pos + 2], infile[pos + 3]); pos += 4; if (infile[pos] != 'S' || infile[pos + 1] != 'F' || infile[pos + 2] != 'A' || infile[pos + 3] != 'T') { lerror = "Unknown file section!"; return(false); } pos += 4; ushort hdr2 = makeu16(infile[pos], infile[pos + 1]); pos += 2; ushort nodec = makeu16(infile[pos], infile[pos + 1]); pos += 2; uint hashr = makeu32(infile[pos], infile[pos + 1], infile[pos + 2], infile[pos + 3]); pos += 4; sarcnode[] nodes = new sarcnode[nodec]; sarcnode tmpnode = new sarcnode(); for (int c = 0; c < nodec; c++) { tmpnode.hash = makeu32(infile[pos], infile[pos + 1], infile[pos + 2], infile[pos + 3]); pos += 4; tmpnode.unk = infile[pos]; pos += 1; tmpnode.off = makeu32(0, infile[pos], infile[pos + 1], infile[pos + 2]); pos += 3; tmpnode.srt = makeu32(infile[pos], infile[pos + 1], infile[pos + 2], infile[pos + 3]); pos += 4; tmpnode.end = makeu32(infile[pos], infile[pos + 1], infile[pos + 2], infile[pos + 3]); pos += 4; nodes[c] = tmpnode; } if (infile[pos] != 'S' || infile[pos + 1] != 'F' || infile[pos + 2] != 'N' || infile[pos + 3] != 'T') { lerror = "Unknown file section!"; return(false); } pos += 4; ushort hdr3 = makeu16(infile[pos], infile[pos + 1]); pos += 2; ushort unk2 = makeu16(infile[pos], infile[pos + 1]); pos += 2; string[] fnames = new string[nodec]; string tmpstr; for (int c = 0; c < nodec; c++) { tmpstr = ""; while (infile[pos] != 0) { tmpstr = tmpstr + ((char)infile[pos]).ToString(); pos += 1; } while (infile[pos] == 0) { pos += 1; } fnames[c] = tmpstr; } if (!System.IO.Directory.Exists(outdir)) { System.IO.Directory.CreateDirectory(outdir); } System.IO.StreamWriter sw; for (int c = 0; c < nodec; c++) { makedirexist(System.IO.Path.GetDirectoryName(outdir + "/" + fnames[c])); sw = new System.IO.StreamWriter(outdir + "/" + fnames[c]); sw.BaseStream.Write(infile, (int)(nodes[c].srt + doff), (int)(nodes[c].end - nodes[c].srt)); sw.Close(); sw.Dispose(); } return(true); }
public static bool extract(byte[] infile, string outdir) { if (infile[0] != 'S' || infile[1] != 'A' || infile[2] != 'R' || infile[3] != 'C') { lerror = "Not a SARC archive!"; return false; } int pos=4; ushort hdr=makeu16(infile[pos], infile[pos+1]); pos += 2; ushort order=makeu16(infile[pos], infile[pos+1]); pos += 2; if (order != 65279) { lerror = "Little endian is not supported!"; return false; } uint size = makeu32(infile[pos], infile[pos+1], infile[pos+2], infile[pos+3]); pos += 4; uint doff = makeu32(infile[pos], infile[pos+1], infile[pos+2], infile[pos+3]); pos += 4; uint unknown = makeu32(infile[pos], infile[pos+1], infile[pos+2], infile[pos+3]); pos += 4; if (infile[pos] != 'S' || infile[pos+1] != 'F' || infile[pos+2] != 'A' || infile[pos+3] != 'T') { lerror = "Unknown file section!"; return false; } pos+=4; ushort hdr2=makeu16(infile[pos], infile[pos+1]); pos += 2; ushort nodec=makeu16(infile[pos], infile[pos+1]); pos += 2; uint hashr = makeu32(infile[pos], infile[pos+1], infile[pos+2], infile[pos+3]); pos += 4; sarcnode[] nodes = new sarcnode[nodec]; sarcnode tmpnode = new sarcnode(); for (int c = 0; c < nodec; c++) { tmpnode.hash = makeu32(infile[pos], infile[pos+1], infile[pos+2], infile[pos+3]); pos += 4; tmpnode.unk = infile[pos]; pos += 1; tmpnode.off = makeu32(0, infile[pos], infile[pos+1], infile[pos+2]); pos += 3; tmpnode.srt = makeu32(infile[pos], infile[pos+1], infile[pos+2], infile[pos+3]); pos += 4; tmpnode.end = makeu32(infile[pos], infile[pos+1], infile[pos+2], infile[pos+3]); pos += 4; nodes[c] = tmpnode; } if (infile[pos] != 'S' || infile[pos+1] != 'F' || infile[pos+2] != 'N' || infile[pos+3] != 'T') { lerror = "Unknown file section!"; return false; } pos+=4; ushort hdr3=makeu16(infile[pos], infile[pos+1]); pos += 2; ushort unk2=makeu16(infile[pos], infile[pos+1]); pos += 2; string[] fnames = new string[nodec]; string tmpstr; for (int c = 0; c < nodec; c++) { tmpstr = ""; while (infile[pos] != 0) { tmpstr = tmpstr + ((char)infile[pos]).ToString(); pos += 1; } while (infile[pos] == 0) pos += 1; fnames[c] = tmpstr; } if (!System.IO.Directory.Exists(outdir)) System.IO.Directory.CreateDirectory(outdir); System.IO.StreamWriter sw; for (int c = 0; c < nodec; c++) { makedirexist(System.IO.Path.GetDirectoryName(outdir + "/" + fnames[c])); sw = new System.IO.StreamWriter(outdir + "/" + fnames[c]); sw.BaseStream.Write(infile, (int) (nodes[c].srt + doff), (int) (nodes[c].end - nodes[c].srt)); sw.Close(); sw.Dispose(); } return true; }