public wnd1(EndianBinaryReader er) : base(er) { long basepos = er.BaseStream.Position - 0x4C; InflationLeft = er.ReadUInt16() / 16f; InflationRight = er.ReadUInt16() / 16f; InflationTop = er.ReadUInt16() / 16f; InflationBottom = er.ReadUInt16() / 16f; FrameSizeLeft = er.ReadUInt16(); FrameSizeRight = er.ReadUInt16(); FrameSizeTop = er.ReadUInt16(); FrameSizeBottom = er.ReadUInt16(); NrFrames = er.ReadByte(); byte tmp = er.ReadByte(); UseLTMaterial = (tmp & 1) == 1; UseVtxColorForAllWindow = (tmp & 2) == 2; Kind = (WindowKind)((tmp >> 2) & 3); DontDrawContent = (tmp & 8) == 16; Padding = er.ReadUInt16(); ContentOffset = er.ReadUInt32(); FrameOffsetTableOffset = er.ReadUInt32(); er.BaseStream.Position = basepos + ContentOffset; Content = new WindowContent(er); er.BaseStream.Position = basepos + FrameOffsetTableOffset; WindowFrameOffsets = er.ReadUInt32s(NrFrames); WindowFrames = new WindowFrame[NrFrames]; for (int i = 0; i < NrFrames; i++) { er.BaseStream.Position = basepos + WindowFrameOffsets[i]; WindowFrames[i] = new WindowFrame(er); } er.BaseStream.Position = basepos + SectionSize; }
public void modelOpen() { string path = textBox1.Text; EndianBinaryReader readModel = new EndianBinaryReader(File.OpenRead(path), Endianness.LittleEndian); nsbmd = new NSBMD_File(); if (readModel.ReadString(Encoding.ASCII, 4) != "BMD0") { readModel.Close(); return; } else { nsbmd.Header.ID = "BMD0"; nsbmd.Header.Magic = readModel.ReadBytes(4); nsbmd.Header.file_size = readModel.ReadInt32(); nsbmd.Header.header_size = readModel.ReadInt16(); nsbmd.Header.nSection = readModel.ReadInt16(); nsbmd.Header.Section_Offset = new Int32[nsbmd.Header.nSection]; for (int i = 0; i < nsbmd.Header.nSection; i++) { nsbmd.Header.Section_Offset[i] = readModel.ReadInt32(); } nsbmd.MDL0.ID = readModel.ReadString(Encoding.ASCII, 4); if (nsbmd.MDL0.ID != "MDL0") { readModel.Close(); return; } nsbmd.MDL0.Section_size = readModel.ReadInt32(); nsbmd.MDL0.Padding1 = readModel.ReadByte(); nsbmd.MDL0.Model_count = readModel.ReadByte(); nsbmd.MDL0.Section_size = readModel.ReadInt16(); nsbmd.MDL0.Constant = readModel.ReadInt16(); nsbmd.MDL0.Subsection_size = readModel.ReadInt16(); nsbmd.MDL0.Constant2 = readModel.ReadInt32(); nsbmd.MDL0.Unknown = new int[nsbmd.MDL0.Model_count]; for (int i = 0; i < nsbmd.MDL0.Model_count; i++) { nsbmd.MDL0.Unknown[i] = readModel.ReadInt32(); } nsbmd.MDL0.Constant3 = readModel.ReadInt16(); nsbmd.MDL0.Section2_size = readModel.ReadInt16(); nsbmd.MDL0.Model_offset = new int[nsbmd.MDL0.Model_count]; for (int i = 0; i < nsbmd.MDL0.Model_count; i++) { nsbmd.MDL0.Model_offset[i] = readModel.ReadInt32(); } nsbmd.MDL0.Model_name = new string[nsbmd.MDL0.Model_count]; for (int i = 0; i < nsbmd.MDL0.Model_count; i++) { nsbmd.MDL0.Model_name[i] = readModel.ReadString(Encoding.ASCII, 16); } readModel.Close(); } }
public pan1(EndianBinaryReader er) { Signature = er.ReadString(Encoding.ASCII, 4); if (Signature != "pan1" && Signature != "pic1" && Signature != "txt1" && Signature != "bnd1" && Signature != "wnd1" && Signature != "prt1") throw new SignatureNotCorrectException(Signature, "pan1, pic1, txt1, bnd1, wnd1, prt1", er.BaseStream.Position - 4); SectionSize = er.ReadUInt32(); Flags = (PaneFlags)er.ReadByte(); Origin = er.ReadByte(); Alpha = er.ReadByte(); MagnifyFlags = (PaneMagnifyFlags)er.ReadByte(); Name = er.ReadString(Encoding.ASCII, 24).Replace("\0", ""); Translation = er.ReadVector3(); Rotation = er.ReadVector3(); Scale = er.ReadVector2(); Size = er.ReadVector2(); }
public static List<Polygon> GetPolygons(EndianBinaryReader reader, int numAllPolygons) { List<Polygon> polygons = new List<Polygon>(); for (int i = 0; i < numAllPolygons; i++) { Polygon polygon = new Polygon(); polygon.polygonType = (PolygonType)reader.ReadByte(); polygon.size = reader.ReadByte(); polygon.BaceFaceMode = (FaceMode)reader.ReadByte(); polygon.unknown = reader.ReadByte(); polygon.vertex1 = reader.ReadUInt16(); polygon.vertex1 /= 4; polygon.vertex2 = reader.ReadUInt16(); polygon.vertex2 /= 4; polygon.vertex3 = reader.ReadUInt16(); polygon.vertex3 /= 4; if (polygon.polygonType == PolygonType.Quad) { polygon.vertex4 = reader.ReadUInt16(); polygon.vertex4 /= 4; } polygon.u1 = reader.ReadByte(); polygon.v1 = reader.ReadByte(); polygon.u2 = reader.ReadByte(); polygon.v2 = reader.ReadByte(); polygon.u3 = reader.ReadByte(); polygon.v3 = reader.ReadByte(); if (polygon.polygonType == PolygonType.Quad) { polygon.u4 = reader.ReadByte(); polygon.v4 = reader.ReadByte(); } polygons.Add(polygon); } return polygons; }
public static WEP FromStream(EndianBinaryReader reader) { /*===================================================================== WEP HEADER (0x50) 80 bytes long =====================================================================*/ reader.Skip(0x04); // TODO: skip magic 0x04 (4 dec) "H01" check for file type? byte numJoints = reader.ReadByte(); byte numGroups = reader.ReadByte(); ushort numTriangles = reader.ReadUInt16(); ushort numQuads = reader.ReadUInt16(); ushort numPolygons = reader.ReadUInt16(); uint ptrTexture1 = (uint)(reader.ReadUInt32() + 0x10); // same as ptrTexture... why? reader.Skip(0x30); // header padding? uint ptrTexture = (uint)(reader.ReadUInt32() + 0x10); uint ptrGroups = (uint)(reader.ReadUInt32() + 0x10); uint ptrVertices = (uint)(reader.ReadUInt32() + 0x10); uint ptrPolygons = (uint)(reader.ReadUInt32() + 0x10); /*===================================================================== LOCALS =====================================================================*/ int numAllPolygons = numTriangles + numQuads + numPolygons; int numOfPalettes = 7; // palettes of 2/3 color count. /*===================================================================== STREAM READER =====================================================================*/ WEP wep = new WEP(); wep.joints = VSTools.GetJoints(reader, numJoints); wep.groups = VSTools.GetGroups(reader, numGroups); wep.vertices = VSTools.GetVertices(reader, wep.groups); wep.polygons = VSTools.GetPolygons(reader, numAllPolygons); wep.textures = VSTools.GetTextures(reader, numOfPalettes); return wep; }
public txt1(EndianBinaryReader er) : base(er) { long baseoffset = er.BaseStream.Position - 0x4C; NrCharacters = er.ReadUInt16(); NrCharacters2 = er.ReadUInt16(); MaterialId = er.ReadUInt16(); FontId = er.ReadUInt16(); PositionType = er.ReadByte(); TextAlignment = er.ReadByte(); TextFlags = er.ReadByte(); Padding = er.ReadByte(); StringOffset = er.ReadUInt32(); TopColor = er.ReadColor8(); BottomColor = er.ReadColor8(); FontSize = er.ReadVector2(); CharSize = er.ReadSingle(); LineSize = er.ReadSingle(); er.BaseStream.Position = baseoffset + StringOffset; Text = er.ReadStringNT(Encoding.Unicode); er.BaseStream.Position = baseoffset + SectionSize; }
/// <summary> /// Constructor /// </summary> /// <param name="path">The path to the MOD module.</param> public ModReader(string path) { using (var mod = new EndianBinaryReader(File.OpenRead(path), Endian.Big)) { SongTitle = Encoding.UTF8.GetString(mod.ReadBytes(20)); Samples = GetSamples(mod); SongLength = mod.ReadByte(); // Skip byte. Unimportant mod.BaseStream.Position += 1; SongPositions = GetSongPositions(mod); ModuleID = Encoding.UTF8.GetString(mod.ReadBytes(4)); // Number of patterns is equal to the largest value in the position table. Patterns = GetPatterns(mod, SongPositions.Max()); } }
private static byte[] DecodeIA8(EndianBinaryReader stream, uint width, uint height) { uint numBlocksW = width / 4; //4 byte block width uint numBlocksH = height / 4; //4 byte block height byte[] decodedData = new byte[width * height * 4]; for (int yBlock = 0; yBlock < numBlocksH; yBlock++) { for (int xBlock = 0; xBlock < numBlocksW; xBlock++) { //For each block, we're going to examine block width / block height number of 'pixels' for (int pY = 0; pY < 4; pY++) { for (int pX = 0; pX < 4; pX++) { //Ensure the pixel we're checking is within bounds of the image. if ((xBlock * 4 + pX >= width) || (yBlock * 4 + pY >= height)) continue; //Now we're looping through each pixel in a block, but a pixel is four bytes long. uint destIndex = (uint)(4 * (width * ((yBlock * 4) + pY) + (xBlock * 4) + pX)); byte byte0 = stream.ReadByte(); byte byte1 = stream.ReadByte(); decodedData[destIndex + 3] = byte0; decodedData[destIndex + 2] = byte1; decodedData[destIndex + 1] = byte1; decodedData[destIndex + 0] = byte1; } } } } return decodedData; }
private static byte[] DecodeIA4(EndianBinaryReader stream, uint width, uint height) { uint numBlocksW = width / 8; uint numBlocksH = height / 4; byte[] decodedData = new byte[width * height * 4]; for (int yBlock = 0; yBlock < height; yBlock++) { for (int xBlock = 0; xBlock < width; xBlock++) { //For each block, we're going to examine block width / block height number of 'pixels' for (int pY = 0; pY < 4; pY++) { for (int pX = 0; pX < 8; pX++) { //Ensure the pixel we're checking is within bounds of the image. if ((xBlock * 8 + pX >= width) || (yBlock * 4 + pY >= height)) continue; byte value = stream.ReadByte(); byte alpha = (byte)((value & 0xF0) >> 4); byte lum = (byte)(value & 0x0F); uint destIndex = (uint)(4 * (width * ((yBlock * 4) + pY) + (xBlock * 8) + pX)); decodedData[destIndex + 0] = (byte)(lum * 0x11); decodedData[destIndex + 1] = (byte)(lum * 0x11); decodedData[destIndex + 2] = (byte)(lum * 0x11); decodedData[destIndex + 3] = (byte)(alpha * 0x11); } } } } return decodedData; }
private static byte[] DecodeI8(EndianBinaryReader stream, uint width, uint height) { uint numBlocksW = width / 8; //8 pixel block width uint numBlocksH = height / 4; //4 pixel block height byte[] decodedData = new byte[width * height * 4]; for (int yBlock = 0; yBlock < numBlocksH; yBlock++) { for (int xBlock = 0; xBlock < numBlocksW; xBlock++) { //For each block, we're going to examine block width / block height number of 'pixels' for (int pY = 0; pY < 4; pY++) { for (int pX = 0; pX < 8; pX++) { //Ensure the pixel we're checking is within bounds of the image. if ((xBlock * 8 + pX >= width) || (yBlock * 4 + pY >= height)) continue; byte data = stream.ReadByte(); uint destIndex = (uint)(4 * (width * ((yBlock * 4) + pY) + (xBlock * 8) + pX)); decodedData[destIndex + 0] = data; decodedData[destIndex + 1] = data; decodedData[destIndex + 2] = data; decodedData[destIndex + 3] = 0xFF; } } } } return decodedData; }
private static byte[] DecodeC8(EndianBinaryReader stream, uint width, uint height, Palette imagePalette, PaletteFormats paletteFormat) { //4 bpp, 8 block width/4 block height, block size 32 bytes, possible palettes (IA8, RGB565, RGB5A3) uint numBlocksW = width / 8; uint numBlocksH = height / 4; byte[] decodedData = new byte[width * height * 8]; //Read the indexes from the file for (int yBlock = 0; yBlock < numBlocksH; yBlock++) { for (int xBlock = 0; xBlock < numBlocksW; xBlock++) { //Inner Loop for pixels for (int pY = 0; pY < 4; pY++) { for (int pX = 0; pX < 8; pX++) { //Ensure we're not reading past the end of the image. if ((xBlock * 8 + pX >= width) || (yBlock * 4 + pY >= height)) continue; byte data = stream.ReadByte(); decodedData[width * ((yBlock * 4) + pY) + (xBlock * 8) + pX] = data; } } } } //Now look them up in the palette and turn them into actual colors. byte[] finalDest = new byte[decodedData.Length / 2]; int pixelSize = paletteFormat == PaletteFormats.IA8 ? 2 : 4; int destOffset = 0; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { UnpackPixelFromPalette(decodedData[y * width + x], ref finalDest, destOffset, imagePalette.GetBytes(), paletteFormat); destOffset += pixelSize; } } return finalDest; }
private RawMapEntity LoadMapEntityFromStream(string chunkFourCC, EndianBinaryReader reader, MapEntityDataDescriptor template) { RawMapEntity obj = new RawMapEntity(); obj.Fields = new PropertyCollection(); obj.FourCC = chunkFourCC; // We're going to examine the Template's properties and load based on the current template type. for (int i = 0; i < template.Fields.Count; i++) { var templateProperty = template.Fields[i]; string propertyName = templateProperty.FieldName; PropertyType type = templateProperty.FieldType; object value = null; switch (type) { case PropertyType.FixedLengthString: value = reader.ReadString(templateProperty.Length).Trim(new[] { '\0' }); break; case PropertyType.String: value = reader.ReadStringUntil('\0'); break; case PropertyType.Byte: value = reader.ReadByte(); break; case PropertyType.Short: value = reader.ReadInt16(); break; case PropertyType.Int32BitField: case PropertyType.Int32: value = reader.ReadInt32(); break; case PropertyType.Float: value = reader.ReadSingle(); break; case PropertyType.Vector3: value = new Vector3(reader.ReadSingle(), reader.ReadSingle(), reader.ReadSingle()); break; case PropertyType.Vector2: value = new Vector2(reader.ReadSingle(), reader.ReadSingle()); break; case PropertyType.Enum: byte enumIndexBytes = reader.ReadByte(); // ToDo: Resolve to actual Enum later. value = enumIndexBytes; break; case PropertyType.ObjectReference: // When we first resolve them, we're going to keep the value as the reference byte, // and then when they are post-processed they'll be turned into a proper type. value = (int)reader.ReadByte(); break; case PropertyType.ObjectReferenceShort: // When we first resolve them, we're going to keep the value as the reference byte, // and then when they are post-processed they'll be turned into a proper type. value = (int)reader.ReadUInt16(); break; case PropertyType.ObjectReferenceArray: // When we first resolve them, we're going to keep the value as the reference byte, // and then when they are post-processed they'll be turned into a proper type. var refList = new BindingList<object>(); for (int refArray = 0; refArray < templateProperty.Length; refArray++) { refList.Add((int)reader.ReadByte()); } value = refList; break; case PropertyType.XYRotation: { Vector3 eulerAngles = new Vector3(); for (int f = 0; f < 2; f++) eulerAngles[f] = (reader.ReadInt16() * (180 / 32786f)); Quaternion xAxis = Quaternion.FromAxisAngle(new Vector3(1, 0, 0), eulerAngles.X * MathE.Deg2Rad); Quaternion yAxis = Quaternion.FromAxisAngle(new Vector3(0, 1, 0), eulerAngles.Y * MathE.Deg2Rad); // Swizzling to the ZYX order seems to be the right one. Quaternion finalRot = yAxis * xAxis; value = finalRot; } break; case PropertyType.XYZRotation: { Vector3 eulerAngles = new Vector3(); for (int f = 0; f < 3; f++) eulerAngles[f] = (reader.ReadInt16() * (180 / 32786f)); Quaternion xAxis = Quaternion.FromAxisAngle(new Vector3(1, 0, 0), eulerAngles.X * MathE.Deg2Rad); Quaternion yAxis = Quaternion.FromAxisAngle(new Vector3(0, 1, 0), eulerAngles.Y * MathE.Deg2Rad); Quaternion zAxis = Quaternion.FromAxisAngle(new Vector3(0, 0, 1), eulerAngles.Z * MathE.Deg2Rad); // Swizzling to the ZYX order seems to be the right one. Quaternion finalRot = zAxis * yAxis * xAxis; value = finalRot; } break; case PropertyType.YRotation: { float yRotation = reader.ReadInt16() * (180 / 32786f); Quaternion yAxis = Quaternion.FromAxisAngle(new Vector3(0, 1, 0), yRotation * MathE.Deg2Rad); value = yAxis; } break; case PropertyType.Color32: value = new Color32(reader.ReadByte(), reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); break; case PropertyType.Color24: value = new Color24(reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); break; case PropertyType.Vector3Byte: type = PropertyType.Vector3Byte; value = new Vector3(reader.ReadByte(), reader.ReadByte(), reader.ReadByte()); break; case PropertyType.Bits: value = (byte)reader.ReadBits(templateProperty.Length); break; } // This... this could get dicy. If the template we just read was a "Name" then we now have the technical name (and value) // of the object. We can then search for the MapObjectDataDescriptor that matches the technical name, and then edit the // remaining fields. However, this gets somewhat dicey, because we're modifying the length of the Fields array for templates // while iterating through it. However, the Name field always comes before any of the fields we'd want to modify, we're going to // do an in-place replacement of the fields (since Fields.Count will increase) and then we get free loading of the complex templates // without later post-processing them. if (templateProperty.FieldName == "Name") { // See if our template list has a complex version of this file, otherwise grab the default. MapObjectDataDescriptor complexDescriptor = m_editorCore.Templates.MapObjectDataDescriptors.Find(x => x.FourCC == chunkFourCC && x.TechnicalName == templateProperty.FieldName); if (complexDescriptor == null) complexDescriptor = m_editorCore.Templates.DefaultMapObjectDataDescriptor; // Determine which field we need to remove, and then insert in the other fields (in order) where it used to be. foreach (var fieldToReplace in complexDescriptor.DataOverrides) { for (int k = 0; k < template.Fields.Count; k++) { if (template.Fields[k].FieldName == fieldToReplace.ParameterName) { // Remove the old field. template.Fields.RemoveAt(k); // Now insert the new fields starting at the location of the one we just replaced. template.Fields.InsertRange(k, fieldToReplace.Values); break; } } } } Property instanceProp = new Property(templateProperty.FieldName, type, value); obj.Fields.Properties.Add(instanceProp); } return obj; }
static void Handle(object client_obj) { string name = Thread.CurrentThread.Name; StreamWriter log = null; try { TcpClient client = (TcpClient)client_obj; using (NetworkStream stream = client.GetStream()) { EndianBinaryReader reader = new EndianBinaryReader(stream); EndianBinaryWriter writer = new EndianBinaryWriter(stream); // Log connection Console.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); // Create log file for current thread log = new StreamWriter(logs_root + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "-" + name + ".txt"); log.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); writer.Write(BYTE_SPECIAL); while (true) { byte cmd_byte = reader.ReadByte(); switch (cmd_byte) { // cmd case BYTE_PING: { int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString()); break; } case BYTE_LOG_STR: { int len_str = reader.ReadInt32(); string str = reader.ReadString(Encoding.ASCII, len_str - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); Log(log, name + " LogString =>(\"" + str + "\")"); break; } case BYTE_DISCONNECT: { Log(log, name + " DISCONNECT"); break; } // sd case BYTE_MOUNT_SD: { Log(log, name + " Trying to mount SD card"); break; } case BYTE_MOUNT_SD_OK: { Log(log, name + " SD card mounted !"); break; } case BYTE_MOUNT_SD_BAD: { Log(log, name + " Can't mount SD card"); break; } // replacement case BYTE_STAT: case BYTE_STAT_ASYNC: { int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); if (cmd_byte == BYTE_STAT) Log(log, name + " FSGetStat(\"" + path + "\")"); else Log(log, name + " FSGetStatAsync(\"" + path + "\")"); break; } case BYTE_OPEN_FILE: case BYTE_OPEN_FILE_ASYNC: { int len_str = reader.ReadInt32(); string str = reader.ReadString(Encoding.ASCII, len_str - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); if (cmd_byte == BYTE_OPEN_FILE) Log(log, name + " FSOpenFile(\"" + str + "\")"); else Log(log, name + " FSOpenFileAsync(\"" + str + "\")"); break; } case BYTE_OPEN_DIR: case BYTE_OPEN_DIR_ASYNC: { int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); if (cmd_byte == BYTE_OPEN_DIR) Log(log, name + " FSOpenDir(\"" + path + "\")"); else Log(log, name + " FSOpenDirAsync(\"" + path + "\")"); break; } case BYTE_CHANGE_DIR: case BYTE_CHANGE_DIR_ASYNC: { int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); if (cmd_byte == BYTE_CHANGE_DIR) Log(log, name + " FSChangeDir(\"" + path + "\")"); else Log(log, name + " FSChangeDirAsync(\"" + path + "\")"); break; } case BYTE_MAKE_DIR: case BYTE_MAKE_DIR_ASYNC: { int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); if (cmd_byte == BYTE_CHANGE_DIR) Log(log, name + " FSMakeDir(\"" + path + "\")"); else Log(log, name + " FSMakeDirAsync(\"" + path + "\")"); break; } case BYTE_RENAME: case BYTE_RENAME_ASYNC: { int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); if (cmd_byte == BYTE_CHANGE_DIR) Log(log, name + " FSRename(\"" + path + "\")"); else Log(log, name + " FSRenameAsync(\"" + path + "\")"); break; } case BYTE_REMOVE: case BYTE_REMOVE_ASYNC: { int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); if (cmd_byte == BYTE_CHANGE_DIR) Log(log, name + " FSRemove(\"" + path + "\")"); else Log(log, name + " FSRemoveAsync(\"" + path + "\")"); break; } // Log case BYTE_CLOSE_FILE: { Log(log, name + " FSCloseFile()"); break; } case BYTE_CLOSE_FILE_ASYNC: { Log(log, name + " FSCloseFileAsync()"); break; } case BYTE_CLOSE_DIR: { Log(log, name + " FSCloseDir()"); break; } case BYTE_CLOSE_DIR_ASYNC: { Log(log, name + " FSCloseDirAsync()"); break; } case BYTE_FLUSH_FILE: { Log(log, name + " FSFlushFile()"); break; } case BYTE_GET_ERROR_CODE_FOR_VIEWER: { Log(log, name + " FSGetErrorCodeForViewer()"); break; } case BYTE_GET_LAST_ERROR: { Log(log, name + " FSGetLastError()"); break; } case BYTE_GET_MOUNT_SOURCE: { Log(log, name + " FsGetMountSource()"); break; } case BYTE_GET_MOUNT_SOURCE_NEXT: { Log(log, name + " FsGetMountSourceNext()"); break; } case BYTE_GET_POS_FILE: { Log(log, name + " FSGetPos()"); break; } case BYTE_SET_POS_FILE: { Log(log, name + " FSSetPos()"); break; } case BYTE_GET_STAT_FILE: { Log(log, name + " FSGetStatFile()"); break; } case BYTE_EOF: { Log(log, name + " FSGetEof()"); break; } case BYTE_READ_FILE: { Log(log, name + " FSReadFile()"); break; } case BYTE_READ_FILE_ASYNC: { Log(log, name + " FSReadFileAsync()"); break; } case BYTE_READ_FILE_WITH_POS: { Log(log, name + " FSReadFileWithPos()"); break; } case BYTE_READ_DIR: { Log(log, name + " FSReadDir()"); break; } case BYTE_READ_DIR_ASYNC: { Log(log, name + " FSReadDirAsync()"); break; } case BYTE_GET_CWD: { Log(log, name + " FSGetCwd()"); break; } case BYTE_SET_STATE_CHG_NOTIF: { Log(log, name + " FSSetStateChangeNotification()"); break; } case BYTE_TRUNCATE_FILE: { Log(log, name + " FSTruncateFile()"); break; } case BYTE_WRITE_FILE: { Log(log, name + " FSWriteFile()"); break; } case BYTE_WRITE_FILE_WITH_POS: { Log(log, name + " FSWriteFileWithPos()"); break; } case BYTE_CREATE_THREAD: { Log(log, name + " CreateThread()"); break; } default: throw new InvalidDataException(); } } } } catch (Exception e) { if (log != null) Log(log, name + " " + e.Message); else Console.WriteLine(name + " " + e.Message); } finally { if (log != null) log.Close(); } Console.WriteLine(name + " Exit"); }
/// <summary> /// Decode the specified stream as a Yaz0 encoded file and return the decoded data as a MemoryStream. /// Throws an <see cref="InvalidDataException"/> if the stream is not positioned to the start of a Yaz0 file. /// </summary> /// <param name="stream">Stream to read data from.</param> /// <returns>Decoded file as <see cref="MemoryStream"/></returns> public MemoryStream Decode(EndianBinaryReader stream) { // 16 byte Header if (stream.ReadUInt32() != 0x59617A30) // "Yaz0" Magic { throw new InvalidDataException("Invalid Magic, not a Yaz0 File"); } int uncompressedSize = stream.ReadInt32(); stream.ReadBytes(8); // Padding byte[] output = new byte[uncompressedSize]; int destPos = 0; byte curCodeByte = 0; uint validBitCount = 0; while (destPos < uncompressedSize) { // The codeByte specifies what to do for the next 8 steps. Read a new one if we've exhausted the current one. if (validBitCount == 0) { curCodeByte = stream.ReadByte(); validBitCount = 8; } if ((curCodeByte & 0x80) != 0) { // If the bit is set then there is no compression, just write the data to the output. output[destPos] = stream.ReadByte(); destPos++; } else { // If the bit is not set, then the data needs to be decompressed. The next two bytes tells the data location and size. // The decompressed data has already been written to the output stream, so we go and retrieve it. byte byte1 = stream.ReadByte(); byte byte2 = stream.ReadByte(); int dist = ((byte1 & 0xF) << 8) | byte2; int copySource = destPos - (dist + 1); int numBytes = byte1 >> 4; if (numBytes == 0) { // Read the third byte which tells you how much data to read. numBytes = stream.ReadByte() + 0x12; } else { numBytes += 2; } // Copy Run for (int k = 0; k < numBytes; k++) { output[destPos] = output[copySource]; copySource++; destPos++; } } // Use the next bit from the code byte curCodeByte <<= 1; validBitCount -= 1; } return new MemoryStream(output); }
public static SEQ FromStream(EndianBinaryReader reader, ContentBase activeSHP) { SHP targetSHP = (SHP)activeSHP; /*===================================================================== TODO: add lenght =====================================================================*/ // base ptr needed because the SEQ could be embedded. uint ptrBase = (uint)reader.BaseStream.Position; byte numFrames = reader.ReadByte(); // total number of frames? var unknownPaddingValue1 = reader.ReadByte(); // padding //Trace.Assert(unknownPaddingValue1 == 0); byte numBones = reader.ReadByte(); var unknownPaddingValue2 = reader.ReadByte(); // padding //Trace.Assert(unknownPaddingValue2 == 0); uint size = reader.ReadUInt32(); var unknownPaddingValue3 = reader.ReadUInt32(); // unknown //Trace.Assert(unknownPaddingValue3 == 0); uint ptrFrames = (uint)reader.ReadUInt32() + 8; // pointer to the frames data section uint ptrSequence = ptrFrames + (uint)numFrames; // pointer to the sequence section // number of animations // length of all the headers / length of one animation header int numAnimations = (((int)ptrSequence - numFrames) - 16) / (numBones * 4 + 10); List<AnimationHeader> headers = new List<AnimationHeader>(); for (int i = 0; i < numAnimations; i++) { AnimationHeader animHeader = new AnimationHeader { length = reader.ReadUInt16(), idOtherAnimation = reader.ReadSByte(), // the intial source animation. Used to get initial frames. mode = reader.ReadByte(), ptrLooping = reader.ReadUInt16(), // seems to point to a data block that controls looping ptrTranslation = reader.ReadUInt16(), // points to a translation vector for the animated mesh (root motion?) ptrMove = reader.ReadUInt16(), // points to a data block that controls movement (root motion?) ptrBones = new ushort[numBones], }; // assign bone ptrs for (int p = 0; p < numBones; p++) { animHeader.ptrBones[p] = reader.ReadUInt16(); } for (int j = 0; j < numBones; j++) { var unknownBoneValues = reader.ReadUInt16(); //TODO: this is 0 for all SEQs? //Trace.Assert(unknownBoneValues == 0); // will show if value is ever NOT zero } headers.Add(animHeader); } // TODO: Never used!? sbyte[] frames = new sbyte[numFrames]; for (int i = 0; i < numFrames; i++) { frames[i] = reader.ReadSByte(); } // get source animation data from .SEQ List<Animation> animations = new List<Animation>(); for (int i = 0; i < numAnimations; i++) { Animation animation = new Animation(); // seek translation data long seekTranslationPtr = (long)(headers[i].ptrTranslation + ptrSequence + ptrBase); reader.BaseStream.Seek(seekTranslationPtr, SeekOrigin.Begin); reader.CurrentEndian = Endian.Big; // this is code used in the opcode portion (machine code uses Big) Int16 x = reader.ReadInt16(); Int16 y = reader.ReadInt16(); Int16 z = reader.ReadInt16(); reader.CurrentEndian = Endian.Little; // TODO: implement move // set base animation if (headers[i].idOtherAnimation != -1) { // TODO: FIX THIS // should store other animation inside as base // I assume it only references animations that // have been constructed first otherwise it will hold a dead copy. // animation.baseAnimation = animations[i]; } // read base pose and keyframes animation.poses = new Vector3[numBones]; animation.keyframes = new List<NullableVector4>[numBones]; for (int k = 0; k < numBones; k++) { animation.keyframes[k] = new List<NullableVector4>(); animation.keyframes[k].Add(NullableVector4.Zero()); // read pose long seekBonePtr = (long)(headers[i].ptrBones[k] + ptrSequence + ptrBase); reader.BaseStream.Seek(seekBonePtr, SeekOrigin.Begin); reader.CurrentEndian = Endian.Big; // machine code uses Big Int16 rx = reader.ReadInt16(); Int16 ry = reader.ReadInt16(); Int16 rz = reader.ReadInt16(); reader.CurrentEndian = Endian.Little; animation.poses[k] = new Vector3(rx, ry, rz); // read keyframe float? f = 0; while (true) { // this could be optimized using out values and an advanced way of recording and reading frames NullableVector4 op = ReadOPCode(reader); if (op == null) break; f += op.W; animation.keyframes[k].Add(op); if (f >= headers[i].length - 1) break; } } animations.Add(animation); } // build useable animation data for (int a = 0; a < numAnimations; a++) { // rotation bones for (int i = 0; i < numBones; i++) { List<NullableVector4> keyframes = animations[a].keyframes[i]; Vector3 pose = animations[a].poses[i]; // multiplication by two at 0xad25c, 0xad274, 0xad28c // value * (180f / uint16.max); float rx = pose.X * 2; float ry = pose.Y * 2; float rz = pose.Z * 2; List<Keyframe> keys = new List<Keyframe>(); float t = 0; for (var j = 0; j < keyframes.Count; j++) { NullableVector4 keyframe = keyframes[j]; float f = (float)keyframe.W; t += f; if (keyframe.X == null) keyframe.X = keyframes[j - 1].X; if (keyframe.Y == null) keyframe.Y = keyframes[j - 1].Y; if (keyframe.Z == null) keyframe.Z = keyframes[j - 1].Z; rx += (float)keyframe.X * f; ry += (float)keyframe.Y * f; rz += (float)keyframe.Z * f; Quaternion q = VSTools.Rot2Quat(rx * VSTools.Rot13ToRad, ry * VSTools.Rot13ToRad, rz * VSTools.Rot13ToRad); Keyframe key = new Keyframe(); key.Time = t * VSTools.TimeScale; key.Rotation = q; keys.Add(key); } animations[a].jointKeys.Add(keys); } // root's translation bone List<Keyframe> rootKey = new List<Keyframe>(); rootKey.Add(new Keyframe()); animations[a].jointKeys.Add(rootKey); // translation bones for (int t = 1; t < numBones; t++) { List<Keyframe> transBone = new List<Keyframe>(); Keyframe key = new Keyframe(); key.Position = new Vector3(targetSHP.joints[t].boneLength, 0, 0); transBone.Add(key); animations[a].jointKeys.Add(transBone); } if (headers[a].idOtherAnimation != -1) { animations[a].baseAnimation = animations[headers[a].idOtherAnimation]; } } return new SEQ(animations); }
public TexCoordGen(EndianBinaryReader er) { Unknown1 = er.ReadByte(); Source = (TexCoordSource)er.ReadByte(); Unknown2 = er.ReadUInt16(); }
public static List<TextureMap> GetTextures(EndianBinaryReader reader, int numOfPalettes) { List<TextureMap> textures = new List<TextureMap>(); UInt32 size = reader.ReadUInt32(); //reader.Skip(0x01); // version number, always 1 for WEPs. SHP? byte temp = reader.ReadByte(); Trace.Assert(temp == 1); int width = reader.ReadByte() * 2; int height = reader.ReadByte() * 2; byte colorsPerPalette = reader.ReadByte(); if (numOfPalettes != 2) { ConstructWeaponPalettes(reader, textures, numOfPalettes, width, height, colorsPerPalette); } else { ConstructCharacterPalettes(reader, textures, numOfPalettes, width, height, colorsPerPalette); } // A linear representation of the texture map, each byte is a palette index. byte[] paletteMap = new byte[width * height]; for (var y = 0; y < height; ++y) { for (var x = 0; x < width; ++x) { paletteMap[(y * width) + x] = reader.ReadByte(); } } for (int i = 0; i < numOfPalettes; i++) { textures[i].map = paletteMap; textures[i].SaveToDisk(i.ToString()); } return textures; }
public void Read(Stream inStream, MesgDefinition defnMesg) { inStream.Position = 1; EndianBinaryReader mesgReader = new EndianBinaryReader(inStream, defnMesg.IsBigEndian); LocalNum = defnMesg.LocalMesgNum; foreach (FieldDefinition fieldDef in defnMesg.GetFields()) { // It's possible the field type found in the field definition may // not agree with the type defined in the profile. The profile // type will be preferred for decode. Field field = GetField(fieldDef.Num); if (field == null) { // We normally won't have fields attached to our skeleton message, // as we add values we need to add the fields too based on the mesg,field // combo in the profile. Must derive from the profile so the scale etc // is correct field = new Field(Profile.GetMesg(this.Num).GetField(fieldDef.Num)); if (field.Num == Fit.FieldNumInvalid) { // If there was no info in the profile the FieldNum will get set to invalid // so preserve the unknown fields info while we know it field.Num = fieldDef.Num; field.Type = fieldDef.Type; } SetField(field); } object value; // strings may be an array and are of variable length if ((field.Type & Fit.BaseTypeNumMask) == Fit.String) { List<byte> utf8Bytes = new List<byte>(); byte b = new byte(); for (int i=0; i<fieldDef.Size; i++) { b = mesgReader.ReadByte(); if (b == 0x00) { field.AddValue(utf8Bytes.ToArray()); utf8Bytes.Clear(); } else { utf8Bytes.Add(b); } } if (utf8Bytes.Count != 0) { field.AddValue(utf8Bytes.ToArray()); utf8Bytes.Clear(); } } else { int numElements = (int)fieldDef.Size / Fit.BaseType[field.Type & Fit.BaseTypeNumMask].size; for (int i=0; i < numElements; i++) { switch (field.Type & Fit.BaseTypeNumMask) { case Fit.Enum: case Fit.Byte: case Fit.UInt8: case Fit.UInt8z: value = mesgReader.ReadByte(); break; case Fit.SInt8: value = mesgReader.ReadSByte(); break; case Fit.SInt16: value = mesgReader.ReadInt16(); break; case Fit.UInt16: case Fit.UInt16z: value = mesgReader.ReadUInt16(); break; case Fit.SInt32: value = mesgReader.ReadInt32(); break; case Fit.UInt32: case Fit.UInt32z: value = mesgReader.ReadUInt32(); break; case Fit.Float32: value = mesgReader.ReadSingle(); break; case Fit.Float64: value = mesgReader.ReadDouble(); break; default: value = mesgReader.ReadBytes(fieldDef.Size); break; } field.SetRawValue(i, value); } } } }
/// <summary> /// Function to retrieve name string either from string table or from current stream pointer. /// </summary> /// <returns>String containing name.</returns> private String ELF_getStringFromStringTable() { Byte currByte; ArrayList name = new ArrayList(128); EndianBinaryReader ebr = new EndianBinaryReader(binFile,(Endian) headerRef["endian"]); // Read characters and build string until terminating null currByte = ebr.ReadByte(); while (currByte != 0) { name.Add(currByte); currByte = ebr.ReadByte(); } if (name.Count > 128) Debug.DebugMSG(ASCIIEncoding.ASCII.GetString((Byte[])name.ToArray(typeof(Byte)), 0, name.Count)); return ASCIIEncoding.ASCII.GetString((Byte[]) name.ToArray(typeof(Byte)), 0, name.Count); }
/// <summary> /// Parse the ELF file's symbol table. /// </summary> private void ParseSymbolTable() { EndianBinaryReader ebr = new EndianBinaryReader(binFile, endian); UInt32 numSymbols = (UInt32) headerRef["numEntriesInSymTable"]; ELF_Symbol sym; Byte info, other; symRef = new Hashtable[numSymbols]; // Read the symbol table for (UInt32 symNum = 0; symNum < numSymbols; symNum++) { symRef[symNum] = new Hashtable(); // Go to current symbol ebr.BaseStream.Seek((Int64) ((UInt64)headerRef["symbolTableAddr"]) + ((UInt32)headerRef["symbolTableEntrySize"] * symNum),SeekOrigin.Begin); sym.st_name = (UInt32) ebr.ReadUInt32(); if (ELF_FileClass.ELFCLASS_32 == hdr.e_ident.fileClass) { sym.st_value = (UInt64) ebr.ReadUInt32(); sym.st_size = (UInt64) ebr.ReadUInt32(); info = ebr.ReadByte(); other = ebr.ReadByte(); sym.st_shndx = ebr.ReadUInt16(); } else { info = ebr.ReadByte(); other = ebr.ReadByte(); sym.st_shndx = ebr.ReadUInt16(); sym.st_value = ebr.ReadUInt64(); sym.st_size = ebr.ReadUInt64(); } sym.st_type = (ELF_SymbolType) (info & 0xF); sym.st_binding = (ELF_SymbolBinding) ((info >> 4) & 0xF); sym.st_visibility = (ELF_SymbolVisibility) (other & 0x3); /* Debug.DebugMSG( "Symbol[" + symNum + "] = \n{" ); Debug.DebugMSG( " Symbol Name Offset : 0x" + sym.st_name.ToString("X8")); Debug.DebugMSG( " Symbol Value : 0x" + sym.st_value.ToString("X16")); Debug.DebugMSG( " Symbol Size : 0x" + sym.st_size.ToString("X16")); Debug.DebugMSG( " Symbol Type : " + sym.st_type); Debug.DebugMSG( " Symbol Binding : " + sym.st_binding); Debug.DebugMSG( " Symbol Visibility : " + sym.st_visibility); Debug.DebugMSG( " Symbol's Relevant Section : 0x" + sym.st_shndx.ToString("X4")); Debug.DebugMSG( "}\n"); */ // Move to name in String Table ebr.BaseStream.Seek( (Int64) ((UInt64)headerRef["stringTableAddr"]) + (sym.st_name), SeekOrigin.Begin); symRef[symNum]["name"] = ELF_getStringFromStringTable(); Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"name\"]: " + ((String)symRef[symNum]["name"]).ToString()); symRef[symNum]["value"] = sym.st_value; Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"value\"]: " + ((UInt64)symRef[symNum]["value"]).ToString("X8")); symRef[symNum]["secNum"] = sym.st_shndx; Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"secNum\"]: " + ((UInt16)symRef[symNum]["secNum"]).ToString("X4")); symRef[symNum]["type"] = sym.st_type; Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"type\"]: " + sym.st_type); symRef[symNum]["binding"] = sym.st_binding; Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"binding\"]: " + sym.st_binding); symRef[symNum]["visibility"] = sym.st_visibility; Debug.DebugMSG("symRef[" + symNum.ToString() + "][\"visibility\"]: " + sym.st_visibility); } Debug.DebugMSG("Parse Symbol Table Done"); }
private static void ConvertFromByaml(EndianBinaryReader reader, string outpath) { if (reader.ReadUInt32() != 0x42590001) throw new InvalidDataException(); uint[] offsets = reader.ReadUInt32s(4); if (offsets[0] > reader.BaseStream.Length) throw new InvalidDataException(); if (offsets[1] > reader.BaseStream.Length) throw new InvalidDataException(); if (offsets[2] > reader.BaseStream.Length) throw new InvalidDataException(); if (offsets[3] > reader.BaseStream.Length) { if (offsets[0] == 0x10) { offsets[3] = offsets[2]; // Splatoon byamls are missing offsets[2] offsets[2] = 0; } else { throw new InvalidDataException(); } } List<string> nodes = new List<string>(); List<string> values = new List<string>(); List<byte[]> data = new List<byte[]>(); if (offsets[0] != 0) { reader.BaseStream.Seek(offsets[0], SeekOrigin.Begin); nodes.AddRange(new ByamlNode.StringList(reader).Strings); } if (offsets[1] != 0) { reader.BaseStream.Seek(offsets[1], SeekOrigin.Begin); values.AddRange(new ByamlNode.StringList(reader).Strings); } if (offsets[2] != 0) { reader.BaseStream.Seek(offsets[2], SeekOrigin.Begin); data.AddRange(new ByamlNode.BinaryDataList(reader).DataList); } ByamlNode tree; ByamlNodeType rootType; reader.BaseStream.Seek(offsets[3], SeekOrigin.Begin); rootType = (ByamlNodeType)reader.ReadByte(); reader.BaseStream.Seek(-1, SeekOrigin.Current); if (rootType == ByamlNodeType.UnamedNode) tree = new ByamlNode.UnamedNode(reader); else tree = new ByamlNode.NamedNode(reader); XmlDocument yaml = new XmlDocument(); yaml.AppendChild(yaml.CreateXmlDeclaration("1.0", "UTF-8", null)); XmlElement root = yaml.CreateElement("yaml"); yaml.AppendChild(root); tree.ToXml(yaml, root, nodes, values, data); using (StreamWriter writer = new StreamWriter(new FileStream(outpath, FileMode.Create), Encoding.UTF8)) { yaml.Save(writer); } }
private static byte[] DecodeRgba32(EndianBinaryReader stream, uint width, uint height) { uint numBlocksW = width / 4; //4 byte block width uint numBlocksH = height / 4; //4 byte block height byte[] decodedData = new byte[width * height * 4]; for (int yBlock = 0; yBlock < numBlocksH; yBlock++) { for (int xBlock = 0; xBlock < numBlocksW; xBlock++) { //For each block, we're going to examine block width / block height number of 'pixels' for (int pY = 0; pY < 4; pY++) { for (int pX = 0; pX < 4; pX++) { //Ensure the pixel we're checking is within bounds of the image. if ((xBlock * 4 + pX >= width) || (yBlock * 4 + pY >= height)) continue; //Now we're looping through each pixel in a block, but a pixel is four bytes long. uint destIndex = (uint)(4 * (width * ((yBlock * 4) + pY) + (xBlock * 4) + pX)); decodedData[destIndex + 3] = stream.ReadByte(); //Alpha decodedData[destIndex + 2] = stream.ReadByte(); //Red } } //...but we have to do it twice, because RGBA32 stores two sub-blocks per block. (AR, and GB) for (int pY = 0; pY < 4; pY++) { for (int pX = 0; pX < 4; pX++) { //Ensure the pixel we're checking is within bounds of the image. if ((xBlock * 4 + pX >= width) || (yBlock * 4 + pY >= height)) continue; //Now we're looping through each pixel in a block, but a pixel is four bytes long. uint destIndex = (uint)(4 * (width * ((yBlock * 4) + pY) + (xBlock * 4) + pX)); decodedData[destIndex + 1] = stream.ReadByte(); //Green decodedData[destIndex + 0] = stream.ReadByte(); //Blue } } } } return decodedData; }
public BlendMode(EndianBinaryReader er) { BlendOperator = (BlendOp)er.ReadByte(); SourceFactor = (BlendSource)er.ReadByte(); DestinationFactor = (BlendDestination)er.ReadByte(); LogicOperator = (BlendLogicOp)er.ReadByte(); }
public VirtualFilesystemDirectory ReadFile(EndianBinaryReader reader) { if (reader.ReadUInt32() != 0x52415243) // "RARC" throw new InvalidDataException("Invalid Magic, not a RARC File"); uint fileSize = reader.ReadUInt32(); reader.SkipUInt32(); // Unknown uint dataOffset = reader.ReadUInt32() + 0x20; reader.Skip(16); // Unknown - 4 unsigned ints uint numNodes = reader.ReadUInt32(); reader.Skip(8); // Unknown - 2 unsigned ints uint fileEntryOffset = reader.ReadUInt32() + 0x20; reader.SkipUInt32(); // Unknown uint stringTableOffset = reader.ReadUInt32() + 0x20; reader.Skip(8); // Unknown - 2 unsigned ints. // Read all of the node headers. Node[] nodes = new Node[numNodes]; for (int i = 0; i < numNodes; i++) { nodes[i] = new Node { Type = new string(reader.ReadChars(4)), Name = ReadStringAtOffset(reader, stringTableOffset, reader.ReadUInt32()), NameHashcode = reader.ReadUInt16(), Entries = new FileEntry[reader.ReadUInt16()], FirstFileOffset = reader.ReadUInt32() }; } // Create a virtual directory for every folder within the ARC before we process any of them. List<VirtualFilesystemDirectory> allDirs = new List<VirtualFilesystemDirectory>(nodes.Length); foreach (Node node in nodes) { VirtualFilesystemDirectory vfDir = new VirtualFilesystemDirectory(node.Name); allDirs.Add(vfDir); } for (int k = 0; k < nodes.Length; k++) { Node node = nodes[k]; VirtualFilesystemDirectory curDir = allDirs[k]; for (int i = 0; i < node.Entries.Length; i++) { // Jump to the entry's offset in the file. reader.BaseStream.Position = fileEntryOffset + ((node.FirstFileOffset + i) * 0x14); // 0x14 is the size of a File Entry in bytes node.Entries[i] = new FileEntry(); node.Entries[i].ID = reader.ReadUInt16(); node.Entries[i].NameHashcode = reader.ReadUInt16(); node.Entries[i].Type = reader.ReadByte(); reader.SkipByte(); // Padding node.Entries[i].Name = ReadStringAtOffset(reader, stringTableOffset, reader.ReadUInt16()); // Skip these ones cause I don't know how computers work. if (node.Entries[i].Name == "." || node.Entries[i].Name == "..") continue; uint entryDataOffset = reader.ReadUInt32(); uint dataSize = reader.ReadUInt32(); // If it's a directory, then entryDataOffset contains the index of the parent node if (node.Entries[i].IsDirectory) { node.Entries[i].SubDirIndex = entryDataOffset; var newSubDir = allDirs[(int)entryDataOffset]; curDir.Children.Add(newSubDir); } else { node.Entries[i].Data = reader.ReadBytesAt(dataOffset + entryDataOffset, (int)dataSize); string fileName = Path.GetFileNameWithoutExtension(node.Entries[i].Name); string extension = Path.GetExtension(node.Entries[i].Name); var vfFileContents = new VirtualFileContents(node.Entries[i].Data); VirtualFilesystemFile vfFile = new VirtualFilesystemFile(fileName, extension, vfFileContents); curDir.Children.Add(vfFile); } reader.SkipInt32(); // Padding } } // The ROOT directory should always be the first node. We don't have access to the node's TYPE anymore // so we're going to assume its always the first one listed. return allDirs.Count > 0 ? allDirs[0] : null; }
static void Handle(object client_obj) { string name = Thread.CurrentThread.Name; FileStream[] files = new FileStream[256]; Dictionary<int, FileStream> files_request = new Dictionary<int, FileStream>(); StreamWriter log = null; Dictionary<string, Dictionary<string, byte>> dir_files = new Dictionary<string, Dictionary<string, byte>>(); try { TcpClient client = (TcpClient)client_obj; using (NetworkStream stream = client.GetStream()) { EndianBinaryReader reader = new EndianBinaryReader(stream); EndianBinaryWriter writer = new EndianBinaryWriter(stream); uint[] ids = reader.ReadUInt32s(4); string LocalRootDump = root + "\\" + "dump" + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + "\\"; string LocalRootInject = root + "\\" + "inject" + "\\" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + "\\"; if (!ids[0].ToString("X8").Equals("00050000")) { writer.Write(BYTE_NORMAL); throw new Exception("Not interested."); } else { if (!Directory.Exists(LocalRootDump)) { Directory.CreateDirectory(LocalRootDump); } if (!Directory.Exists(LocalRootInject)) { Directory.CreateDirectory(LocalRootInject); } } // Log connection Console.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); Console.WriteLine(name + " TitleID: " + ids[0].ToString("X8") + "-" + ids[1].ToString("X8")); // Create log file for current thread log = new StreamWriter(logs_root + "\\" + DateTime.Now.ToString("yyyy-MM-dd") + "-" + name + "-" + ids[0].ToString("X8") + "-" + ids[1].ToString("X8") + ".txt", true, Encoding.ASCII, 1024*64); log.WriteLine(name + " Accepted connection from client " + client.Client.RemoteEndPoint.ToString()); string title_id = ids[0].ToString("X8") + "-" + ids[1].ToString("X8"); log.WriteLine(name + " TitleID: " + title_id); writer.Write(BYTE_SPECIAL); while (true) { //Log(log, "cmd_byte"); byte cmd_byte = reader.ReadByte(); switch (cmd_byte) { case BYTE_OPEN: { //Log(log, "BYTE_OPEN"); Boolean failed = false; int len_path = reader.ReadInt32(); int len_mode = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); string mode = reader.ReadString(Encoding.ASCII, len_mode - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); //Log(log, "old path" + path); //Log(log, "currentID: " + currentPersistentID); if (op_mode == BYTE_MODE_I) path = getRealPathCurrentInject(path, title_id); //Log(log, "new path" + path); if (path.Length == 0) failed = true; if (File.Exists(path) && !failed) { //Log(log, "path exits"); int handle = -1; for (int i = 1; i < files.Length; i++) { if (files[i] == null) { handle = i; break; } } if (handle == -1) { Log(log, name + " Out of file handles!"); writer.Write(BYTE_SPECIAL); writer.Write(-19); writer.Write(0); break; } //Log(log, name + " -> fopen(\"" + path + "\", \"" + mode + "\") = " + handle.ToString()); files[handle] = new FileStream(path, FileMode.Open, FileAccess.Read, FileShare.Read); writer.Write(BYTE_SPECIAL); writer.Write(0); writer.Write(handle); break; } //Log(log, "error fopen"); //else on error: writer.Write(BYTE_NORMAL); break; } case BYTE_SETPOS: { //Log(log, "BYTE_SETPOS"); int fd = reader.ReadInt32(); int pos = reader.ReadInt32(); if ((fd & 0x0fff00ff) == 0x0fff00ff) { int handle = (fd >> 8) & 0xff; if (files[handle] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } FileStream f = files[handle]; Log(log, "Postion was set to " + pos + "for handle " + handle); f.Position = pos; writer.Write(BYTE_SPECIAL); writer.Write(0); } else { writer.Write(BYTE_NORMAL); } break; } case BYTE_INJECTSTART: { long wiiUpersistentID = (long)reader.ReadUInt32(); int dumpCommon = 0; Boolean injectioncanceled = false; SaveSelectorDialog ofd = new SaveSelectorDialog(title_id, wiiUpersistentID); try { DialogResult result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { currentPersistentID = ofd.NewPersistentID; dumpCommon = ofd.DumpCommon; //Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id); if (dumpCommon == 1) Console.WriteLine("clean and inject common folder"); if (dumpCommon == 2) Console.WriteLine("inject common folder"); if (dumpCommon > 0 && currentPersistentID == 0) currentPersistentID = COMMON_PERSISTENTID; } else { Console.WriteLine("Injection canceled"); injectioncanceled = true; } } catch (Exception e) { Console.WriteLine("Injection canceled"); injectioncanceled = true; } if (injectioncanceled) { writer.Write(BYTE_NORMAL); } else { writer.Write(BYTE_SPECIAL); } int dumpmask = MASK_NORMAL; if (currentPersistentID != 0 && currentPersistentID != COMMON_PERSISTENTID) dumpmask |= MASK_USER; if (dumpCommon >= 1) { dumpmask |= MASK_COMMON; if(dumpCommon == 2) dumpmask |= MASK_COMMON_CLEAN; } writer.Write(dumpmask); writer.Write(BYTE_SPECIAL); break; } case BYTE_INJECTEND: { currentPersistentID = 0; //close all opened files for (int i = 1; i < files.Length; i++) { if (files[i] != null) { files[i].Close(); files[i] = null; } } writer.Write(BYTE_OK); //Console.WriteLine("InjectionEND"); break; } case BYTE_DUMPSTART: { long wiiUpersistentID = (long)reader.ReadUInt32(); Boolean dumpCommon = false; Boolean dumpUser = false; currentPersistentID = wiiUpersistentID; Boolean dumpcanceled = false; DumpDialog ofd = new DumpDialog(title_id, wiiUpersistentID); try { DialogResult result = ofd.ShowDialog(); if (result == System.Windows.Forms.DialogResult.OK) { dumpUser = ofd.DumpUser; dumpCommon = ofd.DumpCommon; //Console.WriteLine("Injecting " + currentPersistentID.ToString() + " into " + wiiUpersistentID.ToString() + " for title id " + title_id); if (dumpCommon) Console.WriteLine("dumping common data"); if (dumpUser) Console.WriteLine("dumping user data"); } else { Console.WriteLine("dump canceled"); dumpcanceled = true; } } catch (Exception e) { Console.WriteLine("dump canceled"); dumpcanceled = true; } if (dumpcanceled) { writer.Write(BYTE_NORMAL); } else { writer.Write(BYTE_SPECIAL); } int dumpmask = MASK_NORMAL; if (dumpUser) dumpmask |= MASK_USER; if (dumpCommon) { dumpmask |= MASK_COMMON; } writer.Write(dumpmask); writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMPEND: { currentPersistentID = 0; //close all opened files for (int i = 1; i < files.Length; i++) { if (files[i] != null) { files[i].Close(); files[i] = null; } } writer.Write(BYTE_OK); //Console.WriteLine("dumpEND"); break; } case BYTE_READ_DIR: { Boolean failed = false; int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path-1); if (reader.ReadByte() != 0) throw new InvalidDataException(); int x = 0; //Console.WriteLine("old" + path); if(op_mode == BYTE_MODE_I) path = getRealPathCurrentInject(path, title_id); //Console.WriteLine("new" + path); if(path.Length == 0)failed = true; if (Directory.Exists(path) && !failed) { x = countDirectory(path); if (x > 0) { Dictionary<string, byte> value; if (!dir_files.TryGetValue(path, out value)) { //Console.Write("found no \"" + path + "\" in dic \n"); value = new Dictionary<string, byte>(); string[] fileEntries = Directory.GetFiles(path); foreach (string fn in fileEntries) { string fileName = Path.GetFileName(fn); value.Add(fileName, BYTE_FILE); } string[] subdirectoryEntries = Directory.GetDirectories(path); foreach (string sd in subdirectoryEntries) { string subdirectory = Path.GetFileName(sd); value.Add(subdirectory, BYTE_FOLDER); } dir_files.Add(path, value); //Console.Write("added \"" + path + "\" to dic \n"); } else { //Console.Write("dic for \"" + path + "\" ready \n"); } if (value.Count > 0) { writer.Write(BYTE_OK); //Console.Write("sent ok byte \n"); foreach (var item in value) { //Write writer.Write(item.Value); //Console.Write("type : " + item.Value); writer.Write(item.Key.Length); //Console.Write("length : " + item.Key.Length); writer.Write(item.Key, Encoding.ASCII, true); //Console.Write("filename : " + item.Key); int length = 0; if (item.Value == BYTE_FILE) length = (int)new System.IO.FileInfo(path + "/" + item.Key).Length; writer.Write(length); //Console.Write("filesize : " + length + " \n"); value.Remove(item.Key); //Console.Write("removed from list! " + value.Count + " remaining\n"); break; } writer.Write(BYTE_SPECIAL); // //Console.Write("file sent, wrote special byte \n"); break; } else { dir_files.Remove(path); //Console.Write("removed \"" + path + "\" from dic \n"); } } } writer.Write(BYTE_END); // //Console.Write("list was empty return BYTE_END \n"); //Console.Write("in break \n"); break; } case BYTE_READ: { //Log(log,"BYTE_READ"); int size = reader.ReadInt32(); int fd = reader.ReadInt32(); FileStream f = files[fd]; byte[] buffer = new byte[size]; int sz = (int)f.Length; int rd = 0; //Log(log, "want size:" + size + " for handle: " + fd); writer.Write(BYTE_SPECIAL); rd = f.Read(buffer, 0, buffer.Length); //Log(log,"rd:" + rd); writer.Write(rd); writer.Write(buffer, 0, rd); int offset = (int)f.Position; int progress = (int)(((float)offset / (float)sz) * 100); string strProgress = progress.ToString().PadLeft(3, ' '); string strSize = (sz / 1024).ToString(); string strCurrent = (offset / 1024).ToString().PadLeft(strSize.Length, ' '); Console.Write("\r\t--> {0}% ({1} kB / {2} kB)", strProgress, strCurrent, strSize); //Console.Write("send " + rd ); if (offset == sz) { Console.Write("\n"); log.Write("\r\t--> {0}% ({1} kB / {2} kB)\n", strProgress, strCurrent, strSize); } int ret = -5; if ((ret =reader.ReadByte()) != BYTE_OK) { Console.Write("error, got " + ret + " instead of " + BYTE_OK); //throw new InvalidDataException(); } //Log(log, "break READ"); break; } case BYTE_HANDLE: { //Log(log,"BYTE_HANDLE"); // Read buffer params : fd, path length, path string int fd = reader.ReadInt32(); int len_path = reader.ReadInt32(); string path = reader.ReadString(Encoding.ASCII, len_path - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); //Console.WriteLine("old " + path); if (op_mode == BYTE_MODE_D) path = getRealPathCurrentDump(path, title_id); //Console.WriteLine("new " + path); if (path.Length == 0) { writer.Write(BYTE_SPECIAL); break; } if (!Directory.Exists(path)) { Directory.CreateDirectory(Path.GetDirectoryName(path)); } // Add new file for incoming data files_request.Add(fd, new FileStream(path, FileMode.OpenOrCreate, FileAccess.Write, FileShare.Write)); // Send response if (fastmode) { writer.Write(BYTE_REQUEST); } else { writer.Write(BYTE_REQUEST_SLOW); } LogNoLine(log, "-> ["); // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_DUMP: { //Log(log,"BYTE_DUMP"); // Read buffer params : fd, size, file data int fd = reader.ReadInt32(); int sz = reader.ReadInt32(); byte[] buffer = new byte[sz]; buffer = reader.ReadBytes(sz); // Look for file descriptor foreach (var item in files_request) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) break; LogNoLine(log, "."); // Write to file dump_file.Write(buffer, 0, sz); break; } } // Send response writer.Write(BYTE_SPECIAL); break; } case BYTE_CLOSE: { //Log(log, "BYTE_CLOSE"); int fd = reader.ReadInt32(); if (files[fd] == null) { writer.Write(BYTE_SPECIAL); writer.Write(-38); break; } //Log(log, name + " close(" + fd.ToString() + ")"); FileStream f = files[fd]; writer.Write(BYTE_SPECIAL); writer.Write(0); f.Close(); files[fd] = null; break; } case BYTE_CLOSE_DUMP: { int fd = reader.ReadInt32(); if ((fd & 0x0fff00ff) != 0x0fff00ff) { // Check if it is a file to dump foreach (var item in files_request) { if (item.Key == fd) { FileStream dump_file = item.Value; if (dump_file == null) break; LogNoLine(log,"]"); Log(log, ""); // Close file and remove from request list dump_file.Close(); files_request.Remove(fd); break; } } // Send response writer.Write(BYTE_NORMAL); } break; } case BYTE_PING: { //Log(log, "BYTE_PING"); int val1 = reader.ReadInt32(); int val2 = reader.ReadInt32(); Log(log, name + " PING RECEIVED with values : " + val1.ToString() + " - " + val2.ToString()); break; } case BYTE_G_MODE: { if (op_mode == BYTE_MODE_D) { writer.Write(BYTE_MODE_D); } else if (op_mode == BYTE_MODE_I) { writer.Write(BYTE_MODE_I); } break; } case BYTE_LOG_STR: { //Log(log, "BYTE_LOG_STR"); int len_str = reader.ReadInt32(); string str = reader.ReadString(Encoding.ASCII, len_str - 1); if (reader.ReadByte() != 0) throw new InvalidDataException(); Log(log,"-> " + str); break; } default: Log(log, "xx" + cmd_byte); throw new InvalidDataException(); } } } } catch (Exception e) { if (log != null) Log(log, name + " " + e.Message); else Console.WriteLine(name + " " + e.Message); } finally { foreach (var item in files) { if (item != null) item.Close(); } foreach (var item in files_request) { if (item.Value != null) item.Value.Close(); } if (log != null) log.Close(); } Console.WriteLine(name + " Exit"); }
// headerStart seems to be chunkStart + 0x20 and I don't know why. public void Load(EndianBinaryReader stream, long headerStart, int imageIndex = 0) { Format = (TextureFormats)stream.ReadByte(); AlphaSetting = stream.ReadByte(); Width = stream.ReadUInt16(); Height = stream.ReadUInt16(); WrapS = (WrapModes)stream.ReadByte(); WrapT = (WrapModes)stream.ReadByte(); byte unknown1 = stream.ReadByte(); PaletteFormat = (PaletteFormats)stream.ReadByte(); PaletteCount = stream.ReadUInt16(); int paletteDataOffset = stream.ReadInt32(); BorderColor = new Color32(stream.ReadByte(), stream.ReadByte(), stream.ReadByte(), stream.ReadByte()); MinFilter = (FilterMode)stream.ReadByte(); MagFilter = (FilterMode)stream.ReadByte(); short unknown2 = stream.ReadInt16(); MipMapCount = stream.ReadByte(); byte unknown3 = stream.ReadByte(); LodBias = stream.ReadUInt16(); int imageDataOffset = stream.ReadInt32(); // Load the Palette data stream.BaseStream.Position = headerStart + paletteDataOffset + (0x20 * imageIndex); m_imagePalette = new Palette(); m_imagePalette.Load(stream, PaletteCount); // Now load and decode image data into an ARGB array. stream.BaseStream.Position = headerStart + imageDataOffset + (0x20 * imageIndex); m_rgbaImageData = DecodeData(stream, Width, Height, Format, m_imagePalette, PaletteFormat); }
public UnamedNode(EndianBinaryReader reader) { Address = reader.BaseStream.Position; Nodes = new Collection<ByamlNode>(); int count = reader.ReadInt32() & 0xffffff; byte[] types = reader.ReadBytes(count); while (reader.BaseStream.Position % 4 != 0) reader.ReadByte(); long start = reader.BaseStream.Position; for (int i = 0; i < count; i++) { ByamlNodeType type = (ByamlNodeType)types[i]; switch (type) { case ByamlNodeType.String: Nodes.Add(new String(reader)); break; case ByamlNodeType.Data: Nodes.Add(new Data(reader)); break; case ByamlNodeType.Boolean: Nodes.Add(new Boolean(reader)); break; case ByamlNodeType.Int: Nodes.Add(new Int(reader)); break; case ByamlNodeType.Single: Nodes.Add(new Single(reader)); break; case ByamlNodeType.UnamedNode: reader.BaseStream.Position = reader.ReadInt32(); Nodes.Add(new UnamedNode(reader)); break; case ByamlNodeType.NamedNode: reader.BaseStream.Position = reader.ReadInt32(); Nodes.Add(new NamedNode(reader)); break; default: throw new InvalidDataException(); } reader.BaseStream.Position = start + (i + 1) * 4; } Length = reader.BaseStream.Position - Length; }
public TexMap(EndianBinaryReader er) { TexIndex = er.ReadUInt16(); byte tmp = er.ReadByte(); WrapS = (WrapMode)(tmp & 3); MinFilter = (FilterMode)((tmp >> 2) & 3); tmp = er.ReadByte(); WrapT = (WrapMode)(tmp & 3); MagFilter = (FilterMode)((tmp >> 2) & 3); }
private static NullableVector4 ReadOPCode(EndianBinaryReader reader) { byte op = reader.ReadByte(); if (op == 0) return null; // return abort vector // results float? x = null, y = null, z = null, f = null; if ((op & 0xe0) > 0) { // number of frames, byte case f = op & 0x1f; if (f == 0x1f) { f = 0x20 + reader.ReadByte(); } else { f = 1 + f; } } else { // number of frames, half word case f = op & 0x3; if (f == 0x3) { f = 4 + reader.ReadByte(); } else { f = 1 + f; } // half word values reader.CurrentEndian = Endian.Big; op = (byte)(op << 3); var h = reader.ReadInt16(); if ((h & 0x4) > 0) { x = h >> 3; op = (byte)(op & 0x60); if ((h & 0x2) > 0) { y = reader.ReadInt16(); op = (byte)(op & 0xa0); } if ((h & 0x1) > 0) { z = reader.ReadInt16(); op = (byte)(op & 0xc0); } } else if ((h & 0x2) > 0) { y = h >> 3; op = (byte)(op & 0xa0); if ((h & 0x1) > 0) { z = reader.ReadInt16(); op = (byte)(op & 0xc0); } } else if ((h & 0x1) > 0) { z = h >> 3; op = (byte)(op & 0xc0); } } // byte values (fallthrough) reader.CurrentEndian = Endian.Little; if ((op & 0x80) > 0) { x = reader.ReadSByte(); } if ((op & 0x40) > 0) { y = reader.ReadSByte(); } if ((op & 0x20) > 0) { z = reader.ReadSByte(); } return new NullableVector4(x, y, z, f); }
public BMCParser(EndianBinaryReader reader) { colorList = new List<ByteColorAlpha>(); short numColors = reader.ReadInt16At(40); reader.BaseStream.Position += 44; //int numColors = Helpers.Read16(data, 40); for (int i = 0; i < numColors; i++) { ByteColorAlpha tempCol = new ByteColorAlpha(); tempCol.R = reader.ReadByte(); tempCol.G = reader.ReadByte(); tempCol.B = reader.ReadByte(); tempCol.A = reader.ReadByte(); colorList.Add(tempCol); } }