Ejemplo n.º 1
0
 private void _client_OnDisconnected(object sender, CloseEventArgs e)
 {
     OnDisconnected?.Invoke(this, new OnDisconnectedArgs {
         Username = TwitchUsername
     });
     JoinedChannels.Clear();
 }
Ejemplo n.º 2
0
        public IEnumerable <ServerCommand> GetJoinCommands()
        {
            foreach (var channel in JoinedChannels.ToList())
            {
                yield return(Helpers.CreateServerCommand(ServerCommandType.JCH, new ServerJch {
                    channel = channel.Id, title = channel.Name, character = new ChannelUser {
                        identity = chatManager.OwnCharacterName
                    }
                }));

                yield return(Helpers.CreateServerCommand(ServerCommandType.COL, new ServerCol {
                    channel = channel.Id, oplist = GetOpNames(channel).ToList()
                }));

                var characters = channel.Members.ToList();
                yield return(Helpers.CreateServerCommand(ServerCommandType.ICH, new ServerIch {
                    channel = channel.Id, mode = channel.Mode, users = characters.Select(x => new ChannelUser {
                        identity = x.Character.Name
                    }).ToList()
                }));

                yield return(Helpers.CreateServerCommand(ServerCommandType.CDS, new ServerCds {
                    channel = channel.Id, description = channel.Description
                }));
            }
        }
        /// <summary>
        /// Find an existing channel instance for the provided channel. Lookup is performed basd on ID.
        /// The provided channel may be used if an existing instance is not found.
        /// </summary>
        /// <param name="lookup">A candidate channel to be used for lookup or permanently on lookup failure.</param>
        /// <param name="addToAvailable">Whether the channel should be added to <see cref="AvailableChannels"/> if not already.</param>
        /// <param name="addToJoined">Whether the channel should be added to <see cref="JoinedChannels"/> if not already.</param>
        /// <returns>The found channel.</returns>
        private Channel getChannel(Channel lookup, bool addToAvailable = false, bool addToJoined = false)
        {
            Channel found = null;

            bool lookupCondition(Channel ch) => lookup.Id > 0 ? ch.Id == lookup.Id : lookup.Name == ch.Name;

            var available = AvailableChannels.FirstOrDefault(lookupCondition);
            if (available != null)
                found = available;

            var joined = JoinedChannels.FirstOrDefault(lookupCondition);
            if (found == null && joined != null)
                found = joined;

            if (found == null)
            {
                found = lookup;

                // if we're using a channel object from the server, we want to remove ourselves from the users list.
                // this is because we check the first user in the channel to display a name/icon on tabs for now.
                var foundSelf = found.Users.FirstOrDefault(u => u.Id == api.LocalUser.Value.Id);
                if (foundSelf != null)
                    found.Users.Remove(foundSelf);
            }

            if (joined == null && addToJoined) joinedChannels.Add(found);
            if (available == null && addToAvailable) availableChannels.Add(found);

            return found;
        }
