Ejemplo n.º 1
0
        private async Task SendPump(CancellationToken cancellation)
        {
            using (var session = this.serializerSessionPool.GetSession())
            {
                while (!cancellation.IsCancellationRequested && await this.outgoingReader.WaitToReadAsync(cancellation))
                {
                    while (this.outgoingReader.TryRead(out var item))
                    {
                        WriteMessage(item, session);
                        if (item.Body is IDisposable disposable)
                        {
                            disposable.Dispose();
                        }

                        MessagePool.Return(item);

                        session.PartialReset();

                        var flushResult = await this.connection.Output.FlushAsync(cancellation);

                        if (flushResult.IsCanceled || flushResult.IsCompleted)
                        {
                            return;
                        }
                    }
                }
            }

            void WriteMessage(Message message, SerializerSession session)
            {
                var writer = new Writer <PipeWriter>(this.connection.Output, session);

                this.messageSerializer.Serialize(ref writer, message);
            }
        }
 private void GrabController_OnGrabNothing(ControllerGrabberData controller, IHandleGrabbing grabbedObj)
 {
     if (NetServices.isNetworked && NetServices.isClient)
     {
         // spawn!
         // or if networked, ask server for permission to spawn.
         // also give spawn request feedback, and success/fail feedback... but in separate feedback class.
         var msgReq = MessagePool.Get <SpawnGrabRequestMessage>();
         msgReq.isLeft     = controller.isLeft;
         msgReq.prefabType = GetSpawnType(controller.isLeft);
         ClientNetSender.instance.Send(msgReq, UnityEngine.Networking.QosType.ReliableSequenced);
         MessagePool.Return(msgReq);
     }
     else if (!NetServices.isNetworked)
     {
         // spawn! but beware: it might get out of sync with server... so upon reconnect, all those objects must be destroyed or re-synced! :( how the f**k to do that???
         var newObj  = PrefabManager.instance.Spawn(prefabType, controller.grabPointGO.transform.position, controller.grabPointGO.transform.rotation);
         var grabber = newObj.gameObject.GetComponent <IHandleGrabbing>();
         if (grabber != null)
         {
             controller.Grab(grabber);
         }
         Debug.Log("<color=#aa6000>Spawned non-synced object</color>", newObj.gameObject);
     }
 }
        public override void ClientHandleMessageFromServer(NetMessageType messageType, byte[] buffer)
        {
            // if message from server to clients
            if (messageType == NetMessageType.VRBodyUpdateS2C)
            {
                var msg          = MessagePool.Get <VRBodyUpdateS2CMessage>(buffer);
                var remotePlayer = NetServices.playerManager.players.GetValueOrDefault(msg.netId);
                if (remotePlayer != null)
                {
                    var bodyData = new VRBodyUpdateData()
                    {
                        position = msg.position, //RemotePos(senderPlayer.netId, msg.position),

                        headPosition = msg.headPosition,
                        headRotation = msg.headRotation,

                        leftHandPosition = msg.leftHandPosition,
                        leftHandRotation = msg.leftHandRotation,

                        rightHandPosition = msg.rightHandPosition,
                        rightHandRotation = msg.rightHandRotation
                    };
                    (remotePlayer as NetPlayerBase).GetComponent <VRBodyUpdateSync>().HandleUpdate(bodyData);
                }

                MessagePool.Return(msg);
            }
        }
        public override void ServerHandleMessageFromClient(NetMessageType messageType, byte[] buffer, short clientPlayerNetId)
        {
            // if message is from a client to server
            if (messageType == NetMessageType.VRBodyUpdateC2S)
            {
                var senderPlayer = NetServices.playerManager.players.GetValueOrDefault(clientPlayerNetId);
                if (senderPlayer != null)
                {
                    // deserialize message and have the player sync script handle it further
                    var msg      = MessagePool.Get <VRBodyUpdateC2SMessage>(buffer);
                    var bodyData = new VRBodyUpdateData()
                    {
                        position = msg.position, //ServerPos(senderPlayer.netId, msg.position),

                        headPosition = msg.headPosition,
                        headRotation = msg.headRotation,

                        leftHandPosition = msg.leftHandPosition,
                        leftHandRotation = msg.leftHandRotation,

                        rightHandPosition = msg.rightHandPosition,
                        rightHandRotation = msg.rightHandRotation
                    };

                    // this smells like bad performance. but it keeps dependencies separate.
                    // perhaps instead of GetComponent<> it can be optimized via some local VRPlayerManager that handles references of VR components on all players.
                    // every new system which has dependencies on previous systems can use this paradigm: a manager with references to connect the dependency to the new system, for efficiency, without compromising the dependency.
                    // for now we use the shitty method below because there are bigger bottlenecks
                    (senderPlayer as NetPlayerBase).GetComponent <VRBodyUpdateSync>().HandleUpdate(bodyData);

                    MessagePool.Return(msg);
                }
            }
        }
        public override void ServerHandleMessageFromClient(NetMessageType messageType, byte[] buffer, short clientPlayerNetId)
        {
            switch (messageType)
            {
            case NetMessageType.Grab:
            {
                var msg    = MessagePool.Get <GrabMessage>(buffer);
                var player = NetServices.playerManager.GetPlayer(msg.netId);
                if (player != null)
                {
                    RigidbodySyncComponent rbc = RbSyncManager.instance.Get(msg.syncId);
                    if (rbc != null)
                    {
                        var grabSystem = player.gameObject.GetComponent <VRPlayerGrabSystem>();
                        var cgd        = grabSystem.GetControllerGrabberData(msg.leftHand);
                        cgd.Grab(rbc.GetComponent <IHandleGrabbing>());
                        rbc.StopUpdating(cgd.controller);

                        ServerNetSender.instance.SendToAll(msg, UnityEngine.Networking.QosType.ReliableSequenced, msg.netId);
                    }
                }
                MessagePool.Return(msg);
                break;
            }

            case NetMessageType.Throw:
            {
                var msg    = MessagePool.Get <ThrowMessage>(buffer);
                var player = NetServices.playerManager.GetPlayer(msg.netId);
                if (player != null)
                {
                    RigidbodySyncComponent rbc = RbSyncManager.instance.Get(msg.syncId);
                    if (rbc != null)
                    {
                        var grabSystem = player.gameObject.GetComponent <VRPlayerGrabSystem>();
                        var cgd        = grabSystem.GetControllerGrabberData(msg.leftHand);
                        cgd.Ungrab();
                        rbc.ContinueUpdating(cgd.controller);

                        var rb = rbc.rigidbody;
                        rb.position           = msg.position;
                        rb.rotation           = msg.rotation;
                        rb.velocity           = msg.velocity;
                        rb.maxAngularVelocity = Mathf.Max(rb.maxAngularVelocity, msg.angularVelocity.magnitude);
                        rb.angularVelocity    = msg.angularVelocity;

                        // send to clients now
                        ServerNetSender.instance.SendToAll(msg, UnityEngine.Networking.QosType.ReliableSequenced, msg.netId);
                    }
                }
                MessagePool.Return(msg);
                break;
            }
            }
        }
