using System.Collections.Generic; using System.Linq; using System.Text; namespace SharpChat { public class ChatChannel : IPacketTarget { public string Name { get; set; } public string Password { get; set; } = string.Empty; public bool IsTemporary { get; set; } = false; public int Rank { get; set; } = 0; public ChatUser Owner { get; set; } = null; private List Users { get; } = new List(); private List Typing { get; } = new List(); public bool HasPassword => !string.IsNullOrWhiteSpace(Password); public string TargetName => Name; public ChatChannel() { } public ChatChannel(string name) { Name = name; } public bool HasUser(ChatUser user) { lock (Users) return Users.Contains(user); } public void UserJoin(ChatUser user) { if (!user.InChannel(this)) { // Remove this, a different means for this should be established for V1 compat. user.Channel?.UserLeave(user); user.JoinChannel(this); } lock (Users) { if (!HasUser(user)) Users.Add(user); } } public void UserLeave(ChatUser user) { lock (Users) Users.Remove(user); if (user.InChannel(this)) user.LeaveChannel(this); } public void Send(IServerPacket packet) { lock (Users) { foreach (ChatUser user in Users) user.Send(packet); } } public IEnumerable GetUsers(IEnumerable exclude = null) { lock (Users) { IEnumerable users = Users.OrderByDescending(x => x.Rank); if (exclude != null) users = users.Except(exclude); return users.ToList(); } } public bool IsTyping(ChatUser user) { if(user == null) return false; lock(Typing) return Typing.Any(x => x.User == user && !x.HasExpired); } public bool CanType(ChatUser user) { if(user == null || !HasUser(user)) return false; return !IsTyping(user); } public ChatChannelTyping RegisterTyping(ChatUser user) { if(user == null || !HasUser(user)) return null; ChatChannelTyping typing = new ChatChannelTyping(user); lock(Typing) { Typing.RemoveAll(x => x.HasExpired); Typing.Add(typing); } return typing; } public string Pack() { StringBuilder sb = new StringBuilder(); sb.Append(Name); sb.Append('\t'); sb.Append(string.IsNullOrEmpty(Password) ? '0' : '1'); sb.Append('\t'); sb.Append(IsTemporary ? '1' : '0'); return sb.ToString(); } } }