/// <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()) { //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)) { //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); ByteBuffer bb = new ByteBuffer(NewBufferReceiver); HazelTest.Object ObjectReceived = HazelTest.Object.GetRootAsObject(bb); if (Server.DEBUG) { Console.WriteLine("RECEIVED DATA: "); Console.WriteLine("IDObject RECEIVED: " + ObjectReceived.ID); Console.WriteLine("UID RECEIVED; " + ObjectReceived.Owner); Console.WriteLine("isKinematic: " + ObjectReceived.IsKine); Console.WriteLine("POS RECEIVED: " + ObjectReceived.Pos.X + ", " + ObjectReceived.Pos.Y + ", " + ObjectReceived.Pos.Z); Console.WriteLine("ROT RECEIVED: " + ObjectReceived.Rot.X + ", " + ObjectReceived.Rot.Y + ", " + ObjectReceived.Rot.Z + ", " + ObjectReceived.Rot.W); } //var ReceiveMessageFromGameObjectBuffer = new ReceiveMessageFromGameObject(); //NOT USED! sbyte TypeBuffer = ObjectReceived.Type; //Check if ObjectReceived.ID <> 0 if (ObjectReceived.ID != 0) { var MVobject = new Objects { ID = ObjectReceived.ID, isKine = ObjectReceived.IsKine, PosX = ObjectReceived.Pos.X, PosY = ObjectReceived.Pos.Y, PosZ = ObjectReceived.Pos.Z, RotX = ObjectReceived.Rot.X, RotY = ObjectReceived.Rot.Y, RotZ = ObjectReceived.Rot.Z, RotW = ObjectReceived.Rot.W, UID = ObjectReceived.ID.ToString() + ";" + ObjectReceived.Owner }; if ((byte)PacketId.OBJECT_SPAWN == ObjectReceived.Type) { // Create unique index in Name field col.EnsureIndex(x => x.UID, true); // Insert new customer document (Id will be auto-incremented) col.Insert(MVobject); Console.WriteLine("OBJECT SPAWN SAVED"); } else if ((byte)PacketId.OBJECT_MOVE == ObjectReceived.Type) { //Check if record exist if (col.Count(Query.EQ("UID", ObjectReceived.ID.ToString() + ";" + ObjectReceived.Owner)) == 1) { col.Update(MVobject); //Save data to Objects DB Console.WriteLine("UPDATE OBJECT IN DB"); } else { col.Insert(MVobject); //Save data to Objects DB Console.WriteLine("INSERT OBJECT IN DB"); } Console.WriteLine("OBJECT MOVE"); } else if ((byte)PacketId.OBJECT_UNSPAWN == ObjectReceived.Type) { if (col.Count(Query.EQ("UID", ObjectReceived.ID.ToString() + ";" + ObjectReceived.Owner)) == 1) { col.Delete(Query.EQ("UID", ObjectReceived.ID.ToString() + ";" + ObjectReceived.Owner)); //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 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)) { //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); ByteBuffer bb = new ByteBuffer(NewBufferReceiver); //Decoder FlatBuffer String UIDBuffer = String.Empty; if (STypeBuffer == 2) { HazelMessage.HMessage HMessageReceived = HazelMessage.HMessage.GetRootAsHMessage(bb); if ((sbyte)CommandType.LOGIN == HMessageReceived.Command) { //Cerca e restituisci il tutto foreach (var conn in Server.clients) { if (conn.Value == item.ClientConnected) //SENDTOSERVER { //TODO: Check here if user exist and password correct //Get users collection var col = db.GetCollection <Users>("users"); Console.WriteLine("COMMAND RECIEVED: " + HMessageReceived.Answer); //Parse HMessageReceived string[] words = HMessageReceived.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); } } } } } //Encode FlatBuffer //Create flatbuffer class FlatBufferBuilder fbb = new FlatBufferBuilder(1); StringOffset SOUIDBuffer = fbb.CreateString(UIDBuffer); HazelMessage.HMessage.StartHMessage(fbb); HazelMessage.HMessage.AddCommand(fbb, (sbyte)CommandType.LOGIN); HazelMessage.HMessage.AddAnswer(fbb, SOUIDBuffer); var offset = HazelMessage.HMessage.EndHMessage(fbb); HazelMessage.HMessage.FinishHMessageBuffer(fbb, offset); //Reply to Client 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] = (byte)SendType.SENDTOSERVER; item.ClientConnected.SendBytes(newArray, item.SOClientConnected); } Console.WriteLine("Send to: " + item.ClientConnected.EndPoint.ToString()); //HERE SEND TO ALL CLIENTS OBJECTS DB //TODO: Add code to send all clients //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) { //Create flatbuffer class FlatBufferBuilder fbb_object = new FlatBufferBuilder(1); StringOffset SOUIDBuffer_object = fbb_object.CreateString(o.UID.Split(';')[1] + ";" + o.UID.Split(';')[2]); HazelTest.Object.StartObject(fbb_object); HazelTest.Object.AddType(fbb_object, (sbyte)PacketId.OBJECT_MOVE); HazelTest.Object.AddOwner(fbb_object, SOUIDBuffer_object); HazelTest.Object.AddIsKine(fbb_object, o.isKine); HazelTest.Object.AddID(fbb_object, o.ID); HazelTest.Object.AddPos(fbb_object, Vec3.CreateVec3(fbb_object, o.PosX, o.PosY, o.PosZ)); HazelTest.Object.AddRot(fbb_object, Vec4.CreateVec4(fbb_object, o.RotX, o.RotY, o.RotZ, o.RotW)); var offset_object = HazelTest.Object.EndObject(fbb_object); HazelTest.Object.FinishObjectBuffer(fbb_object, offset_object); //SendMessage using (var ms = new MemoryStream(fbb_object.DataBuffer.Data, fbb_object.DataBuffer.Position, fbb_object.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] = (byte)SendType.SENDTOOTHER; item.ClientConnected.SendBytes(newArray, item.SOClientConnected); } Console.WriteLine("Send MOVE_OBJECT to: " + item.ClientConnected.EndPoint.ToString()); } } } } }
/// <summary> /// Receives the message. /// </summary> /// <param name="BufferReceiver">Buffer receiver.</param> private void ReceiveMessage(byte[] BufferReceiver) { //Remove first byte (type) //https://stackoverflow.com/questions/31550484/faster-code-to-remove-first-elements-from-byte-array byte STypeBuffer = BufferReceiver[0]; //This is NOT TypeBuffer ;-) byte[] NewBufferReceiver = new byte[BufferReceiver.Length - 1]; Array.Copy(BufferReceiver, 1, NewBufferReceiver, 0, NewBufferReceiver.Length); ByteBuffer bb = new ByteBuffer(NewBufferReceiver); if ((STypeBuffer == (byte)SendType.SENDTOALL) || (STypeBuffer == (byte)SendType.SENDTOOTHER)) { /* * if (!HazelTest.Object.)) * { * throw new Exception("Identifier test failed, you sure the identifier is identical to the generated schema's one?"); * } */ //Please see: https://stackoverflow.com/questions/748062/how-can-i-return-multiple-values-from-a-function-in-c HazelTest.Object ObjectReceived = HazelTest.Object.GetRootAsObject(bb); if (DEBUG) { Debug.Log("RECEIVED DATA : "); Debug.Log("IDObject RECEIVED : " + ObjectReceived.ID); Debug.Log("UID RECEIVED ; " + ObjectReceived.Owner); Debug.Log("isKinematc : " + ObjectReceived.IsKine); Debug.Log("POS RECEIVED: " + ObjectReceived.Pos.X + ", " + ObjectReceived.Pos.Y + ", " + ObjectReceived.Pos.Z); Debug.Log("ROT RECEIVED: " + ObjectReceived.Rot.X + ", " + ObjectReceived.Rot.Y + ", " + ObjectReceived.Rot.Z + ", " + ObjectReceived.Rot.W); } var ReceiveMessageFromGameObjectBuffer = new ReceiveMessageFromGameObject(); sbyte TypeBuffer = ObjectReceived.Type; if ((byte)PacketId.PLAYER_JOIN == ObjectReceived.Type) { Debug.Log("Add new Player!"); //Code for new Player //Spawn something? //Using Dispatcher? YES UnityMainThreadDispatcher.Instance().Enqueue(SpawnPlayerInMainThread(new Vector3(ObjectReceived.Pos.X, ObjectReceived.Pos.Y, ObjectReceived.Pos.Z), new Quaternion(ObjectReceived.Rot.X, ObjectReceived.Rot.Y, ObjectReceived.Rot.Z, ObjectReceived.Rot.W), ObjectReceived.Owner)); //PlayerSpawn SendMessage(SendType.SENDTOOTHER, PacketId.PLAYER_SPAWN, 0, this.UID, true, lastPosition, lastRotation); } else if ((byte)PacketId.OBJECT_MOVE == ObjectReceived.Type) { ReceiveMessageFromGameObjectBuffer.MessageType = ObjectReceived.Type; ReceiveMessageFromGameObjectBuffer.GameObjectID = ObjectReceived.ID; ReceiveMessageFromGameObjectBuffer.GameObjectPos = new Vector3(ObjectReceived.Pos.X, ObjectReceived.Pos.Y, ObjectReceived.Pos.Z); ReceiveMessageFromGameObjectBuffer.GameObjectRot = new Quaternion(ObjectReceived.Rot.X, ObjectReceived.Rot.Y, ObjectReceived.Rot.Z, ObjectReceived.Rot.W); if (OnReceiveMessageFromGameObjectUpdate != null) { OnReceiveMessageFromGameObjectUpdate(ReceiveMessageFromGameObjectBuffer); } } else if ((byte)PacketId.PLAYER_MOVE == ObjectReceived.Type) { ReceiveMessageFromGameObjectBuffer.MessageType = ObjectReceived.Type; ReceiveMessageFromGameObjectBuffer.GamePlayerObjectOwner = ObjectReceived.Owner; ReceiveMessageFromGameObjectBuffer.GameObjectPos = new Vector3(ObjectReceived.Pos.X, ObjectReceived.Pos.Y, ObjectReceived.Pos.Z); ReceiveMessageFromGameObjectBuffer.GameObjectRot = new Quaternion(ObjectReceived.Rot.X, ObjectReceived.Rot.Y, ObjectReceived.Rot.Z, ObjectReceived.Rot.W); if (OnReceiveMessageFromGameObjectUpdate != null) { OnReceiveMessageFromGameObjectUpdate(ReceiveMessageFromGameObjectBuffer); } } else if ((byte)PacketId.PLAYER_SPAWN == ObjectReceived.Type) { UnityMainThreadDispatcher.Instance().Enqueue(SpawnPlayerInMainThread(new Vector3(ObjectReceived.Pos.X, ObjectReceived.Pos.Y, ObjectReceived.Pos.Z), new Quaternion(ObjectReceived.Rot.X, ObjectReceived.Rot.Y, ObjectReceived.Rot.Z, ObjectReceived.Rot.W), ObjectReceived.Owner)); } } else if (STypeBuffer == (byte)SendType.SENDTOSERVER) { HazelMessage.HMessage HMessageReceived = HazelMessage.HMessage.GetRootAsHMessage(bb); if ((sbyte)CommandType.LOGIN == HMessageReceived.Command) { this.UID = HMessageReceived.Answer; UnityMainThreadDispatcher.Instance().Enqueue(SetUIDInMainThread(HMessageReceived.Answer)); Debug.Log("UID RECEIVED: " + HMessageReceived.Answer); //PLAYER_JOIN MESSAGE (SENDTOOTHER) SendMessage(SendType.SENDTOOTHER, PacketId.PLAYER_JOIN, 0, this.UID, true, lastPosition, lastRotation); } else if ((sbyte)CommandType.DISCONNECTEDCLIENT == HMessageReceived.Command) { //Debug Disconnected UID Debug.Log("UID RECEIVED and TO DESTROY: " + HMessageReceived.Answer); var DisconnectedClientToDestroyPlayerGameObjectBuffer = new DisconnectedClientToDestroyPlayerGameObject(); DisconnectedClientToDestroyPlayerGameObjectBuffer.PlayerGameObjectUID = HMessageReceived.Answer; if (OnDisconnectedClientUpdate != null) { OnDisconnectedClientUpdate(DisconnectedClientToDestroyPlayerGameObjectBuffer); } } } }
/// <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 STypeBuffer = args.Bytes[0]; //This is NOT TypeBuffer ;-) byte[] NewBufferReceiver = new byte[args.Bytes.Length - 1]; Array.Copy(args.Bytes, 1, NewBufferReceiver, 0, NewBufferReceiver.Length); ByteBuffer bb = new ByteBuffer(NewBufferReceiver); if ((STypeBuffer == (byte)SendType.SENDTOALL) || (STypeBuffer == (byte)SendType.SENDTOOTHER)) { HazelTest.Object ObjectReceived = HazelTest.Object.GetRootAsObject(bb); if (DEBUG) { Console.WriteLine("RECEIVED DATA: "); Console.WriteLine("IDObject RECEIVED: " + ObjectReceived.ID); Console.WriteLine("UID RECEIVED; " + ObjectReceived.Owner); Console.WriteLine("isKinematic: " + ObjectReceived.IsKine); Console.WriteLine("POS RECEIVED: " + ObjectReceived.Pos.X + ", " + ObjectReceived.Pos.Y + ", " + ObjectReceived.Pos.Z); Console.WriteLine("ROT RECEIVED: " + ObjectReceived.Rot.X + ", " + ObjectReceived.Rot.Y + ", " + ObjectReceived.Rot.Z + ", " + ObjectReceived.Rot.W); } //var ReceiveMessageFromGameObjectBuffer = new ReceiveMessageFromGameObject(); //NOT USED! sbyte TypeBuffer = ObjectReceived.Type; if ((byte)PacketId.PLAYER_JOIN == ObjectReceived.Type) { 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); //TO DO: Using Reliable UDP?? } else if ((byte)PacketId.OBJECT_MOVE == ObjectReceived.Type) { Console.WriteLine("OBJECT MOVE"); } else if ((byte)PacketId.PLAYER_MOVE == ObjectReceived.Type) { Console.WriteLine("PLAYER MOVE"); } else if ((byte)PacketId.PLAYER_SPAWN == ObjectReceived.Type) { Console.WriteLine("PLAYER SPAWN"); } else if ((byte)PacketId.OBJECT_SPAWN == ObjectReceived.Type) { Console.WriteLine("OBJECT SPAWN"); //Rez Object Recieved RezObject(ObjectReceived.Owner.Split(';')[1], ObjectReceived.Owner.Split(';')[0], false); } else if ((byte)PacketId.OBJECT_UNSPAWN == ObjectReceived.Type) { Console.WriteLine("OBJECT UNSPAWN"); //De Rez Object Recieved DeRezObject(ObjectReceived.Owner.Split(';')[1], ObjectReceived.Owner.Split(';')[0], false, ObjectReceived.ID); } } else if (STypeBuffer == (byte)SendType.SENDTOSERVER) { HazelMessage.HMessage HMessageReceived = HazelMessage.HMessage.GetRootAsHMessage(bb); if ((sbyte)CommandType.LOGIN == HMessageReceived.Command) { if (HMessageReceived.Answer != String.Empty) { UID = HMessageReceived.Answer; //Set UID for Your Avatar ME //UnityMainThreadDispatcher.Instance().Enqueue(SetUIDInMainThread(HMessageReceived.Answer)); Console.WriteLine("UID RECEIVED: " + HMessageReceived.Answer); //PLAYER_JOIN MESSAGE (SENDTOOTHER) SendMessage(SendType.SENDTOOTHER, PacketId.PLAYER_JOIN, 0, UID + ";" + AvatarName, true, lastPosition, lastRotation); //TO DO: Using Reliable UDP?? } else { Console.WriteLine("UID RECEIVED is EMPTY (NOT VALID PASSWORD): " + HMessageReceived.Answer); //Disconnect if (connection != null) { Console.WriteLine("DisConnecting from: " + connection.EndPoint.ToString()); connection.Close(); } } } else if ((sbyte)CommandType.DISCONNECTEDCLIENT == HMessageReceived.Command) { //Debug Disconnected UID Console.WriteLine("UID RECEIVED and TO DESTROY: " + HMessageReceived.Answer); } } args.Recycle(); }