Esempio n. 1
0
        public static Vector3 ReadVector3(this BitBuffer buffer, BoundedRange[] range)
        {
            var compressed = new CompressedVector3(
                buffer.ReadUInt(),
                buffer.ReadUInt(),
                buffer.ReadUInt());

            return(BoundedRange.Decompress(compressed, range));
        }
Esempio n. 2
0
        /// <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!");
                            }
                        }
                    }
                }
            }
        }
Esempio n. 3
0
        /// <summary>
        /// Sends the message.
        /// </summary>
        /// <param name="SType">ST ype.</param>
        /// <param name="Type">Type.</param>
        /// <param name="IDObject">IDO bject.</param>
        /// <param name="OwnerPlayer">Owner player.</param>
        /// <param name="isKine">If set to <c>true</c> is kine.</param>
        /// <param name="Pos">Position.</param>
        /// <param name="Rot">Rot.</param>
        public static void SendMessage(SendType SType, PacketId Type, ushort IDObject, string OwnerPlayer, bool isKine, Vector3 Pos, Quaternion Rot, Vector3 Vel, float InterTime)
        {
            byte TypeBuffer  = 0;
            byte STypeBuffer = 0;

            //Choose who to send message
            switch (SType)
            {
            case SendType.SENDTOALL:
                STypeBuffer = 0;
                break;

            case SendType.SENDTOOTHER:
                STypeBuffer = 1;
                break;

            case SendType.SENDTOSERVER:
                STypeBuffer = 2;
                break;

            default:
                STypeBuffer = 0;
                break;
            }
            //Console.WriteLine("SENDTYPE SENT: " + STypeBuffer); //DEBUG

            //Choose type message (TO Modify)
            switch (Type)
            {
            case PacketId.PLAYER_JOIN:
                TypeBuffer = 0;
                break;

            case PacketId.OBJECT_MOVE:
                TypeBuffer = 1;
                break;

            case PacketId.PLAYER_SPAWN:
                TypeBuffer = 2;
                break;

            case PacketId.OBJECT_SPAWN:
                TypeBuffer = 3;
                break;

            case PacketId.PLAYER_MOVE:
                TypeBuffer = 4;
                break;

            case PacketId.MESSAGE_SERVER:
                TypeBuffer = 5;
                break;

            default:
                TypeBuffer = 1;
                break;
            }
            //Debug.Log("TYPE SENT: " + TypeBuffer); //DEBUG

            //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(Pos.X, Pos.Y, Pos.Z);
            //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(Rot.X, Rot.Y, Rot.Z, Rot.W);
            //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 and compress Vector3 Velocity
            ushort compressedVelocityX = HalfPrecision.Compress(Vel.X);
            ushort compressedVelocityY = HalfPrecision.Compress(Vel.Y);
            ushort compressedVelocityZ = HalfPrecision.Compress(Vel.Z);

            //Add and compress Interporlation Time
            ushort compressedTimeInterpolation = HalfPrecision.Compress(InterTime);

            //Reset bit buffer for further reusing
            data.Clear();

            data.AddByte((byte)TypeBuffer)
            .AddString(OwnerPlayer)
            .AddBool(isKine)
            .AddUInt(IDObject)
            .AddUInt(compressedPosition.x)
            .AddUInt(compressedPosition.y)
            .AddUInt(compressedPosition.z)
            .AddByte(compressedRotation.m)
            .AddInt(compressedRotation.a)
            .AddInt(compressedRotation.b)
            .AddInt(compressedRotation.c)
            .AddUShort(compressedVelocityX)
            .AddUShort(compressedVelocityY)
            .AddUShort(compressedVelocityZ)
            .AddUShort(compressedTimeInterpolation);

            Console.WriteLine("BitBuffer: " + data.Length.ToString());

            //byte[] BufferNetStack = new byte[data.Length+1];
            //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
            byte[] BufferNetStack = new byte[data.Length];

            data.ToArray(BufferNetStack);

            //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] = STypeBuffer;
            connection.SendBytes(newArray, SendOption.None); //WARNING: ALL MESSAGES ARE NOT RELIABLE!

            if (DEBUG)
            {
                Console.WriteLine("Data Lenghts: " + newArray.Length.ToString());
                Console.WriteLine("Data Lenghts NetStack: " + BufferNetStack.Length.ToString());
                PrintByteArray(BufferNetStack);
                Console.WriteLine("Message sent!");
            }
        }
