private void _client_OnDisconnected(object sender, CloseEventArgs e) { OnDisconnected?.Invoke(this, new OnDisconnectedArgs { Username = TwitchUsername }); JoinedChannels.Clear(); }
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; }
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()); }
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; } }
void OnForceLeaveChannel(string[] args) { var channel = args[0]; JoinedChannels.Remove(channel); ChannelForceLeave(this, new TasEventArgs(args)); }
/// <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())); }
private async Task Process(ChangeTopic changeTopic) { Channel chan; if (JoinedChannels.TryGetValue(changeTopic.ChannelName, out chan)) { chan.Topic = changeTopic.Topic; } ChannelTopicChanged(this, changeTopic); }
public async Task LeaveChannel(string channelName) { if (JoinedChannels.ContainsKey(channelName)) { await SendCommand(new LeaveChannel() { ChannelName = channelName }); } }
/// <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; }
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)); }
/// <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; }
/// <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}")); } }
/// <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 } }; }
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)); }
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); }
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); } }
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)); } } }
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); }
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."); } }
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); } }
/// <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(); } }
/// <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; }
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(); }
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; } }
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 }); } } }
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."); } } }
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 } }); } } } }