Ejemplo n.º 6
0
        private void HandlePlayerLocalStart(byte[] buffer)
        {
            var msg = MessagePool.Get <PlayerLocalStartMessage>(buffer);
            var id  = msg.netId;

            if (GetPlayer(id) != null)
            {
                Debug.LogError(this.ToString() + " HandlePlayerStart another player is already registered with net id == " + id.ToString());
                MessagePool.Return(msg);
                return;
            }

            //var serverOS = msg.serverOriginShift;
            //NetOriginShiftManager.instance.SetServerOriginShift(serverOS);

            // msg.position is serverpos. local player must know about serverOS before it can perform RemotePos
            //var pos = RemotePos(msg.position);
            var pos        = msg.position;
            var color      = msg.color;
            var playerType = msg.playerType;

            // do not use a pool for the local player, since there will only ever be one of those
            var localPlayer = PlayerTypeManager.instance.InstantiatePlayer <INetPlayer>(playerType, GameType.Local, pos);

            localPlayer.SetIsLocal();
            localPlayer.gameObject.name = GetPlayerName();
            // how to set color on player?
            //localPlayer.color = color;

            AddPlayer(localPlayer, id);

            // old code from old system = player rigidbodies were spawned and the rigidbody sync system was used to sync their wobble instead of the player messages. Required for impaling arrows in player's head
            //if (msg.headRbSyncId >= 0 && msg.bodyRbSyncId >= 0)
            //{
            //    localPlayer.SetupRigidbodies(msg.headRbSyncId, msg.bodyRbSyncId);
            //}

            Debug.Log("<color=#dd9922>" + this.ToString() + " HandlePlayerStart created local player" + "</color>" + " by id == " + localPlayer.netId.ToString() + " and name == " + localPlayer.gameObject.name);
            MessagePool.Return(msg);

            if (ConnectUIHandler.instance != null)
            {
                ConnectUIHandler.instance.Disable();
            }
        }
