예제 #1
0
 void commClient_ObjectAttributeReceived(ObjectAttributePacket oap)
 {
     lock (MultiplayerUpdateQueue)
     {
         MultiplayerUpdateQueue.Add(oap);
     }
 }
예제 #2
0
        private void CatchUpClient(int id)
        {
            lock (gameObjects)
            {
                foreach (Gobject go in gameObjects.Values)
                {
                    //ObjectAddedPacket oap1 = new ObjectAddedPacket(-1, go.ID, go.type);
                    //commServer.SendPacket(oap1, id);

                    #region Send Attribute Updates to the client
                    if (go.hasAttributeChanged)
                    {
                        bool[]  bools  = null;
                        int[]   ints   = null;
                        float[] floats = null;
                        go.GetObjectAttributes(out bools, out ints, out floats);
                        ObjectAttributePacket oap = new ObjectAttributePacket(go.ID, bools, ints, floats);
                        commServer.SendPacket(oap, id);
                    }
                    #endregion

                    #region Send Object Updates to the client
                    ObjectUpdatePacket oup = new ObjectUpdatePacket(go.ID, go.type, go.BodyPosition(), go.BodyOrientation(), go.BodyVelocity());
                    commServer.SendPacket(oup, id);
                    #endregion
                }
            }
        }
예제 #3
0
 private void CallObjectAttributeReceived(ObjectAttributePacket oap)
 {
     if (ObjectAttributeReceived == null)
     {
         return;
     }
     ObjectAttributeReceived(oap);
 }
예제 #4
0
        /// <summary>
        /// the physics engine just integrated, so this is the newest information about "reality"
        /// now is the time for the server to send ObjectUpdatePackets to the client for objects that can move
        /// now is the time for the server to send ObjectAttributePackets to the client for objects whose attributes have changed
        /// </summary>
        void physicsManager_PostIntegrate()
        {
            if (isClient)
            {
            }
            else if (isServer)
            {
                if (commServer != null)
                {
                    lock (gameObjects)
                    {
                        foreach (Gobject go in gameObjects.Values)
                        {
                            #region Send Attribute Updates to the client
                            if (go.hasAttributeChanged)
                            {
                                bool[]  bools  = null;
                                int[]   ints   = null;
                                float[] floats = null;
                                go.GetObjectAttributes(out bools, out ints, out floats);
                                ObjectAttributePacket oap = new ObjectAttributePacket(go.ID, bools, ints, floats);
                                commServer.BroadcastPacket(oap);
                            }
                            #endregion

                            #region Send Object Updates to the client

                            if (go.isMoveable && go.IsActive)
                            {
                                go.UpdateCountdown--;
                                if (go.UpdateCountdown == 0 || assetManager.isObjectOwnedByAnyClient(go.ID))
                                {
                                    ObjectUpdatePacket oup = new ObjectUpdatePacket(go.ID, go.type, go.BodyPosition(), go.BodyOrientation(), go.BodyVelocity());
                                    commServer.BroadcastObjectUpdate(oup);
                                    go.UpdateCountdown = 10;
                                }
                            }
                            #endregion
                        }
                    }
                }
            }

            if (cameraManager != null)
            {
                if (UpdateCameraCallback == null)
                {
                    return;
                }
                cameraManager.Update();
                UpdateCamera();

                UpdateCameraCallback(cameraManager.currentCamera, cameraManager.ViewMatrix(), cameraManager.ProjectionMatrix());
            }
        }
예제 #5
0
 private void ProcessInputPacket(Packet packet)
 {
     if (packet is ClientInfoRequestPacket)
     {
         Trace.WriteLine("Received ClientInfoRequest");
         ClientInfoRequestPacket  cir = packet as ClientInfoRequestPacket;
         ClientInfoResponsePacket clientInfoResponse = new ClientInfoResponsePacket(sAlias);
         client.Send(clientInfoResponse);
         CallClientInfoRequestReceived(cir.ID);
     }
     else if (packet is ChatPacket)
     {
         ChatPacket cp = packet as ChatPacket;
         CallChatMessageReceived(new ChatMessage(cp.message, cp.player));
     }
     else if (packet is ObjectAddedPacket)
     {
         Trace.WriteLine("Received ObjectAdded");
         ObjectAddedPacket corp = packet as ObjectAddedPacket;
         CallObjectRequestResponseReceived(corp.Owner, corp.ID, corp.AssetName);
     }
     else if (packet is ObjectUpdatePacket)
     {
         ObjectUpdatePacket oup = packet as ObjectUpdatePacket;
         CallObjectUpdateReceived(oup.objectId, oup.assetName, oup.position, oup.orientation, oup.velocity);
     }
     else if (packet is ObjectActionPacket)
     {
         ObjectActionPacket oap = packet as ObjectActionPacket;
         CallObjectActionReceived(oap.objectId, oap.actionParameters);
     }
     else if (packet is ClientDisconnectPacket)
     {
         ClientDisconnectPacket cdp = packet as ClientDisconnectPacket;
         CallOtherClientDisconnectedFromServer(cdp.id);
     }
     else if (packet is ClientConnectedPacket)
     {
         ClientConnectedPacket ccp = packet as ClientConnectedPacket;
         CallOtherClientConnectedToServer(ccp.ID, ccp.Alias);
     }
     else if (packet is ObjectAttributePacket)
     {
         ObjectAttributePacket oap = packet as ObjectAttributePacket;
         CallObjectAttributeReceived(oap);
     }
     else if (packet is ObjectDeletedPacket)
     {
         Trace.WriteLine("Received ObjectDelete");
         ObjectDeletedPacket odp = packet as ObjectDeletedPacket;
         CallObjectDeleteReceived(odp);
     }
 }
