private void Ping_PingCompleted(object sender, PingCompletedEventArgs e)
        {
            if (!stop.WaitOne(0, true))
            {
                var ping = (Ping)sender;

                if (e != null && e.UserState != null)
                {
                    var address = (IPAddress)e.UserState;

                    PingReceived?.Invoke(address, e.Reply);

                    if (e.Reply.Status == IPStatus.Success)
                    {
                        successful.Add(address);
                    }

                    lock (_lock) active.RemoveAll(o => o == address);

                    CheckCompleted();
                }

                lock (_lock) activeRequests.RemoveAll(o => o == ping);
            }
        }
示例#2
0
        private void OnMessageReceived(string jsonMessage)
        {
            var message = Deserialize <SocketMessageResponse>(jsonMessage);

            if (message.Type == "error")
            {
                var errorMessage = Deserialize <ErrorMessageResponse>(jsonMessage);
                ErrorReceived?.Invoke(errorMessage.Message);
            }
            else if (message.Type == "ping")
            {
                PingReceived?.Invoke();
            }
            else
            {
                HandleMessage(message.Type, jsonMessage);
            }
        }
示例#3
0
        private void OnLineReceived(string line)
        {
            if (line.StartsWith("PING"))
            {
                PingReceived?.Invoke(new PingMessage
                {
                    Message = line.Substring(5)
                });
                return;
            }

            if (!line.StartsWith(":"))
            {
                return;
            }

            var sections = line.Split(':');
            var args     = sections[1].Split(' ');

            if (args[1] == "001")
            {
                IsLoggedIn = true;
                LoggedIn?.Invoke();
                return;
            }

            if (args[1] == "PRIVMSG")
            {
                MessageReceived?.Invoke(new PrivateMessage
                {
                    From    = new Identity(args[0]),
                    Channel = args[2],
                    Message = sections[2]
                });
                return;
            }

            return;
        }
示例#4
0
 protected virtual void OnPingReceived(string serverAddress)
 {
     PingReceived?.Invoke(this, new PingReceivedEventArgs(serverAddress));
 }
示例#5
0
 protected virtual void OnPingReceived(PingReceivedArgs e)
 {
     PingReceived?.Invoke(this, e);
 }
示例#6
0
        private void WebsocketPacketHandler_SocketMessageReceived(List <Packet> packets)
        {
            // Server may send more than one packet.
            // -------------------------------------
            foreach (var packet in packets)
            {
                if (packet.Header == ConnectionAcceptedPacket.ToString())
                {
                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    SendPacket(new ClientInfoPacket(false, UserAgent, packet.Data["hash"].ToString(), 0, false));
                    SendPacket(new OpenAcknowledgedPacket());

                    var eventArgs = new ConnectionAcceptedEventArgs(packet.Data["conn_id"].ToString(), packet.Data["hash"].ToString());
                    ConnectionAccepted?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == ConversationEndedPacket.ToString())
                {
                    // Unusual behavior, server sends "convended" without any data
                    // if "flag stranger" packet is sent and no conversation have
                    // been started before.
                    //
                    // Hence, we have to handle it like this.
                    // -----------------------------------------------------------
                    IsStrangerConnected = false;
                    if (packet.Data != null)
                    {
                        var di        = new DisconnectInfo(true, int.Parse(packet.Data.ToString()));
                        var eventArgs = new ConversationEndedEventArgs(di);

                        ConversationEnded?.Invoke(this, eventArgs);
                    }
                    else
                    {
                        var di        = new DisconnectInfo(true, -1);
                        var eventArgs = new ConversationEndedEventArgs(di);

                        ConversationEnded?.Invoke(this, eventArgs);
                    }
                    continue;
                }

                if (packet.Header == StrangerDisconnectedPacket.ToString())
                {
                    if (CurrentCID != packet.Data.ToString() && EncounteredClientIDs.Contains(packet.Data.ToString()))
                    {
                        EncounteredClientIDs.Remove(packet.Data.ToString());
                        continue;
                    }

                    IsStrangerConnected = false;

                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    var di        = new DisconnectInfo(false, int.Parse(packet.Data.ToString()));
                    var eventArgs = new ConversationEndedEventArgs(di);

                    ConversationEnded?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == MessageReceivedPacket.ToString())
                {
                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    int postId = -1;
                    if (packet.AdditionalFields.ContainsKey("post_id"))
                    {
                        postId = int.Parse(packet.AdditionalFields["post_id"].ToString());
                    }

                    var message = new Message(
                        packet.Data["msg"].ToString(),
                        int.Parse(packet.Data["cid"].ToString()),
                        postId,
                        MessageType.Chat
                        );
                    var eventArgs = new MessageEventArgs(message);
                    MessageReceived?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == OnlinePeopleCountPacket.ToString())
                {
                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    int number;
                    if (!int.TryParse(packet.Data.ToString(), out number))
                    {
                        number = -1;
                    }

                    var eventArgs = new OnlineCountEventArgs(number);
                    OnlinePeopleCountChanged?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == PingPacket.ToString())
                {
                    if (KeepAlive)
                    {
                        PongResponse();
                    }

                    var eventArgs = new PingEventArgs(DateTime.Now);
                    PingReceived?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == RandomTopicReceivedPacket.ToString())
                {
                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    var message = new Message(
                        packet.Data["topic"].ToString(),
                        int.Parse(packet.Data["cid"].ToString()),
                        int.Parse(packet.AdditionalFields["post_id"].ToString()),
                        MessageType.Topic
                        );
                    var eventArgs = new MessageEventArgs(message);
                    MessageReceived?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == ServiceMessageReceivedPacket.ToString())
                {
                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    var message   = new Message(packet.Data.ToString(), -1, -1, MessageType.Service);
                    var eventArgs = new MessageEventArgs(message);
                    MessageReceived?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == StrangerChatstatePacket.ToString())
                {
                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    bool writing;
                    if (!bool.TryParse(packet.Data.ToString(), out writing))
                    {
                        writing = false;
                    }

                    var chatState = writing ? ChatState.Writing : ChatState.Idle;
                    var eventArgs = new ChatstateEventArgs(chatState);

                    StrangerChatstateChanged?.Invoke(this, eventArgs);
                    continue;
                }

                if (packet.Header == StrangerFoundPacket.ToString())
                {
                    if (packet.Data == null)
                    {
                        throw new Exception("Invalid packet received, packet data is null.");
                    }

                    CurrentContactUID = packet.Data["ckey"].ToString();

                    SendPacket(new ConversationStartAcknowledged(CurrentContactUID));
                    ActionID++;

                    EncounteredClientIDs.Add(packet.Data["cid"].ToString());

                    IsSearchingForStranger = false;
                    IsStrangerConnected    = true;

                    var si = new StrangerInfo(
                        int.Parse(packet.Data["cid"].ToString()),
                        packet.Data["ckey"].ToString(),
                        bool.Parse(packet.Data["flaged"].ToString()),
                        packet.Data["info"]
                        );

                    var eventArgs = new StrangerFoundEventArgs(si);
                    StrangerFound?.Invoke(this, eventArgs);
                }
            }
        }