Ejemplo n.º 7
0
        // only used by debug shit
        private void HandleRigidbodySyncSpawn(byte[] buffer)
        {
            var msg     = MessagePool.Get <RigidbodySyncSpawnMessage>(buffer);
            var manager = ClientRbSyncManager.instance;

            if (manager.Has(msg.data.syncId))
            {
                Debug.LogWarning(this.ToString() + " already has a synced rigidbody by id == " + msg.data.syncId.ToString() + ", aborting creation of a new one");
                MessagePool.Return(msg);
                return;
            }

            var data = msg.data;

            // we don't use this for now
            //data.position = RemotePos(data.position);
            NewRigidbodySync(data);
            MessagePool.Return(msg);
        }
        public override void ServerHandleMessageFromClient(NetMessageType messageType, byte[] buffer, short clientPlayerNetId)
        {
            // WE ARE SERVER
            if (messageType == NetMessageType.SpawnGrabRequest)
            {
                var msg = MessagePool.Get <SpawnGrabRequestMessage>(buffer);
                // spawn on server, assign id and tell everyone to also spawn. and tell player to grab... maybe client should grab and then continue with a separate message for that?
                var player = NetServices.playerManager.GetPlayer(clientPlayerNetId);
                if (player != null)
                {
                    var isLeft          = msg.isLeft;
                    var spawnPrefabType = msg.prefabType;

                    // grab stuff
                    var grabSystem = player.gameObject.GetComponent <VRPlayerGrabSystem>();
                    var hand       = grabSystem.GetControllerGrabberData(isLeft);

                    // definitely spawn new object
                    var newObj = PrefabManager.instance.Spawn(spawnPrefabType, hand.grabPointGO.transform.position, hand.grabPointGO.transform.rotation);

                    // initialize new object with a cool new id
                    var rsc    = newObj.gameObject.GetComponent <RigidbodySyncComponent>();
                    var nextId = ServerRbSyncManager.instance.GetNextSyncId();
                    rsc.Initialize(nextId);
                    var grabber = newObj.gameObject.GetComponent <IHandleGrabbing>();
                    if (grabber != null)
                    {
                        hand.Grab(grabber);
                    }

                    // send response so the grab happens across the network
                    var responseMsg = MessagePool.Get <SpawnGrabResponseMessage>();
                    responseMsg.prefabType = msg.prefabType;
                    responseMsg.isLeft     = msg.isLeft;
                    responseMsg.syncId     = nextId;
                    responseMsg.playerId   = clientPlayerNetId;
                    // send to ALL incl. request client
                    ServerNetSender.instance.SendToAll(responseMsg, UnityEngine.Networking.QosType.ReliableSequenced);
                    MessagePool.Return(responseMsg);
                }
                MessagePool.Return(msg);
            }
        }
        public override void ClientHandleMessageFromServer(NetMessageType messageType, byte[] buffer)
        {
            if (messageType == NetMessageType.SpawnGrabResponse)
            {
                var msg = MessagePool.Get <SpawnGrabResponseMessage>(buffer);

                // if player not null, spawn the object and grab it.
                var player = NetServices.playerManager.GetPlayer(msg.playerId);
                if (player != null)
                {
                    var grabSystem = player.gameObject.GetComponent <VRPlayerGrabSystem>();
                    var hand       = grabSystem.GetControllerGrabberData(msg.isLeft);

                    RigidbodySyncComponent rsc;

                    // first, check if object already exists
                    rsc = ClientRbSyncManager.instance.Get(msg.syncId);
                    if (rsc == null)
                    {
                        // spawn obj and sync it
                        var newObj = PrefabManager.instance.Spawn(msg.prefabType, hand.grabPointGO.transform.position, hand.grabPointGO.transform.rotation);
                        rsc = newObj.gameObject.GetComponent <RigidbodySyncComponent>();
                        rsc.Initialize(msg.syncId);
                    }
                    else
                    {
                        if (rsc.prefabType != msg.prefabType)
                        {
                            Debug.LogError("[SpawnSystem] Error: the object " + rsc + " with id " + rsc.syncId + " already exists, but is not of the requested type " + msg.prefabType);
                        }
                    }

                    // grab it
                    var grabber = rsc.GetComponent <IHandleGrabbing>();
                    if (grabber != null)
                    {
                        hand.Grab(grabber);
                    }
                }
                MessagePool.Return(msg);
            }
        }
