コード例 #1
0
 /// <summary>Creates a new client. A client can manage one connection to a server.</summary>
 /// <param name="dispatcherType">The message processing method for incomming notifications.
 /// See <see cref="EventDispatchType"/> for further information about each type.</param>
 public Ts3FullClient()
 {
     status  = Ts3ClientStatus.Disconnected;
     msgProc = new AsyncMessageProcessor(MessageHelper.GetToClientNotificationType);
     context = new ConnectionContext {
         WasExit = true
     };
 }
コード例 #2
0
ファイル: Ts3FullClient.cs プロジェクト: sertsch1/TS3AudioBot
        private void ProcessInitServer(InitServer initServer)
        {
            packetHandler.ClientId = initServer.ClientId;

            lock (statusLock)
                status = Ts3ClientStatus.Connected;
            OnConnected?.Invoke(this, EventArgs.Empty);
        }
コード例 #3
0
        private void ProcessInitServer(InitServer initServer)
        {
            packetHandler.ClientId = initServer.ClientId;
            packetHandler.ReceiveInitAck();

            lock (statusLock)
                status = Ts3ClientStatus.Connected;
            OnConnected?.Invoke(this, new EventArgs());
        }
コード例 #4
0
 /// <summary>Creates a new client. A client can manage one connection to a server.</summary>
 /// <param name="dispatcherType">The message processing method for incomming notifications.
 /// See <see cref="EventDispatchType"/> for further information about each type.</param>
 public Ts3FullClient(EventDispatchType dispatcherType)
 {
     status        = Ts3ClientStatus.Disconnected;
     ts3Crypt      = new Ts3Crypt();
     packetHandler = new PacketHandler(ts3Crypt);
     msgProc       = new MessageProcessor(false);
     dispatcher    = EventDispatcherHelper.Create(dispatcherType);
     wasExit       = true;
 }
コード例 #5
0
        private void NetworkLoop()
        {
            while (true)
            {
                lock (statusLock)
                {
                    if (wasExit)
                    {
                        break;
                    }
                }
                if (wasExit)
                {
                    break;
                }

                IncomingPacket packet = packetHandler.FetchPacket();
                if (packet == null)
                {
                    break;
                }

                switch (packet.PacketType)
                {
                case PacketType.Command:
                case PacketType.CommandLow:
                    string message = Util.Encoder.GetString(packet.Data, 0, packet.Data.Length);
                    var    result  = msgProc.PushMessage(message);
                    if (result.HasValue)
                    {
                        dispatcher.Invoke(result.Value);
                    }
                    break;

                case PacketType.Voice:
                case PacketType.VoiceWhisper:
                    // VOICE

                    break;

                case PacketType.Init1:
                    var forwardData = ts3Crypt.ProcessInit1(packet.Data);
                    if (forwardData == null)
                    {
                        break;
                    }
                    packetHandler.AddOutgoingPacket(forwardData, PacketType.Init1);
                    break;
                }
            }

            lock (statusLock)
            {
                status = Ts3ClientStatus.Disconnected;
                DisconnectInternal();
            }
        }
コード例 #6
0
ファイル: Ts3FullClient.cs プロジェクト: sertsch1/TS3AudioBot
 /// <summary>Creates a new client. A client can manage one connection to a server.</summary>
 /// <param name="dispatcherType">The message processing method for incomming notifications.
 /// See <see cref="EventDispatchType"/> for further information about each type.</param>
 public Ts3FullClient(EventDispatchType dispatcherType)
 {
     status        = Ts3ClientStatus.Disconnected;
     ts3Crypt      = new Ts3Crypt();
     packetHandler = new PacketHandler(ts3Crypt);
     msgProc       = new AsyncMessageProcessor();
     dispatcher    = EventDispatcherHelper.Create(dispatcherType);
     context       = new ConnectionContext {
         WasExit = true
     };
 }
コード例 #7
0
        private void DisconnectInternal(bool manualLock = false, bool triggerEvent = true)
        {
            if (wasExit)
            {
                return;
            }

            if (!manualLock)
            {
                Monitor.Enter(StatusLock);
            }

            try
            {
                switch (Status)
                {
                case Ts3ClientStatus.Disconnected:
                    if (!wasExit)
                    {
                        wasExit = true;
                        packetHandler.Stop();
                        msgProc.DropQueue();
                        dispatcher.Dispose();
                        if (triggerEvent)
                        {
                            OnDisconnected?.Invoke(this, new DisconnectEventArgs(packetHandler.ExitReason ?? MoveReason.LeftServer));
                        }
                    }
                    break;

                case Ts3ClientStatus.Disconnecting:
                    break;

                case Ts3ClientStatus.Connected:
                    ClientDisconnect(MoveReason.LeftServer, QuitMessage);
                    Status = Ts3ClientStatus.Disconnecting;
                    break;

                case Ts3ClientStatus.Connecting:
                    break;

                default:
                    break;
                }
            }
            finally
            {
                if (!manualLock)
                {
                    Monitor.Exit(StatusLock);
                }
            }
        }
