예제 #1
0
        private void ReadDataEvent(NetworkConnection connection, DataStreamReader streamReader)
        {
            try
            {
                int senderActorNumber = connection.InternalId;
                int command           = streamReader.ReadInt();
                switch (command)
                {
                case Commands.AcknowledgeActorNumber:
                {
                    if (_acceptAllPlayers)
                    {
                        AcceptPlayer(senderActorNumber);
                    }
                    break;
                }

                case Commands.PlayerData:
                {
                    string playerData = streamReader.ReadManagedString();
                    PlayerDataReceived?.Invoke(senderActorNumber, playerData);
                    break;
                }

                case Commands.Ping:
                    _lastPingTimes[connection] = Time;
                    float            sendLocalTime = streamReader.ReadFloat();
                    DataStreamWriter writer        = _serverDriver.BeginSend(_unreliablePipeline, connection);
                    writer.WriteInt(Commands.Ping);
                    writer.WriteFloat(sendLocalTime);
                    writer.WriteFloat(Time);
                    writer.WriteFloat(UnityEngine.Time.deltaTime);
                    _serverDriver.EndSend(writer);
                    break;

                case Commands.RequestSpawnMessage:
                {
                    var connections = new NativeList <NetworkConnection>(1, Allocator.Temp)
                    {
                        connection
                    };
                    SendSpawnMessage(NetObjectManager.Instance.NetObjects, connections);
                    connections.Dispose();
                    break;
                }

                case Commands.UpdateNetObjects:
                {
                    int objectsInMessage = streamReader.ReadInt();
                    for (var obj = 0; obj < objectsInMessage; obj++)
                    {
                        int       netObjID  = streamReader.ReadInt();
                        int       size      = streamReader.ReadInt();
                        NetObject netObject = NetObjectManager.Instance.Exists(netObjID)
                                ? NetObjectManager.Instance.Get(netObjID)
                                : null;

                        // ignore illegal updates and those from local host client
                        if (netObject == null ||
                            netObject.OwnerActorNumber != senderActorNumber ||     // cheater?
                            Client.IsHost && Client.Instance.ActorNumber == senderActorNumber)
                        {
                            streamReader.DiscardBytes(size);
                        }
                        else
                        {
                            int bytesRead = streamReader.GetBytesRead();
                            try
                            {
                                netObject.Deserialize(ref streamReader, b => b.ClientAuthoritative);
                            }
                            catch (Exception e)
                            {
                                Debug.LogException(e);
                                int remainingBytes = size + bytesRead - streamReader.GetBytesRead();
                                streamReader.DiscardBytes(remainingBytes);
                            }
                        }
                    }

                    break;
                }

                case Commands.GameAction:
                {
                    int   gameActionID = streamReader.ReadInt();
                    int   actorNumber  = streamReader.ReadInt();
                    float triggerTime  = streamReader.ReadFloat();
                    try
                    {
                        GameAction             gameAction = GameActionManager.Instance.Get(gameActionID);
                        GameAction.IParameters parameters =
                            gameAction.DeserializeParameters(ref streamReader);
                        gameAction.ReceiveOnServer(parameters, actorNumber, senderActorNumber,
                                                   triggerTime);
                        break;
                    }
                    catch (Exception e)
                    {
                        Debug.LogException(e);
                        break;
                    }
                }

                case Commands.NetAssetRPC:
                {
                    float        sentServerTime = streamReader.ReadFloat();
                    int          netAssetID     = streamReader.ReadInt();
                    NetAsset     netAsset       = NetAssetManager.Instance.Get(netAssetID);
                    NetAsset.RPC rpc            = netAsset.DeserializeRPC(ref streamReader);
                    var          messageInfo    = new MessageInfo
                    {
                        SentServerTime = sentServerTime, SenderActorNumber = senderActorNumber
                    };
                    rpc.Invoke(messageInfo);
                    break;
                }

                case Commands.NetObjectRPC:
                {
                    float sentServerTime = streamReader.ReadFloat();
                    int   netObjectID    = streamReader.ReadInt();
                    if (!NetObjectManager.Instance.Exists(netObjectID))
                    {
                        Debug.LogWarning("Ignoring received RPC, because NetObject was not found.");
                        break;
                    }

                    NetObject            netObject      = NetObjectManager.Instance.Get(netObjectID);
                    ushort               netBehaviourID = streamReader.ReadUShort();
                    NetBehaviour         netBehaviour   = netObject.Get(netBehaviourID);
                    NetObjectManager.RPC rpc            =
                        NetObjectManager.Instance.DeserializeRPC(ref streamReader, netBehaviour);
                    var messageInfo = new MessageInfo
                    {
                        SentServerTime = sentServerTime, SenderActorNumber = senderActorNumber
                    };
                    rpc.Invoke(messageInfo);
                    break;
                }

                default:
                    Debug.LogException(new NetException($"Unknown command {command}"));
                    break;
                }
            }
            catch (Exception e)
            {
                Debug.LogException(new NetException("Failed to handle data event", e));
            }
        }