Esempio n. 4
0
        /// <summary>
        /// Sends the message.
        /// </summary>
        /// <param name="SType">SType.</param>
        /// <param name="Type">Type.</param>
        /// <param name="IDObject">IDObject.</param>
        /// <param name="OwnerPlayer">Owner player.</param>
        /// <param name="isKine">If set to <c>true</c> is kinematic.</param>
        /// <param name="Pos">Position.</param>
        /// <param name="Rot">Rotation.</param>
        public static void SendMessage(SendType SType, PacketId Type, ushort IDObject, string OwnerPlayer, bool isKine, Vector3 Pos, Quaternion Rot)
        {
            sbyte TypeBuffer  = 0;
            byte  STypeBuffer = 0;

            //Choose who to send message
            switch (SType)
            {
            case SendType.SENDTOALL:
                STypeBuffer = 0;
                break;

            case SendType.SENDTOOTHER:
                STypeBuffer = 1;
                break;

            case SendType.SENDTOSERVER:
                STypeBuffer = 2;
                break;

            default:
                STypeBuffer = 0;
                break;
            }
            //Console.WriteLine("SENDTYPE SENT: " + STypeBuffer); //DEBUG

            //Choose type message (TO Modify)
            switch (Type)
            {
            case PacketId.PLAYER_JOIN:
                TypeBuffer = 0;
                break;

            case PacketId.OBJECT_MOVE:
                TypeBuffer = 1;
                break;

            case PacketId.PLAYER_SPAWN:
                TypeBuffer = 2;
                break;

            case PacketId.OBJECT_SPAWN:
                TypeBuffer = 3;
                break;

            case PacketId.PLAYER_MOVE:
                TypeBuffer = 4;
                break;

            case PacketId.MESSAGE_SERVER:
                TypeBuffer = 5;
                break;

            default:
                TypeBuffer = 1;
                break;
            }
            //Debug.Log("TYPE SENT: " + TypeBuffer); //DEBUG

            // Create flatbuffer class
            FlatBufferBuilder fbb = new FlatBufferBuilder(1);

            StringOffset SOUIDBuffer = fbb.CreateString(OwnerPlayer);

            HazelTest.Object.StartObject(fbb);
            HazelTest.Object.AddType(fbb, TypeBuffer);
            HazelTest.Object.AddOwner(fbb, SOUIDBuffer);
            HazelTest.Object.AddIsKine(fbb, isKine);
            HazelTest.Object.AddID(fbb, IDObject);
            HazelTest.Object.AddPos(fbb, Vec3.CreateVec3(fbb, Pos.X, Pos.Y, Pos.Z));
            HazelTest.Object.AddRot(fbb, Vec4.CreateVec4(fbb, Rot.X, Rot.Y, Rot.Z, Rot.W));
            if (DEBUG)
            {
                Console.WriteLine("ID SENT: " + IDObject.ToString());
                Console.WriteLine("TYPE SENT: " + TypeBuffer.ToString());
                Console.WriteLine("UID SENT: " + OwnerPlayer);
                Console.WriteLine("IsKINE SENT: " + isKine.ToString());
                Console.WriteLine("POS SENT: " + Pos.X.ToString() + ", " + Pos.Y.ToString() + ", " + Pos.Z.ToString());
                Console.WriteLine("ROT SENT: " + Rot.X.ToString() + ", " + Rot.Y.ToString() + ", " + Rot.Z.ToString() + ", " + Rot.W.ToString());
            }
            var offset = HazelTest.Object.EndObject(fbb);

            HazelTest.Object.FinishObjectBuffer(fbb, offset);

            using (var ms = new MemoryStream(fbb.DataBuffer.Data, fbb.DataBuffer.Position, fbb.Offset))
            {
                //Add type!
                //https://stackoverflow.com/questions/5591329/c-sharp-how-to-add-byte-to-byte-array
                byte[] newArray = new byte[ms.ToArray().Length + 1];
                ms.ToArray().CopyTo(newArray, 1);
                newArray[0] = STypeBuffer;
                connection.SendBytes(newArray, SendOption.None); //WARNING: ALL MESSAGES ARE NOT RELIABLE!
                if (DEBUG)
                {
                    Console.WriteLine("Data Lenghts: " + newArray.Length.ToString());
                    Console.WriteLine("Message sent!");
                }
            }

            //Add example in NetStack
            // 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(Pos.X, Pos.Y, Pos.Z);
            //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(Rot.X, Rot.Y, Rot.Z, Rot.W);
            // 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);

            // Create a new bit buffer with 128 chunks
            BitBuffer data = new BitBuffer(128);

            data.AddByte((byte)TypeBuffer)
            .AddString(OwnerPlayer)
            .AddBool(isKine)
            .AddUInt(IDObject)
            .AddUInt(compressedPosition.x)
            .AddUInt(compressedPosition.y)
            .AddUInt(compressedPosition.z)
            .AddByte(compressedRotation.m)
            .AddInt(compressedRotation.a)
            .AddInt(compressedRotation.b)
            .AddInt(compressedRotation.c);

            Console.WriteLine("BitBuffer: " + data.Length.ToString());

            //byte[] BufferNetStack = new byte[data.Length+1];
            byte[] BufferNetStack = new byte[data.Length + 3];

            data.ToArray(BufferNetStack);

            if (DEBUG)
            {
                Console.WriteLine("Data Lenghts NetStack: " + BufferNetStack.Length.ToString());
                PrintByteArray(BufferNetStack);
                Console.WriteLine("Message sent!");
            }
        }