Ejemplo n.º 10
0
        private void HandlePlayerRemoteConnect(byte[] buffer)
        {
            var msg = MessagePool.Get <PlayerRemoteConnectMessage>(buffer);
            var id  = msg.netId;

            if (GetPlayer(id) != null)
            {
                Debug.LogError(this.ToString() + " HandlePlayerConnect another player is already registered with net id == " + id.ToString());
                MessagePool.Return(msg);
                return;
            }

            ////Debug.Log(this.ToString() + " HandlePlayerConnect create remote player by id == " + id.ToString() + ", name == " + msg.name.ToString() + ", at position == " + msg.position.ToString());

            var os = msg.originShift;

            // remote connect = a new player connected. his origin shift is startingPos on his start.
            //NetOriginShiftManager.instance.SetPlayerOriginShift(id, os);

            // if using origin shift, server position data must be calculated with server origin shift.
            //var pos = RemotePos(msg.position);
            var pos   = msg.position;
            var color = msg.color;
            var name  = msg.name;

            // use the pool for remotes, they are all the same
            var player = PlayerTypeManager.instance.InstantiatePlayer <INetPlayer>(msg.playerType, GameType.Remote, pos);

            //player.color = color;
            player.gameObject.name = name;

            AddPlayer(player, id);

            //if (msg.headRbSyncId >= 0 && msg.bodyRbSyncId >= 0)
            //{
            //    player.SetupRigidbodies(msg.headRbSyncId, msg.bodyRbSyncId);
            //}

            Debug.Log("<color=#dd9922>" + this.ToString() + " HandlePlayerConnect created remote player" + "</color>" + " by id == " + player.netId.ToString() + " and name == " + player.gameObject.name);
            MessagePool.Return(msg);
        }
Ejemplo n.º 11
0
        public override void OnConnect(int connectionId, NetworkError error)
        {
            if (error != NetworkError.Ok)
            {
                Debug.LogError("<color=red>" + this.ToString() + " OnConnect could not establish a connection to server" + "</color>" + ", error == " + error.ToString());
                return;
            }

            // if reconnect, send a reconnect message with the previous netId so the server reestablishes the same player as this client
            // {}
            // else {

            // Connection to server established, send a name message
            var nameMessage = MessagePool.Get <PlayerLocalConnectMessage>();

            nameMessage.name       = GetPlayerName();
            nameMessage.playerType = PlayerTypeManager.instance.GetCurrentPlayerType(); // PlayerType.Normal; // TODO: get player type choice?
            _network.Send(nameMessage, QosType.Reliable);
            MessagePool.Return(nameMessage);

            // }

            Debug.Log("<color=#339900>" + this.ToString() + " OnConnect. Connection Id == " + connectionId.ToString() + "</color>" + ", error == " + error.ToString());
        }
Ejemplo n.º 12
0
        private void HandlePlayerDisconnect(byte[] buffer)
        {
            var msg    = MessagePool.Get <PlayerDisconnectMessageDefault>(buffer);
            var player = GetPlayer <INetPlayer>(msg.netId);

            if (player == null)
            {
                Debug.LogError(this.ToString() + " HandlePlayerDisconnect received disconnect message for unknown player with net id == " + msg.netId.ToString());
                MessagePool.Return(msg);
                return;
            }

            Debug.Log(this.ToString() + " HandlePlayerDisconnect for player by netId == " + msg.netId.ToString() + ", player name == " + player.gameObject.name.ToString());

            //NetOriginShiftManager.instance.RemovePlayer(msg.netId);

            if (!RemovePlayer(msg.netId))
            {
                Debug.LogWarning(this.ToString() + " found player by id == " + msg.netId.ToString() + ", removal was unsuccessful");
            }

            PlayerTypeManager.instance.Return(player.gameObject);
            MessagePool.Return(msg);
        }
Ejemplo n.º 13
0
        private void HandleRigidbodySyncUpdate(byte[] buffer)
        {
            var msg     = MessagePool.Get <RigidbodySyncUpdateMessage>(buffer);
            var manager = ClientRbSyncManager.instance;
            var initial = msg.initial;
            var data    = msg.data;
            var count   = data.Count;

            for (int i = 0; i < count; i++)
            {
                var d = data[i];
                //d.position = RemotePos(d.position);
                var rb = manager.Get(d.syncId);
                if (rb == null)
                {
                    // if the client does not have the synced rigidbody, create if from the data received
                    rb = NewRigidbodySync(d);
                }

                rb.HandleUpdate(d, initial);
            }

            MessagePool.Return(msg);
        }