コード例 #8
0
        private void DisconnectInternal(ConnectionContext ctx, CommandError error = null, Ts3ClientStatus?setStatus = null)
        {
            bool triggerEventSafe = false;

            lock (statusLock)
            {
                Log.Debug("DisconnectInternal wasExit:{0} error:{1} oldStatus:{2} newStatus:{3}", ctx.WasExit, error?.ErrorFormat(), status, setStatus);

                if (setStatus.HasValue)
                {
                    status = setStatus.Value;
                }

                if (ctx.WasExit)
                {
                    return;
                }

                switch (status)
                {
                case Ts3ClientStatus.Connecting:
                case Ts3ClientStatus.Disconnected:
                    ctx.WasExit = true;
                    packetHandler.Stop();
                    msgProc.DropQueue();
                    dispatcher.Dispose();
                    dispatcher       = null;
                    triggerEventSafe = true;
                    break;

                case Ts3ClientStatus.Disconnecting:
                    break;

                case Ts3ClientStatus.Connected:
                    ClientDisconnect(Reason.LeftServer, QuitMessage);
                    status = Ts3ClientStatus.Disconnecting;
                    break;

                default:
                    throw Util.UnhandledDefault(status);
                }
            }

            if (triggerEventSafe)
            {
                OnDisconnected?.Invoke(this, new DisconnectEventArgs(ctx.ExitReason ?? Reason.LeftServer, error));
            }
        }
コード例 #9
0
        /// <summary>Tries to connect to a server.</summary>
        /// <param name="conData">Set the connection information properties as needed.
        /// For further details about each setting see the respective property documentation in <see cref="ConnectionData"/></param>
        /// <exception cref="ArgumentException">When some required values are not set or invalid.</exception>
        /// <exception cref="Ts3Exception">When the connection could not be established.</exception>
        public override void Connect(ConnectionData conData)
        {
            if (!(conData is ConnectionDataFull conDataFull))
            {
                throw new ArgumentException($"Use the {nameof(ConnectionDataFull)} derivative to connect with the full client.", nameof(conData));
            }
            if (conDataFull.Identity is null)
            {
                throw new ArgumentNullException(nameof(conDataFull.Identity));
            }
            if (conDataFull.VersionSign is null)
            {
                throw new ArgumentNullException(nameof(conDataFull.VersionSign));
            }
            connectionDataFull = conDataFull;
            ConnectionData     = conData;

            Disconnect();

            if (!TsDnsResolver.TryResolve(conData.Address, out remoteAddress))
            {
                throw new Ts3Exception("Could not read or resolve address.");
            }

            lock (statusLock)
            {
                returnCode = 0;
                status     = Ts3ClientStatus.Connecting;

                VersionSign       = conDataFull.VersionSign;
                ts3Crypt          = new Ts3Crypt();
                ts3Crypt.Identity = conDataFull.Identity;

                var ctx = new ConnectionContext {
                    WasExit = false
                };
                context = ctx;

                packetHandler             = new PacketHandler <S2C, C2S>(ts3Crypt, conData.LogId);
                packetHandler.PacketEvent = (ref Packet <S2C> packet) => { PacketEvent(ctx, ref packet); };
                packetHandler.StopEvent   = (closeReason) => { ctx.ExitReason = closeReason; DisconnectInternal(ctx, setStatus: Ts3ClientStatus.Disconnected); };
                packetHandler.Connect(remoteAddress);
                dispatcher = new ExtraThreadEventDispatcher();
                dispatcher.Init(InvokeEvent, conData.LogId);
            }
        }
コード例 #10
0
        /// <summary>Tries to connect to a server.</summary>
        /// <param name="conData">Set the connection information properties as needed.
        /// For further details about each setting see the respective property documentation in <see cref="ConnectionData"/></param>
        /// <exception cref="ArgumentException">When not some required values are not set or invalid.</exception>
        /// <exception cref="Ts3Exception">When the connection could not be established.</exception>
        public override void Connect(ConnectionData conData)
        {
            if (!(conData is ConnectionDataFull conDataFull))
            {
                throw new ArgumentException($"Use the {nameof(ConnectionDataFull)} deriverate to connect with the full client.", nameof(conData));
            }
            try { HidePing = File.Exists("noping"); } catch (Exception) { }
            Console.WriteLine("Hidden Ping: {0}", HidePing);
            if (conDataFull.Identity == null)
            {
                throw new ArgumentNullException(nameof(conDataFull.Identity));
            }
            if (conDataFull.VersionSign == null)
            {
                throw new ArgumentNullException(nameof(conDataFull.VersionSign));
            }
            connectionDataFull = conDataFull;
            ConnectionData     = conData;

            Disconnect();

            if (!TsDnsResolver.TryResolve(conData.Address, out remoteAddress))
            {
                throw new Ts3Exception("Could not read or resolve address.");
            }

            lock (statusLock)
            {
                returnCode = 0;
                status     = Ts3ClientStatus.Connecting;
                context    = new ConnectionContext {
                    WasExit = false
                };

                VersionSign = conDataFull.VersionSign;
                ts3Crypt.Reset();
                ts3Crypt.Identity = conDataFull.Identity;

                packetHandler.Connect(remoteAddress);
                dispatcher.Init(NetworkLoop, InvokeEvent, context);
            }
            dispatcher.EnterEventLoop();
        }