Esempio n. 5
0
        /// <summary>
        /// Datas the received.
        /// </summary>
        /// <param name="sender">Sender.</param>
        /// <param name="args">Arguments.</param>
        private static void DataReceived(object sender, DataReceivedEventArgs args)
        {
            Console.WriteLine("Received (" + string.Join <byte>(", ", args.Bytes) + ") from " + connection.EndPoint.ToString());
            //Decode parse received data
            //Remove first byte (type)
            //https://stackoverflow.com/questions/31550484/faster-code-to-remove-first-elements-from-byte-array
            byte SendTypeBuffer = args.Bytes[0];

            byte[] NewBufferReceiver = new byte[args.Bytes.Length - 1];
            Array.Copy(args.Bytes, 1, NewBufferReceiver, 0, NewBufferReceiver.Length);
            //Check SendType
            if ((SendTypeBuffer == (byte)SendType.SENDTOALL) || (SendTypeBuffer == (byte)SendType.SENDTOOTHER))
            {
                //Deserialize message using NetStack
                //Reset bit buffer for further reusing
                data.Clear();
                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);

                //Show DATA received
                if (DEBUG)
                {
                    Console.WriteLine("ID RECEIVED: " + IDObject.ToString());
                    Console.WriteLine("TYPE RECEIVED: " + TypeBuffer.ToString());
                    Console.WriteLine("UID RECEIVED: " + OwnerPlayer);
                    Console.WriteLine("IsKINE 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("VEL RECEIVED: " + VelocityReceived.X.ToString() + ", " + VelocityReceived.Y.ToString() + ", " + VelocityReceived.Z.ToString());
                    Console.WriteLine("INTERPOLATION TIME: " + InterpolationTime.ToString());
                }

                if ((byte)PacketId.PLAYER_JOIN == TypeBuffer)
                {
                    Console.WriteLine("Add new Player!");
                    //Code for new Player
                    //Spawn something? YES
                    //Using Dispatcher? NO
                    //PlayerSpawn
                    SendMessage(SendType.SENDTOOTHER, PacketId.PLAYER_SPAWN, 0, UID + ";" + AvatarName, true, lastPosition, lastRotation, VelocityDefaultZero, 0f);
                    //TODO: Using Reliable UDP??
                }
                else if ((byte)PacketId.OBJECT_MOVE == TypeBuffer)
                {
                    Console.WriteLine("OBJECT MOVE");
                }
                else if ((byte)PacketId.PLAYER_MOVE == TypeBuffer)
                {
                    Console.WriteLine("PLAYER MOVE");
                }
                else if ((byte)PacketId.PLAYER_SPAWN == TypeBuffer)
                {
                    Console.WriteLine("PLAYER SPAWN");
                }
                else if ((byte)PacketId.OBJECT_SPAWN == TypeBuffer)
                {
                    Console.WriteLine("OBJECT SPAWN");
                    //Rez Object Received
                    //RezObject(OwnerPlayer.Split(';')[1], OwnerPlayer.Split(';')[0], false);
                }
                else if ((byte)PacketId.OBJECT_UNSPAWN == TypeBuffer)
                {
                    Console.WriteLine("OBJECT UNSPAWN");
                    //De Rez Object Received
                    //DeRezObject(OwnerPlayer.Split(';')[1], OwnerPlayer.Split(';')[0], false, ObjectReceived.ID);
                }
            }
            else if (SendTypeBuffer == (byte)SendType.SENDTOSERVER)
            {
                //Deserialize message using NetStack
                //Reset bit buffer for further reusing
                data.Clear();
                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);

                if ((byte)CommandType.LOGIN == CommandTypeBuffer)
                {
                    if (Answer != String.Empty)
                    {
                        UID = Answer;
                        //Set UID for Your Avatar ME
                        //UnityMainThreadDispatcher.Instance().Enqueue(SetUIDInMainThread(HMessageReceived.Answer));
                        Console.WriteLine("UID RECEIVED: " + Answer);
                        //PLAYER_JOIN MESSAGE (SENDTOOTHER)
                        SendMessage(SendType.SENDTOOTHER, PacketId.PLAYER_JOIN, 0, UID + ";" + AvatarName, true, lastPosition, lastRotation, VelocityDefaultZero, 0f);
                        //TO DO: Using Reliable UDP??
                    }
                    else
                    {
                        Console.WriteLine("UID RECEIVED is EMPTY (NOT VALID PASSWORD): " + Answer);
                        //Disconnect
                        if (connection != null)
                        {
                            Console.WriteLine("DisConnecting from: " + connection.EndPoint.ToString());
                            connection.Close();
                        }
                    }
                }
                else if ((byte)CommandType.DISCONNECTEDCLIENT == CommandTypeBuffer)
                {
                    //Debug Disconnected UID
                    Console.WriteLine("UID RECEIVED and TO DESTROY: " + Answer);
                }
            }
            args.Recycle();
        }