/// <summary> /// Parses and handles a "clientlist" response and updates the dictionary of client ID/nicknames /// </summary> /// <param name="clientList">The client list response</param> private void AddClients(string clientList) { var clientStrings = clientList.Split('|'); foreach (var clientString in clientStrings) { if (clientString.Contains(Properties.ClientID) && clientString.Contains(Properties.ClientNickname)) { uint clientId = DecodeUtility.DecodeUIntProperty(clientString, Properties.ClientID); string clientNickname = DecodeUtility.DecodeStringProperty(clientString, true, Properties.ClientNickname); uint channelId = 0; if (clientString.Contains(Properties.ChannelID) || clientString.Contains(Properties.TargetChannelID)) { channelId = DecodeUtility.DecodeUIntProperty(clientString, Properties.ChannelID, Properties.TargetChannelID); } var client = new Client(clientId, clientNickname, channelId); this.clients.AddOrUpdate(clientId, client, (key, oldValue) => client); // If they joined the current channel, raise the client entered channel event if (client.ChannelID == this.CurrentChannelID) { this.localClients.AddOrUpdate(clientId, this.clients[clientId], (key, oldValue) => this.clients[clientId]); this.RaiseClientEnteredChannel(new Data.ClientEventArgs(clientId, this.clients[clientId].Name)); } } } }
/// <summary> /// Handles the ClientUpdated TS notification /// </summary> /// <param name="notificationString">The notification string</param> private void HandleClientUpdated(string notificationString) { // Someone changed their nickname if (notificationString.Contains(Properties.ClientNickname)) { uint clientId = DecodeUtility.DecodeUIntProperty(notificationString, Properties.ClientID); if (this.clients.ContainsKey(clientId)) { string clientNickname = DecodeUtility.DecodeStringProperty(notificationString, true, Properties.ClientNickname); this.clients[clientId].Name = clientNickname; } } }
/// <summary> /// Handles the ClientExitedView TS notification /// </summary> /// <param name="notificationString">The notification string</param> private void HandleClientExitedView(string notificationString) { // Someone left the server var clientId = DecodeUtility.DecodeUIntProperty(notificationString, Properties.ClientID); Client client; if (this.clients.TryRemove(clientId, out client)) { if (client.ChannelID == this.currentChannelID) { // They were in our channel, so raise the client left channel event Client throwAway; this.localClients.TryRemove(clientId, out throwAway); this.RaiseClientExitedChannel(new Data.ClientEventArgs(clientId, client.Name)); } } }
internal static Channel FromChannelString(string channelString) { var parts = channelString.Split(' ', '\n', '\r'); uint id = DecodeUtility.DecodeUIntProperty(channelString, Properties.ChannelID); uint parentId = 0; if (parts.FirstOrDefault(part => part.StartsWith(Properties.ParentID)) != null || parts.FirstOrDefault(part => part.StartsWith(Properties.ChannelParentID)) != null) { parentId = DecodeUtility.DecodeUIntProperty(channelString, Properties.ParentID, Properties.ChannelParentID); } uint order = 0; if (parts.FirstOrDefault(part => part.StartsWith(Properties.ChannelOrder)) != null) { order = DecodeUtility.DecodeUIntProperty(channelString, Properties.ChannelOrder); } string name = string.Empty; if (parts.FirstOrDefault(part => part.StartsWith(Properties.ChannelName)) != null) { name = DecodeUtility.DecodeStringProperty(channelString, true, Properties.ChannelName); } uint clientsCount = 0; if (parts.FirstOrDefault(part => part.StartsWith(Properties.ChannelClientsCount)) != null) { clientsCount = DecodeUtility.DecodeUIntProperty(channelString, Properties.ChannelClientsCount); } bool isSpacer = SpacerInfo.Parse(name) != null; Channel channelInfo = new Channel(id, name, isSpacer) { ParentID = parentId, Order = order, ClientsCount = clientsCount }; return(channelInfo); }
/// <summary> /// Handles the ClientMoved TS notification /// </summary> /// <param name="notificationString">The notification string</param> private void HandleClientMoved(string notificationString) { // Client moved channel if (this.currentClientID == DecodeUtility.DecodeUIntProperty(notificationString, Properties.ClientID)) { // The current user moved channel, so update our current channel uint prevChannelId = this.currentChannelID; uint channelId = DecodeUtility.DecodeUIntProperty(notificationString, Properties.ChannelID, Properties.TargetChannelID); this.currentChannelID = channelId; logger.Trace("New Channel ID: {0}", this.currentChannelID); this.RequestCurrentChannelInfo(); foreach (var client in this.localClients.Values) { this.RaiseClientExitedChannel(new ClientEventArgs(client.ID, client.Name)); } this.localClients.Clear(); // Also raise channel updated for the channel that lost the client and the channel that gained the client if (this.channels.ContainsKey(prevChannelId)) { this.channels[prevChannelId].ClientsCount--; this.RaiseChannelUpdated(new ChannelEventArgs(this.channels[prevChannelId])); } if (this.channels.ContainsKey(this.currentChannelID)) { this.channels[this.currentChannelID].ClientsCount++; this.RaiseChannelUpdated(new ChannelEventArgs(this.channels[this.currentChannelID])); } // Request the client list for the current channel Task.Factory.StartNew(() => { string result = this.TsConnection.SendCommand(new Command("clientlist")); if (!string.IsNullOrEmpty(result)) { this.AddClients(result); } }); } else { // Someone else moved - raise the client entered/exited based on what channel they moved to uint clientId = DecodeUtility.DecodeUIntProperty(notificationString, Properties.ClientID); uint newChannelId = DecodeUtility.DecodeUIntProperty(notificationString, Properties.ChannelID, Properties.TargetChannelID); uint prevChannelId = 0; if (this.clients.ContainsKey(clientId)) { prevChannelId = this.clients[clientId].ChannelID; if (this.localClients.ContainsKey(clientId)) { // Someone left the channel Client throwAway; this.localClients.TryRemove(clientId, out throwAway); this.RaiseClientExitedChannel(new Data.ClientEventArgs(clientId, this.clients[clientId].Name)); } else if (newChannelId == this.currentChannelID) { // Someone joined the channel this.localClients.AddOrUpdate(clientId, this.clients[clientId], (key, oldValue) => this.clients[clientId]); this.RaiseClientEnteredChannel(new Data.ClientEventArgs(clientId, this.clients[clientId].Name)); } this.clients[clientId].ChannelID = newChannelId; } else { this.AddClients(notificationString); } // Also raise channel updated for the channel that lost the client and the channel that gained the client if (this.channels.ContainsKey(prevChannelId)) { this.channels[prevChannelId].ClientsCount--; this.RaiseChannelUpdated(new ChannelEventArgs(this.channels[prevChannelId])); } if (this.channels.ContainsKey(newChannelId)) { this.channels[newChannelId].ClientsCount++; this.RaiseChannelUpdated(new ChannelEventArgs(this.channels[newChannelId])); } } }