예제 #6
0
        private void ProcessInputPacket(ClientPacketInfo cpi)
        {
            if (cpi == null)
            {
                return;
            }

            Packet packet = cpi.packet;

            if (packet is ClientInfoResponsePacket)
            {
                Debug.WriteLine("Received Client info Response");
                //client connects. Server sends infoRequest, Client sends infoResponse.
                ClientInfoResponsePacket cirp = packet as ClientInfoResponsePacket;
                CallClientConnected(cpi.id, cirp.Alias);

                // Let everyone know they joined
                ClientConnectedPacket ccp = new ClientConnectedPacket(cpi.id, cirp.Alias);
                BroadcastPacket(ccp);
            }
            else if (packet is ClientReadyPacket)
            {
                ClientReadyPacket crp = packet as ClientReadyPacket;
                CallClientReadyReceived(crp.Id, crp.Alias);
            }
            else if (packet is ChatPacket)
            {
                ChatPacket cp = packet as ChatPacket;
                BroadcastChatMessage(cp.message, cp.player);
                CallChatMessageReceived(new ChatMessage(cp.message, cp.player));
            }
            else if (packet is ObjectRequestPacket)
            {
                Debug.WriteLine("Received ObjectRequestPacket");
                ObjectRequestPacket corp = packet as ObjectRequestPacket;
                CallObjectRequestReceived(cpi.id, corp.AssetName);
            }
            else if (packet is ObjectUpdatePacket)
            {
                ObjectUpdatePacket oup = packet as ObjectUpdatePacket;
                CallObjectUpdateReceived(oup.objectId, oup.assetName, oup.position, oup.orientation, oup.velocity);
            }
            else if (packet is ObjectActionPacket)
            {
                ObjectActionPacket oap = packet as ObjectActionPacket;
                CallObjectActionReceived(oap.objectId, oap.actionParameters);
            }
            else if (packet is ObjectAttributePacket)
            {
                ObjectAttributePacket oap = packet as ObjectAttributePacket;
                CallObjectAttributeReceived(oap);
            }
        }
예제 #7
0
 void commServer_ObjectAttributeReceived(ObjectAttributePacket oap)
 { // DO NOTHING, READ BELOW for WHY we should DO NOTHING.
   /*
    * If the client and server send a change at the same time
    * the server could tell the client, you just got a radar.
    * the client could have requested to drop a laser
    *
    * if the server sends before it receives the client's request, then it tells the client, you now have a laser and a radar.
    * When the server gets the client's request, the server won't know (currently) what changed, so it has to take the client at face value (no laser and no radar)
    * this is a more general version of the issue with ActionValues and detecting what changed.
    *
    * solutions:
    *  1 the messages need to be true deltas (The server needs to know what, specifically, changed that caused the attribute packet so that it can do only that which was requested. Drop the laser!)
    *  2
    *
    * Implementations:
    *  1 Put old and new in the AttributePacket
    *  2 relay which value to change and to what value. (this can be done by sending the delta, not the actual value)
    *
    * Example:
    * Say a rover's laser is dropped.
    * For the rover, that is boolean value number 2 at index 1
    * instead of sending a false for hasLaser, signify the delta with a true (it did change [flipped])
    * Instead of sending a 70 for energy left, signify the delta with a -5 (it did change by -5)
    * Instead of sending a 20.5 for throttle, signify the delta with a +1.5 (it did change by +1.5)
    *
    * What about synchronization?
    * Will the client get out of sync with the server or vice-a-versa?
    * What if the server sends hard values and the client reports deltas as requests?
    * The client doesn't modify its attributes.
    * The client sends input to the server.
    * the server modifies attributes.
    *
    * Currently, the server processes input.
    * To go forward, the ActionManager is updated about the requets to go forward.
    * Before the client integrates, ActionManager wraps up the input for the object into an Object Action Packet sent to the server.
    * Sever simulates the input, does integration, and replies with an Object Update Packet
    * the client applies that Object Update Packet before integrating.
    *
    * The server needing to process Object Attribute Packets is based on the client processing input which affects other clients.
    * ULTIMATE SOLUTION: If the laser drop were just another ActionValue for the server to simulate, the server would not need to process object attribute requests from the client.
    *
    * That being said, how much needs to be simulated on the server?
    * ANYTHING THAT AFFECTS ANOTHER CLIENT
    *  - changes in Appearance
    *  - changes in Behavior
    *
    * If it only affects the source client, it doesn't need to be sent.
    * Thus, managing internal inventory, or changing where energy is routed can be done locally without server involvement.
    *
    */
 }
