No longer keep track of connections within the ChatUser class.
This commit is contained in:
parent
06af94e94f
commit
13ae843c8d
28 changed files with 202 additions and 209 deletions
|
@ -46,11 +46,6 @@ namespace SharpChat {
|
|||
user.LeaveChannel(this);
|
||||
}
|
||||
|
||||
public void Send(IServerPacket packet) {
|
||||
foreach(ChatUser user in Users)
|
||||
user.Send(packet);
|
||||
}
|
||||
|
||||
public IEnumerable<ChatUser> GetUsers(IEnumerable<ChatUser> exclude = null) {
|
||||
IEnumerable<ChatUser> users = Users.OrderByDescending(x => x.Rank);
|
||||
|
||||
|
|
|
@ -17,7 +17,7 @@ namespace SharpChat {
|
|||
|
||||
public string Id { get; private set; }
|
||||
public bool IsDisposed { get; private set; }
|
||||
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.MinValue;
|
||||
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.Now;
|
||||
public ChatUser User { get; set; }
|
||||
|
||||
private int CloseCode { get; set; } = 1000;
|
||||
|
@ -39,6 +39,10 @@ namespace SharpChat {
|
|||
}
|
||||
}
|
||||
|
||||
public bool IsAlive => !IsDisposed && !HasTimedOut;
|
||||
|
||||
public bool IsAuthed => IsAlive && User is not null;
|
||||
|
||||
public ChatConnection(IWebSocketConnection sock) {
|
||||
Socket = sock;
|
||||
Id = RNG.SecureRandomString(ID_LENGTH);
|
||||
|
|
|
@ -5,6 +5,7 @@ using SharpChat.Packet;
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
|
||||
namespace SharpChat {
|
||||
public class ChatContext {
|
||||
|
@ -25,18 +26,21 @@ namespace SharpChat {
|
|||
}
|
||||
|
||||
public void Update() {
|
||||
lock(UsersAccess)
|
||||
foreach(ChatUser user in Users) {
|
||||
IEnumerable<ChatConnection> timedOut = user.GetDeadConnections();
|
||||
|
||||
foreach(ChatConnection conn in timedOut) {
|
||||
user.RemoveConnection(conn);
|
||||
lock(ConnectionsAccess) {
|
||||
foreach(ChatConnection conn in Connections)
|
||||
if(!conn.IsDisposed && conn.HasTimedOut) {
|
||||
conn.Dispose();
|
||||
Logger.Write($"Nuked session {conn.Id} from {user.Username} (timeout)");
|
||||
Logger.Write($"Nuked connection {conn.Id} associated with {conn.User}.");
|
||||
}
|
||||
|
||||
if(!user.HasConnections)
|
||||
Connections.RemoveWhere(conn => conn.IsDisposed);
|
||||
|
||||
lock(UsersAccess)
|
||||
foreach(ChatUser user in Users)
|
||||
if(!Connections.Any(conn => conn.User == user)) {
|
||||
UserLeave(null, user, UserDisconnectReason.TimeOut);
|
||||
Logger.Write($"Timed out {user} (no more connections).");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -46,18 +50,24 @@ namespace SharpChat {
|
|||
|
||||
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
|
||||
if(duration > TimeSpan.Zero)
|
||||
user.Send(new ForceDisconnectPacket(ForceDisconnectReason.Banned, DateTimeOffset.Now + duration));
|
||||
SendTo(user, new ForceDisconnectPacket(ForceDisconnectReason.Banned, DateTimeOffset.Now + duration));
|
||||
else
|
||||
user.Send(new ForceDisconnectPacket(ForceDisconnectReason.Kicked));
|
||||
SendTo(user, new ForceDisconnectPacket(ForceDisconnectReason.Kicked));
|
||||
|
||||
lock(ConnectionsAccess) {
|
||||
foreach(ChatConnection conn in Connections)
|
||||
if(conn.User == user)
|
||||
conn.Dispose();
|
||||
Connections.RemoveWhere(conn => conn.IsDisposed);
|
||||
}
|
||||
|
||||
user.Close();
|
||||
UserLeave(user.Channel, user, reason);
|
||||
}
|
||||
|
||||
public void HandleJoin(ChatUser user, ChatChannel chan, ChatConnection conn, int maxMsgLength) {
|
||||
lock(EventsAccess) {
|
||||
if(!chan.HasUser(user)) {
|
||||
chan.Send(new UserConnectPacket(DateTimeOffset.Now, user));
|
||||
SendTo(chan, new UserConnectPacket(DateTimeOffset.Now, user));
|
||||
Events.AddEvent(new UserConnectEvent(DateTimeOffset.Now, user, chan));
|
||||
}
|
||||
|
||||
|
@ -94,28 +104,27 @@ namespace SharpChat {
|
|||
|
||||
lock(EventsAccess) {
|
||||
chan.UserLeave(user);
|
||||
chan.Send(new UserDisconnectPacket(DateTimeOffset.Now, user, reason));
|
||||
SendTo(chan, new UserDisconnectPacket(DateTimeOffset.Now, user, reason));
|
||||
Events.AddEvent(new UserDisconnectEvent(DateTimeOffset.Now, user, chan, reason));
|
||||
}
|
||||
}
|
||||
|
||||
public void SwitchChannel(ChatUser user, ChatChannel chan, string password) {
|
||||
if(user.CurrentChannel == chan) {
|
||||
//user.Send(true, "samechan", chan.Name);
|
||||
user.ForceChannel();
|
||||
ForceChannel(user);
|
||||
return;
|
||||
}
|
||||
|
||||
if(!user.Can(ChatUserPermissions.JoinAnyChannel) && chan.Owner != user) {
|
||||
if(chan.Rank > user.Rank) {
|
||||
user.Send(new LegacyCommandResponse(LCR.CHANNEL_INSUFFICIENT_HIERARCHY, true, chan.Name));
|
||||
user.ForceChannel();
|
||||
SendTo(user, new LegacyCommandResponse(LCR.CHANNEL_INSUFFICIENT_HIERARCHY, true, chan.Name));
|
||||
ForceChannel(user);
|
||||
return;
|
||||
}
|
||||
|
||||
if(chan.Password != password) {
|
||||
user.Send(new LegacyCommandResponse(LCR.CHANNEL_INVALID_PASSWORD, true, chan.Name));
|
||||
user.ForceChannel();
|
||||
SendTo(user, new LegacyCommandResponse(LCR.CHANNEL_INVALID_PASSWORD, true, chan.Name));
|
||||
ForceChannel(user);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -131,18 +140,18 @@ namespace SharpChat {
|
|||
ChatChannel oldChan = user.CurrentChannel;
|
||||
|
||||
lock(EventsAccess) {
|
||||
oldChan.Send(new UserChannelLeavePacket(user));
|
||||
SendTo(oldChan, new UserChannelLeavePacket(user));
|
||||
Events.AddEvent(new UserChannelLeaveEvent(DateTimeOffset.Now, user, oldChan));
|
||||
chan.Send(new UserChannelJoinPacket(user));
|
||||
SendTo(chan, new UserChannelJoinPacket(user));
|
||||
Events.AddEvent(new UserChannelJoinEvent(DateTimeOffset.Now, user, chan));
|
||||
|
||||
user.Send(new ContextClearPacket(chan, ContextClearMode.MessagesUsers));
|
||||
user.Send(new ContextUsersPacket(chan.GetUsers(new[] { user })));
|
||||
SendTo(user, new ContextClearPacket(chan, ContextClearMode.MessagesUsers));
|
||||
SendTo(user, new ContextUsersPacket(chan.GetUsers(new[] { user })));
|
||||
|
||||
foreach(IChatEvent msg in Events.GetTargetEventLog(chan.Name))
|
||||
user.Send(new ContextMessagePacket(msg));
|
||||
SendTo(user, new ContextMessagePacket(msg));
|
||||
|
||||
user.ForceChannel(chan);
|
||||
ForceChannel(user, chan);
|
||||
oldChan.UserLeave(user);
|
||||
chan.UserJoin(user);
|
||||
}
|
||||
|
@ -153,9 +162,50 @@ namespace SharpChat {
|
|||
}
|
||||
|
||||
public void Send(IServerPacket packet) {
|
||||
lock(UsersAccess)
|
||||
foreach(ChatUser user in Users)
|
||||
user.Send(packet);
|
||||
if(packet == null)
|
||||
throw new ArgumentNullException(nameof(packet));
|
||||
|
||||
lock(ConnectionsAccess)
|
||||
foreach(ChatConnection conn in Connections)
|
||||
if(conn.IsAuthed)
|
||||
conn.Send(packet);
|
||||
}
|
||||
|
||||
public void SendTo(ChatUser user, IServerPacket packet) {
|
||||
if(user == null)
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
if(packet == null)
|
||||
throw new ArgumentNullException(nameof(packet));
|
||||
|
||||
lock(ConnectionsAccess)
|
||||
foreach(ChatConnection conn in Connections)
|
||||
if(conn.IsAlive && conn.User == user)
|
||||
conn.Send(packet);
|
||||
}
|
||||
|
||||
public void SendTo(ChatChannel channel, IServerPacket packet) {
|
||||
if(channel == null)
|
||||
throw new ArgumentNullException(nameof(channel));
|
||||
if(packet == null)
|
||||
throw new ArgumentNullException(nameof(packet));
|
||||
|
||||
lock(ConnectionsAccess) {
|
||||
IEnumerable<ChatConnection> conns = Connections.Where(c => c.IsAuthed && channel.HasUser(c.User));
|
||||
foreach(ChatConnection conn in conns)
|
||||
conn.Send(packet);
|
||||
}
|
||||
}
|
||||
|
||||
public IPAddress[] GetRemoteAddresses(ChatUser user) {
|
||||
lock(ConnectionsAccess)
|
||||
return Connections.Where(c => c.IsAlive && c.User == user).Select(c => c.RemoteAddress).Distinct().ToArray();
|
||||
}
|
||||
|
||||
public void ForceChannel(ChatUser user, ChatChannel chan = null) {
|
||||
if(user == null)
|
||||
throw new ArgumentNullException(nameof(user));
|
||||
|
||||
SendTo(user, new UserChannelForceJoinPacket(chan ?? user.CurrentChannel));
|
||||
}
|
||||
|
||||
public void UpdateChannel(ChatChannel channel, string name = null, bool? temporary = null, int? hierarchy = null, string password = null) {
|
||||
|
@ -187,10 +237,10 @@ namespace SharpChat {
|
|||
// Users that no longer have access to the channel/gained access to the channel by the hierarchy change should receive delete and create packets respectively
|
||||
lock(UsersAccess)
|
||||
foreach(ChatUser user in Users.Where(u => u.Rank >= channel.Rank)) {
|
||||
user.Send(new ChannelUpdatePacket(prevName, channel));
|
||||
SendTo(user, new ChannelUpdatePacket(prevName, channel));
|
||||
|
||||
if(nameUpdated)
|
||||
user.ForceChannel();
|
||||
ForceChannel(user);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -213,7 +263,7 @@ namespace SharpChat {
|
|||
// Broadcast deletion of channel
|
||||
lock(UsersAccess)
|
||||
foreach(ChatUser user in Users.Where(u => u.Rank >= channel.Rank))
|
||||
user.Send(new ChannelDeletePacket(channel));
|
||||
SendTo(user, new ChannelDeletePacket(channel));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,9 +1,7 @@
|
|||
using SharpChat.Misuzu;
|
||||
using SharpChat.Packet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Net;
|
||||
using System.Text;
|
||||
|
||||
namespace SharpChat {
|
||||
|
@ -83,7 +81,6 @@ namespace SharpChat {
|
|||
public class ChatUser : BasicUser, IPacketTarget {
|
||||
public DateTimeOffset SilencedUntil { get; set; }
|
||||
|
||||
private readonly List<ChatConnection> Connections = new();
|
||||
private readonly List<ChatChannel> Channels = new();
|
||||
|
||||
public readonly ChatRateLimiter RateLimiter = new();
|
||||
|
@ -98,12 +95,6 @@ namespace SharpChat {
|
|||
public bool IsSilenced
|
||||
=> DateTimeOffset.UtcNow - SilencedUntil <= TimeSpan.Zero;
|
||||
|
||||
public bool HasConnections => Connections.Where(c => !c.HasTimedOut && !c.IsDisposed).Any();
|
||||
|
||||
public int ConnectionCount => Connections.Where(c => !c.HasTimedOut && !c.IsDisposed).Count();
|
||||
|
||||
public IEnumerable<IPAddress> RemoteAddresses => Connections.Select(c => c.RemoteAddress);
|
||||
|
||||
public ChatUser() {}
|
||||
|
||||
public ChatUser(MisuzuAuthInfo auth) {
|
||||
|
@ -125,26 +116,6 @@ namespace SharpChat {
|
|||
SilencedUntil = auth.SilencedUntil;
|
||||
}
|
||||
|
||||
public void Send(IServerPacket packet) {
|
||||
foreach(ChatConnection conn in Connections)
|
||||
conn.Send(packet);
|
||||
}
|
||||
|
||||
public void Close() {
|
||||
foreach(ChatConnection conn in Connections)
|
||||
conn.Dispose();
|
||||
Connections.Clear();
|
||||
}
|
||||
|
||||
public void ForceChannel(ChatChannel chan = null) {
|
||||
Send(new UserChannelForceJoinPacket(chan ?? CurrentChannel));
|
||||
}
|
||||
|
||||
public void FocusChannel(ChatChannel chan) {
|
||||
if(InChannel(chan))
|
||||
CurrentChannel = chan;
|
||||
}
|
||||
|
||||
public bool InChannel(ChatChannel chan) {
|
||||
return Channels.Contains(chan);
|
||||
}
|
||||
|
@ -165,27 +136,6 @@ namespace SharpChat {
|
|||
return Channels.ToList();
|
||||
}
|
||||
|
||||
public void AddConnection(ChatConnection conn) {
|
||||
if(conn == null)
|
||||
return;
|
||||
conn.User = this;
|
||||
|
||||
Connections.Add(conn);
|
||||
}
|
||||
|
||||
public void RemoveConnection(ChatConnection conn) {
|
||||
if(conn == null)
|
||||
return;
|
||||
if(!conn.IsDisposed) // this could be possible
|
||||
conn.User = null;
|
||||
|
||||
Connections.Remove(conn);
|
||||
}
|
||||
|
||||
public IEnumerable<ChatConnection> GetDeadConnections() {
|
||||
return Connections.Where(x => x.HasTimedOut || x.IsDisposed).ToList();
|
||||
}
|
||||
|
||||
public bool NameEquals(string name) {
|
||||
return string.Equals(name, Username, StringComparison.InvariantCultureIgnoreCase)
|
||||
|| string.Equals(name, Nickname, StringComparison.InvariantCultureIgnoreCase)
|
||||
|
|
|
@ -22,7 +22,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
ctx.User.Status = ChatUserStatus.Away;
|
||||
ctx.User.StatusMessage = statusText;
|
||||
ctx.Channel.Send(new UserUpdatePacket(ctx.User));
|
||||
ctx.Chat.SendTo(ctx.Channel, new UserUpdatePacket(ctx.User));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,12 +18,12 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.BanUser | ChatUserPermissions.KickUser)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
Task.Run(async () => {
|
||||
ctx.User.Send(new BanListPacket(
|
||||
ctx.Chat.SendTo(ctx.User, new BanListPacket(
|
||||
await Misuzu.GetBanListAsync()
|
||||
));
|
||||
}).Wait();
|
||||
|
|
|
@ -9,11 +9,11 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.Broadcast)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
ctx.Chat.Send(new LegacyCommandResponse(LCR.BROADCAST, false, string.Join(' ', ctx.Args)));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.BROADCAST, false, string.Join(' ', ctx.Args)));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(ctx.User.Can(ChatUserPermissions.CreateChannel)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -17,7 +17,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
bool createChanHasHierarchy;
|
||||
if(!ctx.Args.Any() || (createChanHasHierarchy = firstArg.All(char.IsDigit) && ctx.Args.Length < 2)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -27,20 +27,20 @@ namespace SharpChat.Commands {
|
|||
createChanHierarchy = 0;
|
||||
|
||||
if(createChanHierarchy > ctx.User.Rank) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.INSUFFICIENT_HIERARCHY));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.INSUFFICIENT_HIERARCHY));
|
||||
return;
|
||||
}
|
||||
|
||||
string createChanName = string.Join('_', ctx.Args.Skip(createChanHasHierarchy ? 1 : 0));
|
||||
|
||||
if(!ChatChannel.CheckName(createChanName)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_NAME_INVALID));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NAME_INVALID));
|
||||
return;
|
||||
}
|
||||
|
||||
lock(ctx.Chat.ChannelsAccess) {
|
||||
if(ctx.Chat.Channels.Any(c => c.NameEquals(createChanName))) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_ALREADY_EXISTS, true, createChanName));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_ALREADY_EXISTS, true, createChanName));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -54,11 +54,11 @@ namespace SharpChat.Commands {
|
|||
ctx.Chat.Channels.Add(createChan);
|
||||
lock(ctx.Chat.UsersAccess) {
|
||||
foreach(ChatUser ccu in ctx.Chat.Users.Where(u => u.Rank >= ctx.Channel.Rank))
|
||||
ccu.Send(new ChannelCreatePacket(ctx.Channel));
|
||||
ctx.Chat.SendTo(ccu, new ChannelCreatePacket(ctx.Channel));
|
||||
}
|
||||
|
||||
ctx.Chat.SwitchChannel(ctx.User, createChan, createChan.Password);
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_CREATED, false, createChan.Name));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_CREATED, false, createChan.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.Args.Any() || string.IsNullOrWhiteSpace(ctx.Args.FirstOrDefault())) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,18 +22,18 @@ namespace SharpChat.Commands {
|
|||
delChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(delChanName));
|
||||
|
||||
if(delChan == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, delChanName));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, delChanName));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ctx.User.Can(ChatUserPermissions.DeleteChannel) && delChan.Owner != ctx.User) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_DELETE_FAILED, true, delChan.Name));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_DELETE_FAILED, true, delChan.Name));
|
||||
return;
|
||||
}
|
||||
|
||||
lock(ctx.Chat.ChannelsAccess)
|
||||
ctx.Chat.RemoveChannel(delChan);
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_DELETED, false, delChan.Name));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_DELETED, false, delChan.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -15,14 +15,14 @@ namespace SharpChat.Commands {
|
|||
bool deleteAnyMessage = ctx.User.Can(ChatUserPermissions.DeleteAnyMessage);
|
||||
|
||||
if(!deleteAnyMessage && !ctx.User.Can(ChatUserPermissions.DeleteOwnMessage)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
string firstArg = ctx.Args.FirstOrDefault();
|
||||
|
||||
if(string.IsNullOrWhiteSpace(firstArg) || !firstArg.All(char.IsDigit) || !long.TryParse(firstArg, out long delSeqId)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -30,7 +30,7 @@ namespace SharpChat.Commands {
|
|||
IChatEvent delMsg = ctx.Chat.Events.GetEvent(delSeqId);
|
||||
|
||||
if(delMsg == null || delMsg.Sender.Rank > ctx.User.Rank || (!deleteAnyMessage && delMsg.Sender.UserId != ctx.User.UserId)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.MESSAGE_DELETE_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.MESSAGE_DELETE_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -14,8 +14,8 @@ namespace SharpChat.Commands {
|
|||
joinChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(joinChanStr));
|
||||
|
||||
if(joinChan == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, joinChanStr));
|
||||
ctx.User.ForceChannel();
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, joinChanStr));
|
||||
ctx.Chat.ForceChannel(ctx.User);
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ namespace SharpChat.Commands {
|
|||
bool isBanning = ctx.NameEquals("ban");
|
||||
|
||||
if(!ctx.User.Can(isBanning ? ChatUserPermissions.BanUser : ChatUserPermissions.KickUser)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -32,19 +32,19 @@ namespace SharpChat.Commands {
|
|||
|
||||
lock(ctx.Chat.UsersAccess)
|
||||
if(banUserTarget == null || (banUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, banUser == null ? "User" : banUserTarget));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, banUser == null ? "User" : banUserTarget));
|
||||
return;
|
||||
}
|
||||
|
||||
if(banUser == ctx.User || banUser.Rank >= ctx.User.Rank) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.DisplayName));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.DisplayName));
|
||||
return;
|
||||
}
|
||||
|
||||
TimeSpan duration = isBanning ? TimeSpan.MaxValue : TimeSpan.Zero;
|
||||
if(!string.IsNullOrWhiteSpace(banDurationStr) && double.TryParse(banDurationStr, out double durationSeconds)) {
|
||||
if(durationSeconds < 0) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -60,18 +60,19 @@ namespace SharpChat.Commands {
|
|||
string banReason = string.Join(' ', ctx.Args.Skip(banReasonIndex));
|
||||
|
||||
Task.Run(async () => {
|
||||
string userId = banUser.UserId.ToString();
|
||||
string userIp = ctx.Chat.GetRemoteAddresses(banUser).FirstOrDefault()?.ToString() ?? string.Empty;
|
||||
|
||||
// obviously it makes no sense to only check for one ip address but that's current misuzu limitations
|
||||
MisuzuBanInfo fbi = await Misuzu.CheckBanAsync(
|
||||
banUser.UserId.ToString(), banUser.RemoteAddresses.First().ToString()
|
||||
);
|
||||
MisuzuBanInfo fbi = await Misuzu.CheckBanAsync(userId, userIp);
|
||||
|
||||
if(fbi.IsBanned && !fbi.HasExpired) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.DisplayName));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.DisplayName));
|
||||
return;
|
||||
}
|
||||
|
||||
await Misuzu.CreateBanAsync(
|
||||
banUser.UserId.ToString(), banUser.RemoteAddresses.First().ToString(),
|
||||
userId, userIp,
|
||||
ctx.User.UserId.ToString(), ctx.Connection.RemoteAddress.ToString(),
|
||||
duration, banReason
|
||||
);
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace SharpChat.Commands {
|
|||
bool setOthersNick = ctx.User.Can(ChatUserPermissions.SetOthersNickname);
|
||||
|
||||
if(!setOthersNick && !ctx.User.Can(ChatUserPermissions.SetOwnNickname)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
ChatUser targetUser = null;
|
||||
|
@ -26,7 +26,7 @@ namespace SharpChat.Commands {
|
|||
targetUser ??= ctx.User;
|
||||
|
||||
if(ctx.Args.Length < offset) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -44,13 +44,13 @@ namespace SharpChat.Commands {
|
|||
|
||||
lock(ctx.Chat.UsersAccess)
|
||||
if(!string.IsNullOrWhiteSpace(nickStr) && ctx.Chat.Users.Any(u => u.NameEquals(nickStr))) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.NAME_IN_USE, true, nickStr));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.NAME_IN_USE, true, nickStr));
|
||||
return;
|
||||
}
|
||||
|
||||
string previousName = targetUser == ctx.User ? (targetUser.Nickname ?? targetUser.Username) : null;
|
||||
targetUser.Nickname = nickStr;
|
||||
ctx.Channel.Send(new UserUpdatePacket(targetUser, previousName));
|
||||
ctx.Chat.SendTo(ctx.Channel, new UserUpdatePacket(targetUser, previousName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -20,13 +20,13 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.BanUser | ChatUserPermissions.KickUser)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
string unbanAddrTarget = ctx.Args.FirstOrDefault();
|
||||
if(string.IsNullOrWhiteSpace(unbanAddrTarget) || !IPAddress.TryParse(unbanAddrTarget, out IPAddress unbanAddr)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -36,15 +36,15 @@ namespace SharpChat.Commands {
|
|||
MisuzuBanInfo banInfo = await Misuzu.CheckBanAsync(ipAddr: unbanAddrTarget);
|
||||
|
||||
if(!banInfo.IsBanned || banInfo.HasExpired) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget));
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasBanned = await Misuzu.RevokeBanAsync(banInfo, MisuzuClient.BanRevokeKind.RemoteAddress);
|
||||
if(wasBanned)
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_UNBANNED, false, unbanAddrTarget));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_UNBANNED, false, unbanAddrTarget));
|
||||
else
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget));
|
||||
}).Wait();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,14 +19,14 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.BanUser | ChatUserPermissions.KickUser)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
bool unbanUserTargetIsName = true;
|
||||
string unbanUserTarget = ctx.Args.FirstOrDefault();
|
||||
if(string.IsNullOrWhiteSpace(unbanUserTarget)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -46,15 +46,15 @@ namespace SharpChat.Commands {
|
|||
MisuzuBanInfo banInfo = await Misuzu.CheckBanAsync(unbanUserTarget, userIdIsName: unbanUserTargetIsName);
|
||||
|
||||
if(!banInfo.IsBanned || banInfo.HasExpired) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget));
|
||||
return;
|
||||
}
|
||||
|
||||
bool wasBanned = await Misuzu.RevokeBanAsync(banInfo, MisuzuClient.BanRevokeKind.UserId);
|
||||
if(wasBanned)
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_UNBANNED, false, unbanUserTarget));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_UNBANNED, false, unbanUserTarget));
|
||||
else
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget));
|
||||
}).Wait();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.SetChannelPassword) || ctx.Channel.Owner != ctx.User) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -20,7 +20,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
lock(ctx.Chat.ChannelsAccess)
|
||||
ctx.Chat.UpdateChannel(ctx.Channel, password: chanPass);
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_PASSWORD_CHANGED, false));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_PASSWORD_CHANGED, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,18 +11,18 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.SetChannelHierarchy) || ctx.Channel.Owner != ctx.User) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!ctx.Args.Any() || !int.TryParse(ctx.Args.First(), out int chanHierarchy) || chanHierarchy > ctx.User.Rank) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.INSUFFICIENT_HIERARCHY));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.INSUFFICIENT_HIERARCHY));
|
||||
return;
|
||||
}
|
||||
|
||||
lock(ctx.Chat.ChannelsAccess)
|
||||
ctx.Chat.UpdateChannel(ctx.Channel, hierarchy: chanHierarchy);
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_HIERARCHY_CHANGED, false));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_HIERARCHY_CHANGED, false));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.SeeIPAddress)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, "/ip"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, "/ip"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -20,12 +20,12 @@ namespace SharpChat.Commands {
|
|||
|
||||
lock(ctx.Chat.UsersAccess)
|
||||
if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, ipUserStr ?? "User"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, ipUserStr ?? "User"));
|
||||
return;
|
||||
}
|
||||
|
||||
foreach(IPAddress ip in ipUser.RemoteAddresses.Distinct().ToArray())
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.IP_ADDRESS, false, ipUser.Username, ip));
|
||||
foreach(IPAddress ip in ctx.Chat.GetRemoteAddresses(ipUser))
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.IP_ADDRESS, false, ipUser.Username, ip));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(ctx.User.UserId != 1) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.SilenceUser)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -19,22 +19,22 @@ namespace SharpChat.Commands {
|
|||
|
||||
lock(ctx.Chat.UsersAccess)
|
||||
if(string.IsNullOrWhiteSpace(silUserStr) || (silUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(silUserStr))) == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, silUserStr ?? "User"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, silUserStr ?? "User"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(silUser == ctx.User) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.SILENCE_SELF));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.SILENCE_SELF));
|
||||
return;
|
||||
}
|
||||
|
||||
if(silUser.Rank >= ctx.User.Rank) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.SILENCE_HIERARCHY));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.SILENCE_HIERARCHY));
|
||||
return;
|
||||
}
|
||||
|
||||
if(silUser.IsSilenced) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.SILENCE_ALREADY));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.SILENCE_ALREADY));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
if(ctx.Args.Length > 1) {
|
||||
if(!double.TryParse(ctx.Args.ElementAt(1), out double silenceSeconds)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -50,8 +50,8 @@ namespace SharpChat.Commands {
|
|||
}
|
||||
|
||||
silUser.SilencedUntil = silenceUntil;
|
||||
silUser.Send(new LegacyCommandResponse(LCR.SILENCED, false));
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.TARGET_SILENCED, false, silUser.DisplayName));
|
||||
ctx.Chat.SendTo(silUser, new LegacyCommandResponse(LCR.SILENCED, false));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.TARGET_SILENCED, false, silUser.DisplayName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -10,7 +10,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(!ctx.User.Can(ChatUserPermissions.SilenceUser)) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -19,23 +19,23 @@ namespace SharpChat.Commands {
|
|||
|
||||
lock(ctx.Chat.UsersAccess)
|
||||
if(string.IsNullOrWhiteSpace(unsilUserStr) || (unsilUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(unsilUserStr))) == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, unsilUserStr ?? "User"));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, unsilUserStr ?? "User"));
|
||||
return;
|
||||
}
|
||||
|
||||
if(unsilUser.Rank >= ctx.User.Rank) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.UNSILENCE_HIERARCHY));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.UNSILENCE_HIERARCHY));
|
||||
return;
|
||||
}
|
||||
|
||||
if(!unsilUser.IsSilenced) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.NOT_SILENCED));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.NOT_SILENCED));
|
||||
return;
|
||||
}
|
||||
|
||||
unsilUser.SilencedUntil = DateTimeOffset.MinValue;
|
||||
unsilUser.Send(new LegacyCommandResponse(LCR.UNSILENCED, false));
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.TARGET_UNSILENCED, false, unsilUser.DisplayName));
|
||||
ctx.Chat.SendTo(unsilUser, new LegacyCommandResponse(LCR.UNSILENCED, false));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.TARGET_UNSILENCED, false, unsilUser.DisplayName));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
public void Dispatch(ChatCommandContext ctx) {
|
||||
if(ctx.Args.Length < 2) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -22,7 +22,7 @@ namespace SharpChat.Commands {
|
|||
whisperUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(whisperUserStr));
|
||||
|
||||
if(whisperUser == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, whisperUserStr));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, whisperUserStr));
|
||||
return;
|
||||
}
|
||||
if(whisperUser == ctx.User)
|
||||
|
@ -30,7 +30,7 @@ namespace SharpChat.Commands {
|
|||
|
||||
string whisperStr = string.Join(' ', ctx.Args.Skip(1));
|
||||
|
||||
whisperUser.Send(new ChatMessageAddPacket(new ChatMessage {
|
||||
ctx.Chat.SendTo(whisperUser, new ChatMessageAddPacket(new ChatMessage {
|
||||
DateTime = DateTimeOffset.Now,
|
||||
Target = whisperUser,
|
||||
TargetName = whisperUser.TargetName,
|
||||
|
@ -38,7 +38,7 @@ namespace SharpChat.Commands {
|
|||
Text = whisperStr,
|
||||
Flags = ChatMessageFlags.Private,
|
||||
}));
|
||||
ctx.User.Send(new ChatMessageAddPacket(new ChatMessage {
|
||||
ctx.Chat.SendTo(ctx.User, new ChatMessageAddPacket(new ChatMessage {
|
||||
DateTime = DateTimeOffset.Now,
|
||||
Target = whisperUser,
|
||||
TargetName = whisperUser.TargetName,
|
||||
|
|
|
@ -28,19 +28,19 @@ namespace SharpChat.Commands {
|
|||
if(whoChanSB.Length > 2)
|
||||
whoChanSB.Length -= 2;
|
||||
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USERS_LISTING_SERVER, false, whoChanSB));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_SERVER, false, whoChanSB));
|
||||
} else {
|
||||
ChatChannel whoChan;
|
||||
lock(ctx.Chat.ChannelsAccess)
|
||||
whoChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(whoChanStr));
|
||||
|
||||
if(whoChan == null) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, whoChanStr));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, whoChanStr));
|
||||
return;
|
||||
}
|
||||
|
||||
if(whoChan.Rank > ctx.User.Rank || (whoChan.HasPassword && !ctx.User.Can(ChatUserPermissions.JoinAnyChannel))) {
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USERS_LISTING_ERROR, true, whoChanStr));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_ERROR, true, whoChanStr));
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -58,7 +58,7 @@ namespace SharpChat.Commands {
|
|||
if(whoChanSB.Length > 2)
|
||||
whoChanSB.Length -= 2;
|
||||
|
||||
ctx.User.Send(new LegacyCommandResponse(LCR.USERS_LISTING_CHANNEL, false, whoChan.Name, whoChanSB));
|
||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_CHANNEL, false, whoChan.Name, whoChanSB));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,6 +1,5 @@
|
|||
namespace SharpChat {
|
||||
public interface IPacketTarget {
|
||||
string TargetName { get; }
|
||||
void Send(IServerPacket packet);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -99,28 +99,27 @@ namespace SharpChat.PacketHandlers {
|
|||
}
|
||||
|
||||
lock(ctx.Chat.UsersAccess) {
|
||||
ChatUser aUser = ctx.Chat.Users.FirstOrDefault(u => u.UserId == fai.UserId);
|
||||
ChatUser user = ctx.Chat.Users.FirstOrDefault(u => u.UserId == fai.UserId);
|
||||
|
||||
if(aUser == null)
|
||||
aUser = new ChatUser(fai);
|
||||
if(user == null)
|
||||
user = new ChatUser(fai);
|
||||
else {
|
||||
aUser.ApplyAuth(fai);
|
||||
aUser.Channel?.Send(new UserUpdatePacket(aUser));
|
||||
user.ApplyAuth(fai);
|
||||
if(user.Channel != null)
|
||||
ctx.Chat.SendTo(user.Channel, new UserUpdatePacket(user));
|
||||
}
|
||||
|
||||
// Enforce a maximum amount of connections per user
|
||||
if(aUser.ConnectionCount >= MaxConnections) {
|
||||
lock(ctx.Chat.ConnectionsAccess)
|
||||
if(ctx.Chat.Connections.Count(conn => conn.User == user) >= MaxConnections) {
|
||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.MaxSessions));
|
||||
ctx.Connection.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
// Bumping the ping to prevent upgrading
|
||||
ctx.Connection.BumpPing();
|
||||
|
||||
aUser.AddConnection(ctx.Connection);
|
||||
|
||||
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, $"Welcome to Flashii Chat, {aUser.Username}!"));
|
||||
ctx.Connection.User = user;
|
||||
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, $"Welcome to Flashii Chat, {user.Username}!"));
|
||||
|
||||
if(File.Exists("welcome.txt")) {
|
||||
IEnumerable<string> lines = File.ReadAllLines("welcome.txt").Where(x => !string.IsNullOrWhiteSpace(x));
|
||||
|
@ -130,7 +129,7 @@ namespace SharpChat.PacketHandlers {
|
|||
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, line));
|
||||
}
|
||||
|
||||
ctx.Chat.HandleJoin(aUser, DefaultChannel, ctx.Connection, MaxMessageLength);
|
||||
ctx.Chat.HandleJoin(user, DefaultChannel, ctx.Connection, MaxMessageLength);
|
||||
}
|
||||
}).Wait();
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
using SharpChat.Misuzu;
|
||||
using SharpChat.Packet;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
|
@ -32,11 +33,16 @@ namespace SharpChat.PacketHandlers {
|
|||
lock(BumpAccess) {
|
||||
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
|
||||
(string, string)[] bumpList;
|
||||
lock(ctx.Chat.UsersAccess)
|
||||
bumpList = ctx.Chat.Users
|
||||
.Where(u => u.HasConnections && u.Status == ChatUserStatus.Online)
|
||||
.Select(u => (u.UserId.ToString(), u.RemoteAddresses.FirstOrDefault()?.ToString() ?? string.Empty))
|
||||
lock(ctx.Chat.UsersAccess) {
|
||||
IEnumerable<ChatUser> filtered = ctx.Chat.Users.Where(u => u.Status == ChatUserStatus.Online);
|
||||
|
||||
lock(ctx.Chat.ConnectionsAccess)
|
||||
filtered = filtered.Where(u => ctx.Chat.Connections.Any(c => c.User == u));
|
||||
|
||||
bumpList = filtered
|
||||
.Select(u => (u.UserId.ToString(), ctx.Chat.GetRemoteAddresses(u).FirstOrDefault()?.ToString() ?? string.Empty))
|
||||
.ToArray();
|
||||
}
|
||||
|
||||
if(bumpList.Any())
|
||||
Task.Run(async () => {
|
||||
|
|
|
@ -51,7 +51,7 @@ namespace SharpChat.PacketHandlers {
|
|||
|
||||
if(user.Status != ChatUserStatus.Online) {
|
||||
user.Status = ChatUserStatus.Online;
|
||||
channel.Send(new UserUpdatePacket(user));
|
||||
ctx.Chat.SendTo(channel, new UserUpdatePacket(user));
|
||||
}
|
||||
|
||||
int maxMsgLength = MaxMessageLength;
|
||||
|
@ -97,7 +97,7 @@ namespace SharpChat.PacketHandlers {
|
|||
|
||||
lock(ctx.Chat.EventsAccess) {
|
||||
ctx.Chat.Events.AddEvent(message);
|
||||
channel.Send(new ChatMessageAddPacket(message));
|
||||
ctx.Chat.SendTo(channel, new ChatMessageAddPacket(message));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -143,29 +143,18 @@ namespace SharpChat {
|
|||
private void OnClose(IWebSocketConnection sock) {
|
||||
Logger.Write($"Connection closed from {sock.ConnectionInfo.ClientIpAddress}:{sock.ConnectionInfo.ClientPort}");
|
||||
|
||||
ChatConnection conn;
|
||||
lock(Context.ConnectionsAccess)
|
||||
conn = Context.GetConnection(sock);
|
||||
lock(Context.ConnectionsAccess) {
|
||||
ChatConnection conn = Context.GetConnection(sock);
|
||||
if(conn == null)
|
||||
return;
|
||||
|
||||
// Remove connection from user
|
||||
if(conn?.User != null) {
|
||||
// RemoveConnection sets conn.User to null so we must grab a local copy.
|
||||
ChatUser user = conn.User;
|
||||
|
||||
user.RemoveConnection(conn);
|
||||
|
||||
if(!user.HasConnections)
|
||||
Context.UserLeave(null, user);
|
||||
}
|
||||
|
||||
// Update context
|
||||
Context.Update();
|
||||
|
||||
// Remove connection from server
|
||||
lock(Context.ConnectionsAccess)
|
||||
Context.Connections.Remove(conn);
|
||||
|
||||
conn?.Dispose();
|
||||
if(conn.User != null && !Context.Connections.Any(c => c.User == conn.User))
|
||||
Context.UserLeave(null, conn.User);
|
||||
}
|
||||
|
||||
Context.Update();
|
||||
}
|
||||
|
||||
private void OnError(IWebSocketConnection sock, Exception ex) {
|
||||
|
@ -210,7 +199,7 @@ namespace SharpChat {
|
|||
}).Wait();
|
||||
return;
|
||||
} else if(conn.User.RateLimiter.State == ChatRateLimitState.Warning)
|
||||
conn.User.Send(new FloodWarningPacket());
|
||||
Context.SendTo(conn.User, new FloodWarningPacket());
|
||||
}
|
||||
|
||||
ChatPacketHandlerContext context = new(msg, Context, conn);
|
||||
|
|
Loading…
Reference in a new issue