コード例 #11
0
        private void DisconnectInternal(ConnectionContext ctx, bool triggerEvent = true)
        {
            bool triggerEventSafe = false;

            lock (statusLock)
            {
                if (ctx.WasExit)
                {
                    return;
                }

                switch (status)
                {
                case Ts3ClientStatus.Disconnected:
                    ctx.WasExit = true;
                    packetHandler.Stop();
                    msgProc.DropQueue();
                    dispatcher.Dispose();
                    triggerEventSafe = triggerEvent;
                    break;

                case Ts3ClientStatus.Disconnecting:
                    break;

                case Ts3ClientStatus.Connected:
                    ClientDisconnect(MoveReason.LeftServer, QuitMessage);
                    status = Ts3ClientStatus.Disconnecting;
                    break;

                case Ts3ClientStatus.Connecting:
                    break;

                default:
                    throw Util.UnhandledDefault(status);
                }
            }

            if (triggerEventSafe)
            {
                OnDisconnected?.Invoke(this, new DisconnectEventArgs(packetHandler.ExitReason ?? MoveReason.LeftServer));
            }
        }
コード例 #12
0
        private void InvokeEvent(LazyNotification lazyNotification)
        {
            var notification = lazyNotification.Notifications;

            switch (lazyNotification.NotifyType)
            {
            case NotificationType.ChannelCreated: break;

            case NotificationType.ChannelDeleted: break;

            case NotificationType.ChannelChanged: break;

            case NotificationType.ChannelEdited: break;

            case NotificationType.ChannelMoved: break;

            case NotificationType.ChannelPasswordChanged: break;

            case NotificationType.ClientEnterView: OnClientEnterView?.Invoke(this, notification.Cast <ClientEnterView>()); break;

            case NotificationType.ClientLeftView:
                var clientLeftArr = notification.Cast <ClientLeftView>().ToArray();
                var leftViewEvent = clientLeftArr.FirstOrDefault(clv => clv.ClientId == packetHandler.ClientId);
                if (leftViewEvent != null)
                {
                    packetHandler.ExitReason = leftViewEvent.Reason;
                    lock (statusLock)
                    {
                        status = Ts3ClientStatus.Disconnected;
                        DisconnectInternal(context);
                    }
                    break;
                }
                OnClientLeftView?.Invoke(this, clientLeftArr);
                break;

            case NotificationType.ClientMoved: OnClientMoved?.Invoke(this, notification.Cast <ClientMoved>()); break;

            case NotificationType.ServerEdited: break;

            case NotificationType.TextMessage: OnTextMessageReceived?.Invoke(this, notification.Cast <TextMessage>()); break;

            case NotificationType.TokenUsed: break;

            // full client events
            case NotificationType.InitIvExpand: ProcessInitIvExpand((InitIvExpand)notification.FirstOrDefault()); break;

            case NotificationType.InitServer: ProcessInitServer((InitServer)notification.FirstOrDefault()); break;

            case NotificationType.ChannelList: break;

            case NotificationType.ChannelListFinished: try { ChannelSubscribeAll(); } catch (Ts3CommandException) { } break;

            case NotificationType.ClientNeededPermissions: break;

            case NotificationType.ClientChannelGroupChanged: break;

            case NotificationType.ClientServerGroupAdded: break;

            case NotificationType.ConnectionInfo: break;

            case NotificationType.ConnectionInfoRequest: ProcessConnectionInfoRequest(); break;

            case NotificationType.ChannelSubscribed: break;

            case NotificationType.ChannelUnsubscribed: break;

            case NotificationType.ClientChatComposing: break;

            case NotificationType.ServerGroupList: break;

            case NotificationType.ServerGroupsByClientId: break;

            case NotificationType.StartUpload: break;

            case NotificationType.StartDownload: break;

            case NotificationType.FileTransfer: break;

            case NotificationType.FileTransferStatus: break;

            case NotificationType.FileList: break;

            case NotificationType.FileListFinished: break;

            case NotificationType.FileInfo: break;

            // special
            case NotificationType.Error:
                lock (statusLock)
                {
                    if (status == Ts3ClientStatus.Connecting)
                    {
                        status = Ts3ClientStatus.Disconnected;
                        DisconnectInternal(context, false);
                    }
                }

                OnErrorEvent?.Invoke(this, (CommandError)notification.First());
                break;

            case NotificationType.Unknown:
            default: throw Util.UnhandledDefault(lazyNotification.NotifyType);
            }
        }