Ejemplo n.º 4
0
        public event EventHandler <TasSayEventArgs> Said = delegate { }; // this is fired when any kind of say message is recieved


        /// <summary>
        ///     Say something through chat system
        /// </summary>
        /// <param Name="place">Pick user (private message) channel or battle</param>
        /// <param Name="channel">Channel or User Name</param>
        /// <param Name="inputtext">chat text</param>
        /// <param Name="isEmote">is message emote? (channel or battle only)</param>
        /// <param Name="linePrefix">text to be inserted in front of each line (example: "!pm xyz")</param>
        public async Task Say(SayPlace place, string channel, string inputtext, bool isEmote, bool isRing = false)
        {
            if (string.IsNullOrEmpty(inputtext))
            {
                return;
            }
            var lines = inputtext.Split(new[] { '\n' }, StringSplitOptions.RemoveEmptyEntries);

            foreach (var text in lines)
            {
                if (string.IsNullOrEmpty(text))
                {
                    continue;
                }

                var args = new SayingEventArgs(place, channel, text, isEmote);
                Saying(this, args);
                if (args.Cancel)
                {
                    continue;
                }

                if ((args.SayPlace == SayPlace.Channel) && !JoinedChannels.ContainsKey(args.Channel))
                {
                    await JoinChannel(args.Channel);
                }

                var say = new Say()
                {
                    Target = args.Channel, Place = args.SayPlace, Text = args.Text, IsEmote = args.IsEmote, Ring = isRing
                };

                await SendCommand(say);
            }
        }
        private void handleChannelMessages(IEnumerable<Message> messages)
        {
            var channels = JoinedChannels.ToList();

            foreach (var group in messages.GroupBy(m => m.ChannelId))
                channels.Find(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
        }
Ejemplo n.º 6
0
        protected override void OnDisabled()
        {
            base.OnDisabled();

            RegisteredChatCommands.Clear();
            ChatButtonHighlighted = false;
            LeaveEventHandled     = true;
            SendEventHandled      = true;

            RegisteredChatCommands.Clear();
            ChannelMessages.Clear();
            PrivateMessages.Clear();
            ConsoleMessages.Clear();
            PlayerChannels.Clear();
            JoinedChannels.Clear();
            JoinedPmChannels.Clear();
            HighlightChannel.Clear();
            HighlightPm.Clear();

            SelectedChannel   = null;
            SelectedPmChannel = null;

            SelectTextBox = false;
            SendText      = "";

            Queuer.Clear();

            if (ChatLocked)
            {
                InputLockManager.RemoveControlLock(LmpChatLock);
                ChatLocked = false;
            }
        }
Ejemplo n.º 7
0
        void OnForceLeaveChannel(string[] args)
        {
            var channel = args[0];

            JoinedChannels.Remove(channel);
            ChannelForceLeave(this, new TasEventArgs(args));
        }
Ejemplo n.º 8
0
 /// <summary>
 /// Returns a JoinedChannel object using a passed string/>.
 /// </summary>
 /// <param name="channel">String channel to search for.</param>
 public JoinedChannel GetJoinedChannel(string channel)
 {
     if (JoinedChannels.Count == 0)
     {
         throw new BadStateException("Must be connected to at least one channel.");
     }
     return(JoinedChannels.FirstOrDefault(x => x.Channel.ToLower() == channel.ToLower()));
 }
Ejemplo n.º 9
0
        private async Task Process(ChangeTopic changeTopic)
        {
            Channel chan;

            if (JoinedChannels.TryGetValue(changeTopic.ChannelName, out chan))
            {
                chan.Topic = changeTopic.Topic;
            }
            ChannelTopicChanged(this, changeTopic);
        }
Ejemplo n.º 10
0
 public async Task LeaveChannel(string channelName)
 {
     if (JoinedChannels.ContainsKey(channelName))
     {
         await SendCommand(new LeaveChannel()
         {
             ChannelName = channelName
         });
     }
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Start disconnecting from the Twitch IRC chat.
        /// </summary>
        public void Disconnect()
        {
            Log("Disconnect Twitch Chat Client...");

            _client.Close();

            // Clear instance data
            JoinedChannels.Clear();
            PreviousWhisper = null;
        }
Ejemplo n.º 12
0
 public Channel GetJoinedChannel(string channelName)
 {
     if (JoinedChannels.ContainsKey(channelName))
     {
         return(JoinedChannels[channelName]);
     }
     else
     {
         return(null);
     }
 }
        /// <summary>
        /// Opens a new private channel.
        /// </summary>
        /// <param name="user">The user the private channel is opened with.</param>
        public void OpenPrivateChannel(User user)
        {
            if (user == null)
                throw new ArgumentNullException(nameof(user));

            if (user.Id == api.LocalUser.Value.Id)
                return;

            CurrentChannel.Value = JoinedChannels.FirstOrDefault(c => c.Type == ChannelType.PM && c.Users.Count == 1 && c.Users.Any(u => u.Id == user.Id))
                                   ?? JoinChannel(new Channel(user));
        }
Ejemplo n.º 14
0
        /// <summary>
        /// Start disconnecting from the Twitch IRC chat.
        /// </summary>
        public void Disconnect()
        {
            log("Disconnect Twitch Chat Client...");

            // Not sure if this is the proper way to handle this. It is UI blocking, so in order to presrve UI functionality, I delegated it to a task.
            Task.Factory.StartNew(() => { _client.Close(); });

            // Clear instance data
            JoinedChannels.Clear();
            PreviousWhisper = null;
        }
Ejemplo n.º 15
0
        /// <summary>
        /// Leaves (PART) the Twitch IRC chat of <paramref name="channel"/>.
        /// </summary>
        /// <param name="channel">The channel to leave.</param>
        /// <returns>True is returned if the passed channel was found, false if channel not found.</returns>
        public void LeaveChannel(string channel)
        {
            // Channel MUST be lower case
            channel = channel.ToLower();
            log($"Leaving channel: {channel}");
            JoinedChannel joinedChannel = JoinedChannels.FirstOrDefault(x => x.Channel.ToLower() == channel.ToLower());

            if (joinedChannel != null)
            {
                _client.Send(Rfc2812.Part($"#{channel}"));
            }
        }
Ejemplo n.º 16
0
        /// <summary>
        /// Opens a new private channel.
        /// </summary>
        /// <param name="user">The user the private channel is opened with.</param>
        public void OpenPrivateChannel(User user)
        {
            if (user == null)
            {
                throw new ArgumentNullException(nameof(user));
            }

            CurrentChannel.Value = JoinedChannels.FirstOrDefault(c => c.Type == ChannelType.PM && c.Users.Count == 1 && c.Users.Any(u => u.Id == user.Id))
                                   ?? new Channel {
                Name = user.Username, Users = { user }
            };
        }
Ejemplo n.º 17
0
        public void LeaveChannel(string channelName)
        {
            var args = new CancelEventArgs <string>(channelName);

            ChannelLeaving(this, args);
            if (args.Cancel)
            {
                return;
            }
            con.SendCommand("LEAVE", channelName);
            JoinedChannels.Remove(channelName);
            ChannelLeft(this, new TasEventArgs(channelName));
        }
Ejemplo n.º 18
0
        protected override Task Poll()
        {
            if (!api.IsLoggedIn)
            {
                return(base.Poll());
            }

            var fetchReq = new GetUpdatesRequest(lastMessageId);

            var tcs = new TaskCompletionSource <bool>();

            fetchReq.Success += updates =>
            {
                if (updates?.Presence != null)
                {
                    foreach (var channel in updates.Presence)
                    {
                        // we received this from the server so should mark the channel already joined.
                        channel.Joined.Value = true;
                        joinChannel(channel);
                    }

                    //todo: handle left channels

                    handleChannelMessages(updates.Messages);

                    foreach (var group in updates.Messages.GroupBy(m => m.ChannelId))
                    {
                        JoinedChannels.FirstOrDefault(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
                    }

                    lastMessageId = updates.Messages.LastOrDefault()?.Id ?? lastMessageId;
                }

                if (!channelsInitialised)
                {
                    channelsInitialised = true;
                    // we want this to run after the first presence so we can see if the user is in any channels already.
                    initializeChannels();
                }

                tcs.SetResult(true);
            };

            fetchReq.Failure += _ => tcs.SetResult(false);

            api.Queue(fetchReq);

            return(tcs.Task);
        }
Ejemplo n.º 19
0
        public void JoinChannel(Channel channel)
        {
            if (channel == null)
            {
                return;
            }

            // ReSharper disable once AccessToModifiedClosure
            var existing = JoinedChannels.FirstOrDefault(c => c.Id == channel.Id);

            if (existing != null)
            {
                // if we already have this channel loaded, we don't want to make a second one.
                channel = existing;
            }
            else
            {
                var foundSelf = channel.Users.FirstOrDefault(u => u.Id == api.LocalUser.Value.Id);
                if (foundSelf != null)
                {
                    channel.Users.Remove(foundSelf);
                }

                JoinedChannels.Add(channel);

                if (channel.Type == ChannelType.Public && !channel.Joined)
                {
                    var req = new JoinChannelRequest(channel, api.LocalUser);
                    req.Success += () =>
                    {
                        channel.Joined.Value = true;
                        JoinChannel(channel);
                    };
                    req.Failure += ex => LeaveChannel(channel);
                    api.Queue(req);
                    return;
                }
            }

            if (CurrentChannel.Value == null)
            {
                CurrentChannel.Value = channel;
            }

            if (!channel.MessagesLoaded)
            {
                // let's fetch a small number of messages to bring us up-to-date with the backlog.
                fetchInitalMessages(channel);
            }
        }
Ejemplo n.º 20
0
        void OnJoin(string[] args)
        {
            if (!JoinedChannels.ContainsKey(args[0]))
            {
                JoinedChannels.Add(args[0], Channel.Create(args[0]));

                var cancelEventArgs = new CancelEventArgs <TasEventArgs>(new TasEventArgs(args));
                PreviewChannelJoined(this, cancelEventArgs);
                if (!cancelEventArgs.Cancel)
                {
                    ChannelJoined(this, new TasEventArgs(args));
                }
            }
        }
Ejemplo n.º 21
0
        private void fetchUpdates()
        {
            fetchMessagesScheduleder?.Cancel();
            fetchMessagesScheduleder = Scheduler.AddDelayed(() =>
            {
                var fetchReq = new GetUpdatesRequest(lastMessageId);

                fetchReq.Success += updates =>
                {
                    if (updates?.Presence != null)
                    {
                        foreach (var channel in updates.Presence)
                        {
                            if (!channel.Joined.Value)
                            {
                                // we received this from the server so should mark the channel already joined.
                                channel.Joined.Value = true;

                                JoinChannel(channel);
                            }
                        }

                        if (!channelsInitialised)
                        {
                            channelsInitialised = true;
                            // we want this to run after the first presence so we can see if the user is in any channels already.
                            initializeChannels();
                        }

                        //todo: handle left channels

                        handleChannelMessages(updates.Messages);

                        foreach (var group in updates.Messages.GroupBy(m => m.ChannelId))
                        {
                            JoinedChannels.FirstOrDefault(c => c.Id == group.Key)?.AddNewMessages(group.ToArray());
                        }

                        lastMessageId = updates.Messages.LastOrDefault()?.Id ?? lastMessageId;
                    }

                    fetchUpdates();
                };

                fetchReq.Failure += delegate { fetchUpdates(); };

                api.Queue(fetchReq);
            }, update_poll_interval);
        }
Ejemplo n.º 22
0
 private void queueingJoinCheck()
 {
     if (joinChannelQueue.Count > 0)
     {
         currentlyJoiningChannels = true;
         JoinedChannel channelToJoin = joinChannelQueue.Dequeue();
         log($"Joining channel: {channelToJoin.Channel}");
         _client.Send(Rfc2812.Join($"#{channelToJoin.Channel}"));
         JoinedChannels.Add(new JoinedChannel(channelToJoin.Channel));
     }
     else
     {
         log("Finished channel joining queue.");
     }
 }
Ejemplo n.º 23
0
        public bool GetJoinedChannel(string channelName, out ChatChannelBase channel)
        {
            var result = JoinedChannels.Where(c => c.Property.ChannelName == channelName);

            if (result.Count() == 1)
            {
                channel = result.First();
                return(true);
            }
            else
            {
                channel = null;
                return(false);
            }
        }
Ejemplo n.º 24
0
 /// <summary>
 /// Join the Twitch IRC chat of <paramref name="channel"/>.
 /// </summary>
 /// <param name="channel">The channel to join.</param>
 /// <param name="overrideCheck">Override a join check.</param>
 public void JoinChannel(string channel, bool overrideCheck = false)
 {
     // Channel MUST be lower case
     channel = channel.ToLower();
     // Check to see if client is already in channel
     if (JoinedChannels.FirstOrDefault(x => x.Channel.ToLower() == channel && !overrideCheck) != null)
     {
         return;
     }
     joinChannelQueue.Enqueue(new JoinedChannel(channel));
     if (!currentlyJoiningChannels)
     {
         queueingJoinCheck();
     }
 }
Ejemplo n.º 25
0
        /// <summary>
        /// Start disconnecting from the Twitch IRC chat.
        /// </summary>
        public void Disconnect()
        {
            if (_logging)
            {
                Common.Log("Disconnect Twitch Chat Client...");
            }

            // Disconnect invoked on purpose, so we can disable auto retry
            _client.AutoRetry = false;

            // Not sure if this is the proper way to handle this. It is UI blocking, so in order to presrve UI functionality, I delegated it to a task.
            Task.Factory.StartNew(() => { _client.Disconnect(); });

            // Clear instance data
            JoinedChannels.Clear();
            PreviousWhisper = null;
            IsConnected     = false;
        }
Ejemplo n.º 26
0
        public void Reconnect()
        {
            Log("Reconnecting to: " + _credentials.TwitchHost + ":" + _credentials.TwitchPort);

            if (IsConnected)
            {
                _client.Dispose();
            }

            JoinedChannels.Clear();

            _client                  = new WebSocket($"ws://{_credentials.TwitchHost}:{_credentials.TwitchPort}");
            _client.Opened          += _client_OnConnected;
            _client.MessageReceived += _client_OnMessage;
            _client.Closed          += _client_OnDisconnected;
            _client.Error           += _client_OnError;
            _client.Open();
        }
Ejemplo n.º 27
0
        public void LeaveChannel(Channel channel)
        {
            if (channel == null)
            {
                return;
            }

            if (channel == CurrentChannel.Value)
            {
                CurrentChannel.Value = null;
            }

            JoinedChannels.Remove(channel);

            if (channel.Joined.Value)
            {
                api.Queue(new LeaveChannelRequest(channel, api.LocalUser));
                channel.Joined.Value = false;
            }
        }
Ejemplo n.º 28
0
        private async Task Process(ChannelUserRemoved arg)
        {
            Channel chan;

            if (JoinedChannels.TryGetValue(arg.ChannelName, out chan))
            {
                User org;
                if (chan.Users.TryRemove(arg.UserName, out org))
                {
                    if (arg.UserName == UserName)
                    {
                        ChannelLeft(this, chan);
                    }
                    ChannelUserRemoved(this, new ChannelUserRemovedInfo()
                    {
                        Channel = chan, User = org
                    });
                }
            }
        }
Ejemplo n.º 29
0
 private void queueingJoinCheck()
 {
     if (joinChannelQueue.Count > 0)
     {
         currentlyJoiningChannels = true;
         JoinedChannel channelToJoin = joinChannelQueue.Dequeue();
         if (_logging)
         {
             Common.Log($"Joining channel: {channelToJoin.Channel}");
         }
         _client.WriteLine(Rfc2812.Join($"#{channelToJoin.Channel}"));
         JoinedChannels.Add(new JoinedChannel(channelToJoin.Channel));
     }
     else
     {
         if (_logging)
         {
             Common.Log("Finished channel joining queue.");
         }
     }
 }
Ejemplo n.º 30
0
        private async Task Process(ChannelUserAdded arg)
        {
            Channel chan;

            if (JoinedChannels.TryGetValue(arg.ChannelName, out chan))
            {
                if (!chan.Users.ContainsKey(arg.UserName))
                {
                    User user;
                    if (ExistingUsers.TryGetValue(arg.UserName, out user))
                    {
                        chan.Users[arg.UserName] = user;
                        ChannelUserAdded(this, new ChannelUserInfo()
                        {
                            Channel = chan, Users = new List <User>()
                            {
                                user
                            }
                        });
                    }
                }
            }
        }