Ejemplo n.º 14
0
        public override void OnDisconnect(int connectionId, NetworkError error)
        {
            var player = GetPlayer <INetPlayer>(connectionId);

            if (player == null)
            {
                Debug.LogWarning(this.ToString() + " OnDisconnect received disconnect from unknown player with connection ID == " + connectionId.ToString());
                return;
            }

            Debug.Log(this.ToString() + " OnDisconnect. Removing player (" + player.ToString() + ") by net id == " + player.netId.ToString() + ". Connection  Id == " + connectionId.ToString() + ", error == " + error.ToString());

            // Remove disconnected players - before sending out message, to avoid sending to the leaver
            var netId = player.netId;

            RemovePlayer(player);
            PlayerTypeManager.instance.Return(player.gameObject);

            // inform all other clients of the leaver, except the one actually leaving (since he is already disconnected)
            var msg = MessagePool.Get <PlayerDisconnectMessageDefault>(netId);

            _network.SendToAll(msg, QosType.Reliable);
            MessagePool.Return(msg);
        }
Ejemplo n.º 15
0
        private void HandlePlayerLocalConnect(int connectionId, byte[] buffer)
        {
            var localConnectMsg = MessagePool.Get <PlayerLocalConnectMessage>(buffer);
            var name            = localConnectMsg.name;
            var playerType      = localConnectMsg.playerType;

            MessagePool.Return(localConnectMsg);

            var player = GetPlayer <INetPlayer>(connectionId);

            if (player != null)
            {
                Debug.LogWarning(this.ToString() + " HandlePlayerName another player is already registered with connection id == " + connectionId.ToString()
                                 + ", existing player name == " + player.gameObject.name + ", new player's desired name == " + name);
                return;
            }

            if (string.IsNullOrEmpty(name))
            {
                name = "Random Name"; // TODO: what to do about players with no name? (can it even happen?)
            }

            var netId = GetNextPlayerId();

            var pos = _startPositions[netId % _startPositions.Count].transform.position;

            // send a special 'start message' to the new player so that the local player prefab can be set up. also tells it about the server origin shift
            var startMsg = MessagePool.Get <PlayerLocalStartMessage>(netId);

            startMsg.position   = pos;
            startMsg.playerType = playerType;

            _network.Send(connectionId, startMsg, QosType.ReliableSequenced);
            MessagePool.Return(startMsg);

            // a new client has connected - inform all other clients of the new player. and don't send this to the new player.
            var connectMsg = MessagePool.Get <PlayerRemoteConnectMessage>(netId);

            connectMsg.position   = pos;
            connectMsg.name       = name;
            connectMsg.playerType = playerType;

            _network.SendToAll(connectMsg, QosType.Reliable, netId);

            // Inform the new player of all the existing client players (if there are any).
            if (_players.Count > 0)
            {
                var enumerator = _players.GetEnumerator();
                try
                {
                    while (enumerator.MoveNext()) // AddPlayer() adds the player at the end of the function, so don't worry.
                    {
                        // send to the new connecting player, but send a connect message containing details of all the other existing clients
                        var p = (INetPlayer)enumerator.Current.Value;
                        connectMsg.netId    = p.netId;
                        connectMsg.position = p.gameObject.transform.position; // position on the server. the client receiver will handle the trasformation using RemotePos(), though it needs the server OS which is why the start message is reliable sequenced.
                        //connectMsg.originShift = NetOriginShiftManager.instance.GetPlayerOriginShift(p.netId);
                        //connectMsg.color = p.color;
                        connectMsg.name = p.gameObject.name;
                        //connectMsg.playerType = p.playerType;
                        //connectMsg.headRbSyncId = p.headSync.syncId;
                        //connectMsg.bodyRbSyncId = p.bodySync.syncId;

                        _network.Send(connectionId, connectMsg, QosType.Reliable);
                    }
                }
                finally
                {
                    enumerator.Dispose();
                }
            }

            MessagePool.Return(connectMsg);

            // actually create and add the new player
            var newPlayer = PlayerTypeManager.instance.InstantiatePlayer <INetPlayer>(playerType, GameType.Server, pos);

            //newPlayer.color = color;
            newPlayer.gameObject.name = name;

            AddPlayer(newPlayer, connectionId, netId);

            Debug.Log(this.ToString() + " HandlePlayerName() - added new player by net id == " + netId.ToString() + " and name == " + name + " for connection id == " + connectionId.ToString());
        }