예제 #8
0
        public override void physicsManager_PostIntegrate()
        {
            if (commServer != null)
            {
                lock (gameObjects)
                {
                    foreach (Entity go in gameObjects.Values)
                    {
                        #region Send Attribute Updates to the client
                        if (go.hasAttributeChanged)
                        {
                            bool[]  bools  = null;
                            int[]   ints   = null;
                            float[] floats = null;
                            go.GetObjectAttributes(out bools, out ints, out floats);
                            ObjectAttributePacket oap = new ObjectAttributePacket(go.ID, bools, ints, floats);
                            commServer.BroadcastPacket(oap);
                        }
                        #endregion

                        #region Send Object Updates to the client

                        if (go.isMoveable && go.IsActive)
                        {
                            go.UpdateCountdown--;
                            if (go.UpdateCountdown == 0 || assetManager.isObjectOwnedByAnyClient(go.ID))
                            {
                                ObjectUpdatePacket oup = new ObjectUpdatePacket(go.ID, go.config.Name, go.Position, go.Orientation, go.Velocity);
                                commServer.BroadcastObjectUpdate(oup);
                                go.UpdateCountdown = 10;
                            }
                        }
                        #endregion
                    }
                }
            }
            base.physicsManager_PostIntegrate();
        }
예제 #9
0
        public override void physicsManager_PreIntegrate()
        {
            lock (gameObjects)
            {
                #region Send Action Updates to the server
                foreach (int i in clientControlledObjects)
                {
                    if (!gameObjects.ContainsKey(i))
                    {
                        continue;
                    }
                    Entity go = gameObjects[i];
                    if (!go.actionManager.actionApplied)
                    {
                        continue;
                    }

                    if (go is RoverObject)
                    {
                    }
                    object[] vals = go.actionManager.GetActionValues();
                    go.actionManager.ValueSwap();
                    commClient.SendObjectAction(go.ID, vals);
                }
                #endregion

                #region Process packets from the server
                List <object> ShouldRetry = new List <object>();
                lock (MultiplayerUpdateQueue)
                {
                    while (MultiplayerUpdateQueue.Count > 0)
                    {
                        Packet p = MultiplayerUpdateQueue[0] as Packet;
                        MultiplayerUpdateQueue.RemoveAt(0);

                        if (p is ObjectUpdatePacket)
                        {
                            #region Process Update Packets from the server
                            ObjectUpdatePacket oup = p as ObjectUpdatePacket;

                            if (!gameObjects.ContainsKey(oup.objectId))
                            {
                                AddNewObject(oup.objectId, oup.assetName);
                                ShouldRetry.Add(oup);
                                continue;
                                // TODO -  Should we continue instead of not updating this frame?
                            }
                            // (can't yet due to AddNewObject waiting until the next integrate to actually add it)
                            Entity go = gameObjects[oup.objectId];
                            if (go.hasNotDoneFirstInterpoladation)
                            {
                                go.Interpoladate(oup.position, oup.orientation, oup.velocity, 1.0f); // Server knows best!
                            }
                            else
                            {
                                go.Interpoladate(oup.position, oup.orientation, oup.velocity); // split realities 50/50
                            }
                            #endregion
                        }
                        else if (p is ObjectAttributePacket)
                        {
                            #region Process Attribute Packets from the server
                            ObjectAttributePacket oap = p as ObjectAttributePacket;
                            if (gameObjects.ContainsKey(oap.objectId))
                            {
                                Entity go = gameObjects[oap.objectId];
                                bool   locallyOwnedAndOperated = false;

                                if (go.OwningClientId == MyClientID)
                                {
                                    locallyOwnedAndOperated = true;
                                }
                                go.SetObjectAttributes(oap.booleans, oap.ints, oap.floats, locallyOwnedAndOperated);
                            }
                            #endregion
                        }
                    }
                    while (ShouldRetry.Count > 0)
                    {
                        MultiplayerUpdateQueue.Add(ShouldRetry[0]);
                        ShouldRetry.RemoveAt(0);
                    }
                }

                #endregion
            }
        }