public override void ConvertClCorpseMessageCallback(Int32 gameVersion, BitBuffer bitBuffer) { if (gameVersion >= (Int32)Versions.CounterStrike16) { return; } // Convert the model sequence number. // string, 3x long, 3x short, long, byte (sequence number), byte, byte, byte (CS 1.6 only). bitBuffer.ReadString(); // model name bitBuffer.SeekBytes(22); Byte sequence = bitBuffer.ReadByte(); UInt32? newSequence = sequence; ConvertSequenceNumber(gameVersion, ref newSequence); if (newSequence != sequence) { // Sequence number has changed, replace the old one with the new one. bitBuffer.SeekBytes(-1); bitBuffer.RemoveBytes(1); bitBuffer.InsertBytes(new Byte[] { (Byte)newSequence }); } }
/// <summary> /// Consumers the thread. /// </summary> /// <param name="arg">Argument.</param> private static void ConsumerThread(object arg) { ClientMessageReceived item; //while (true) Console.WriteLine("Queue: " + Server.QueueMessages.Count.ToString()); while (!Server.QueueMessages.IsEmpty) { bool isSuccessful = Server.QueueMessages.TryDequeue(out item); Console.WriteLine("Dequeue: " + isSuccessful); if (isSuccessful) { //https://stackoverflow.com/questions/943398/get-int-value-from-enum-in-c-sharp //https://msdn.microsoft.com/it-it/library/system.enum.getvalues(v=vs.110).aspx //http://csharp.net-informations.com/statements/enum.htm if (((byte)SendType.SENDTOALL).ToString() == item.MessageBytes.GetValue(0).ToString()) //0 { //BROADCAST (SENDTOALL) Console.WriteLine("BROADCAST (SENDTOALL)"); //Send data received to all client in List foreach (var conn in Server.clients) { if (true) { conn.Value.SendBytes(item.MessageBytes, item.SOClientConnected); Console.WriteLine("Send to: " + conn.Value.EndPoint.ToString()); } } } else if ((byte)SendType.SENDTOOTHER == (byte)item.MessageBytes.GetValue(0)) //1 { //BROADCAST (SENDTOOTHER) Console.WriteLine("BROADCAST (SENDTOOTHER)"); //Call Objects Table var col = db.GetCollection <Objects>("objects"); //Parser Message //Remove first byte (type) //https://stackoverflow.com/questions/31550484/faster-code-to-remove-first-elements-from-byte-array byte STypeBuffer = item.MessageBytes[0]; byte[] NewBufferReceiver = new byte[item.MessageBytes.Length - 1]; Array.Copy(item.MessageBytes, 1, NewBufferReceiver, 0, NewBufferReceiver.Length); //Deserialize message using NetStack //Reset bit buffer for further reusing BitBuffer data = new BitBuffer(1024); data.FromArray(NewBufferReceiver, NewBufferReceiver.Length); byte TypeBuffer = data.ReadByte(); string OwnerPlayer = data.ReadString(); bool isKine = data.ReadBool(); uint IDObject = data.ReadUInt(); CompressedVector3 position = new CompressedVector3(data.ReadUInt(), data.ReadUInt(), data.ReadUInt()); CompressedQuaternion rotation = new CompressedQuaternion(data.ReadByte(), data.ReadShort(), data.ReadShort(), data.ReadShort()); // Read Vector3 Compress Velocity //ushort compressedVelocityX = HalfPrecision.Compress(speed); Vector3 VelocityReceived = new Vector3(HalfPrecision.Decompress(data.ReadUShort()), HalfPrecision.Decompress(data.ReadUShort()), HalfPrecision.Decompress(data.ReadUShort())); //Read Float InterpolationTime float InterpolationTime = HalfPrecision.Decompress(data.ReadUShort()); // Check if bit buffer is fully unloaded Console.WriteLine("Bit buffer is empty: " + data.IsFinished); //Decompress Vector and Quaternion //Create a new BoundedRange array for Vector3 position, each entry has bounds and precision BoundedRange[] worldBounds = new BoundedRange[3]; worldBounds[0] = new BoundedRange(-50f, 50f, 0.05f); // X axis worldBounds[1] = new BoundedRange(0f, 25f, 0.05f); // Y axis worldBounds[2] = new BoundedRange(-50f, 50f, 0.05f); // Z axis //Decompress position data Vector3 decompressedPosition = BoundedRange.Decompress(position, worldBounds); // Decompress rotation data Quaternion decompressedRotation = SmallestThree.Decompress(rotation); if (Server.DEBUG) { Console.WriteLine("RECEIVED DATA: "); Console.WriteLine("TYPE RECEIVED: " + TypeBuffer.ToString()); Console.WriteLine("IDObject RECEIVED: " + IDObject.ToString()); Console.WriteLine("UID RECEIVED: " + OwnerPlayer); Console.WriteLine("isKinematic RECEIVED: " + isKine.ToString()); Console.WriteLine("POS RECEIVED: " + decompressedPosition.X.ToString() + ", " + decompressedPosition.Y.ToString() + ", " + decompressedPosition.Z.ToString()); Console.WriteLine("ROT RECEIVED: " + decompressedRotation.X.ToString() + ", " + decompressedRotation.Y.ToString() + ", " + decompressedRotation.Z.ToString() + ", " + decompressedRotation.W.ToString()); Console.WriteLine("PosX: " + decompressedPosition.X); Console.WriteLine("PosY: " + decompressedPosition.Y); Console.WriteLine("PosZ: " + decompressedPosition.Z); Console.WriteLine("VEL RECEIVED: " + VelocityReceived.X.ToString() + ", " + VelocityReceived.Y.ToString() + ", " + VelocityReceived.Z.ToString()); Console.WriteLine("INTERPOLATION TIME: " + InterpolationTime.ToString()); //var ReceiveMessageFromGameObjectBuffer = new ReceiveMessageFromGameObject(); //NOT USED! } //Check if ObjectReceived.ID <> 0 if (IDObject != 0) { var MVobject = new Objects { IDObject = (int)IDObject, isKine = isKine, PosX = decompressedPosition.X, PosY = decompressedPosition.Y, PosZ = decompressedPosition.Z, RotX = decompressedRotation.X, RotY = decompressedRotation.Y, RotZ = decompressedRotation.Z, RotW = decompressedRotation.W, UID = IDObject.ToString() + ";" + OwnerPlayer }; //Debug Console.WriteLine("MVobject PosX: " + MVobject.PosX); Console.WriteLine("MVobject PosY: " + MVobject.PosY); Console.WriteLine("MVobject PosZ: " + MVobject.PosZ); if ((byte)PacketId.OBJECT_SPAWN == TypeBuffer) { // Insert new customer document (Id will be auto-incremented) col.Insert(MVobject); // Create unique index in Name field col.EnsureIndex(x => x.UID, true); Console.WriteLine("OBJECT SPAWN SAVED"); } else if ((byte)PacketId.OBJECT_MOVE == TypeBuffer) { //Check if record exist if (col.Count(Query.EQ("UID", IDObject.ToString() + ";" + OwnerPlayer)) == 1) { //Search and update // Now, search for document your document var ObjectsFinded = col.FindOne(x => x.UID == IDObject.ToString() + ";" + OwnerPlayer); //Update data ObjectsFinded.isKine = isKine; ObjectsFinded.PosX = decompressedPosition.X; ObjectsFinded.PosY = decompressedPosition.Y; ObjectsFinded.PosZ = decompressedPosition.Z; ObjectsFinded.RotX = decompressedRotation.X; ObjectsFinded.RotY = decompressedRotation.Y; ObjectsFinded.RotZ = decompressedRotation.Z; ObjectsFinded.RotW = decompressedRotation.W; //Save data to Objects DB if (col.Update(ObjectsFinded)) { Console.WriteLine("UPDATE OBJECT IN DB"); } else { Console.WriteLine("*NOT* UPDATED OBJECT IN DB"); } } else { col.Insert(MVobject); //Insert data to Objects DB col.EnsureIndex(x => x.UID, true); //Create unique index in Name field Console.WriteLine("INSERT OBJECT IN DB"); } Console.WriteLine("OBJECT MOVE"); } else if ((byte)PacketId.OBJECT_UNSPAWN == TypeBuffer) { if (col.Count(Query.EQ("UID", IDObject.ToString() + ";" + OwnerPlayer)) == 1) { col.Delete(Query.EQ("UID", IDObject.ToString() + ";" + OwnerPlayer)); //Save data to Objects DB Console.WriteLine("DELETE OBJECT FROM DB"); } else { Console.WriteLine("OBJECT UNSPAWN NOT IN DB");; } Console.WriteLine("OBJECT UNSPAWN"); } } // END Check ObjectReceived.ID <> 0 //Send data received to all other client in List Console.WriteLine("SEND MESSAGE TO OTHER CLIENTS"); foreach (var conn in Server.clients) { if (conn.Value != item.ClientConnected) //SENDTOOTHER { conn.Value.SendBytes(item.MessageBytes, item.SOClientConnected); Console.WriteLine("Send to: " + conn.Value.EndPoint.ToString()); } } } else if ((byte)SendType.SENDTOSERVER == (byte)item.MessageBytes.GetValue(0)) //2 { //FOR NOW ECHO SERVER (SENDTOSERVER) Console.WriteLine("CLIENT TO SERVER (SENDTOSERVER)"); //Parser Message //Remove first byte (type) //https://stackoverflow.com/questions/31550484/faster-code-to-remove-first-elements-from-byte-array byte STypeBuffer = item.MessageBytes[0]; byte[] NewBufferReceiver = new byte[item.MessageBytes.Length - 1]; Array.Copy(item.MessageBytes, 1, NewBufferReceiver, 0, NewBufferReceiver.Length); //Deserialize message using NetStack //Reset bit buffer for further reusing BitBuffer data = new BitBuffer(1024); data.FromArray(NewBufferReceiver, NewBufferReceiver.Length); byte CommandTypeBuffer = data.ReadByte(); string Answer = data.ReadString(); // Check if bit buffer is fully unloaded Console.WriteLine("Bit buffer is empty: " + data.IsFinished); String UIDBuffer = String.Empty; if (STypeBuffer == 2) { if ((sbyte)CommandType.LOGIN == CommandTypeBuffer) { //Cerca e restituisci il tutto foreach (var conn in Server.clients) { if (conn.Value == item.ClientConnected) //SENDTOSERVER { //DONE: Check here if user exist and password correct //Get users collection var col = db.GetCollection <Users>("users"); Console.WriteLine("COMMAND RECEIVED: " + Answer); //Parse HMessageReceived string[] words = Answer.Split(';'); //words[0] = Login; words[1] = Password if (col.Count(Query.EQ("UserName", words[0])) == 1) { var results = col.Find(Query.EQ("UserName", words[0])); string UserPasswordRecord = string.Empty; foreach (var c in results) { Console.WriteLine("#{0} - {1}", c.Id, c.UserName); UserPasswordRecord = c.UserPassword; } //Verify password ScryptEncoder encoder = new ScryptEncoder(); //Check password if (encoder.Compare(words[1], UserPasswordRecord)) { //OK UIDBuffer = conn.Key; Console.WriteLine("UID: " + UIDBuffer); } else { //*NOT* OK UIDBuffer = string.Empty; Console.WriteLine("UID: ERROR PASSWORD" + UIDBuffer); } } else { UIDBuffer = string.Empty; Console.WriteLine("UID: USER NOT EXISTS!" + UIDBuffer); } } } } } //Reset bit buffer for further reusing data.Clear(); data.AddByte((byte)CommandType.LOGIN) .AddString(UIDBuffer); byte[] BufferNetStack = new byte[data.Length]; data.ToArray(BufferNetStack); data.Clear(); //SEND MESSAGE // Add type! //https://stackoverflow.com/questions/5591329/c-sharp-how-to-add-byte-to-byte-array byte[] newArray = new byte[BufferNetStack.Length + 1]; BufferNetStack.CopyTo(newArray, 1); newArray[0] = (byte)SendType.SENDTOSERVER; item.ClientConnected.SendBytes(newArray, item.SOClientConnected); if (DEBUG) { Console.WriteLine("Data Lenghts: " + newArray.Length.ToString()); Console.WriteLine("Data Lenghts NetStack: " + BufferNetStack.Length.ToString()); Console.WriteLine("Data Lenghts BitBuffer: " + data.Length.ToString()); Console.WriteLine("Message sent!"); } Console.WriteLine("Send to: " + item.ClientConnected.EndPoint.ToString()); //HERE SEND TO ALL CLIENTS OBJECTS DB //DONE: Add code to send all clients Console.WriteLine("SEND ALL OBJECTS TO CLIENT"); //Call Objects Table var col_objects = db.GetCollection <Objects>("objects"); //Recovers all objects in the table var results_objects = col_objects.Find(Query.GT("_id", 0)); //Foreach send them to the client connected foreach (var o in results_objects) { Console.WriteLine("SEND IDOBJECT: " + o.IDObject.ToString()); //SEND USING NETSTACK SERIALIZATION // Create a new BoundedRange array for Vector3 position, each entry has bounds and precision BoundedRange[] worldBounds = new BoundedRange[3]; worldBounds[0] = new BoundedRange(-50f, 50f, 0.05f); // X axis worldBounds[1] = new BoundedRange(0f, 25f, 0.05f); // Y axis worldBounds[2] = new BoundedRange(-50f, 50f, 0.05f); // Z axis //Convert from HazelUDPTestClient.Vector3 at System.Numerics.Vector3 System.Numerics.Vector3 InternalPos = new System.Numerics.Vector3(o.PosX, o.PosY, o.PosZ); //Compress position data CompressedVector3 compressedPosition = BoundedRange.Compress(InternalPos, worldBounds); // Read compressed data Console.WriteLine("Compressed position - X: " + compressedPosition.x + ", Y:" + compressedPosition.y + ", Z:" + compressedPosition.z); //Convert from HazelUDPTestClient.Quaternion at System.Numerics.Quaternion System.Numerics.Quaternion InternalRot = new System.Numerics.Quaternion(o.RotX, o.RotY, o.RotZ, o.RotW); // Compress rotation data CompressedQuaternion compressedRotation = SmallestThree.Compress(InternalRot); // Read compressed data Console.WriteLine("Compressed rotation - M: " + compressedRotation.m + ", A:" + compressedRotation.a + ", B:" + compressedRotation.b + ", C:" + compressedRotation.c); //Add Velocity Vector (0,0,0) Vector3 velocity = Vector3.Zero; //Add and compress Interporlation Time ushort compressedTimeInterpolation = HalfPrecision.Compress(0f); //Reset bit buffer for further reusing data.Clear(); //Serialization data.AddByte((byte)PacketId.OBJECT_MOVE) .AddString(o.UID.Split(';')[1]) //OwnerPlayer .AddBool(o.isKine) .AddUInt((uint)o.IDObject) .AddUInt(compressedPosition.x) .AddUInt(compressedPosition.y) .AddUInt(compressedPosition.z) .AddByte(compressedRotation.m) .AddShort(compressedRotation.a) .AddShort(compressedRotation.b) .AddShort(compressedRotation.c) //Add dummy date (0,0,0) .AddUShort(HalfPrecision.Compress(velocity.X)) .AddUShort(HalfPrecision.Compress(velocity.Y)) .AddUShort(HalfPrecision.Compress(velocity.Z)) .AddUShort(compressedTimeInterpolation); Console.WriteLine("BitBuffer: " + data.Length.ToString()); byte[] BufferNetStackObject = new byte[data.Length]; data.ToArray(BufferNetStackObject); data.Clear(); //https://discordapp.com/channels/515987760281288707/515987760281288711/527744788745814028 //MA soprattutto: https://discordapp.com/channels/515987760281288707/515987760281288711/536428267851350017 //Okay guys, after some debugging I've found the mistake in the original BitBuffer implementation, //Alex forgot to check index boundaries during conversion so this is why + 4 bytes was required for shifting. //Now it's fixed and no longer needed I hope //https://github.com/nxrighthere/NetStack/commit/f381a88751fa0cb72af2cad7652a973d570d3dda //SEND MESSAGE // Add type! //https://stackoverflow.com/questions/5591329/c-sharp-how-to-add-byte-to-byte-array byte[] newArrayObject = new byte[BufferNetStackObject.Length + 1]; //Create +1 NewArrayObject BufferNetStackObject.CopyTo(newArrayObject, 1); //Coping start from position 1 (NOT 0) newArrayObject[0] = (byte)SendType.SENDTOOTHER; //Coping position 0 byte SendType item.ClientConnected.SendBytes(newArrayObject, item.SOClientConnected); //Send new packet if (DEBUG) { Console.WriteLine("Data Lenghts: " + newArray.Length.ToString()); Console.WriteLine("Data Lenghts NetStack: " + BufferNetStack.Length.ToString()); Console.WriteLine("Message sent!"); } } } } } }
public override void Load(BitBuffer bitBuffer) { base.Load(bitBuffer); playerId = bitBuffer.GetInt(); }
public static AbilityInput FromBytes(int id, BitBuffer bitBuffer) { return(new AbilityInput(id, (AbilityType)bitBuffer.GetByte(), PositionInfo.FromBytes(bitBuffer))); }
public ISerializable Deserialize(byte[] bytes) { BitBuffer buffer = new BitBuffer(); return(Deserialize(buffer)); }
public PlayerLeftMessage(BitBuffer buffer) { Deserialize(buffer); }
public void Serialize(BitBuffer buffer) { buffer.PutInt(packetNumber); entities.ForEach(c => c.Serialize(buffer)); }
public override void Encode(BitBuffer buffer) { buffer.WriteCharArray(512, Test); }
/// <summary> /// Reads a 24-bit long value, decodes it into a timestamp using the GlobalBaseTimestamp and returns it. /// </summary> public static long ReadTimestamp(this BitBuffer buffer) { return((long)buffer.ReadBits(24) + NetworkUtils.GlobalBaseTimestamp); }
public static void RemoveComponents(GameContext game, BitBuffer buffer, ushort componentCount) { for (int i = 0; i < componentCount; i++) { var entityId = buffer.ReadUShort(); var componentId = buffer.ReadUShort(); var e = game.GetEntityWithId(entityId); switch (componentId) { case 0: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Id component"); e.RemoveId(); } break; case 1: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Position component"); e.RemovePosition(); } break; case 2: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Direction component"); e.RemoveDirection(); } break; case 3: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Sprite component"); e.RemoveSprite(); } break; case 4: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Mover component"); e.isMover = false; } break; case 5: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Move component"); e.RemoveMove(); } break; case 6: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed LastMoveTick component"); e.RemoveLastMoveTick(); } break; case 7: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed MoverID component"); e.RemoveMoverID(); } break; case 8: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Tick component"); e.RemoveTick(); } break; case 9: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Ice component"); e.RemoveIce(); } break; case 10: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Character component"); e.isCharacter = false; } break; case 11: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed ControlledBy component"); e.RemoveControlledBy(); } break; case 12: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Connection component"); e.RemoveConnection(); } break; case 13: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Removed Sync component"); e.isSync = false; } break; } } }
public static void ChangeComponents(GameContext game, BitBuffer buffer, ushort componentCount) { for (int i = 0; i < componentCount; i++) { var entityId = buffer.ReadUShort(); var componentId = buffer.ReadUShort(); var e = game.GetEntityWithId(entityId); switch (componentId) { case 0: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Id component"); var lookup = GameComponentsLookup.Id; var comp = e.CreateComponent <IdComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 1: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Position component"); var lookup = GameComponentsLookup.Position; var comp = e.CreateComponent <PositionComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 2: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Direction component"); var lookup = GameComponentsLookup.Direction; var comp = e.CreateComponent <DirectionComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 3: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Sprite component"); var lookup = GameComponentsLookup.Sprite; var comp = e.CreateComponent <SpriteComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 4: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Mover component"); e.isMover = true; } break; case 5: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Move component"); var lookup = GameComponentsLookup.Move; var comp = e.CreateComponent <MoveComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 6: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed LastMoveTick component"); var lookup = GameComponentsLookup.LastMoveTick; var comp = e.CreateComponent <LastMoveTickComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 7: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed MoverID component"); var lookup = GameComponentsLookup.MoverID; var comp = e.CreateComponent <MoverIDComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 8: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Tick component"); var lookup = GameComponentsLookup.Tick; var comp = e.CreateComponent <TickComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 9: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Ice component"); var lookup = GameComponentsLookup.Ice; var comp = e.CreateComponent <IceComponent>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 10: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Character component"); e.isCharacter = true; } break; case 11: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed ControlledBy component"); var lookup = GameComponentsLookup.ControlledBy; var comp = e.CreateComponent <ControlledBy>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 12: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Connection component"); var lookup = GameComponentsLookup.Connection; var comp = e.CreateComponent <Connection>(lookup); comp.Deserialize(buffer); e.ReplaceComponent(lookup, comp); } break; case 13: { Logger.I.Log("UnpackEntityUtility", $" Entity-{entityId}: Changed Sync component"); e.isSync = true; } break; } } }
public static void MakeEntity(GameEntity e, BitBuffer buffer) { var addedComponents = new StringBuilder(128); var componentsCount = buffer.ReadUShort(); for (int j = 0; j < componentsCount; j++) { var componentId = buffer.ReadUShort(); switch (componentId) { case 0: { addedComponents.Append(" Id "); var lookup = GameComponentsLookup.Id; var comp = e.CreateComponent <IdComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 1: { addedComponents.Append(" Position "); var lookup = GameComponentsLookup.Position; var comp = e.CreateComponent <PositionComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 2: { addedComponents.Append(" Direction "); var lookup = GameComponentsLookup.Direction; var comp = e.CreateComponent <DirectionComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 3: { addedComponents.Append(" Sprite "); var lookup = GameComponentsLookup.Sprite; var comp = e.CreateComponent <SpriteComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 4: { addedComponents.Append(" Mover "); e.isMover = true; } break; case 5: { addedComponents.Append(" Move "); var lookup = GameComponentsLookup.Move; var comp = e.CreateComponent <MoveComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 6: { addedComponents.Append(" LastMoveTick "); var lookup = GameComponentsLookup.LastMoveTick; var comp = e.CreateComponent <LastMoveTickComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 7: { addedComponents.Append(" MoverID "); var lookup = GameComponentsLookup.MoverID; var comp = e.CreateComponent <MoverIDComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 8: { addedComponents.Append(" Tick "); var lookup = GameComponentsLookup.Tick; var comp = e.CreateComponent <TickComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 9: { addedComponents.Append(" Ice "); var lookup = GameComponentsLookup.Ice; var comp = e.CreateComponent <IceComponent>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 10: { addedComponents.Append(" Character "); e.isCharacter = true; } break; case 11: { addedComponents.Append(" ControlledBy "); var lookup = GameComponentsLookup.ControlledBy; var comp = e.CreateComponent <ControlledBy>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 12: { addedComponents.Append(" Connection "); var lookup = GameComponentsLookup.Connection; var comp = e.CreateComponent <Connection>(lookup); comp.Deserialize(buffer); e.AddComponent(lookup, comp); } break; case 13: { addedComponents.Append(" Sync "); e.isSync = true; } break; } } }
public static void Pack(GameEntity e, BitBuffer buffer) { ushort counter = 0; var hasId = false; if (e.hasId) { hasId = true; counter++; } var hasPosition = false; if (e.hasPosition) { hasPosition = true; counter++; } var hasDirection = false; if (e.hasDirection) { hasDirection = true; counter++; } var hasSprite = false; if (e.hasSprite) { hasSprite = true; counter++; } var hasMover = false; if (e.isMover) { hasMover = true; counter++; } var hasMove = false; if (e.hasMove) { hasMove = true; counter++; } var hasLastMoveTick = false; if (e.hasLastMoveTick) { hasLastMoveTick = true; counter++; } var hasMoverID = false; if (e.hasMoverID) { hasMoverID = true; counter++; } var hasTick = false; if (e.hasTick) { hasTick = true; counter++; } var hasIce = false; if (e.hasIce) { hasIce = true; counter++; } var hasCharacter = false; if (e.isCharacter) { hasCharacter = true; counter++; } var hasControlledBy = false; if (e.hasControlledBy) { hasControlledBy = true; counter++; } var hasConnection = false; if (e.hasConnection) { hasConnection = true; counter++; } var hasSync = false; if (e.isSync) { hasSync = true; counter++; } buffer.AddUShort(counter); if (hasId) { e.id.Serialize(buffer); } if (hasPosition) { e.position.Serialize(buffer); } if (hasDirection) { e.direction.Serialize(buffer); } if (hasSprite) { e.sprite.Serialize(buffer); } if (hasMover) { buffer.AddUShort(4); } if (hasMove) { e.move.Serialize(buffer); } if (hasLastMoveTick) { e.lastMoveTick.Serialize(buffer); } if (hasMoverID) { e.moverID.Serialize(buffer); } if (hasTick) { e.tick.Serialize(buffer); } if (hasIce) { e.ice.Serialize(buffer); } if (hasCharacter) { buffer.AddUShort(10); } if (hasControlledBy) { e.controlledBy.Serialize(buffer); } if (hasConnection) { e.connection.Serialize(buffer); } if (hasSync) { buffer.AddUShort(13); } }
/// <summary> /// When overridden in a derived class, sets the position within the current stream. /// </summary> /// <returns> /// The new position within the current stream. /// </returns> public override long Seek(long offset, SeekOrigin origin) { BitBuffer.Clear(); return(BaseStream.Seek(offset, origin)); }
public override void Parse(BitBuffer buffer) { Test = buffer.ReadCharArray(512); }
public int Decompress(Stream inData, int inLen, Stream outData, int outLen) { BitBuffer bitbuf = new BitBuffer(inData); long startpos = inData.Position; long endpos = inData.Position + inLen; byte[] window = m_state.window; uint window_posn = m_state.window_posn; uint window_size = m_state.window_size; uint R0 = m_state.R0; uint R1 = m_state.R1; uint R2 = m_state.R2; uint i, j; int togo = outLen, this_run, main_element, match_length, match_offset, length_footer, extra, verbatim_bits; int rundest, runsrc, copy_length, aligned_bits; bitbuf.InitBitStream(); // Read header if necessary. if (m_state.header_read == 0) { uint intel = bitbuf.ReadBits(1); if (intel != 0) { // Read the filesize. i = bitbuf.ReadBits(16); j = bitbuf.ReadBits(16); m_state.intel_filesize = (int)((i << 16) | j); } m_state.header_read = 1; } // Main decoding loop. while (togo > 0) { // last block finished, new block expected. if (m_state.block_remaining == 0) { // TODO may screw something up here if (m_state.block_type == LzxConstants.BLOCKTYPE.UNCOMPRESSED) { if ((m_state.block_length & 1) == 1) { inData.ReadByte(); /* realign bitstream to word */ } bitbuf.InitBitStream(); } m_state.block_type = (LzxConstants.BLOCKTYPE)bitbuf.ReadBits(3);; i = bitbuf.ReadBits(16); j = bitbuf.ReadBits(8); m_state.block_remaining = m_state.block_length = (uint)((i << 8) | j); switch (m_state.block_type) { case LzxConstants.BLOCKTYPE.ALIGNED: for (i = 0, j = 0; i < 8; i++) { j = bitbuf.ReadBits(3); m_state.ALIGNED_len[i] = (byte)j; } MakeDecodeTable(LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS, m_state.ALIGNED_len, m_state.ALIGNED_table); // Rest of aligned header is same as verbatim goto case LzxConstants.BLOCKTYPE.VERBATIM; case LzxConstants.BLOCKTYPE.VERBATIM: ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf); ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf); MakeDecodeTable(LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS, m_state.MAINTREE_len, m_state.MAINTREE_table); if (m_state.MAINTREE_len[0xE8] != 0) { m_state.intel_started = 1; } ReadLengths(m_state.LENGTH_len, 0, LzxConstants.NUM_SECONDARY_LENGTHS, bitbuf); MakeDecodeTable(LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS, m_state.LENGTH_len, m_state.LENGTH_table); break; case LzxConstants.BLOCKTYPE.UNCOMPRESSED: m_state.intel_started = 1; // Because we can't assume otherwise. bitbuf.EnsureBits(16); // Get up to 16 pad bits into the buffer. if (bitbuf.GetBitsLeft() > 16) { inData.Seek(-2, SeekOrigin.Current); /* and align the bitstream! */ } byte hi, mh, ml, lo; lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte(); R0 = (uint)(lo | ml << 8 | mh << 16 | hi << 24); lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte(); R1 = (uint)(lo | ml << 8 | mh << 16 | hi << 24); lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte(); R2 = (uint)(lo | ml << 8 | mh << 16 | hi << 24); break; default: return(-1); // TODO throw proper exception } } // Buffer exhaustion check. if (inData.Position > (startpos + inLen)) { /* It's possible to have a file where the next run is less than * 16 bits in size. In this case, the READ_HUFFSYM() macro used * in building the tables will exhaust the buffer, so we should * allow for this, but not allow those accidentally read bits to * be used (so we check that there are at least 16 bits * remaining - in this boundary case they aren't really part of * the compressed data). */ if (inData.Position > (startpos + inLen + 2) || bitbuf.GetBitsLeft() < 16) { return(-1); //TODO throw proper exception } } while ((this_run = (int)m_state.block_remaining) > 0 && togo > 0) { if (this_run > togo) { this_run = togo; } togo -= this_run; m_state.block_remaining -= (uint)this_run; // Apply 2^x-1 mask. window_posn &= window_size - 1; // Runs can't straddle the window wraparound. if ((window_posn + this_run) > window_size) { return(-1); // TODO: throw proper exception } switch (m_state.block_type) { case LzxConstants.BLOCKTYPE.VERBATIM: while (this_run > 0) { main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len, LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS, bitbuf); if (main_element < LzxConstants.NUM_CHARS) { // Literal: 0 to NUM_CHARS-1. window[window_posn++] = (byte)main_element; this_run--; } else { // Match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) main_element -= LzxConstants.NUM_CHARS; match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS; if (match_length == LzxConstants.NUM_PRIMARY_LENGTHS) { length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len, LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS, bitbuf); match_length += length_footer; } match_length += LzxConstants.MIN_MATCH; match_offset = main_element >> 3; if (match_offset > 2) { // Not repeated offset. if (match_offset != 3) { extra = extra_bits[match_offset]; verbatim_bits = (int)bitbuf.ReadBits((byte)extra); match_offset = (int)position_base[match_offset] - 2 + verbatim_bits; } else { match_offset = 1; } // Update repeated offset LRU queue. R2 = R1; R1 = R0; R0 = (uint)match_offset; } else if (match_offset == 0) { match_offset = (int)R0; } else if (match_offset == 1) { match_offset = (int)R1; R1 = R0; R0 = (uint)match_offset; } else // match_offset == 2 { match_offset = (int)R2; R2 = R0; R0 = (uint)match_offset; } rundest = (int)window_posn; this_run -= match_length; // Copy any wrapped around source data if (window_posn >= match_offset) { // No wrap runsrc = rundest - match_offset; } else { runsrc = rundest + ((int)window_size - match_offset); copy_length = match_offset - (int)window_posn; if (copy_length < match_length) { match_length -= copy_length; window_posn += (uint)copy_length; while (copy_length-- > 0) { window[rundest++] = window[runsrc++]; } runsrc = 0; } } window_posn += (uint)match_length; // Copy match data - no worries about destination wraps while (match_length-- > 0) { window[rundest++] = window[runsrc++]; } } } break; case LzxConstants.BLOCKTYPE.ALIGNED: while (this_run > 0) { main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len, LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS, bitbuf); if (main_element < LzxConstants.NUM_CHARS) { // Literal 0 to NUM_CHARS-1 window[window_posn++] = (byte)main_element; this_run -= 1; } else { // Match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) main_element -= LzxConstants.NUM_CHARS; match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS; if (match_length == LzxConstants.NUM_PRIMARY_LENGTHS) { length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len, LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS, bitbuf); match_length += length_footer; } match_length += LzxConstants.MIN_MATCH; match_offset = main_element >> 3; if (match_offset > 2) { // Not repeated offset. extra = extra_bits[match_offset]; match_offset = (int)position_base[match_offset] - 2; if (extra > 3) { // Verbatim and aligned bits. extra -= 3; verbatim_bits = (int)bitbuf.ReadBits((byte)extra); match_offset += (verbatim_bits << 3); aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len, LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS, bitbuf); match_offset += aligned_bits; } else if (extra == 3) { // Aligned bits only. aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len, LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS, bitbuf); match_offset += aligned_bits; } else if (extra > 0) // extra==1, extra==2 { // Verbatim bits only. verbatim_bits = (int)bitbuf.ReadBits((byte)extra); match_offset += verbatim_bits; } else // extra == 0 { // ??? match_offset = 1; } // Update repeated offset LRU queue. R2 = R1; R1 = R0; R0 = (uint)match_offset; } else if (match_offset == 0) { match_offset = (int)R0; } else if (match_offset == 1) { match_offset = (int)R1; R1 = R0; R0 = (uint)match_offset; } else // match_offset == 2 { match_offset = (int)R2; R2 = R0; R0 = (uint)match_offset; } rundest = (int)window_posn; this_run -= match_length; // Copy any wrapped around source data if (window_posn >= match_offset) { // No wrap runsrc = rundest - match_offset; } else { runsrc = rundest + ((int)window_size - match_offset); copy_length = match_offset - (int)window_posn; if (copy_length < match_length) { match_length -= copy_length; window_posn += (uint)copy_length; while (copy_length-- > 0) { window[rundest++] = window[runsrc++]; } runsrc = 0; } } window_posn += (uint)match_length; // Copy match data - no worries about destination wraps. while (match_length-- > 0) { window[rundest++] = window[runsrc++]; } } } break; case LzxConstants.BLOCKTYPE.UNCOMPRESSED: if ((inData.Position + this_run) > endpos) { return(-1); // TODO: Throw proper exception } byte[] temp_buffer = new byte[this_run]; inData.Read(temp_buffer, 0, this_run); temp_buffer.CopyTo(window, (int)window_posn); window_posn += (uint)this_run; break; default: return(-1); // TODO: Throw proper exception } } } if (togo != 0) { return(-1); // TODO: Throw proper exception } int start_window_pos = (int)window_posn; if (start_window_pos == 0) { start_window_pos = (int)window_size; } start_window_pos -= outLen; outData.Write(window, start_window_pos, outLen); m_state.window_posn = window_posn; m_state.R0 = R0; m_state.R1 = R1; m_state.R2 = R2; // TODO: Finish intel E8 decoding. // Intel E8 decoding. if ((m_state.frames_read++ < 32768) && m_state.intel_filesize != 0) { if (outLen <= 6 || m_state.intel_started == 0) { m_state.intel_curpos += outLen; } else { int dataend = outLen - 10; uint curpos = (uint)m_state.intel_curpos; m_state.intel_curpos = (int)curpos + outLen; while (outData.Position < dataend) { if (outData.ReadByte() != 0xE8) { curpos++; continue; } } } return(-1); } return(0); }
// TODO throw exceptions instead of returns private void ReadLengths(byte[] lens, uint first, uint last, BitBuffer bitbuf) { uint x, y; int z; // hufftbl pointer here? for(x = 0; x < 20; x++) { y = bitbuf.ReadBits(4); m_state.PRETREE_len[x] = (byte)y; } MakeDecodeTable(LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS, m_state.PRETREE_len, m_state.PRETREE_table); for(x = first; x < last;) { z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len, LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS, bitbuf); if(z == 17) { y = bitbuf.ReadBits(4); y += 4; while(y-- != 0) lens[x++] = 0; } else if(z == 18) { y = bitbuf.ReadBits(5); y += 20; while(y-- != 0) lens[x++] = 0; } else if(z == 19) { y = bitbuf.ReadBits(1); y += 4; z = (int)ReadHuffSym(m_state.PRETREE_table, m_state.PRETREE_len, LzxConstants.PRETREE_MAXSYMBOLS, LzxConstants.PRETREE_TABLEBITS, bitbuf); z = lens[x] - z; if(z < 0) z += 17; while(y-- != 0) lens[x++] = (byte)z; } else { z = lens[x] - z; if(z < 0) z += 17; lens[x++] = (byte)z; } } }
//TODO compression: specify min value, max value and precision (as bit count or float or 1/x) //utility methods for min value = 0 //should the min, max be inclusive or exclusive? maybe both variants /// <summary> /// Writes the specified Vector3 into the buffer as 3 floats. /// </summary> public static void Write(this BitBuffer buffer, Vector3 value) { buffer.Write(value.x); buffer.Write(value.y); buffer.Write(value.z); }
private uint ReadHuffSym(ushort[] table, byte[] lengths, uint nsyms, uint nbits, BitBuffer bitbuf) { uint i, j; bitbuf.EnsureBits(16); if ((i = table[bitbuf.PeekBits((byte)nbits)]) >= nsyms) { j = (uint)(1 << (int)((sizeof(uint) * 8) - nbits)); do { j >>= 1; i <<= 1; i |= (bitbuf.GetBuffer() & j) != 0 ? (uint)1 : 0; if (j == 0) { return(0); // TODO throw proper exception } } while((i = table[i]) >= nsyms); } j = lengths[i]; bitbuf.RemoveBits((byte)j); return(i); }
/// <summary> /// Reads a Vector3 from the buffer from 3 floats. /// </summary> public static Vector3 ReadVector3(this BitBuffer buffer) { return(new Vector3(buffer.ReadFloat(), buffer.ReadFloat(), buffer.ReadFloat())); }
public override void OnDeserialize(BitBuffer d) { base.OnDeserialize(d); this._levelIndex = d.ReadByte(); }
/// <summary> /// Writes the timestamp as a 24-bit long value encoded using the GlobalBaseTimestamp. /// </summary> public static void WriteTimestamp(this BitBuffer buffer, long timestamp) { buffer.WriteBits((ulong)(timestamp - NetworkUtils.GlobalBaseTimestamp), 24); }
public void Serialize(BitBuffer buffer) { buffer.EnqueueInt(playerId); }
public void PutBytes(BitBuffer bitBuffer) { bitBuffer.PutByte((byte)_id); bitBuffer.PutByte((byte)GetInputType()); PutExtraBytes(bitBuffer); }
public IBitBufferSerializable Deserialize(BitBuffer buffer) { playerId = buffer.DequeueInt(); return(this); }
protected abstract void PutExtraBytes(BitBuffer bitBuffer);
protected override void PutExtraBytes(BitBuffer bitBuffer) { bitBuffer.PutByte((byte)_type); _target.PutBytes(bitBuffer); }
public void Deserialize(BitBuffer bitBuffer) { Message = bitBuffer.ReadString(); Sender = bitBuffer.ReadUShort(); }
public override void Save(BitBuffer bitBuffer) { base.Save(bitBuffer); bitBuffer.PutInt(playerId); }
public void Serialize(BitBuffer bitBuffer) { bitBuffer.AddUShort(10); }
public static void Execute(IServerHandler handler, BitBuffer buffer, ushort commandCount) { for (int i = 0; i < commandCount; i++) { var commandId = buffer.ReadUShort(); switch (commandId) { case 0: { Logger.I.Log("ServerCommandExecutor", "Executing ClientCreateIceCommand"); var c = new ClientCreateIceCommand(); c.Deserialize(buffer); handler.HandleCreateIceCommand(ref c); break; } case 1: { Logger.I.Log("ServerCommandExecutor", "Executing ClientBeeMoveCommand"); var c = new ClientBeeMoveCommand(); c.Deserialize(buffer); handler.HandleBeeMoveCommand(ref c); break; } case 2: { Logger.I.Log("ServerCommandExecutor", "Executing ClientChatMessageCommand"); var c = new ClientChatMessageCommand(); c.Deserialize(buffer); handler.HandleChatMessageCommand(ref c); break; } case 3: { Logger.I.Log("ServerCommandExecutor", "Executing ClientCreateBeeCommand"); var c = new ClientCreateBeeCommand(); c.Deserialize(buffer); handler.HandleCreateBeeCommand(ref c); break; } case 4: { Logger.I.Log("ServerCommandExecutor", "Executing ClientRequestCharacterCommand"); var c = new ClientRequestCharacterCommand(); c.Deserialize(buffer); handler.HandleRequestCharacterCommand(ref c); break; } case 5: { Logger.I.Log("ServerCommandExecutor", "Executing ClientSetTickrateCommand"); var c = new ClientSetTickrateCommand(); c.Deserialize(buffer); handler.HandleSetTickrateCommand(ref c); break; } case 6: { Logger.I.Log("ServerCommandExecutor", "Executing ClientTestCommand"); var c = new ClientTestCommand(); c.Deserialize(buffer); handler.HandleTestCommand(ref c); break; } } } }
public void Deserialize(BitBuffer bitBuffer) { }
public int Decompress(Stream inData, int inLen, Stream outData, int outLen) { BitBuffer bitbuf = new BitBuffer(inData); long startpos = inData.Position; long endpos = inData.Position + inLen; byte[] window = m_state.window; uint window_posn = m_state.window_posn; uint window_size = m_state.window_size; uint R0 = m_state.R0; uint R1 = m_state.R1; uint R2 = m_state.R2; uint i, j; int togo = outLen, this_run, main_element, match_length, match_offset, length_footer, extra, verbatim_bits; int rundest, runsrc, copy_length, aligned_bits; bitbuf.InitBitStream(); /* read header if necessary */ if(m_state.header_read == 0) { uint intel = bitbuf.ReadBits(1); if(intel != 0) { // read the filesize i = bitbuf.ReadBits(16); j = bitbuf.ReadBits(16); m_state.intel_filesize = (int)((i << 16) | j); } m_state.header_read = 1; } /* main decoding loop */ while(togo > 0) { /* last block finished, new block expected */ if(m_state.block_remaining == 0) { // TODO may screw something up here if(m_state.block_type == LzxConstants.BLOCKTYPE.UNCOMPRESSED) { if((m_state.block_length & 1) == 1) inData.ReadByte(); /* realign bitstream to word */ bitbuf.InitBitStream(); } m_state.block_type = (LzxConstants.BLOCKTYPE)bitbuf.ReadBits(3);; i = bitbuf.ReadBits(16); j = bitbuf.ReadBits(8); m_state.block_remaining = m_state.block_length = (uint)((i << 8) | j); switch(m_state.block_type) { case LzxConstants.BLOCKTYPE.ALIGNED: for(i = 0, j = 0; i < 8; i++) { j = bitbuf.ReadBits(3); m_state.ALIGNED_len[i] = (byte)j; } MakeDecodeTable(LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS, m_state.ALIGNED_len, m_state.ALIGNED_table); /* rest of aligned header is same as verbatim */ goto case LzxConstants.BLOCKTYPE.VERBATIM; case LzxConstants.BLOCKTYPE.VERBATIM: ReadLengths(m_state.MAINTREE_len, 0, 256, bitbuf); ReadLengths(m_state.MAINTREE_len, 256, m_state.main_elements, bitbuf); MakeDecodeTable(LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS, m_state.MAINTREE_len, m_state.MAINTREE_table); if(m_state.MAINTREE_len[0xE8] != 0) m_state.intel_started = 1; ReadLengths(m_state.LENGTH_len, 0, LzxConstants.NUM_SECONDARY_LENGTHS, bitbuf); MakeDecodeTable(LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS, m_state.LENGTH_len, m_state.LENGTH_table); break; case LzxConstants.BLOCKTYPE.UNCOMPRESSED: m_state.intel_started = 1; /* because we can't assume otherwise */ bitbuf.EnsureBits(16); /* get up to 16 pad bits into the buffer */ if(bitbuf.GetBitsLeft() > 16) inData.Seek(-2, SeekOrigin.Current); /* and align the bitstream! */ byte hi, mh, ml, lo; lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte(); R0 = (uint)(lo | ml << 8 | mh << 16 | hi << 24); lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte(); R1 = (uint)(lo | ml << 8 | mh << 16 | hi << 24); lo = (byte)inData.ReadByte(); ml = (byte)inData.ReadByte(); mh = (byte)inData.ReadByte(); hi = (byte)inData.ReadByte(); R2 = (uint)(lo | ml << 8 | mh << 16 | hi << 24); break; default: return -1; // TODO throw proper exception } } /* buffer exhaustion check */ if(inData.Position > (startpos + inLen)) { /* it's possible to have a file where the next run is less than * 16 bits in size. In this case, the READ_HUFFSYM() macro used * in building the tables will exhaust the buffer, so we should * allow for this, but not allow those accidentally read bits to * be used (so we check that there are at least 16 bits * remaining - in this boundary case they aren't really part of * the compressed data) */ Console.WriteLine("WTF"); if(inData.Position > (startpos+inLen+2) || bitbuf.GetBitsLeft() < 16) return -1; //TODO throw proper exception } while((this_run = (int)m_state.block_remaining) > 0 && togo > 0) { if(this_run > togo) this_run = togo; togo -= this_run; m_state.block_remaining -= (uint)this_run; /* apply 2^x-1 mask */ window_posn &= window_size - 1; /* runs can't straddle the window wraparound */ if((window_posn + this_run) > window_size) return -1; //TODO throw proper exception switch(m_state.block_type) { case LzxConstants.BLOCKTYPE.VERBATIM: while(this_run > 0) { main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len, LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS, bitbuf); if(main_element < LzxConstants.NUM_CHARS) { /* literal: 0 to NUM_CHARS-1 */ window[window_posn++] = (byte)main_element; this_run--; } else { /* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */ main_element -= LzxConstants.NUM_CHARS; match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS; if(match_length == LzxConstants.NUM_PRIMARY_LENGTHS) { length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len, LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS, bitbuf); match_length += length_footer; } match_length += LzxConstants.MIN_MATCH; match_offset = main_element >> 3; if(match_offset > 2) { /* not repeated offset */ if(match_offset != 3) { extra = extra_bits[match_offset]; verbatim_bits = (int)bitbuf.ReadBits((byte)extra); match_offset = (int)position_base[match_offset] - 2 + verbatim_bits; } else { match_offset = 1; } /* update repeated offset LRU queue */ R2 = R1; R1 = R0; R0 = (uint)match_offset; } else if(match_offset == 0) { match_offset = (int)R0; } else if(match_offset == 1) { match_offset = (int)R1; R1 = R0; R0 = (uint)match_offset; } else /* match_offset == 2 */ { match_offset = (int)R2; R2 = R0; R0 = (uint)match_offset; } rundest = (int)window_posn; this_run -= match_length; /* copy any wrapped around source data */ if(window_posn >= match_offset) { /* no wrap */ runsrc = rundest - match_offset; } else { runsrc = rundest + ((int)window_size - match_offset); copy_length = match_offset - (int)window_posn; if(copy_length < match_length) { match_length -= copy_length; window_posn += (uint)copy_length; while(copy_length-- > 0) window[rundest++] = window[runsrc++]; runsrc = 0; } } window_posn += (uint)match_length; /* copy match data - no worries about destination wraps */ while(match_length-- > 0) window[rundest++] = window[runsrc++]; } } break; case LzxConstants.BLOCKTYPE.ALIGNED: while(this_run > 0) { main_element = (int)ReadHuffSym(m_state.MAINTREE_table, m_state.MAINTREE_len, LzxConstants.MAINTREE_MAXSYMBOLS, LzxConstants.MAINTREE_TABLEBITS, bitbuf); if(main_element < LzxConstants.NUM_CHARS) { /* literal 0 to NUM_CHARS-1 */ window[window_posn++] = (byte)main_element; this_run--; } else { /* match: NUM_CHARS + ((slot<<3) | length_header (3 bits)) */ main_element -= LzxConstants.NUM_CHARS; match_length = main_element & LzxConstants.NUM_PRIMARY_LENGTHS; if(match_length == LzxConstants.NUM_PRIMARY_LENGTHS) { length_footer = (int)ReadHuffSym(m_state.LENGTH_table, m_state.LENGTH_len, LzxConstants.LENGTH_MAXSYMBOLS, LzxConstants.LENGTH_TABLEBITS, bitbuf); match_length += length_footer; } match_length += LzxConstants.MIN_MATCH; match_offset = main_element >> 3; if(match_offset > 2) { /* not repeated offset */ extra = extra_bits[match_offset]; match_offset = (int)position_base[match_offset] - 2; if(extra > 3) { /* verbatim and aligned bits */ extra -= 3; verbatim_bits = (int)bitbuf.ReadBits((byte)extra); match_offset += (verbatim_bits << 3); aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len, LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS, bitbuf); match_offset += aligned_bits; } else if(extra == 3) { /* aligned bits only */ aligned_bits = (int)ReadHuffSym(m_state.ALIGNED_table, m_state.ALIGNED_len, LzxConstants.ALIGNED_MAXSYMBOLS, LzxConstants.ALIGNED_TABLEBITS, bitbuf); match_offset += aligned_bits; } else if (extra > 0) /* extra==1, extra==2 */ { /* verbatim bits only */ verbatim_bits = (int)bitbuf.ReadBits((byte)extra); match_offset += verbatim_bits; } else /* extra == 0 */ { /* ??? */ match_offset = 1; } /* update repeated offset LRU queue */ R2 = R1; R1 = R0; R0 = (uint)match_offset; } else if( match_offset == 0) { match_offset = (int)R0; } else if(match_offset == 1) { match_offset = (int)R1; R1 = R0; R0 = (uint)match_offset; } else /* match_offset == 2 */ { match_offset = (int)R2; R2 = R0; R0 = (uint)match_offset; } rundest = (int)window_posn; this_run -= match_length; /* copy any wrapped around source data */ if(window_posn >= match_offset) { /* no wrap */ runsrc = rundest - match_offset; } else { runsrc = rundest + ((int)window_size - match_offset); copy_length = match_offset - (int)window_posn; if(copy_length < match_length) { match_length -= copy_length; window_posn += (uint)copy_length; while(copy_length-- > 0) window[rundest++] = window[runsrc++]; runsrc = 0; } } window_posn += (uint)match_length; /* copy match data - no worries about destination wraps */ while(match_length-- > 0) window[rundest++] = window[runsrc++]; } } break; case LzxConstants.BLOCKTYPE.UNCOMPRESSED: if((inData.Position + this_run) > endpos) return -1; //TODO throw proper exception byte[] temp_buffer = new byte[this_run]; inData.Read(temp_buffer, 0, this_run); temp_buffer.CopyTo(window, window_posn); window_posn += (uint)this_run; break; default: return -1; //TODO throw proper exception } } } if(togo != 0) return -1; //TODO throw proper exception int start_window_pos = (int)window_posn; if(start_window_pos == 0) start_window_pos = (int)window_size; start_window_pos -= outLen; outData.Write(window, start_window_pos, outLen); m_state.window_posn = window_posn; m_state.R0 = R0; m_state.R1 = R1; m_state.R2 = R2; // TODO finish intel E8 decoding /* intel E8 decoding */ if((m_state.frames_read++ < 32768) && m_state.intel_filesize != 0) { if(outLen <= 6 || m_state.intel_started == 0) { m_state.intel_curpos += outLen; } else { int dataend = outLen - 10; uint curpos = (uint)m_state.intel_curpos; uint filesize = (uint)m_state.intel_filesize; uint abs_off, rel_off; m_state.intel_curpos = (int)curpos + outLen; while(outData.Position < dataend) { if(outData.ReadByte() != 0xE8) { curpos++; continue; } //abs_off = } } return -1; } return 0; }
public ConnectionAction(BitBuffer buffer) { }
private uint ReadHuffSym(ushort[] table, byte[] lengths, uint nsyms, uint nbits, BitBuffer bitbuf) { uint i, j; bitbuf.EnsureBits(16); if((i = table[bitbuf.PeekBits((byte)nbits)]) >= nsyms) { j = (uint)(1 << (int)((sizeof(uint)*8) - nbits)); do { j >>= 1; i <<= 1; i |= (bitbuf.GetBuffer() & j) != 0 ? (uint)1 : 0; if(j == 0) return 0; // TODO throw proper exception } while((i = table[i]) >= nsyms); } j = lengths[i]; bitbuf.RemoveBits((byte)j); return i; }
public override void Serialize(BitBuffer buffer) { }