public int ReadFrom(byte[] Buffer, int StartIndex = 0) { int cursor = StartIndex; uint signature = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; if (signature == SIGNATURE) { RooVersion = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; // supported version ? if (RooVersion >= RooFile.MINVERSION) { Challenge = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetClient = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetServer = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; } else throw new Exception("RooVersion too old, got: " + RooVersion + " Expected greater " + RooFile.MINVERSION); } else throw new Exception("Wrong file signature: " + signature + " (expected " + SIGNATURE + ")."); // // Client part (was encrypted once) // // Check if file is encrypted if (BitConverter.ToUInt32(Buffer, cursor) == ENCRYPTIONFLAG) { #if WINCLR && X86 EncryptionEnabled = true; cursor += TypeSizes.INT; // get additional values for decryption EncryptedStreamLength = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; ExpectedResponse = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; Crush32.Decrypt(Buffer, cursor, EncryptedStreamLength, Challenge, ExpectedResponse, GetPassword()); #else throw new Exception(ERRORCRUSHPLATFORM); #endif } else EncryptionEnabled = false; // Get the basic infos, like room dimension and section offsets RoomSizeX = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; RoomSizeY = BitConverter.ToUInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetBSPTree = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetWalls = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetWallsEditor = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetSideDefs = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetSectors = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; OffsetThings = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; // used to save section item counts ushort len; // Section 1: BSP-Tree cursor = OffsetBSPTree + (Convert.ToByte(EncryptionEnabled) * 12); len = BitConverter.ToUInt16(Buffer, cursor); cursor += TypeSizes.SHORT; BSPTree = new List<RooBSPItem>(len); for (int i = 0; i < len; i++) { RooBSPItem bspItem = RooBSPItem.ExtractBSPItem(RooVersion, Buffer, cursor); cursor += bspItem.ByteLength; BSPTree.Add(bspItem); } // Section 2: Walls cursor = OffsetWalls + (Convert.ToByte(EncryptionEnabled) * 12); len = BitConverter.ToUInt16(Buffer, cursor); cursor += TypeSizes.SHORT; Walls = new List<RooWall>(len); for (int i = 0; i < len; i++) { RooWall lineDef = new RooWall(RooVersion, Buffer, cursor); cursor += lineDef.ByteLength; lineDef.Num = i + 1; Walls.Add(lineDef); } // Section 3: WallsEditor cursor = OffsetWallsEditor + (Convert.ToByte(EncryptionEnabled) * 12); len = BitConverter.ToUInt16(Buffer, cursor); cursor += TypeSizes.SHORT; WallsEditor = new List<RooWallEditor>(len); for (int i = 0; i < len; i++) { RooWallEditor wallEditor = new RooWallEditor(Buffer, cursor); cursor += wallEditor.ByteLength; wallEditor.Num = i + 1; WallsEditor.Add(wallEditor); } // Section 4: SideDefs cursor = OffsetSideDefs + (Convert.ToByte(EncryptionEnabled) * 12); len = BitConverter.ToUInt16(Buffer, cursor); cursor += TypeSizes.SHORT; SideDefs = new List<RooSideDef>(len); for (int i = 0; i < len; i++) { RooSideDef sideDef = new RooSideDef(Buffer, cursor); cursor += sideDef.ByteLength; sideDef.Num = i + 1; sideDef.TextureChanged += OnSideTextureChanged; SideDefs.Add(sideDef); } // Section 5: Sectors cursor = OffsetSectors + (Convert.ToByte(EncryptionEnabled) * 12); len = BitConverter.ToUInt16(Buffer, cursor); cursor += TypeSizes.SHORT; bool hasSpeed = (RooVersion >= VERSIONSPEED); Sectors = new List<RooSector>(len); for (int i = 0; i < len; i++) { RooSector sectorDef = new RooSector(RooVersion, Buffer, cursor, hasSpeed); cursor += sectorDef.ByteLength; sectorDef.Num = i + 1; sectorDef.TextureChanged += OnSectorTextureChanged; sectorDef.Moved += OnSectorMoved; Sectors.Add(sectorDef); } // Section 6: Things cursor = OffsetThings + (Convert.ToByte(EncryptionEnabled) * 12); len = BitConverter.ToUInt16(Buffer, cursor); cursor += TypeSizes.SHORT; Things = new List<RooThing>(len); if (len > 2) { for (int i = 0; i < len; i++) { RooThingExtended rooThing = new RooThingExtended(Buffer, cursor); cursor += rooThing.ByteLength; Things.Add(rooThing); } } else { for (int i = 0; i < len; i++) { RooThing rooThing = new RooThing(Buffer, cursor); cursor += rooThing.ByteLength; Things.Add(rooThing); } } // some older maps don't have the roomid // so if we've already reached the serveroffset, set it to 0 if (cursor == OffsetServer) { RoomID = 0; } else { // get roomid RoomID = BitConverter.ToInt32(Buffer, cursor); cursor += TypeSizes.INT; } // // Server part // // load grids Grids = new RooGrids(RooVersion, Buffer, cursor); cursor += Grids.ByteLength; return cursor - StartIndex; }
public unsafe void ReadFrom(ref byte* Buffer) { // save the startptr, we need it later byte* readStartPtr = Buffer; uint signature = *((uint*)Buffer); Buffer += TypeSizes.INT; if (signature == SIGNATURE) { RooVersion = *((uint*)Buffer); Buffer += TypeSizes.INT; // supported version ? if (RooVersion >= RooFile.MINVERSION) { Challenge = *((uint*)Buffer); Buffer += TypeSizes.INT; OffsetClient = *((uint*)Buffer); Buffer += TypeSizes.INT; OffsetServer = *((int*)Buffer); Buffer += TypeSizes.INT; } else throw new Exception("RooVersion too old, got: " + RooVersion + " Expected greater " + RooFile.MINVERSION); } else throw new Exception("Wrong file signature: " + signature + " (expected " + SIGNATURE + ")."); // // Client part (was encrypted once) // // Check if file is encrypted if (*((uint*)Buffer) == ENCRYPTIONFLAG) { #if WINCLR && X86 EncryptionEnabled = true; Buffer += TypeSizes.INT; // get additional values for decryption EncryptedStreamLength = *((int*)Buffer); Buffer += TypeSizes.INT; ExpectedResponse = *((uint*)Buffer); Buffer += TypeSizes.INT; Crush32.Decrypt(Buffer, EncryptedStreamLength, Challenge, ExpectedResponse, GetPassword()); #else throw new Exception(ERRORCRUSHPLATFORM); #endif } else EncryptionEnabled = false; // Get the basic infos, like room dimension and section offsets RoomSizeX = *((uint*)Buffer); Buffer += TypeSizes.INT; RoomSizeY = *((uint*)Buffer); Buffer += TypeSizes.INT; OffsetBSPTree = *((int*)Buffer); Buffer += TypeSizes.INT; OffsetWalls = *((int*)Buffer); Buffer += TypeSizes.INT; OffsetWallsEditor = *((int*)Buffer); Buffer += TypeSizes.INT; OffsetSideDefs = *((int*)Buffer); Buffer += TypeSizes.INT; OffsetSectors = *((int*)Buffer); Buffer += TypeSizes.INT; OffsetThings = *((int*)Buffer); Buffer += TypeSizes.INT; // used to save section item counts ushort len; // Section 1: BSP-Tree len = *((ushort*)Buffer); Buffer += TypeSizes.SHORT; BSPTree = new List<RooBSPItem>(len); for (int i = 0; i < len; i++) { RooBSPItem bspItem = RooBSPItem.ExtractBSPItem(RooVersion, ref Buffer); BSPTree.Add(bspItem); } // Section 2: Walls len = *((ushort*)Buffer); Buffer += TypeSizes.SHORT; Walls = new List<RooWall>(len); for (int i = 0; i < len; i++) { RooWall lineDef = new RooWall(RooVersion, ref Buffer); lineDef.Num = i + 1; Walls.Add(lineDef); } // Section 3: WallsEditor len = *((ushort*)Buffer); Buffer += TypeSizes.SHORT; WallsEditor = new List<RooWallEditor>(len); for (int i = 0; i < len; i++) { RooWallEditor wallEditor = new RooWallEditor(ref Buffer); wallEditor.Num = i + 1; WallsEditor.Add(wallEditor); } // Section 4: SideDefs len = *((ushort*)Buffer); Buffer += TypeSizes.SHORT; SideDefs = new List<RooSideDef>(len); for (int i = 0; i < len; i++) { RooSideDef sideDef = new RooSideDef(ref Buffer); sideDef.Num = i + 1; sideDef.TextureChanged += OnSideTextureChanged; SideDefs.Add(sideDef); } // Section 5: Sectors len = *((ushort*)Buffer); Buffer += TypeSizes.SHORT; bool hasSpeed = (RooVersion >= VERSIONSPEED); Sectors = new List<RooSector>(len); for (int i = 0; i < len; i++) { RooSector sectorDef = new RooSector(RooVersion, ref Buffer, hasSpeed); sectorDef.TextureChanged += OnSectorTextureChanged; sectorDef.Moved += OnSectorMoved; sectorDef.Num = i + 1; Sectors.Add(sectorDef); } // Section 6: Things // There is old and new variant of "thing" len = *((ushort*)Buffer); Buffer += TypeSizes.SHORT; Things = new List<RooThing>(len); if (len > 2) { for (int i = 0; i < len; i++) Things.Add(new RooThingExtended(ref Buffer)); } else { for (int i = 0; i < len; i++) Things.Add(new RooThing(ref Buffer)); } // some older maps don't have the roomid // so if we've already reached the serveroffset, set it to 0 if (Buffer - readStartPtr == OffsetServer) { RoomID = 0; } else { // roomid RoomID = *((int*)Buffer); Buffer += TypeSizes.INT; } // // Server part // Grids = new RooGrids(RooVersion, ref Buffer); }