示例#7
0
        public void Tick()
        {
            if (!_clientDriver.IsCreated)
            {
                return;
            }
            _clientDriver.ScheduleUpdate().Complete();

            if (_timeout > 0 && IsConnected && Time.time - LastPongTime > _timeout)
            {
                Debug.LogWarning("Disconnected due to timeout");
                Disconnect();
                return;
            }

            // listen for events
            NetworkEvent.Type eventType;
            while ((eventType = _clientToServerConnection.PopEvent(_clientDriver, out DataStreamReader streamReader))
                   != NetworkEvent.Type.Empty)
            {
                if (eventType == NetworkEvent.Type.Connect)
                {
                    Debug.Log("Connected!");
                    State = ClientState.Connected;
                    Connected?.Invoke();
                }
                else if (eventType == NetworkEvent.Type.Data)
                {
                    DataReceived?.Invoke(streamReader.Length);
                    int command = streamReader.ReadInt();
                    switch (command)
                    {
                    case Commands.AssignActorNumber:
                    {
                        ActorNumber = streamReader.ReadInt();
                        Debug.Log($"Got assigned actor number {ActorNumber}");
                        DataStreamWriter writer =
                            _clientDriver.BeginSend(_reliablePipeline, _clientToServerConnection);
                        writer.WriteInt(Commands.AcknowledgeActorNumber);
                        _clientDriver.EndSend(writer);
                        DataSent?.Invoke(writer.Length);
                        break;
                    }

                    case Commands.AcceptPlayer:
                    {
                        DataStreamWriter writer =
                            _clientDriver.BeginSend(_reliablePipeline, _clientToServerConnection);
                        writer.WriteInt(Commands.RequestSpawnMessage);
                        writer.WriteInt(SceneManager.sceneCount);
                        for (var i = 0; i < SceneManager.sceneCount; i++)
                        {
                            writer.WriteInt(SceneManager.GetSceneAt(i).buildIndex);
                        }
                        SceneManager.sceneLoaded += OnSceneLoaded;
                        _clientDriver.EndSend(writer);
                        break;
                    }

                    case Commands.Ping:
                    {
                        LastPongTime = Time.time;
                        float sendLocalTime   = streamReader.ReadFloat();
                        float serverTime      = streamReader.ReadFloat();
                        float serverDeltaTime = streamReader.ReadFloat();
                        RoundTripTime = Time.time - sendLocalTime;
                        Latency       = IsHost
                                ? 0
                                : Mathf.Max(0, (RoundTripTime - serverDeltaTime / 2 - Time.deltaTime / 2) / 2);
                        // estimated server time NOW is received serverTime + latency for one trip + average frame wait on client side
                        float serverTimeOffset = serverTime - Time.time + Latency + Time.deltaTime / 2;
                        _averageServerTimeOffset = Mathf.Abs(_averageServerTimeOffset - serverTime) > 0.5f
                                ? serverTimeOffset
                                : 0.9f * _averageServerTimeOffset + 0.1f * serverTimeOffset;
                        PingReceived?.Invoke(RoundTripTime, Latency);
                        break;
                    }

                    case Commands.SpawnNetObjects:
                    {
                        if (IsHost)
                        {
                            break;
                        }
                        int count = streamReader.ReadInt();

                        for (var i = 0; i < count; i++)
                        {
                            int        netObjID         = streamReader.ReadInt();
                            ushort     prefabIndex      = streamReader.ReadUShort();
                            int        ownerActorNumber = streamReader.ReadInt();
                            Vector3    position         = streamReader.ReadVector3();
                            Quaternion rotation         = streamReader.ReadQuaternion();
                            int        sceneBuildIndex  = streamReader.ReadInt();
                            int        size             = streamReader.ReadInt();
                            int        bytesRead        = streamReader.GetBytesRead();
                            Scene      scene            = SceneManager.GetSceneByBuildIndex(sceneBuildIndex);
                            var        deserialized     = false;
                            if (scene != null && scene.isLoaded)
                            {
                                NetObject netObject = NetObjectManager.Instance.SpawnOnClient(netObjID, prefabIndex,
                                                                                              ownerActorNumber, position, rotation, scene);
                                if (netObject != null)
                                {
                                    netObject.Deserialize(ref streamReader, behaviour => true);
                                    deserialized = true;
                                }
                            }

                            if (!deserialized)
                            {
                                streamReader.DiscardBytes(size);
                            }
                            if (streamReader.GetBytesRead() - bytesRead != size)
                            {
                                Debug.LogWarning("Did not deserialize properly!");
                            }
                        }

                        break;
                    }

                    case Commands.UpdateNetAssets:
                    {
                        if (IsHost)
                        {
                            break;
                        }
                        int assetsInMessage = streamReader.ReadInt();
                        for (var i = 0; i < assetsInMessage; i++)
                        {
                            int assetNetID = streamReader.ReadInt();
                            int size       = streamReader.ReadInt();
                            int bytesRead  = streamReader.GetBytesRead();
                            try
                            {
                                NetAsset netAsset = NetAssetManager.Instance.Get(assetNetID);
                                netAsset.Deserialize(ref streamReader);
                            }
                            catch (Exception e)
                            {
                                Debug.LogException(new NetException($"Failed to update net asset {assetNetID}", e));
                                streamReader.DiscardBytes(size + bytesRead - streamReader.GetBytesRead());
                            }
                        }

                        break;
                    }

                    case Commands.UpdateNetObjects:
                    {
                        if (IsHost)
                        {
                            break;
                        }
                        int objectsInMessage = streamReader.ReadInt();
                        for (var i = 0; i < objectsInMessage; i++)
                        {
                            int netObjID = streamReader.ReadInt();
                            int size     = streamReader.ReadInt();
                            if (NetObjectManager.Instance.Exists(netObjID))
                            {
                                NetObject netObject = NetObjectManager.Instance.Get(netObjID);
                                int       bytesRead = streamReader.GetBytesRead();
                                try
                                {
                                    netObject.Deserialize(ref streamReader, behaviour => !behaviour.HasAuthority);
                                }
                                catch (Exception e)
                                {
                                    Debug.LogException(
                                        new NetException($"Failed to update net object {netObjID}", e));
                                    streamReader.DiscardBytes(size + bytesRead - streamReader.GetBytesRead());
                                }
                            }
                            else
                            {
                                streamReader.DiscardBytes(size);
                            }
                        }

                        break;
                    }

                    case Commands.UnspawnNetObjects:
                    {
                        if (IsHost)
                        {
                            break;
                        }
                        int count = streamReader.ReadInt();
                        for (var i = 0; i < count; i++)
                        {
                            int netObjID = streamReader.ReadInt();
                            NetObjectManager.Instance.Unspawn(netObjID);
                        }

                        break;
                    }

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

                    case Commands.NetAssetRPC:
                    {
                        if (IsHost)
                        {
                            break;
                        }
                        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 = Server.ServerActorNumber
                        };
                        rpc.Invoke(messageInfo);
                        break;
                    }

                    case Commands.NetObjectRPC:
                    {
                        if (IsHost)
                        {
                            break;
                        }
                        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 = Server.ServerActorNumber
                        };
                        rpc.Invoke(messageInfo);
                        break;
                    }

                    default:
                        Debug.LogError($"Unknown event type {eventType}");
                        break;
                    }
                }
                else if (eventType == NetworkEvent.Type.Disconnect)
                {
                    Debug.Log("Disconnected!");
                    SceneManager.sceneLoaded -= OnSceneLoaded;
                    Disconnected?.Invoke();
                    State = ClientState.Disconnected;
                    _clientToServerConnection = default;
                }
            }
        }
 private void Queue_PingReceived(IPAddress address, PingReply reply)
 {
     PingReceived?.Invoke(this, address, reply);
 }
示例#9
0
 private void OnPingReceived()
 {
     PingReceived?.Invoke();
 }