public static ShapefileHeader Read(BinaryReader reader) { ShapefileHeader header = new ShapefileHeader(); int fileType = reader.ReadInt32BE(); if (fileType != 9994) throw new Exception("The first four bytes of this file indicate this is not a shape file."); // skip 5 unsed bytes reader.BaseStream.Seek(20L, SeekOrigin.Current); header.FileLength = reader.ReadInt32BE(); int version = reader.ReadInt32(); if (version != 1000) throw new Exception("Shapefile is not the proper version"); header.ShapeType = (ShapefileGeometryType)reader.ReadInt32(); double[] coords = new double[4]; for (int i = 0; i < 4; i++) coords[i] = reader.ReadDouble(); header.Bounds = new Envelope(coords[0], coords[2], coords[1], coords[3]); // Skip to end of header reader.BaseStream.Seek(100L, SeekOrigin.Begin); return header; }
private void ParseIndex(Stream stream, int i) { using (var br = new BinaryReader(stream)) { stream.Seek(-12, SeekOrigin.End); int count = br.ReadInt32(); stream.Seek(0, SeekOrigin.Begin); if (count * (16 + 4 + 4) > stream.Length) throw new Exception("ParseIndex failed"); for (int j = 0; j < count; ++j) { byte[] key = br.ReadBytes(16); if (key.IsZeroed()) // wtf? key = br.ReadBytes(16); if (key.IsZeroed()) // wtf? throw new Exception("key.IsZeroed()"); IndexEntry entry = new IndexEntry(); entry.Index = i; entry.Size = br.ReadInt32BE(); entry.Offset = br.ReadInt32BE(); CDNIndexData.Add(key, entry); } } }
public Sample(BinaryReader reader) : this() { SourceStart = reader.ReadInt32BE(); SourceLength = reader.ReadUInt16BE()*2; LoopStart = reader.ReadInt32BE(); Data = new byte[SourceLength]; }
public InstallHandler(BinaryReader stream, BackgroundWorkerEx worker) { worker?.ReportProgress(0, "Loading \"install\"..."); stream.ReadBytes(2); // IN byte b1 = stream.ReadByte(); byte b2 = stream.ReadByte(); short numTags = stream.ReadInt16BE(); int numFiles = stream.ReadInt32BE(); int numMaskBytes = (numFiles + 7) / 8; List<InstallTag> Tags = new List<InstallTag>(); for (int i = 0; i < numTags; i++) { InstallTag tag = new InstallTag(); tag.Name = stream.ReadCString(); tag.Type = stream.ReadInt16BE(); byte[] bits = stream.ReadBytes(numMaskBytes); for (int j = 0; j < numMaskBytes; j++) bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023); tag.Bits = new BitArray(bits); Tags.Add(tag); } for (int i = 0; i < numFiles; i++) { InstallEntry entry = new InstallEntry(); entry.Name = stream.ReadCString(); entry.MD5 = stream.ReadBytes(16); entry.Size = stream.ReadInt32BE(); InstallData.Add(entry); entry.Tags = Tags.FindAll(tag => tag.Bits[i]); worker?.ReportProgress((int)((i + 1) / (float)numFiles * 100)); } }
public InstallHandler(BinaryReader stream) { stream.ReadBytes(2); // IN byte b1 = stream.ReadByte(); byte b2 = stream.ReadByte(); short numTags = stream.ReadInt16BE(); int numFiles = stream.ReadInt32BE(); int numMaskBytes = (numFiles + 7) / 8; List<InstallTag> Tags = new List<InstallTag>(); for (int i = 0; i < numTags; i++) { InstallTag tag = new InstallTag(); tag.Name = stream.ReadCString(); tag.Type = stream.ReadInt16BE(); byte[] bits = stream.ReadBytes(numMaskBytes); for (int j = 0; j < numMaskBytes; j++) bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023); tag.Bits = new BitArray(bits); Tags.Add(tag); } for (int i = 0; i < numFiles; i++) { InstallEntry entry = new InstallEntry(); entry.Name = stream.ReadCString(); entry.MD5 = stream.Read<MD5Hash>(); entry.Size = stream.ReadInt32BE(); InstallData.Add(entry); entry.Tags = Tags.FindAll(tag => tag.Bits[i]); } }
public static void ValidateIndex(string shapefilePath) { string indexPath = Path.ChangeExtension(shapefilePath, ".shx"); int posShouldBe = 50, recordNum = 1; using (BinaryReader shape = new BinaryReader(new FileStream(shapefilePath, FileMode.Open))) using (BinaryReader index = new BinaryReader(new FileStream(indexPath, FileMode.Open))) { ShapefileHeader shapeHeader = ShapefileHeader.Read(shape); ShapefileHeader indexHeader = ShapefileHeader.Read(index); if (shapeHeader.FileLength * 2 != new FileInfo(shapefilePath).Length) Console.WriteLine("length"); if (indexHeader.FileLength * 2 != new FileInfo(indexPath).Length) Console.WriteLine("length"); while (index.BaseStream.Position < index.BaseStream.Length) { int filePos = index.ReadInt32BE(); if (filePos != posShouldBe) Console.WriteLine("Ding"); int indexContentLength = index.ReadInt32BE(); shape.BaseStream.Seek(filePos * 2, SeekOrigin.Begin); int shapeRecordNumber = shape.ReadInt32BE(); int shapeContentLength = shape.ReadInt32BE(); if (shapeRecordNumber != recordNum++ || shapeContentLength != indexContentLength) Console.WriteLine("Ding"); posShouldBe += indexContentLength + 4; } } }
private void ParseIndex(string idx) { using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var br = new BinaryReader(fs)) { int h2Len = br.ReadInt32(); int h2Check = br.ReadInt32(); byte[] h2 = br.ReadBytes(h2Len); long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0; fs.Position = padPos; int dataLen = br.ReadInt32(); int dataCheck = br.ReadInt32(); int numBlocks = dataLen / 18; for (int i = 0; i < numBlocks; i++) { IndexEntry info = new IndexEntry(); byte[] key = br.ReadBytes(9); byte indexHigh = br.ReadByte(); int indexLow = br.ReadInt32BE(); info.Index = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30)); info.Offset = (indexLow & 0x3FFFFFFF); info.Size = br.ReadInt32(); // duplicate keys wtf... //IndexData[key] = info; // use last key if (!LocalIndexData.ContainsKey(key)) // use first key LocalIndexData.Add(key, info); } padPos = (dataLen + 0x0FFF) & 0xFFFFF000; fs.Position = padPos; fs.Position += numBlocks * 18; //for (int i = 0; i < numBlocks; i++) //{ // var bytes = br.ReadBytes(18); // unknown data //} //if (fs.Position != fs.Length) // throw new Exception("idx file under read"); } }
public DownloadHandler(BinaryReader stream, BackgroundWorkerEx worker) { worker?.ReportProgress(0, "Loading \"download\"..."); stream.Skip(2); // DL byte b1 = stream.ReadByte(); byte b2 = stream.ReadByte(); byte b3 = stream.ReadByte(); int numFiles = stream.ReadInt32BE(); short numTags = stream.ReadInt16BE(); int numMaskBytes = (numFiles + 7) / 8; for (int i = 0; i < numFiles; i++) { MD5Hash key = stream.Read<MD5Hash>(); //byte[] unk = stream.ReadBytes(0xA); stream.Skip(0xA); //var entry = new DownloadEntry() { Index = i, Unk = unk }; var entry = new DownloadEntry() { Index = i }; DownloadData.Add(key, entry); worker?.ReportProgress((int)((i + 1) / (float)numFiles * 100)); } for (int i = 0; i < numTags; i++) { DownloadTag tag = new DownloadTag(); string name = stream.ReadCString(); tag.Type = stream.ReadInt16BE(); byte[] bits = stream.ReadBytes(numMaskBytes); for (int j = 0; j < numMaskBytes; j++) bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023); tag.Bits = new BitArray(bits); Tags.Add(name, tag); } }
public DownloadHandler(BinaryReader stream) { stream.Skip(2); // DL byte b1 = stream.ReadByte(); byte b2 = stream.ReadByte(); byte b3 = stream.ReadByte(); int numFiles = stream.ReadInt32BE(); short numTags = stream.ReadInt16BE(); int numMaskBytes = numFiles / 8 + (numFiles % 8 > 0 ? 1 : 0); for (int i = 0; i < numFiles; i++) { byte[] key = stream.ReadBytes(0x10); byte[] unk = stream.ReadBytes(0xA); DownloadEntry entry = new DownloadEntry() { Index = i, Unk = unk }; DownloadData.Add(key, entry); } for (int i = 0; i < numTags; i++) { DownloadTag tag = new DownloadTag(); string name = stream.ReadCString(); tag.Type = stream.ReadInt16BE(); byte[] bits = stream.ReadBytes(numMaskBytes); for (int j = 0; j < numMaskBytes; j++) bits[j] = (byte)((bits[j] * 0x0202020202 & 0x010884422010) % 1023); tag.Bits = new BitArray(bits); Tags.Add(name, tag); } }
public OverTable(BinaryReader reader) { Count = reader.ReadInt32BE(); Voices = new Voice[Count*4]; for(int i = 0; i < Count*4; i++) { Voices[i] = new Voice(reader); } }
public InstrumentTable(BinaryReader reader) { Count = reader.ReadInt32BE(); Instruments = new Instrument[Count]; for(int i = 0; i < Count; i++) { Instruments[i] = new Instrument(reader); } }
public NoteTable(BinaryReader reader) { Count = reader.ReadInt32BE(); Notes = new Note[Count]; for(int i = 0; i < Count; i++) { Notes[i] = new Note(reader); } }
public void run() { try { for (;;) { if (!this.mParent.connectionAlive) { this.mParent.forceDisconnect("Connection Lost"); return; } if (this.mParent.kickTargetTimestamp != 0) { if (this.mParent.kickTargetTimestamp < Utils.getTimestamp()) { this.mParent.forceDisconnect("Kicked from server"); return; } continue; } #region Process Packet //Packet ID and Vaildity Check. uint temp = this.mInput.ReadVarUInt32(); if (temp < 1 || temp > 48) { this.mParent.errorDisconnect(mDirection, "Sent invalid packet ID [" + temp + "]."); return; } Packet packetID = (Packet)temp; //Packet Size and Compression Check. bool compressed = false; int packetSize = this.mInput.ReadVarInt32(); if (packetSize < 0) { packetSize = -packetSize; compressed = true; } //Create buffer for forwarding byte[] dataBuffer = this.mInput.ReadFully(packetSize); //Do decompression MemoryStream ms = new MemoryStream(); if (compressed) { ZlibStream compressedStream = new ZlibStream(new MemoryStream(dataBuffer), CompressionMode.Decompress); byte[] buffer = new byte[32768]; for (;;) { int read = compressedStream.Read(buffer, 0, buffer.Length); if (read <= 0) break; ms.Write(buffer, 0, read); } ms.Seek(0, SeekOrigin.Begin); } else { ms = new MemoryStream(dataBuffer); } //Create packet parser BinaryReader packetData = new BinaryReader(ms); #endregion //Return data for packet processor object returnData = true; if (packetID != Packet.Heartbeat && packetID != Packet.UniverseTimeUpdate) { if (mDirection == Direction.Client) #region Handle Client Packets { #region Protocol State Security ClientState curState = this.mParent.clientState; if (curState != ClientState.Connected) { if (curState == ClientState.PendingConnect && packetID != Packet.ClientConnect) { this.mParent.forceDisconnect("Violated PendingConnect protocol state with " + packetID); } else if (curState == ClientState.PendingAuthentication && packetID != Packet.HandshakeResponse) { this.mParent.forceDisconnect("Violated PendingAuthentication protocol state with " + packetID); } else if (curState == ClientState.PendingConnectResponse) { this.mParent.forceDisconnect("Violated PendingConnectResponse protocol state with " + packetID); } } #endregion if (packetID == Packet.ChatSend) { returnData = new Packet11ChatSend(this.mParent, packetData, this.mDirection).onReceive(); } else if (packetID == Packet.ClientConnect) { this.mParent.clientState = ClientState.PendingAuthentication; returnData = new Packet7ClientConnect(this.mParent, packetData, this.mDirection).onReceive(); MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); passwordSalt = Utils.GenerateSecureSalt(); packetWrite.WriteStarString(""); packetWrite.WriteStarString(passwordSalt); packetWrite.WriteBE(StarryboundServer.config.passwordRounds); this.mParent.sendClientPacket(Packet.HandshakeChallenge, packet.ToArray()); } else if (packetID == Packet.HandshakeResponse) { string claimResponse = packetData.ReadStarString(); string passwordHash = packetData.ReadStarString(); string verifyHash = Utils.StarHashPassword(StarryboundServer.config.proxyPass, this.mParent.playerData.account + passwordSalt, StarryboundServer.config.passwordRounds); if (passwordHash != verifyHash) { this.mParent.rejectPreConnected("Your password was incorrect."); } this.mParent.clientState = ClientState.PendingConnectResponse; returnData = false; } else if (packetID == Packet.WarpCommand) { uint warp = packetData.ReadUInt32BE(); WorldCoordinate coord = packetData.ReadStarWorldCoordinate(); string player = packetData.ReadStarString(); WarpType cmd = (WarpType)warp; if (cmd == WarpType.WarpToHomePlanet) { this.mParent.playerData.inPlayerShip = false; } else if (cmd == WarpType.WarpToOrbitedPlanet) { this.mParent.playerData.inPlayerShip = false; } else if (cmd == WarpType.WarpToOwnShip) { this.mParent.playerData.inPlayerShip = true; } else if (cmd == WarpType.WarpToPlayerShip) { this.mParent.playerData.inPlayerShip = true; } StarryboundServer.logDebug("WarpCommand", "[" + this.mParent.playerData.client + "][" + warp + "]" + (coord != null ? "[" + coord.ToString() + "]" : "") + "[" + player + "]"); } else if (packetID == Packet.ModifyTileList || packetID == Packet.DamageTileGroup || packetID == Packet.DamageTile || packetID == Packet.ConnectWire || packetID == Packet.DisconnectAllWires) { if (!this.mParent.playerData.canBuild) continue; if (this.mParent.playerData.loc != null) { string planetCheck = this.mParent.playerData.loc.ToString(); string spawnPlanet = StarryboundServer.serverConfig.defaultWorldCoordinate; if (StarryboundServer.serverConfig.defaultWorldCoordinate.Split(':').Length == 5) spawnPlanet = spawnPlanet + ":0"; if ((planetCheck == spawnPlanet) && !this.mParent.playerData.group.hasPermission("admin.spawnbuild") && !this.mParent.playerData.inPlayerShip) { continue; } } } } #endregion else #region Handle Server Packets { if (packetID == Packet.ChatReceive) { returnData = new Packet5ChatReceive(this.mParent, packetData, this.mDirection).onReceive(); } else if (packetID == Packet.ProtocolVersion) { uint protocolVersion = packetData.ReadUInt32BE(); if (protocolVersion != StarryboundServer.ProtocolVersion) { MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); packetWrite.WriteBE(protocolVersion); this.mParent.sendClientPacket(Packet.ProtocolVersion, packet.ToArray()); this.mParent.rejectPreConnected("Starrybound Server was unable to handle the parent server protocol version."); returnData = false; } } else if (packetID == Packet.HandshakeChallenge) { string claimMessage = packetData.ReadString(); string passwordSalt = packetData.ReadStarString(); int passwordRounds = packetData.ReadInt32BE(); MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); string passwordHash = Utils.StarHashPassword(StarryboundServer.config.serverPass, StarryboundServer.config.serverAccount + passwordSalt, passwordRounds); packetWrite.WriteStarString(""); packetWrite.WriteStarString(passwordHash); this.mParent.sendServerPacket(Packet.HandshakeResponse, packet.ToArray()); returnData = false; } else if (packetID == Packet.ConnectResponse) { while (this.mParent.clientState != ClientState.PendingConnectResponse) { } //TODO: needs timeout returnData = new Packet2ConnectResponse(this.mParent, packetData, this.mDirection).onReceive(); } else if (packetID == Packet.WorldStart) { if (!this.mParent.playerData.sentMotd) { this.mParent.sendChatMessage(Config.GetMotd()); this.mParent.playerData.sentMotd = true; } byte[] planet = packetData.ReadStarByteArray(); byte[] worldStructure = packetData.ReadStarByteArray(); byte[] sky = packetData.ReadStarByteArray(); byte[] serverWeather = packetData.ReadStarByteArray(); float spawnX = packetData.ReadSingleBE(); float spawnY = packetData.ReadSingleBE(); uint mapParamsSize = packetData.ReadVarUInt32(); Dictionary<string, object> mapParams = new Dictionary<string, object>(); for (int i = 0; i < mapParamsSize; i++) { mapParams.Add(packetData.ReadStarString(), packetData.ReadStarVariant()); } uint clientID = packetData.ReadUInt32BE(); bool bool1 = packetData.ReadBoolean(); WorldCoordinate coords = Utils.findGlobalCoords(sky); if (coords != null) { this.mParent.playerData.loc = coords; StarryboundServer.logDebug("WorldStart", "[" + this.mParent.playerData.client + "][" + bool1 + ":" + clientID + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "][" + this.mParent.playerData.inPlayerShip + "]"); } } else if (packetID == Packet.WorldStop) { string status = packetData.ReadStarString(); } else if (packetID == Packet.GiveItem) { string name = packetData.ReadStarString(); uint count = packetData.ReadVarUInt32(); List<object> itemDesc = packetData.ReadStarVariant(); } else if (packetID == Packet.EnvironmentUpdate) { byte[] sky = packetData.ReadStarByteArray(); byte[] serverWeather = packetData.ReadStarByteArray(); /*WorldCoordinate coords = Utils.findGlobalCoords(sky); if (coords != null) { this.mParent.playerData.loc = coords; StarryboundServer.logDebug("EnvUpdate", "[" + this.mParent.playerData.client + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "]"); }*/ } else if (packetID == Packet.ClientContextUpdate) { try { byte[] clientContextData = packetData.ReadStarByteArray(); if (clientContextData.Length != 0) { BinaryReader clientContextReader = new BinaryReader(new MemoryStream(clientContextData)); byte[] data = clientContextReader.ReadStarByteArray(); if (data.Length > 8) //Should at least be more than 8 bytes for it to contain the data we want. { BinaryReader dataReader = new BinaryReader(new MemoryStream(data)); byte dataBufferLength = dataReader.ReadByte(); if (dataBufferLength == 2) { byte arrayLength = dataReader.ReadByte(); if (arrayLength == 2 || arrayLength == 4) //Only observed these being used so far for what we want. { byte dataType = dataReader.ReadByte(); //04 = String, 0E = CelestialLog if (dataType == 4) { string string1 = dataReader.ReadStarString(); if (dataReader.BaseStream.Position != dataReader.BaseStream.Length) { if (string1 == "null") { byte[] worldHeader = dataReader.ReadStarByteArray(); //0008020A000C byte[] worldData = dataReader.ReadStarByteArray(); byte typeByte = dataReader.ReadByte(); //0E = CelestialLog if (typeByte == 14) { Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog(); log.TryGetValue("loc", out this.mParent.playerData.loc); if (!log.TryGetValue("home", out this.mParent.playerData.home)) this.mParent.playerData.home = this.mParent.playerData.loc; StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "][" + this.mParent.playerData.inPlayerShip + "]"); StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurHome:[" + this.mParent.playerData.home.ToString() + "]"); } } } } else if (dataType == 14) { Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog(); log.TryGetValue("loc", out this.mParent.playerData.loc); if (!log.TryGetValue("home", out this.mParent.playerData.home)) this.mParent.playerData.home = this.mParent.playerData.loc; StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurLoc:[" + this.mParent.playerData.loc.ToString() + "][" + this.mParent.playerData.inPlayerShip + "]"); StarryboundServer.logDebug("ClientContext", "[" + this.mParent.playerData.client + "] CurHome:[" + this.mParent.playerData.home.ToString() + "]"); } } } } } } catch (Exception e) { StarryboundServer.logException("[" + this.mParent.playerData.client + "] Failed to parse ClientContextUpdate from Server: " + e.Message); } } } #endregion } #if DEBUG if(packetID != Packet.Heartbeat) { //if (ms.Position != ms.Length) //StarryboundServer.logDebug("ForwardThread", "[" + this.mParent.playerData.client + "] [" + this.mDirection.ToString() + "][" + packetID + "] failed parse (" + ms.Position + " != " + ms.Length + ")"); //StarryboundServer.logDebug("ForwardThread", "[" + this.mParent.playerData.client + "] [" + this.mDirection.ToString() + "][" + packetID + "] Dumping " + ms.Length + " bytes: " + Utils.ByteArrayToString(ms.ToArray())); } #endif //Check return data if (returnData is Boolean) { if ((Boolean)returnData == false) continue; } else if (returnData is int) { if ((int)returnData == -1) { this.mParent.forceDisconnect("Command processor requested to drop client"); } } #region Forward Packet //Write data to dest this.mOutput.WriteVarUInt32((uint)packetID); if (compressed) { this.mOutput.WriteVarInt32(-packetSize); this.mOutput.Write(dataBuffer, 0, packetSize); } else { this.mOutput.WriteVarInt32(packetSize); this.mOutput.Write(dataBuffer, 0, packetSize); } this.mOutput.Flush(); #endregion //If disconnect was forwarded to client, lets disconnect. if(packetID == Packet.ServerDisconnect && mDirection == Direction.Server) { this.mParent.forceDisconnect(); } } } catch (EndOfStreamException) { this.mParent.forceDisconnect(); } catch (Exception e) { this.mParent.errorDisconnect(mDirection, "ForwardThread Exception: " + e.ToString()); } }
public static Texture LoadPng(Stream stream) { List<byte> idat = new List<byte> (); byte bitDepth = 0; ColorType colorType = ColorType.Grayscale; ByteColor[] palette = null; int width = 0, height = 0; using (var reader = new BinaryReader (stream)) { if (reader.ReadUInt64 () != PNG_SIGNATURE) { throw new Exception ("Not a PNG file"); } string chunktype = ""; byte[] typeBuf = new byte[4]; while (chunktype != "IEND") { var length = reader.ReadInt32BE (); reader.Read (typeBuf, 0, 4); chunktype = Encoding.ASCII.GetString (typeBuf); switch (chunktype) { case "IHDR": width = reader.ReadInt32BE (); height = reader.ReadInt32BE (); bitDepth = reader.ReadByte (); colorType = (ColorType)reader.ReadByte (); if (reader.ReadByte () != 0) { throw new Exception (); //Compression method } if (reader.ReadByte () != 0) { throw new Exception (); //Filter method } if (reader.ReadByte () != 0) { throw new NotImplementedException (); //Interlacing } break; case "PLTE": if (length % 3 != 0) throw new Exception (); //Invalid Palette int count = length / 3; palette = new ByteColor[length / 3]; for (int i = 0; i < count; i++) { palette [i] = new ByteColor ( reader.ReadByte (), reader.ReadByte (), reader.ReadByte (), 255); } break; case "tRNS": if (colorType == ColorType.Palette) { for (int i = 0; i < length; i++) { palette [i].A = reader.ReadByte (); } } else { throw new NotImplementedException (); //Are the others BigEndian? Investigate } break; case "IDAT": idat.AddRange (reader.ReadBytes (length)); break; default: reader.BaseStream.Seek (length, SeekOrigin.Current); break; } reader.BaseStream.Seek (4, SeekOrigin.Current); //Skip CRC } } byte[] decompressedBytes = null; using (var compressedStream = new MemoryStream (idat.ToArray (), 2, idat.Count - 6)) { //skip zlib header using (var decompressedStream = new MemoryStream ()) { try { using (var deflateStream = new DeflateStream (compressedStream, CompressionMode.Decompress)) { deflateStream.CopyTo (decompressedStream); } decompressedBytes = decompressedStream.ToArray (); } catch (Exception exception) { throw new Exception ("An error occurred during DEFLATE decompression.", exception); } } } var scanlines = GetScanlines (decompressedBytes, bitDepth, colorType, width); var colors = GetData (scanlines, width, height, colorType, bitDepth, palette); var texture = new Texture (width, height); texture.SetData (colors, null); return texture; }
private void ParseIndex(string idx) { using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var br = new BinaryReader(fs)) { int h2Len = br.ReadInt32(); int h2Check = br.ReadInt32(); byte[] h2 = br.ReadBytes(h2Len); long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0; fs.Position = padPos; int dataLen = br.ReadInt32(); int dataCheck = br.ReadInt32(); int numBlocks = dataLen / 18; for (int i = 0; i < numBlocks; i++) { IndexEntry info = new IndexEntry(); MD5Hash key = br.Read<MD5Hash>(); byte indexHigh = br.ReadByte(); int indexLow = br.ReadInt32BE(); info.Index = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30)); info.Offset = (indexLow & 0x3FFFFFFF); info.Size = br.ReadInt32(); if (!LocalIndexData.ContainsKey(key)) LocalIndexData.Add(key, info); } padPos = (dataLen + 0x0FFF) & 0xFFFFF000; fs.Position = padPos; fs.Position += numBlocks * 18; } }
public EncodingHandler(BinaryReader stream) { stream.Skip(2); // EN byte b1 = stream.ReadByte(); byte checksumSizeA = stream.ReadByte(); byte checksumSizeB = stream.ReadByte(); ushort flagsA = stream.ReadUInt16(); ushort flagsB = stream.ReadUInt16(); int numEntriesA = stream.ReadInt32BE(); int numEntriesB = stream.ReadInt32BE(); byte b4 = stream.ReadByte(); int stringBlockSize = stream.ReadInt32BE(); stream.Skip(stringBlockSize); stream.Skip(numEntriesA * 32); long chunkStart = stream.BaseStream.Position; for (int i = 0; i < numEntriesA; ++i) { ushort keysCount; while ((keysCount = stream.ReadUInt16()) != 0) { int fileSize = stream.ReadInt32BE(); MD5Hash hash = stream.Read<MD5Hash>(); EncodingEntry entry = new EncodingEntry(); entry.Size = fileSize; // how do we handle multiple keys? for (int ki = 0; ki < keysCount; ++ki) { MD5Hash key = stream.Read<MD5Hash>(); // use first key for now if (ki == 0) entry.Key = key; else Log.Write("Multiple encoding keys for MD5 hash {0} -> {1}", hash.ToHexString(), key.ToHexString()); } EncodingData.Add(hash, entry); } // each chunk is 4096 bytes, and zero padding at the end long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart) % CHUNK_SIZE); if (remaining > 0) stream.BaseStream.Position += remaining; } for (int i = 0; i < numEntriesB; ++i) { byte[] firstKey = stream.ReadBytes(16); byte[] blockHash = stream.ReadBytes(16); } long chunkStart2 = stream.BaseStream.Position; for (int i = 0; i < numEntriesB; ++i) { byte[] key = stream.ReadBytes(16); int stringIndex = stream.ReadInt32BE(); byte unk1 = stream.ReadByte(); int fileSize = stream.ReadInt32BE(); // each chunk is 4096 bytes, and zero padding at the end long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart2) % CHUNK_SIZE); if (remaining > 0) stream.BaseStream.Position += remaining; } }
public CASCHandler(CASCFolder root, BackgroundWorker worker) { if (!OnlineMode) { var idxFiles = GetIdxFiles(Properties.Settings.Default.WowPath); if (idxFiles.Count == 0) throw new FileNotFoundException("idx files missing!"); worker.ReportProgress(0); int idxIndex = 0; foreach (var idx in idxFiles) { using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var br = new BinaryReader(fs)) { int h2Len = br.ReadInt32(); int h2Check = br.ReadInt32(); byte[] h2 = br.ReadBytes(h2Len); long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0; fs.Position = padPos; int dataLen = br.ReadInt32(); int dataCheck = br.ReadInt32(); int numBlocks = dataLen / 18; for (int i = 0; i < numBlocks; i++) { IndexEntry info = new IndexEntry(); byte[] key = br.ReadBytes(9); int indexHigh = br.ReadByte(); int indexLow = br.ReadInt32BE(); info.Index = (int)((byte)(indexHigh << 2) | ((indexLow & 0xC0000000) >> 30)); info.Offset = (indexLow & 0x3FFFFFFF); info.Size = br.ReadInt32(); // duplicate keys wtf... //IndexData[key] = info; // use last key if (!LocalIndexData.ContainsKey(key)) // use first key LocalIndexData.Add(key, info); } padPos = (dataLen + 0x0FFF) & 0xFFFFF000; fs.Position = padPos; fs.Position += numBlocks * 18; //for (int i = 0; i < numBlocks; i++) //{ // var bytes = br.ReadBytes(18); // unknown data //} if (fs.Position != fs.Position) throw new Exception("idx file under read"); } worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100)); } Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count); } worker.ReportProgress(0); using (var fs = OpenEncodingFile()) using (var br = new BinaryReader(fs)) { br.ReadBytes(2); // EN byte b1 = br.ReadByte(); byte b2 = br.ReadByte(); byte b3 = br.ReadByte(); ushort s1 = br.ReadUInt16(); ushort s2 = br.ReadUInt16(); int numEntries = br.ReadInt32BE(); int i1 = br.ReadInt32BE(); byte b4 = br.ReadByte(); int entriesOfs = br.ReadInt32BE(); fs.Position += entriesOfs; // skip strings fs.Position += numEntries * 32; //for (int i = 0; i < numEntries; ++i) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} for (int i = 0; i < numEntries; ++i) { ushort keysCount; while ((keysCount = br.ReadUInt16()) != 0) { int fileSize = br.ReadInt32BE(); byte[] md5 = br.ReadBytes(16); var entry = new EncodingEntry(); entry.Size = fileSize; for (int ki = 0; ki < keysCount; ++ki) { byte[] key = br.ReadBytes(16); entry.Keys.Add(key); } //Encodings[md5] = entry; EncodingData.Add(md5, entry); } //br.ReadBytes(28); while (br.PeekChar() == 0) fs.Position++; worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } //var pos = br.BaseStream.Position; //for (int i = 0; i < i1; ++i) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingData.Count); } worker.ReportProgress(0); using (var fs = OpenRootFile()) using (var br = new BinaryReader(fs)) { while (fs.Position < fs.Length) { int count = br.ReadInt32(); RootBlock block = new RootBlock(); block.Unk1 = br.ReadUInt32(); block.Flags = (LocaleFlags)br.ReadUInt32(); if (block.Flags == LocaleFlags.None) throw new Exception("block.Flags == LocaleFlags.None"); RootEntry[] entries = new RootEntry[count]; for (var i = 0; i < count; ++i) { entries[i] = new RootEntry(); entries[i].Block = block; entries[i].Unk1 = br.ReadInt32(); } for (var i = 0; i < count; ++i) { entries[i].MD5 = br.ReadBytes(16); ulong hash = br.ReadUInt64(); entries[i].Hash = hash; // don't load other locales //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0) // continue; if (!RootData.ContainsKey(hash)) { RootData[hash] = new List<RootEntry>(); RootData[hash].Add(entries[i]); } else RootData[hash].Add(entries[i]); } worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count); } worker.ReportProgress(0); if (File.Exists(listFile)) { FolderNames[Hasher.ComputeHash("root")] = "root"; using (StreamReader sr = new StreamReader(listFile)) { string file; int filesCount = 0; CASCFolder folder = root; while ((file = sr.ReadLine()) != null) { ulong fileHash = Hasher.ComputeHash(file); // skip invalid names if (!RootData.ContainsKey(fileHash)) { Logger.WriteLine("Invalid file name: {0}", file); continue; } filesCount++; string[] parts = file.Split('\\'); for (int i = 0; i < parts.Length; ++i) { bool isFile = (i == parts.Length - 1); ulong hash = isFile ? fileHash : Hasher.ComputeHash(parts[i]); ICASCEntry entry = folder.GetEntry(hash); if (entry == null) { if (isFile) { entry = new CASCFile(hash); FileNames[hash] = file; } else { entry = new CASCFolder(hash); FolderNames[hash] = parts[i]; } folder.SubEntries[hash] = entry; if (isFile) { folder = root; break; } } folder = entry as CASCFolder; } if ((filesCount % 1000) == 0) worker.ReportProgress((int)((float)sr.BaseStream.Position / (float)sr.BaseStream.Length * 100)); } Logger.WriteLine("CASCHandler: loaded {0} file names", FileNames.Count); } } else { throw new FileNotFoundException("list file missing!"); } }
private bool ReadTOC() { TOCItemFil tif; sio.FileStream fsr; sio.BinaryReader brr; long prevPos, newPos; string tocName = "game.toc"; sio.DirectoryInfo di; sio.FileInfo fi; int namesTableEntryCount; int namesTableStart; int itemNamePtr; bool itemIsDir = false; int itemPos; int itemLen; string itemName; string itemGamePath = ""; string itemPath; int itemNum; int shift; //int dirIdx = 0; //int endIdx = 999999; int[] dirEntry = new int[512]; int dirEntryCount = 0; dirEntry[1] = 99999999; int mod = 1; bool error = false; string errorText = ""; int i, j; toc = new TOCClass(resPath); itemNum = toc.fils.Count; shift = toc.fils.Count - 1; for (i = 2; i < 6; i++) { fi = new sio.FileInfo(toc.fils[i].path); if (!fi.Exists) { errorText = string.Format("File '{0}' not found", toc.fils[i].path); error = true; } else { toc.fils[i].len = (int)fi.Length; toc.totalLen += toc.fils[i].len; } } toc.dataStart = toc.totalLen; if (!error) { fsr = new sio.FileStream(toc.fils[2].path, sio.FileMode.Open, sio.FileAccess.Read); brr = new sio.BinaryReader(fsr, ste.Default); fsr.Position = 0x1c; if (brr.ReadInt32() != 0x3d9f33c2) { errorText = "Not a GameCube image"; error = true; } fsr.Position = 0x0400; toc.fils[2].pos = 0x0; toc.fils[3].pos = 0x2440; brr.ReadInt32BE(); fsr.Position += 0x1c; toc.fils[4].pos = brr.ReadInt32BE(); toc.fils[5].pos = brr.ReadInt32BE(); brr.ReadInt32BE(); fsr.Position += 0x08; toc.dataStart = brr.ReadInt32BE(); brr.Close(); fsr.Close(); } if (!error) { fsr = new sio.FileStream(resPath + "&&systemdata\\" + tocName, sio.FileMode.Open, sio.FileAccess.Read); brr = new sio.BinaryReader(fsr, ste.Default); i = brr.ReadInt32(); if (i != 1) { error = true; errorText = "Multiple FST image?\r\nPlease mail me info about this image"; } i = brr.ReadInt32(); if (i != 0) { error = true; errorText = "Multiple FST image?\r\nPlease mail me info about this image"; } namesTableEntryCount = brr.ReadInt32BE() - 1; namesTableStart = (namesTableEntryCount * 12) + 12; if (retrieveFilesInfo) { sspbProgress.Minimum = 0; sspbProgress.Maximum = 100; sspbProgress.Step = 1; sspbProgress.Value = 0; mod = (int)Math.Floor((float)(namesTableEntryCount + itemNum) / sspbProgress.Maximum); if (mod == 0) { sspbProgress.Maximum = namesTableEntryCount + itemNum; mod = 1; } } for (int cnt = 0; cnt < namesTableEntryCount; cnt++) { itemNamePtr = brr.ReadInt32BE(); if (itemNamePtr >> 0x18 == 1) { itemIsDir = true; } itemNamePtr &= 0x00ffffff; itemPos = brr.ReadInt32BE(); itemLen = brr.ReadInt32BE(); prevPos = fsr.Position; newPos = namesTableStart + itemNamePtr; fsr.Position = newPos; itemName = brr.ReadStringNT(); fsr.Position = prevPos; while (dirEntry[dirEntryCount + 1] <= itemNum) { dirEntryCount -= 2; } if (itemIsDir) { dirEntryCount += 2; dirEntry[dirEntryCount] = (itemPos > 0) ? itemPos + shift : itemPos; itemPos += shift; itemLen += shift; dirEntry[dirEntryCount + 1] = itemLen; toc.dirCount += 1; } else { toc.filCount += 1; } itemPath = itemName; j = dirEntry[dirEntryCount]; for (i = 0; i < 256; i++) { if (j == 0) { itemGamePath = itemPath; itemPath = resPath + itemPath; break; } else { itemPath = itemPath.Insert(0, toc.fils[j].name + '\\'); j = toc.fils[j].dirIdx; } } if (itemIsDir) { itemPath += '\\'; } if (retrieveFilesInfo) { if (itemIsDir) { di = new sio.DirectoryInfo(itemPath); if (!di.Exists) { errorText = string.Format("Directory '{0}' not found", itemPath); error = true; } } else { fi = new sio.FileInfo(itemPath); if (!fi.Exists) { errorText = string.Format("File '{0}' not found", itemPath); error = true; } else { itemLen = (int)fi.Length; toc.totalLen += itemLen; } } if (error) { break; } if (itemNum % mod == 0) { if (sspbProgress.Value < sspbProgress.Maximum) { sspbProgress.Value += 1; } //sslblAction.Text = string.Format("Check: '{0}'…", itemPath.Replace(resPath, "")); } } tif = new TOCItemFil(itemNum, dirEntry[dirEntryCount], itemPos, itemLen, itemIsDir, itemName, itemGamePath, itemPath); toc.fils.Add(tif); toc.fils[0].len = toc.fils.Count; if (itemIsDir) { dirEntry[dirEntryCount] = itemNum; itemIsDir = false; } itemNum += 1; } brr.Close(); fsr.Close(); } if (retrieveFilesInfo) { sspbProgress.Value = 0; } if (error) { MessageBox.Show(errorText, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); //sslblAction.Text = "Ready"; return(false);; } CalcNextFileIds(); //sslblAction.Text = "Building Structure…"; error = GenerateTreeView(fileNameSort); //sslblAction.Text = "Ready"; rootOpened = true; LoadInfo(!rootOpened); return(error); }
public void run() { try { for (;;) { if (!this.client.connectionAlive) { this.client.forceDisconnect(direction, "Connection no longer alive"); return; } if (this.client.kickTargetTimestamp != 0) { if (this.client.kickTargetTimestamp < Utils.getTimestamp()) { this.client.closeConnection(); return; } continue; } #region Process Packet //Packet ID and Vaildity Check. uint temp = this.incoming.ReadVarUInt32(); if (temp < 1 || temp > 48) { this.client.forceDisconnect(direction, "Sent invalid packet ID [" + temp + "]."); return; } Packet packetID = (Packet)temp; //Packet Size and Compression Check. bool compressed = false; int packetSize = this.incoming.ReadVarInt32(); if (packetSize < 0) { packetSize = -packetSize; compressed = true; } //Create buffer for forwarding byte[] dataBuffer = this.incoming.ReadFully(packetSize); //Do decompression MemoryStream ms = new MemoryStream(); if (compressed) { ZlibStream compressedStream = new ZlibStream(new MemoryStream(dataBuffer), CompressionMode.Decompress); byte[] buffer = new byte[32768]; for (;;) { int read = compressedStream.Read(buffer, 0, buffer.Length); if (read <= 0) break; ms.Write(buffer, 0, read); } ms.Seek(0, SeekOrigin.Begin); } else { ms = new MemoryStream(dataBuffer); } //Create packet parser BinaryReader packetData = new BinaryReader(ms); #endregion //Return data for packet processor object returnData = true; if (packetID != Packet.Heartbeat && packetID != Packet.UniverseTimeUpdate) { if (direction == Direction.Client) #region Handle Client Packets { #region Protocol State Security ClientState curState = this.client.state; if (curState != ClientState.Connected) { if (curState == ClientState.PendingConnect && packetID != Packet.ClientConnect) { this.client.rejectPreConnected("Violated PendingConnect protocol state with " + packetID); return; } else if (curState == ClientState.PendingAuthentication && packetID != Packet.HandshakeResponse) { this.client.rejectPreConnected("Violated PendingAuthentication protocol state with " + packetID); return; } else if (curState == ClientState.PendingConnectResponse) { int startTime = Utils.getTimestamp(); while (true) { if (this.client.state == ClientState.Connected) break; if (Utils.getTimestamp() > startTime + StarryboundServer.config.connectTimeout) { this.client.rejectPreConnected("Connection Failed: Server did not respond in time."); return; } } } } #endregion if (packetID == Packet.ChatSend) { returnData = new Packet11ChatSend(this.client, packetData, this.direction).onReceive(); } else if (packetID == Packet.ClientConnect) { this.client.state = ClientState.PendingAuthentication; returnData = new Packet7ClientConnect(this.client, packetData, this.direction).onReceive(); MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); passwordSalt = Utils.GenerateSecureSalt(); packetWrite.WriteStarString(""); packetWrite.WriteStarString(passwordSalt); packetWrite.WriteBE(StarryboundServer.config.passwordRounds); this.client.sendClientPacket(Packet.HandshakeChallenge, packet.ToArray()); } else if (packetID == Packet.HandshakeResponse) { string claimResponse = packetData.ReadStarString(); string passwordHash = packetData.ReadStarString(); string verifyHash = Utils.StarHashPassword(StarryboundServer.config.proxyPass, this.client.playerData.account + passwordSalt, StarryboundServer.config.passwordRounds); if (passwordHash != verifyHash) { this.client.rejectPreConnected("Your password was incorrect."); return; } this.client.state = ClientState.PendingConnectResponse; returnData = false; } else if (packetID == Packet.WarpCommand) { WarpType cmd = (WarpType)packetData.ReadUInt32BE(); WorldCoordinate coord = packetData.ReadStarWorldCoordinate(); string player = packetData.ReadStarString(); if (cmd == WarpType.WarpToPlayerShip) { Client target = StarryboundServer.getClient(player); if (target != null) { if (!this.client.playerData.canAccessShip(target.playerData)) { this.client.sendChatMessage("^#5dc4f4;You cannot access this player's ship due to their ship access settings."); StarryboundServer.logDebug("ShipAccess", "Preventing " + this.client.playerData.name + " from accessing " + target.playerData.name + "'s ship."); MemoryStream packetWarp = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packetWarp); packetWrite.WriteBE((uint)WarpType.WarpToOwnShip); packetWrite.Write(new WorldCoordinate()); packetWrite.WriteStarString(""); client.sendServerPacket(Packet.WarpCommand, packetWarp.ToArray()); returnData = false; } } } StarryboundServer.logDebug("WarpCommand", "[" + this.client.playerData.client + "][" + cmd + "]" + (coord != null ? "[" + coord.ToString() + "]" : "") + "[" + player + "]"); } else if (packetID == Packet.ModifyTileList || packetID == Packet.DamageTileGroup || packetID == Packet.DamageTile || packetID == Packet.ConnectWire || packetID == Packet.DisconnectAllWires) { if(!this.client.playerData.canIBuild()) returnData = false; } else if (packetID == Packet.EntityCreate) { while(true) { EntityType type = (EntityType)packetData.Read(); if(type == EntityType.EOF) break; byte[] entityData = packetData.ReadStarByteArray(); int entityId = packetData.ReadVarInt32(); if(type == EntityType.Projectile) { BinaryReader entity = new BinaryReader(new MemoryStream(entityData)); string projectileKey = entity.ReadStarString(); object projParams = entity.ReadStarVariant(); if (StarryboundServer.config.projectileBlacklist.Contains(projectileKey)) { MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); packetWrite.WriteVarInt32(entityId); packetWrite.Write(false); this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray()); returnData = false; } if (StarryboundServer.serverConfig.useDefaultWorldCoordinate && StarryboundServer.config.spawnWorldProtection) { if (this.client.playerData.loc != null) { if (StarryboundServer.config.projectileBlacklistSpawn.Contains(projectileKey) && StarryboundServer.spawnPlanet.Equals(this.client.playerData.loc) && !this.client.playerData.group.hasPermission("admin.spawnbuild") && !this.client.playerData.inPlayerShip) { MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); packetWrite.WriteVarInt32(entityId); packetWrite.Write(false); this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray()); returnData = false; } } else { MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); packetWrite.WriteVarInt32(entityId); packetWrite.Write(false); this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray()); returnData = false; } } } else if (type == EntityType.Object || type == EntityType.Plant || type == EntityType.PlantDrop || type == EntityType.Monster) { if (!this.client.playerData.canIBuild()) { MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); packetWrite.WriteVarInt32(entityId); packetWrite.Write(false); this.client.sendClientPacket(Packet.EntityDestroy, packet.ToArray()); returnData = false; } } } } else if (packetID == Packet.SpawnEntity) { while(true) { EntityType type = (EntityType)packetData.Read(); if (type == EntityType.EOF) break; byte[] entityData = packetData.ReadStarByteArray(); if (type == EntityType.Projectile) { BinaryReader entity = new BinaryReader(new MemoryStream(entityData)); string projectileKey = entity.ReadStarString(); object projParams = entity.ReadStarVariant(); if (StarryboundServer.config.projectileBlacklist.Contains(projectileKey)) { returnData = false; } if (StarryboundServer.serverConfig.useDefaultWorldCoordinate && StarryboundServer.config.spawnWorldProtection) { if (this.client.playerData.loc != null) { if (StarryboundServer.config.projectileBlacklistSpawn.Contains(projectileKey) ^ StarryboundServer.config.projectileSpawnListIsWhitelist) { if (StarryboundServer.spawnPlanet.Equals(this.client.playerData.loc) && !this.client.playerData.group.hasPermission("admin.spawnbuild") && !this.client.playerData.inPlayerShip) { returnData = false; } } } else { returnData = false; } } } else if (type == EntityType.Object || type == EntityType.Plant || type == EntityType.PlantDrop || type == EntityType.Monster) { if (!this.client.playerData.canIBuild()) returnData = false; } } } } #endregion else #region Handle Server Packets { if (packetID == Packet.ChatReceive) { returnData = new Packet5ChatReceive(this.client, packetData, this.direction).onReceive(); } else if (packetID == Packet.ProtocolVersion) { uint protocolVersion = packetData.ReadUInt32BE(); if (protocolVersion != StarryboundServer.ProtocolVersion) { MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); packetWrite.WriteBE(protocolVersion); this.client.sendClientPacket(Packet.ProtocolVersion, packet.ToArray()); this.client.rejectPreConnected("Connection Failed: Unable to handle parent server protocol version."); return; } } else if (packetID == Packet.HandshakeChallenge) { string claimMessage = packetData.ReadString(); string passwordSalt = packetData.ReadStarString(); int passwordRounds = packetData.ReadInt32BE(); MemoryStream packet = new MemoryStream(); BinaryWriter packetWrite = new BinaryWriter(packet); string passwordHash = Utils.StarHashPassword(StarryboundServer.privatePassword, passwordSalt, passwordRounds); packetWrite.WriteStarString(""); packetWrite.WriteStarString(passwordHash); this.client.sendServerPacket(Packet.HandshakeResponse, packet.ToArray()); returnData = false; } else if (packetID == Packet.ConnectResponse) { int startTime = Utils.getTimestamp(); while (true) { if (this.client.state == ClientState.PendingConnectResponse) break; if (Utils.getTimestamp() > startTime + StarryboundServer.config.connectTimeout) { this.client.rejectPreConnected("Connection Failed: Client did not respond with handshake."); return; } } returnData = new Packet2ConnectResponse(this.client, packetData, this.direction).onReceive(); } else if (packetID == Packet.WorldStart) { if (!this.client.playerData.sentMotd) { this.client.sendChatMessage(Config.GetMotd()); if (!this.client.playerData.group.hasPermission("world.build")) this.client.sendChatMessage("^#f75d5d;" + StarryboundServer.config.buildErrorMessage); this.client.playerData.sentMotd = true; } byte[] planet = packetData.ReadStarByteArray(); byte[] worldStructure = packetData.ReadStarByteArray(); byte[] sky = packetData.ReadStarByteArray(); byte[] serverWeather = packetData.ReadStarByteArray(); float spawnX = packetData.ReadSingleBE(); float spawnY = packetData.ReadSingleBE(); uint mapParamsSize = packetData.ReadVarUInt32(); Dictionary<string, object> mapParams = new Dictionary<string, object>(); int isPlayerShip = 0; for (int i = 0; i < mapParamsSize; i++) { string key = packetData.ReadStarString(); var value = packetData.ReadStarVariant(); mapParams.Add(key, value); if(key == "fuel.level") { isPlayerShip++; } else if(key == "fuel.max") { isPlayerShip++; } } this.client.playerData.inPlayerShip = (isPlayerShip == 2); uint clientID = packetData.ReadUInt32BE(); bool bool1 = packetData.ReadBoolean(); WorldCoordinate coords = Utils.findGlobalCoords(sky); if (coords != null) { this.client.playerData.loc = coords; StarryboundServer.logDebug("WorldStart", "[" + this.client.playerData.client + "][" + bool1 + ":" + clientID + "] CurLoc:[" + this.client.playerData.loc.ToString() + "][" + this.client.playerData.inPlayerShip + "]"); } else StarryboundServer.logDebug("WorldStart", "[" + this.client.playerData.client + "][" + bool1 + ":" + clientID + "] InPlayerShip:[" + this.client.playerData.inPlayerShip + "]"); } else if (packetID == Packet.WorldStop) { string status = packetData.ReadStarString(); } else if (packetID == Packet.GiveItem) { string name = packetData.ReadStarString(); uint count = packetData.ReadVarUInt32(); var itemDesc = packetData.ReadStarVariant(); } else if (packetID == Packet.EnvironmentUpdate) { byte[] sky = packetData.ReadStarByteArray(); byte[] serverWeather = packetData.ReadStarByteArray(); if (this.client.playerData.loc == null) { WorldCoordinate coords = Utils.findGlobalCoords(sky); if (coords != null) { this.client.playerData.loc = coords; StarryboundServer.logDebug("EnvUpdate", "[" + this.client.playerData.client + "] CurLoc:[" + this.client.playerData.loc.ToString() + "]"); } } } else if (packetID == Packet.ClientContextUpdate) { try { byte[] clientContextData = packetData.ReadStarByteArray(); if (clientContextData.Length != 0) { BinaryReader clientContextReader = new BinaryReader(new MemoryStream(clientContextData)); byte[] data = clientContextReader.ReadStarByteArray(); if (data.Length > 8) //Should at least be more than 8 bytes for it to contain the data we want. { BinaryReader dataReader = new BinaryReader(new MemoryStream(data)); byte dataBufferLength = dataReader.ReadByte(); if (dataBufferLength == 2) { byte arrayLength = dataReader.ReadByte(); if (arrayLength == 2 || arrayLength == 4) //Only observed these being used so far for what we want. { byte dataType = dataReader.ReadByte(); //04 = String, 0E = CelestialLog if (dataType == 4) { string string1 = dataReader.ReadStarString(); if (dataReader.BaseStream.Position != dataReader.BaseStream.Length) { if (string1 == "null") { byte[] worldHeader = dataReader.ReadStarByteArray(); //0008020A000C byte[] worldData = dataReader.ReadStarByteArray(); byte typeByte = dataReader.ReadByte(); //0E = CelestialLog if (typeByte == 14) { Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog(); log.TryGetValue("loc", out this.client.playerData.loc); if (!log.TryGetValue("home", out this.client.playerData.home)) this.client.playerData.home = this.client.playerData.loc; StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurLoc:[" + this.client.playerData.loc.ToString() + "][" + this.client.playerData.inPlayerShip + "]"); StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurHome:[" + this.client.playerData.home.ToString() + "]"); } } } } else if (dataType == 14) { Dictionary<string, WorldCoordinate> log = dataReader.ReadStarCelestialLog(); log.TryGetValue("loc", out this.client.playerData.loc); if (!log.TryGetValue("home", out this.client.playerData.home)) this.client.playerData.home = this.client.playerData.loc; StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurLoc:[" + this.client.playerData.loc.ToString() + "][" + this.client.playerData.inPlayerShip + "]"); StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] CurHome:[" + this.client.playerData.home.ToString() + "]"); } } } } } } catch (Exception e) { StarryboundServer.logDebug("ClientContext", "[" + this.client.playerData.client + "] Failed to parse ClientContextUpdate from Server: " + e.ToString()); } } else if (packetID == Packet.EntityCreate) { MemoryStream sendStream = new MemoryStream(); BinaryWriter sendWriter = new BinaryWriter(sendStream); bool test = true; while (true) { EntityType type = (EntityType)packetData.Read(); if (type == EntityType.EOF) break; byte[] entityData = packetData.ReadStarByteArray(); int entityId = packetData.ReadVarInt32(); if (type == EntityType.Player) { byte[] buffer = new byte[16]; Buffer.BlockCopy(entityData, 0, buffer, 0, 16); buffer = Utils.HashUUID(buffer); Buffer.BlockCopy(buffer, 0, entityData, 0, 16); returnData = test = false; } sendWriter.Write((byte)type); sendWriter.WriteVarUInt64((ulong)entityData.Length); sendWriter.Write(entityData); sendWriter.WriteVarInt32(entityId); } if(test == false) { this.outgoing.WriteVarUInt32((uint)packetID); this.outgoing.WriteVarInt32((int)sendStream.Length); this.outgoing.Write(sendStream.ToArray()); this.outgoing.Flush(); } } } #endregion } //Check return data if (returnData is Boolean) { if ((Boolean)returnData == false) continue; } else if (returnData is int) { if ((int)returnData == -1) { this.client.forceDisconnect(direction, "Command processor requested to drop client"); return; } } #region Forward Packet //Write data to dest this.outgoing.WriteVarUInt32((uint)packetID); if (compressed) { this.outgoing.WriteVarInt32(-packetSize); this.outgoing.Write(dataBuffer, 0, packetSize); } else { this.outgoing.WriteVarInt32(packetSize); this.outgoing.Write(dataBuffer, 0, packetSize); } this.outgoing.Flush(); #endregion //If disconnect was forwarded to client, lets disconnect. if(packetID == Packet.ServerDisconnect && direction == Direction.Server) { this.client.closeConnection(); } } } catch (ThreadAbortException) { } catch (EndOfStreamException) { this.client.forceDisconnect(direction, "End of stream"); } catch (Exception e) { if(e.InnerException != null) { if(e.InnerException is System.Net.Sockets.SocketException) { this.client.forceDisconnect(direction, e.InnerException.Message); return; } } this.client.forceDisconnect(direction, "ForwardThread Exception: " + e.ToString()); } }
public SongTable(BinaryReader reader) { Count = reader.ReadInt32BE(); Songs = new Song[Count]; for(int i = 0; i < Count; i++) { Songs[i] = new Song(reader); } }
public HippelCosoFile(Stream stream, byte[] sampleData) { long pos = stream.Position; var reader = new BinaryReader(stream, Encoding.ASCII); string coso = new string(reader.ReadChars(4)); if(coso == "COSO") { int frqseqs = reader.ReadInt32BE(); int volseqs = reader.ReadInt32BE(); int patternsPtr = reader.ReadInt32BE(); int voicesPtr = reader.ReadInt32BE(); int songsData = reader.ReadInt32BE(); int headers = reader.ReadInt32BE(); int samplesPtr = reader.ReadInt32BE(); /*string tfmx = new string(reader.ReadChars(4)); if(tfmx == "TFMX") { reader.ReadInt16BE(); reader.ReadInt16BE(); reader.ReadInt16BE(); int npatterns = reader.ReadInt16BE()+1; reader.ReadInt16BE(); reader.ReadInt16BE(); short nsongs = reader.ReadInt16BE(); short nsamples = reader.ReadInt16BE(); }*/ int nsamples = (samplesPtr-headers)/10 - 1; stream.Position = pos+headers; Samples = new Sample[nsamples]; for(int i = 0; i < nsamples; i++) { Samples[i] = new Sample(reader); } if(sampleData == null) { int endPos = Samples.Max(i => i.SourceStart+i.SourceLength); stream.Position = samplesPtr; sampleData = reader.ReadBytes(endPos); } if(sampleData.Length > 0) { for(int i = 0; i < nsamples; i++) { var inst = Samples[i]; Array.Copy(sampleData, inst.SourceStart, inst.Data, 0, inst.SourceLength); } } int nsongs = (headers-songsData)/6; stream.Position = pos+songsData; Songs = new Song[nsongs]; for(int i = 0; i < nsongs; i++) { Songs[i] = new Song(reader); } int nvoices = (songsData-voicesPtr)/3; stream.Position = pos+voicesPtr; Voices = new Voice[nvoices]; for(int i = 0; i < nvoices; i++) { Voices[i] = new Voice(reader); } stream.Position = pos+patternsPtr; int npatterns = (voicesPtr-patternsPtr)/2; Patterns = new Pattern[npatterns]; for(int i = 0; i < npatterns; i++) { Patterns[i] = new Pattern(reader); } /*var patterns = new List<Pattern>(); while(stream.Position < pos+voicesPtr) { patterns.Add(new Pattern(reader)); } int c = patterns.Count; int x = voices.Max(v => v.PatternAddress);*/ //int npatterns = (voicesPtr-patternsPtr)/ /*stream.Position = pos+tracks; Pattern[] notes = new Pattern[nnotes]; for(int i = 0; i < nnotes; i++) { notes[i] = new Pattern(reader); } for(int j = 0; j < 12; j++) { Console.WriteLine("Byte "+j); Console.WriteLine(notes.Select(n => n.Data).Any(d => d[j] > 10)); }*/ } }
public SonicArrangerFile(Stream stream) { var reader = new BinaryReader(stream, Encoding.ASCII); string soar = new string(reader.ReadChars(4)); if(soar != "SOAR") { stream.Position = 0; long start = ReadTo(reader, pcstart); int songptr = 0x28; int ovtbptr = reader.ReadInt32BE(); int notbptr = reader.ReadInt32BE(); int intbptr = reader.ReadInt32BE(); int syntptr = reader.ReadInt32BE(); stream.Position = start+songptr; int songs = (ovtbptr-songptr)/12; Songs = new Song[songs]; for(int i = 0; i < songs; i++) { Songs[i] = new Song(reader); } stream.Position = start+ovtbptr; int voices = (notbptr-ovtbptr)/4; Voices = new Voice[voices]; for(int i = 0; i < voices; i++) { Voices[i] = new Voice(reader); } stream.Position = start+notbptr; int notes = (intbptr-notbptr)/4; Notes = new Note[notes]; for(int i = 0; i < notes; i++) { Notes[i] = new Note(reader); } stream.Position = start+intbptr; int instrs = (syntptr-intbptr)/152; Instruments = new Instrument[instrs]; for(int i = 0; i < instrs; i++) { Instruments[i] = new Instrument(reader); } }else{ Version = new string(reader.ReadChars(4)); string tag; while(true) { tag = new string(reader.ReadChars(4)); switch(tag) { case "STBL": Songs = new SongTable(reader).Songs; break; case "OVTB": Voices = new OverTable(reader).Voices; break; case "NTBL": Notes = new NoteTable(reader).Notes; break; case "INST": Instruments = new InstrumentTable(reader).Instruments; break; default: return; } } } }
private unsafe void ParseIndex(string idx) { using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var br = new BinaryReader(fs)) { int h2Len = br.ReadInt32(); int h2Check = br.ReadInt32(); byte[] h2 = br.ReadBytes(h2Len); long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0; fs.Position = padPos; int dataLen = br.ReadInt32(); int dataCheck = br.ReadInt32(); int numBlocks = dataLen / 18; //byte[] buf = new byte[8]; for (int i = 0; i < numBlocks; i++) { IndexEntry info = new IndexEntry(); byte[] keyBytes = br.ReadBytes(9); Array.Resize(ref keyBytes, 16); MD5Hash key; fixed (byte *ptr = keyBytes) key = *(MD5Hash*)ptr; byte indexHigh = br.ReadByte(); int indexLow = br.ReadInt32BE(); info.Index = (indexHigh << 2 | (byte)((indexLow & 0xC0000000) >> 30)); info.Offset = (indexLow & 0x3FFFFFFF); //for (int j = 3; j < 8; j++) // buf[7 - j] = br.ReadByte(); //long val = BitConverter.ToInt64(buf, 0); //info.Index = (int)(val / 0x40000000); //info.Offset = (int)(val % 0x40000000); info.Size = br.ReadInt32(); // duplicate keys wtf... //IndexData[key] = info; // use last key if (!LocalIndexData.ContainsKey(key)) // use first key LocalIndexData.Add(key, info); } padPos = (dataLen + 0x0FFF) & 0xFFFFF000; fs.Position = padPos; fs.Position += numBlocks * 18; //for (int i = 0; i < numBlocks; i++) //{ // var bytes = br.ReadBytes(18); // unknown data //} //if (fs.Position != fs.Length) // throw new Exception("idx file under read"); } }
private CASCHandler(CASCConfig config, CDNHandler cdn, BackgroundWorker worker) { this.config = config; this.cdn = cdn; if (!config.OnlineMode) { var idxFiles = GetIdxFiles(this.config.BasePath); if (idxFiles.Count == 0) throw new FileNotFoundException("idx files missing!"); if (worker != null) worker.ReportProgress(0); int idxIndex = 0; foreach (var idx in idxFiles) { using (var fs = new FileStream(idx, FileMode.Open, FileAccess.Read, FileShare.ReadWrite)) using (var br = new BinaryReader(fs)) { int h2Len = br.ReadInt32(); int h2Check = br.ReadInt32(); byte[] h2 = br.ReadBytes(h2Len); long padPos = (8 + h2Len + 0x0F) & 0xFFFFFFF0; fs.Position = padPos; int dataLen = br.ReadInt32(); int dataCheck = br.ReadInt32(); int numBlocks = dataLen / 18; for (int i = 0; i < numBlocks; i++) { IndexEntry info = new IndexEntry(); byte[] key = br.ReadBytes(9); int indexHigh = br.ReadByte(); int indexLow = br.ReadInt32BE(); info.Index = (int)((byte)(indexHigh << 2) | ((indexLow & 0xC0000000) >> 30)); info.Offset = (indexLow & 0x3FFFFFFF); info.Size = br.ReadInt32(); // duplicate keys wtf... //IndexData[key] = info; // use last key if (!LocalIndexData.ContainsKey(key)) // use first key LocalIndexData.Add(key, info); } padPos = (dataLen + 0x0FFF) & 0xFFFFF000; fs.Position = padPos; fs.Position += numBlocks * 18; //for (int i = 0; i < numBlocks; i++) //{ // var bytes = br.ReadBytes(18); // unknown data //} if (fs.Position != fs.Position) throw new Exception("idx file under read"); } if (worker != null) worker.ReportProgress((int)((float)++idxIndex / (float)idxFiles.Count * 100)); } Logger.WriteLine("CASCHandler: loaded {0} indexes", LocalIndexData.Count); } if (worker != null) worker.ReportProgress(0); using (var fs = OpenEncodingFile()) using (var br = new BinaryReader(fs)) { br.ReadBytes(2); // EN byte b1 = br.ReadByte(); byte b2 = br.ReadByte(); byte b3 = br.ReadByte(); ushort s1 = br.ReadUInt16(); ushort s2 = br.ReadUInt16(); int numEntries = br.ReadInt32BE(); int i1 = br.ReadInt32BE(); byte b4 = br.ReadByte(); int entriesOfs = br.ReadInt32BE(); fs.Position += entriesOfs; // skip strings fs.Position += numEntries * 32; //for (int i = 0; i < numEntries; ++i) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} for (int i = 0; i < numEntries; ++i) { ushort keysCount; while ((keysCount = br.ReadUInt16()) != 0) { int fileSize = br.ReadInt32BE(); byte[] md5 = br.ReadBytes(16); var entry = new EncodingEntry(); entry.Size = fileSize; for (int ki = 0; ki < keysCount; ++ki) { byte[] key = br.ReadBytes(16); entry.Keys.Add(key); } //Encodings[md5] = entry; EncodingData.Add(md5, entry); } //br.ReadBytes(28); while (br.PeekChar() == 0) fs.Position++; if (worker != null) worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } //var pos = br.BaseStream.Position; //for (int i = 0; i < i1; ++i) //{ // br.ReadBytes(16); // br.ReadBytes(16); //} Logger.WriteLine("CASCHandler: loaded {0} encoding data", EncodingData.Count); } if (worker != null) worker.ReportProgress(0); using (var fs = OpenRootFile()) using (var br = new BinaryReader(fs)) { while (fs.Position < fs.Length) { int count = br.ReadInt32(); RootBlock block = new RootBlock(); block.Unk1 = br.ReadUInt32(); block.Flags = (LocaleFlags)br.ReadUInt32(); if (block.Flags == LocaleFlags.None) throw new Exception("block.Flags == LocaleFlags.None"); RootEntry[] entries = new RootEntry[count]; for (var i = 0; i < count; ++i) { entries[i] = new RootEntry(); entries[i].Block = block; entries[i].Unk1 = br.ReadInt32(); } for (var i = 0; i < count; ++i) { entries[i].MD5 = br.ReadBytes(16); ulong hash = br.ReadUInt64(); entries[i].Hash = hash; // don't load other locales //if (block.Flags != LocaleFlags.All && (block.Flags & LocaleFlags.enUS) == 0) // continue; if (!RootData.ContainsKey(hash)) { RootData[hash] = new List<RootEntry>(); RootData[hash].Add(entries[i]); } else RootData[hash].Add(entries[i]); } if (worker != null) worker.ReportProgress((int)((float)fs.Position / (float)fs.Length * 100)); } Logger.WriteLine("CASCHandler: loaded {0} root data", RootData.Count); } if (worker != null) worker.ReportProgress(0); }
#pragma warning disable CS0219 public override string GetTitle(BinaryReader fileStream) { // using the official id3 tag documentation // http://id3.org/id3v2.3.0#ID3_tag_version_2.3.0 int read_count = 10; // read + validate header [10 bytes] // skipped for TagID >03 bytes byte version_major = fileStream.ReadByte(); // >01 bytes byte version_minor = fileStream.ReadByte(); // >01 bytes byte data_flags = fileStream.ReadByte(); // >01 bytes byte[] tag_size = fileStream.ReadBytes(4); // >04 bytes int tag_size_int = 0; for (int i = 0; i < 4; i++) tag_size_int |= tag_size[3 - i] << (i * 7); read_count += 10; #region ID3v2 if (version_major == 2) { while (read_count < tag_size_int + 10) { // frame header [06 bytes] int frame_id = fileStream.ReadInt24BE(); // >03 bytes int frame_size = fileStream.ReadInt24BE(); // >03 bytes read_count += 6; if (frame_id == v2_TT2) { string title; byte[] textBuffer = fileStream.ReadBytes(frame_size); if (textBuffer[0] == 0) title = Encoding.GetEncoding(28591).GetString(textBuffer, 1, frame_size - 1); else throw new FormatException("The id3 tag is damaged"); return title; } else { fileStream.ReadBytes(frame_size); read_count += frame_size; } } throw new FormatException("The id3 tag contains no title"); } #endregion #region ID3v3/4 else if (version_major == 3 || version_major == 4) { while (read_count < tag_size_int + 10) { // frame header [10 bytes] uint frame_id = fileStream.ReadUInt32BE(); // >04 bytes int frame_size = fileStream.ReadInt32BE(); // >04 bytes ushort frame_flags = fileStream.ReadUInt16BE(); // >02 bytes read_count += 10; // content if (frame_id == v3_TIT2) { string title; byte[] textBuffer = fileStream.ReadBytes(frame_size); // is a string, so the first byte is a indicator byte switch (textBuffer[0]) { case 0: title = Encoding.GetEncoding(28591).GetString(textBuffer, 1, frame_size - 1); break; case 1: title = Encoding.Unicode.GetString(textBuffer, 1, frame_size - 1); break; case 2: title = new UnicodeEncoding(true, false).GetString(textBuffer, 1, frame_size - 1); break; case 3: title = Encoding.UTF8.GetString(textBuffer, 1, frame_size - 1); break; default: throw new FormatException("The id3 tag is damaged"); } return title; } else if (frame_id == 0) break; else { fileStream.ReadBytes(frame_size); read_count += frame_size; } } throw new FormatException("The id3 tag contains no title"); } #endregion return null; }
public AssetCabinet(Stream stream, UnityParser parser) { Parser = parser; BinaryReader reader = new BinaryReader(stream); UsedLength = reader.ReadInt32BE(); ContentLengthCopy = reader.ReadInt32BE(); Format = reader.ReadInt32BE(); DataPosition = reader.ReadInt32BE(); Unknown6 = reader.ReadInt32BE(); Version = reader.ReadName0(); Unknown7 = reader.ReadInt32(); int numTypes = reader.ReadInt32(); Types = new List<TypeDefinition>(numTypes); for (int i = 0; i < numTypes; i++) { TypeDefinition t = new TypeDefinition(); t.typeId = reader.ReadInt32(); t.definitions = new TypeDefinitionString(); ReadType(reader, t.definitions); Types.Add(t); } Unknown8 = reader.ReadInt32(); int numComponents = reader.ReadInt32(); Components = new List<Component>(numComponents); for (int i = 0; i < numComponents; i++) { int pathID = reader.ReadInt32(); uint offset = (uint)(parser.HeaderLength + parser.Offset) + (uint)DataPosition + reader.ReadUInt32(); uint size = reader.ReadUInt32(); NotLoaded comp = new NotLoaded(this, pathID, (UnityClassID)reader.ReadInt32(), (UnityClassID)reader.ReadInt32()); comp.offset = offset; comp.size = size; Components.Add(comp); } int numRefs = reader.ReadInt32(); References = new Reference[numRefs]; for (int i = 0; i < numRefs; i++) { References[i] = new Reference(); References[i].guid = new Guid(reader.ReadBytes(16)); References[i].type = reader.ReadInt32(); References[i].filePath = reader.ReadName0(); References[i].assetPath = reader.ReadName0(); } if (stream.Position != UsedLength + (parser.HeaderLength + parser.Offset) + 0x13) { Report.ReportLog("Unexpected Length Pos=" + stream.Position.ToString("X") + " UsedLength=" + UsedLength.ToString("X")); } long padding = (stream.Position + 16) & ~(long)15; if (padding != parser.HeaderLength + parser.Offset + DataPosition) { Report.ReportLog("Unexpected DataPosition"); } RemovedList = new List<NotLoaded>(); loadingReferencials = false; reported = new HashSet<string>(); for (int i = 0; i < Components.Count; i++) { Component asset = Components[i]; if (asset.classID1 == UnityClassID.AssetBundle) { Bundle = LoadComponent(stream, i, (NotLoaded)asset); break; } } }
public EncodingHandler(BinaryReader stream, BackgroundWorkerEx worker) { worker?.ReportProgress(0, "Loading \"encoding\"..."); stream.Skip(2); // EN byte b1 = stream.ReadByte(); byte checksumSizeA = stream.ReadByte(); byte checksumSizeB = stream.ReadByte(); ushort flagsA = stream.ReadUInt16(); ushort flagsB = stream.ReadUInt16(); int numEntriesA = stream.ReadInt32BE(); int numEntriesB = stream.ReadInt32BE(); byte b4 = stream.ReadByte(); int stringBlockSize = stream.ReadInt32BE(); stream.Skip(stringBlockSize); //string[] strings = Encoding.ASCII.GetString(stream.ReadBytes(stringBlockSize)).Split(new[] { '\0' }, StringSplitOptions.RemoveEmptyEntries); stream.Skip(numEntriesA * 32); //for (int i = 0; i < numEntriesA; ++i) //{ // byte[] firstHash = stream.ReadBytes(16); // byte[] blockHash = stream.ReadBytes(16); //} long chunkStart = stream.BaseStream.Position; for (int i = 0; i < numEntriesA; ++i) { ushort keysCount; while ((keysCount = stream.ReadUInt16()) != 0) { int fileSize = stream.ReadInt32BE(); byte[] md5 = stream.ReadBytes(16); EncodingEntry entry = new EncodingEntry(); entry.Size = fileSize; // how do we handle multiple keys? for (int ki = 0; ki < keysCount; ++ki) { byte[] key = stream.ReadBytes(16); // use first key for now if (ki == 0) entry.Key = key; else Logger.WriteLine("Multiple encoding keys for MD5 {0}: {1}", md5.ToHexString(), key.ToHexString()); } //Encodings[md5] = entry; EncodingData.Add(md5, entry); } // each chunk is 4096 bytes, and zero padding at the end long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart) % CHUNK_SIZE); if (remaining > 0) stream.BaseStream.Position += remaining; worker?.ReportProgress((int)((i + 1) / (float)numEntriesA * 100)); } stream.Skip(numEntriesB * 32); //for (int i = 0; i < numEntriesB; ++i) //{ // byte[] firstKey = stream.ReadBytes(16); // byte[] blockHash = stream.ReadBytes(16); //} long chunkStart2 = stream.BaseStream.Position; for (int i = 0; i < numEntriesB; ++i) { byte[] key = stream.ReadBytes(16); int stringIndex = stream.ReadInt32BE(); byte unk1 = stream.ReadByte(); int fileSize = stream.ReadInt32BE(); // each chunk is 4096 bytes, and zero padding at the end long remaining = CHUNK_SIZE - ((stream.BaseStream.Position - chunkStart2) % CHUNK_SIZE); if (remaining > 0) stream.BaseStream.Position += remaining; } // string block till the end of file }