Cleaned up the names of some of the base classes.
This commit is contained in:
parent
bd23d3aa15
commit
1a8c44a4ba
57 changed files with 336 additions and 336 deletions
SharpChat
BuildInfo.csChannelInfo.csChatContext.csColour.cs
Commands
BanListCommand.csChannelCreateCommand.csChannelDeleteCommand.csChannelJoinCommand.csChannelPasswordCommand.csChannelRankCommand.csKickBanCommand.csMessageActionCommand.csMessageBroadcastCommand.csMessageDeleteCommand.csMessageWhisperCommand.csPardonAddressCommand.csPardonUserCommand.csShutdownRestartCommand.csUserAFKCommand.csUserNickCommand.csWhoCommand.csWhoisCommand.cs
ConnectionInfo.csEventStorage
Events
IChatCommand.csIChatPacketHandler.csIPacketHandler.csIUserCommand.csMisuzu
Packet
AuthSuccessPacket.csMOTDPacket.csMessageAddPacket.csMessageBroadcastPacket.csMessagePopulatePacket.csUserChannelJoinPacket.csUserConnectPacket.csUserDisconnectLogPacket.csUserDisconnectPacket.csUserUpdatePacket.csUsersPopulatePacket.cs
PacketHandlerContext.csPacketHandlers
Program.csSockChatServer.csUserCommandContext.csUserDisconnectReason.csUserInfo.csUserPermissions.csUserStatus.csUtility.cs
|
@ -2,7 +2,7 @@
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public static class SharpInfo {
|
public static class BuildInfo {
|
||||||
private const string NAME = @"SharpChat";
|
private const string NAME = @"SharpChat";
|
||||||
private const string UNKNOWN = @"XXXXXXX";
|
private const string UNKNOWN = @"XXXXXXX";
|
||||||
|
|
||||||
|
@ -12,7 +12,7 @@ namespace SharpChat {
|
||||||
|
|
||||||
public static string ProgramName { get; }
|
public static string ProgramName { get; }
|
||||||
|
|
||||||
static SharpInfo() {
|
static BuildInfo() {
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
IsDebugBuild = true;
|
IsDebugBuild = true;
|
||||||
#endif
|
#endif
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatChannel {
|
public class ChannelInfo {
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public string Password { get; set; }
|
public string Password { get; set; }
|
||||||
public bool IsTemporary { get; set; }
|
public bool IsTemporary { get; set; }
|
||||||
|
@ -12,7 +12,7 @@ namespace SharpChat {
|
||||||
public bool HasPassword
|
public bool HasPassword
|
||||||
=> !string.IsNullOrWhiteSpace(Password);
|
=> !string.IsNullOrWhiteSpace(Password);
|
||||||
|
|
||||||
public ChatChannel(
|
public ChannelInfo(
|
||||||
string name,
|
string name,
|
||||||
string? password = null,
|
string? password = null,
|
||||||
bool isTemporary = false,
|
bool isTemporary = false,
|
||||||
|
@ -30,7 +30,7 @@ namespace SharpChat {
|
||||||
return string.Equals(name, Name, StringComparison.InvariantCultureIgnoreCase);
|
return string.Equals(name, Name, StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsOwner(ChatUser user) {
|
public bool IsOwner(UserInfo user) {
|
||||||
return OwnerId > 0
|
return OwnerId > 0
|
||||||
&& user != null
|
&& user != null
|
||||||
&& OwnerId == user.UserId;
|
&& OwnerId == user.UserId;
|
|
@ -13,13 +13,13 @@ namespace SharpChat {
|
||||||
|
|
||||||
public readonly SemaphoreSlim ContextAccess = new(1, 1);
|
public readonly SemaphoreSlim ContextAccess = new(1, 1);
|
||||||
|
|
||||||
public Dictionary<string, ChatChannel> Channels { get; } = new();
|
public Dictionary<string, ChannelInfo> Channels { get; } = new();
|
||||||
public List<ChatConnection> Connections { get; } = new();
|
public List<ConnectionInfo> Connections { get; } = new();
|
||||||
public Dictionary<long, ChatUser> Users { get; } = new();
|
public Dictionary<long, UserInfo> Users { get; } = new();
|
||||||
public IEventStorage Events { get; }
|
public IEventStorage Events { get; }
|
||||||
public HashSet<ChannelUserAssoc> ChannelUsers { get; } = new();
|
public HashSet<ChannelUserAssoc> ChannelUsers { get; } = new();
|
||||||
public Dictionary<long, RateLimiter> UserRateLimiters { get; } = new();
|
public Dictionary<long, RateLimiter> UserRateLimiters { get; } = new();
|
||||||
public Dictionary<long, ChatChannel> UserLastChannel { get; } = new();
|
public Dictionary<long, ChannelInfo> UserLastChannel { get; } = new();
|
||||||
|
|
||||||
public ChatContext(IEventStorage evtStore) {
|
public ChatContext(IEventStorage evtStore) {
|
||||||
Events = evtStore;
|
Events = evtStore;
|
||||||
|
@ -41,12 +41,12 @@ namespace SharpChat {
|
||||||
if(targetIds.Length != 2)
|
if(targetIds.Length != 2)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ChatUser[] users = Users.Where(kvp => targetIds.Contains(kvp.Key)).Select(kvp => kvp.Value).ToArray();
|
UserInfo[] users = Users.Where(kvp => targetIds.Contains(kvp.Key)).Select(kvp => kvp.Value).ToArray();
|
||||||
ChatUser? target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
|
UserInfo? target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
|
||||||
if(target == null)
|
if(target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
foreach(ChatUser user in users)
|
foreach(UserInfo user in users)
|
||||||
SendTo(user, new MessageAddPacket(
|
SendTo(user, new MessageAddPacket(
|
||||||
mce.MessageId,
|
mce.MessageId,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
|
@ -56,7 +56,7 @@ namespace SharpChat {
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
ChatChannel? channel = Channels.Values.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
|
ChannelInfo? channel = Channels.Values.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
|
||||||
if(channel != null)
|
if(channel != null)
|
||||||
SendTo(channel, new MessageAddPacket(
|
SendTo(channel, new MessageAddPacket(
|
||||||
mce.MessageId,
|
mce.MessageId,
|
||||||
|
@ -82,7 +82,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update() {
|
public void Update() {
|
||||||
foreach(ChatConnection conn in Connections)
|
foreach(ConnectionInfo conn in Connections)
|
||||||
if(!conn.IsDisposed && conn.HasTimedOut) {
|
if(!conn.IsDisposed && conn.HasTimedOut) {
|
||||||
conn.Dispose();
|
conn.Dispose();
|
||||||
Logger.Write($"Nuked connection {conn.Id} associated with {conn.User}.");
|
Logger.Write($"Nuked connection {conn.Id} associated with {conn.User}.");
|
||||||
|
@ -92,9 +92,9 @@ namespace SharpChat {
|
||||||
if(removed > 0)
|
if(removed > 0)
|
||||||
Logger.Write($"Removed {removed} nuked connections from the list.");
|
Logger.Write($"Removed {removed} nuked connections from the list.");
|
||||||
|
|
||||||
foreach(ChatUser user in Users.Values)
|
foreach(UserInfo user in Users.Values)
|
||||||
if(!Connections.Any(conn => conn.User == user)) {
|
if(!Connections.Any(conn => conn.User == user)) {
|
||||||
HandleDisconnect(user, ChatUserDisconnectReason.TimeOut);
|
HandleDisconnect(user, UserDisconnectReason.TimeOut);
|
||||||
Logger.Write($"Timed out {user} (no more connections).");
|
Logger.Write($"Timed out {user} (no more connections).");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -108,39 +108,39 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsInChannel(ChatUser? user, ChatChannel? channel) {
|
public bool IsInChannel(UserInfo? user, ChannelInfo? channel) {
|
||||||
return user != null
|
return user != null
|
||||||
&& channel != null
|
&& channel != null
|
||||||
&& ChannelUsers.Contains(new ChannelUserAssoc(user.UserId, channel.Name));
|
&& ChannelUsers.Contains(new ChannelUserAssoc(user.UserId, channel.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetUserChannelNames(ChatUser user) {
|
public string[] GetUserChannelNames(UserInfo user) {
|
||||||
return ChannelUsers.Where(cu => cu.UserId == user.UserId).Select(cu => cu.ChannelName).ToArray();
|
return ChannelUsers.Where(cu => cu.UserId == user.UserId).Select(cu => cu.ChannelName).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatChannel[] GetUserChannels(ChatUser user) {
|
public ChannelInfo[] GetUserChannels(UserInfo user) {
|
||||||
string[] names = GetUserChannelNames(user);
|
string[] names = GetUserChannelNames(user);
|
||||||
return Channels.Values.Where(c => names.Any(n => c.NameEquals(n))).ToArray();
|
return Channels.Values.Where(c => names.Any(n => c.NameEquals(n))).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public long[] GetChannelUserIds(ChatChannel channel) {
|
public long[] GetChannelUserIds(ChannelInfo channel) {
|
||||||
return ChannelUsers.Where(cu => channel.NameEquals(cu.ChannelName)).Select(cu => cu.UserId).ToArray();
|
return ChannelUsers.Where(cu => channel.NameEquals(cu.ChannelName)).Select(cu => cu.UserId).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatUser[] GetChannelUsers(ChatChannel channel) {
|
public UserInfo[] GetChannelUsers(ChannelInfo channel) {
|
||||||
long[] targetIds = GetChannelUserIds(channel);
|
long[] targetIds = GetChannelUserIds(channel);
|
||||||
return Users.Values.Where(u => targetIds.Contains(u.UserId)).ToArray();
|
return Users.Values.Where(u => targetIds.Contains(u.UserId)).ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateUser(
|
public void UpdateUser(
|
||||||
ChatUser user,
|
UserInfo user,
|
||||||
string? userName = null,
|
string? userName = null,
|
||||||
string? nickName = null,
|
string? nickName = null,
|
||||||
ChatColour? colour = null,
|
Colour? colour = null,
|
||||||
ChatUserStatus? status = null,
|
UserStatus? status = null,
|
||||||
string? statusText = null,
|
string? statusText = null,
|
||||||
int? rank = null,
|
int? rank = null,
|
||||||
ChatUserPermissions? perms = null,
|
UserPermissions? perms = null,
|
||||||
bool? isSuper = null,
|
bool? isSuper = null,
|
||||||
bool silent = false
|
bool silent = false
|
||||||
) {
|
) {
|
||||||
|
@ -204,14 +204,14 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BanUser(ChatUser user, TimeSpan duration, ChatUserDisconnectReason reason = ChatUserDisconnectReason.Kicked) {
|
public void BanUser(UserInfo user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
|
||||||
if(duration > TimeSpan.Zero) {
|
if(duration > TimeSpan.Zero) {
|
||||||
DateTimeOffset expires = duration >= TimeSpan.MaxValue ? DateTimeOffset.MaxValue : DateTimeOffset.Now + duration;
|
DateTimeOffset expires = duration >= TimeSpan.MaxValue ? DateTimeOffset.MaxValue : DateTimeOffset.Now + duration;
|
||||||
SendTo(user, new ForceDisconnectPacket(expires));
|
SendTo(user, new ForceDisconnectPacket(expires));
|
||||||
} else
|
} else
|
||||||
SendTo(user, new ForceDisconnectPacket());
|
SendTo(user, new ForceDisconnectPacket());
|
||||||
|
|
||||||
foreach(ChatConnection conn in Connections)
|
foreach(ConnectionInfo conn in Connections)
|
||||||
if(conn.User == user)
|
if(conn.User == user)
|
||||||
conn.Dispose();
|
conn.Dispose();
|
||||||
Connections.RemoveAll(conn => conn.IsDisposed);
|
Connections.RemoveAll(conn => conn.IsDisposed);
|
||||||
|
@ -226,13 +226,13 @@ namespace SharpChat {
|
||||||
"user:disconnect" => new UserDisconnectLogPacket(
|
"user:disconnect" => new UserDisconnectLogPacket(
|
||||||
msg.Created,
|
msg.Created,
|
||||||
msg.Sender?.LegacyNameWithStatus ?? string.Empty,
|
msg.Sender?.LegacyNameWithStatus ?? string.Empty,
|
||||||
(ChatUserDisconnectReason)msg.Data.RootElement.GetProperty("reason").GetByte()
|
(UserDisconnectReason)msg.Data.RootElement.GetProperty("reason").GetByte()
|
||||||
),
|
),
|
||||||
_ => new MessagePopulatePacket(msg),
|
_ => new MessagePopulatePacket(msg),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleJoin(ChatUser user, ChatChannel chan, ChatConnection conn, int maxMsgLength) {
|
public void HandleJoin(UserInfo user, ChannelInfo chan, ConnectionInfo conn, int maxMsgLength) {
|
||||||
if(!IsInChannel(user, chan)) {
|
if(!IsInChannel(user, chan)) {
|
||||||
SendTo(chan, new UserConnectPacket(
|
SendTo(chan, new UserConnectPacket(
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
|
@ -270,14 +270,14 @@ namespace SharpChat {
|
||||||
UserLastChannel[user.UserId] = chan;
|
UserLastChannel[user.UserId] = chan;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleDisconnect(ChatUser user, ChatUserDisconnectReason reason = ChatUserDisconnectReason.Leave) {
|
public void HandleDisconnect(UserInfo user, UserDisconnectReason reason = UserDisconnectReason.Leave) {
|
||||||
UpdateUser(user, status: ChatUserStatus.Offline);
|
UpdateUser(user, status: UserStatus.Offline);
|
||||||
Users.Remove(user.UserId);
|
Users.Remove(user.UserId);
|
||||||
UserLastChannel.Remove(user.UserId);
|
UserLastChannel.Remove(user.UserId);
|
||||||
|
|
||||||
ChatChannel[] channels = GetUserChannels(user);
|
ChannelInfo[] channels = GetUserChannels(user);
|
||||||
|
|
||||||
foreach(ChatChannel chan in channels) {
|
foreach(ChannelInfo chan in channels) {
|
||||||
ChannelUsers.Remove(new ChannelUserAssoc(user.UserId, chan.Name));
|
ChannelUsers.Remove(new ChannelUserAssoc(user.UserId, chan.Name));
|
||||||
|
|
||||||
SendTo(chan, new UserDisconnectPacket(DateTimeOffset.Now, user.UserId, user.LegacyNameWithStatus, reason));
|
SendTo(chan, new UserDisconnectPacket(DateTimeOffset.Now, user.UserId, user.LegacyNameWithStatus, reason));
|
||||||
|
@ -288,13 +288,13 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SwitchChannel(ChatUser user, ChatChannel chan, string password) {
|
public void SwitchChannel(UserInfo user, ChannelInfo chan, string password) {
|
||||||
if(UserLastChannel.TryGetValue(user.UserId, out ChatChannel? ulc) && chan == ulc) {
|
if(UserLastChannel.TryGetValue(user.UserId, out ChannelInfo? ulc) && chan == ulc) {
|
||||||
ForceChannel(user);
|
ForceChannel(user);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!user.Permissions.HasFlag(ChatUserPermissions.JoinAnyChannel) && chan.IsOwner(user)) {
|
if(!user.Permissions.HasFlag(UserPermissions.JoinAnyChannel) && chan.IsOwner(user)) {
|
||||||
if(chan.Rank > user.Rank) {
|
if(chan.Rank > user.Rank) {
|
||||||
SendTo(user, new ChannelRankTooLowErrorPacket(chan.Name));
|
SendTo(user, new ChannelRankTooLowErrorPacket(chan.Name));
|
||||||
ForceChannel(user);
|
ForceChannel(user);
|
||||||
|
@ -311,11 +311,11 @@ namespace SharpChat {
|
||||||
ForceChannelSwitch(user, chan);
|
ForceChannelSwitch(user, chan);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForceChannelSwitch(ChatUser user, ChatChannel chan) {
|
public void ForceChannelSwitch(UserInfo user, ChannelInfo chan) {
|
||||||
if(!Channels.ContainsValue(chan))
|
if(!Channels.ContainsValue(chan))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ChatChannel oldChan = UserLastChannel[user.UserId];
|
ChannelInfo oldChan = UserLastChannel[user.UserId];
|
||||||
|
|
||||||
SendTo(oldChan, new UserChannelLeavePacket(user.UserId));
|
SendTo(oldChan, new UserChannelLeavePacket(user.UserId));
|
||||||
Events.AddEvent("chan:leave", user, oldChan, flags: StoredEventFlags.Log);
|
Events.AddEvent("chan:leave", user, oldChan, flags: StoredEventFlags.Log);
|
||||||
|
@ -339,36 +339,36 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(IServerPacket packet) {
|
public void Send(IServerPacket packet) {
|
||||||
foreach(ChatConnection conn in Connections)
|
foreach(ConnectionInfo conn in Connections)
|
||||||
if(conn.IsAuthed)
|
if(conn.IsAuthed)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendTo(ChatUser user, IServerPacket packet) {
|
public void SendTo(UserInfo user, IServerPacket packet) {
|
||||||
foreach(ChatConnection conn in Connections)
|
foreach(ConnectionInfo conn in Connections)
|
||||||
if(conn.IsAlive && conn.User == user)
|
if(conn.IsAlive && conn.User == user)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendTo(ChatChannel channel, IServerPacket packet) {
|
public void SendTo(ChannelInfo channel, IServerPacket packet) {
|
||||||
// might be faster to grab the users first and then cascade into that SendTo
|
// might be faster to grab the users first and then cascade into that SendTo
|
||||||
IEnumerable<ChatConnection> conns = Connections.Where(c => c.IsAuthed && IsInChannel(c.User, channel));
|
IEnumerable<ConnectionInfo> conns = Connections.Where(c => c.IsAuthed && IsInChannel(c.User, channel));
|
||||||
foreach(ChatConnection conn in conns)
|
foreach(ConnectionInfo conn in conns)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SendToUserChannels(ChatUser user, IServerPacket packet) {
|
public void SendToUserChannels(UserInfo user, IServerPacket packet) {
|
||||||
IEnumerable<ChatChannel> chans = Channels.Values.Where(c => IsInChannel(user, c));
|
IEnumerable<ChannelInfo> chans = Channels.Values.Where(c => IsInChannel(user, c));
|
||||||
IEnumerable<ChatConnection> conns = Connections.Where(conn => conn.IsAuthed && ChannelUsers.Any(cu => cu.UserId == conn.User?.UserId && chans.Any(chan => chan.NameEquals(cu.ChannelName))));
|
IEnumerable<ConnectionInfo> conns = Connections.Where(conn => conn.IsAuthed && ChannelUsers.Any(cu => cu.UserId == conn.User?.UserId && chans.Any(chan => chan.NameEquals(cu.ChannelName))));
|
||||||
foreach(ChatConnection conn in conns)
|
foreach(ConnectionInfo conn in conns)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IPAddress[] GetRemoteAddresses(ChatUser user) {
|
public IPAddress[] GetRemoteAddresses(UserInfo user) {
|
||||||
return Connections.Where(c => c.IsAlive && c.User == user).Select(c => c.RemoteAddress).Distinct().ToArray();
|
return Connections.Where(c => c.IsAlive && c.User == user).Select(c => c.RemoteAddress).Distinct().ToArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForceChannel(ChatUser user, ChatChannel? chan = null) {
|
public void ForceChannel(UserInfo user, ChannelInfo? chan = null) {
|
||||||
if(chan == null && !UserLastChannel.TryGetValue(user.UserId, out chan))
|
if(chan == null && !UserLastChannel.TryGetValue(user.UserId, out chan))
|
||||||
throw new ArgumentException("no channel???");
|
throw new ArgumentException("no channel???");
|
||||||
|
|
||||||
|
@ -376,7 +376,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateChannel(
|
public void UpdateChannel(
|
||||||
ChatChannel channel,
|
ChannelInfo channel,
|
||||||
bool? temporary = null,
|
bool? temporary = null,
|
||||||
int? minRank = null,
|
int? minRank = null,
|
||||||
string? password = null
|
string? password = null
|
||||||
|
@ -396,16 +396,16 @@ namespace SharpChat {
|
||||||
channel.Password = password;
|
channel.Password = password;
|
||||||
|
|
||||||
// TODO: Users that no longer have access to the channel/gained access to the channel by the rank change should receive delete and create packets respectively
|
// TODO: Users that no longer have access to the channel/gained access to the channel by the rank change should receive delete and create packets respectively
|
||||||
foreach(ChatUser user in Users.Values.Where(u => u.Rank >= channel.Rank)) {
|
foreach(UserInfo user in Users.Values.Where(u => u.Rank >= channel.Rank)) {
|
||||||
SendTo(user, new ChannelUpdatePacket(prevName, channel.Name, channel.HasPassword, channel.IsTemporary));
|
SendTo(user, new ChannelUpdatePacket(prevName, channel.Name, channel.HasPassword, channel.IsTemporary));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveChannel(ChatChannel channel) {
|
public void RemoveChannel(ChannelInfo channel) {
|
||||||
if(channel == null || !Channels.Any())
|
if(channel == null || !Channels.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ChatChannel? defaultChannel = Channels.Values.FirstOrDefault();
|
ChannelInfo? defaultChannel = Channels.Values.FirstOrDefault();
|
||||||
if(defaultChannel == null)
|
if(defaultChannel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -414,11 +414,11 @@ namespace SharpChat {
|
||||||
|
|
||||||
// Move all users back to the main channel
|
// Move all users back to the main channel
|
||||||
// TODO: Replace this with a kick. SCv2 supports being in 0 channels, SCv1 should force the user back to DefaultChannel.
|
// TODO: Replace this with a kick. SCv2 supports being in 0 channels, SCv1 should force the user back to DefaultChannel.
|
||||||
foreach(ChatUser user in GetChannelUsers(channel))
|
foreach(UserInfo user in GetChannelUsers(channel))
|
||||||
SwitchChannel(user, defaultChannel, string.Empty);
|
SwitchChannel(user, defaultChannel, string.Empty);
|
||||||
|
|
||||||
// Broadcast deletion of channel
|
// Broadcast deletion of channel
|
||||||
foreach(ChatUser user in Users.Values.Where(u => u.Rank >= channel.Rank))
|
foreach(UserInfo user in Users.Values.Where(u => u.Rank >= channel.Rank))
|
||||||
SendTo(user, new ChannelDeletePacket(channel.Name));
|
SendTo(user, new ChannelDeletePacket(channel.Name));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,27 +1,27 @@
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public readonly struct ChatColour {
|
public readonly struct Colour {
|
||||||
public readonly byte Red;
|
public readonly byte Red;
|
||||||
public readonly byte Green;
|
public readonly byte Green;
|
||||||
public readonly byte Blue;
|
public readonly byte Blue;
|
||||||
public readonly bool Inherits;
|
public readonly bool Inherits;
|
||||||
|
|
||||||
public static ChatColour None { get; } = new();
|
public static Colour None { get; } = new();
|
||||||
|
|
||||||
public ChatColour() {
|
public Colour() {
|
||||||
Red = 0;
|
Red = 0;
|
||||||
Green = 0;
|
Green = 0;
|
||||||
Blue = 0;
|
Blue = 0;
|
||||||
Inherits = true;
|
Inherits = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatColour(byte red, byte green, byte blue) {
|
public Colour(byte red, byte green, byte blue) {
|
||||||
Red = red;
|
Red = red;
|
||||||
Green = green;
|
Green = green;
|
||||||
Blue = blue;
|
Blue = blue;
|
||||||
Inherits = false;
|
Inherits = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(ChatColour other) {
|
public bool Equals(Colour other) {
|
||||||
return Inherits == other.Inherits
|
return Inherits == other.Inherits
|
||||||
&& Red == other.Red
|
&& Red == other.Red
|
||||||
&& Green == other.Green
|
&& Green == other.Green
|
||||||
|
@ -38,7 +38,7 @@
|
||||||
return (Red << 16) | (Green << 8) | Blue;
|
return (Red << 16) | (Green << 8) | Blue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChatColour FromRawRGB(int rgb) {
|
public static Colour FromRawRGB(int rgb) {
|
||||||
return new(
|
return new(
|
||||||
(byte)((rgb >> 16) & 0xFF),
|
(byte)((rgb >> 16) & 0xFF),
|
||||||
(byte)((rgb >> 8) & 0xFF),
|
(byte)((rgb >> 8) & 0xFF),
|
||||||
|
@ -52,7 +52,7 @@
|
||||||
return Inherits ? MSZ_INHERIT : ToRawRGB();
|
return Inherits ? MSZ_INHERIT : ToRawRGB();
|
||||||
}
|
}
|
||||||
|
|
||||||
public static ChatColour FromMisuzu(int raw) {
|
public static Colour FromMisuzu(int raw) {
|
||||||
return (raw & MSZ_INHERIT) > 0
|
return (raw & MSZ_INHERIT) > 0
|
||||||
? None
|
? None
|
||||||
: FromRawRGB(raw);
|
: FromRawRGB(raw);
|
|
@ -5,21 +5,21 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class BanListCommand : IChatCommand {
|
public class BanListCommand : IUserCommand {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public BanListCommand(MisuzuClient msz) {
|
public BanListCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz;
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("bans")
|
return ctx.NameEquals("bans")
|
||||||
|| ctx.NameEquals("banned");
|
|| ctx.NameEquals("banned");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.KickUser)
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.KickUser)
|
||||||
&& !ctx.User.Permissions.HasFlag(ChatUserPermissions.BanUser)) {
|
&& !ctx.User.Permissions.HasFlag(UserPermissions.BanUser)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,13 +2,13 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class ChannelCreateCommand : IChatCommand {
|
public class ChannelCreateCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("create");
|
return ctx.NameEquals("create");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.CreateChannel)) {
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.CreateChannel)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -33,7 +33,7 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
string createChanName = string.Join('_', ctx.Args.Skip(createChanHasHierarchy ? 1 : 0));
|
string createChanName = string.Join('_', ctx.Args.Skip(createChanHasHierarchy ? 1 : 0));
|
||||||
|
|
||||||
if(!ChatChannel.CheckName(createChanName)) {
|
if(!ChannelInfo.CheckName(createChanName)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNameFormatErrorPacket());
|
ctx.Chat.SendTo(ctx.User, new ChannelNameFormatErrorPacket());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -43,15 +43,15 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatChannel createChan = new(
|
ChannelInfo createChan = new(
|
||||||
createChanName,
|
createChanName,
|
||||||
isTemporary: !ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelPermanent),
|
isTemporary: !ctx.User.Permissions.HasFlag(UserPermissions.SetChannelPermanent),
|
||||||
rank: createChanHierarchy,
|
rank: createChanHierarchy,
|
||||||
ownerId: ctx.User.UserId
|
ownerId: ctx.User.UserId
|
||||||
);
|
);
|
||||||
|
|
||||||
ctx.Chat.Channels.Add(createChan.Name, createChan);
|
ctx.Chat.Channels.Add(createChan.Name, createChan);
|
||||||
foreach(ChatUser ccu in ctx.Chat.Users.Values.Where(u => u.Rank >= ctx.Channel.Rank))
|
foreach(UserInfo ccu in ctx.Chat.Users.Values.Where(u => u.Rank >= ctx.Channel.Rank))
|
||||||
ctx.Chat.SendTo(ccu, new ChannelCreatePacket(
|
ctx.Chat.SendTo(ccu, new ChannelCreatePacket(
|
||||||
ctx.Channel.Name,
|
ctx.Channel.Name,
|
||||||
ctx.Channel.HasPassword,
|
ctx.Channel.HasPassword,
|
||||||
|
|
|
@ -2,29 +2,29 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class ChannelDeleteCommand : IChatCommand {
|
public class ChannelDeleteCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("delchan") || (
|
return ctx.NameEquals("delchan") || (
|
||||||
ctx.NameEquals("delete")
|
ctx.NameEquals("delete")
|
||||||
&& ctx.Args.FirstOrDefault()?.All(char.IsDigit) == false
|
&& ctx.Args.FirstOrDefault()?.All(char.IsDigit) == false
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.Args.Any() || string.IsNullOrWhiteSpace(ctx.Args.FirstOrDefault())) {
|
if(!ctx.Args.Any() || string.IsNullOrWhiteSpace(ctx.Args.FirstOrDefault())) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandFormatErrorPacket());
|
ctx.Chat.SendTo(ctx.User, new CommandFormatErrorPacket());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string delChanName = string.Join('_', ctx.Args);
|
string delChanName = string.Join('_', ctx.Args);
|
||||||
ChatChannel? delChan = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(delChanName));
|
ChannelInfo? delChan = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(delChanName));
|
||||||
|
|
||||||
if(delChan == null) {
|
if(delChan == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(delChanName));
|
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(delChanName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.DeleteChannel) || !delChan.IsOwner(ctx.User)) {
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.DeleteChannel) || !delChan.IsOwner(ctx.User)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelDeleteNotAllowedErrorPacket(delChan.Name));
|
ctx.Chat.SendTo(ctx.User, new ChannelDeleteNotAllowedErrorPacket(delChan.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,14 +2,14 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class ChannelJoinCommand : IChatCommand {
|
public class ChannelJoinCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("join");
|
return ctx.NameEquals("join");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
string joinChanStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
string joinChanStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
||||||
ChatChannel? joinChan = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(joinChanStr));
|
ChannelInfo? joinChan = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(joinChanStr));
|
||||||
|
|
||||||
if(joinChan == null) {
|
if(joinChan == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(joinChanStr));
|
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(joinChanStr));
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
using SharpChat.Packet;
|
using SharpChat.Packet;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class ChannelPasswordCommand : IChatCommand {
|
public class ChannelPasswordCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("pwd")
|
return ctx.NameEquals("pwd")
|
||||||
|| ctx.NameEquals("password");
|
|| ctx.NameEquals("password");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelPassword) || !ctx.Channel.IsOwner(ctx.User)) {
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelPassword) || !ctx.Channel.IsOwner(ctx.User)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class ChannelRankCommand : IChatCommand {
|
public class ChannelRankCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("rank")
|
return ctx.NameEquals("rank")
|
||||||
|| ctx.NameEquals("privilege")
|
|| ctx.NameEquals("privilege")
|
||||||
|| ctx.NameEquals("priv");
|
|| ctx.NameEquals("priv");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelHierarchy) || !ctx.Channel.IsOwner(ctx.User)) {
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelHierarchy) || !ctx.Channel.IsOwner(ctx.User)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,22 +5,22 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class KickBanCommand : IChatCommand {
|
public class KickBanCommand : IUserCommand {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public KickBanCommand(MisuzuClient msz) {
|
public KickBanCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz;
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("kick")
|
return ctx.NameEquals("kick")
|
||||||
|| ctx.NameEquals("ban");
|
|| ctx.NameEquals("ban");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
bool isBanning = ctx.NameEquals("ban");
|
bool isBanning = ctx.NameEquals("ban");
|
||||||
|
|
||||||
if(!ctx.User.Permissions.HasFlag(isBanning ? ChatUserPermissions.BanUser : ChatUserPermissions.KickUser)) {
|
if(!ctx.User.Permissions.HasFlag(isBanning ? UserPermissions.BanUser : UserPermissions.KickUser)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -28,7 +28,7 @@ namespace SharpChat.Commands {
|
||||||
string banUserTarget = ctx.Args.ElementAtOrDefault(0) ?? string.Empty;
|
string banUserTarget = ctx.Args.ElementAtOrDefault(0) ?? string.Empty;
|
||||||
string? banDurationStr = ctx.Args.ElementAtOrDefault(1);
|
string? banDurationStr = ctx.Args.ElementAtOrDefault(1);
|
||||||
int banReasonIndex = 1;
|
int banReasonIndex = 1;
|
||||||
ChatUser? banUser = null;
|
UserInfo? banUser = null;
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(banUserTarget) || (banUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) {
|
if(string.IsNullOrEmpty(banUserTarget) || (banUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(banUserTarget));
|
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(banUserTarget));
|
||||||
|
|
|
@ -3,13 +3,13 @@ using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class MessageActionCommand : IChatCommand {
|
public class MessageActionCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("action")
|
return ctx.NameEquals("action")
|
||||||
|| ctx.NameEquals("me");
|
|| ctx.NameEquals("me");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.Args.Any())
|
if(!ctx.Args.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -3,14 +3,14 @@ using SharpChat.Packet;
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class MessageBroadcastCommand : IChatCommand {
|
public class MessageBroadcastCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("say")
|
return ctx.NameEquals("say")
|
||||||
|| ctx.NameEquals("broadcast");
|
|| ctx.NameEquals("broadcast");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.Broadcast)) {
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.Broadcast)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,18 @@ using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands
|
namespace SharpChat.Commands
|
||||||
{
|
{
|
||||||
public class MessageDeleteCommand : IChatCommand {
|
public class MessageDeleteCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("delmsg") || (
|
return ctx.NameEquals("delmsg") || (
|
||||||
ctx.NameEquals("delete")
|
ctx.NameEquals("delete")
|
||||||
&& ctx.Args.FirstOrDefault()?.All(char.IsDigit) == true
|
&& ctx.Args.FirstOrDefault()?.All(char.IsDigit) == true
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
bool deleteAnyMessage = ctx.User.Permissions.HasFlag(ChatUserPermissions.DeleteAnyMessage);
|
bool deleteAnyMessage = ctx.User.Permissions.HasFlag(UserPermissions.DeleteAnyMessage);
|
||||||
|
|
||||||
if(!deleteAnyMessage && !ctx.User.Permissions.HasFlag(ChatUserPermissions.DeleteOwnMessage)) {
|
if(!deleteAnyMessage && !ctx.User.Permissions.HasFlag(UserPermissions.DeleteOwnMessage)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,20 +4,20 @@ using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class MessageWhisperCommand : IChatCommand {
|
public class MessageWhisperCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("whisper")
|
return ctx.NameEquals("whisper")
|
||||||
|| ctx.NameEquals("msg");
|
|| ctx.NameEquals("msg");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(ctx.Args.Length < 2) {
|
if(ctx.Args.Length < 2) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandFormatErrorPacket());
|
ctx.Chat.SendTo(ctx.User, new CommandFormatErrorPacket());
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string whisperUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
string whisperUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
||||||
ChatUser? whisperUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(whisperUserStr));
|
UserInfo? whisperUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(whisperUserStr));
|
||||||
|
|
||||||
if(whisperUser == null) {
|
if(whisperUser == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(whisperUserStr));
|
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(whisperUserStr));
|
||||||
|
@ -29,7 +29,7 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
ctx.Chat.DispatchEvent(new MessageCreateEvent(
|
ctx.Chat.DispatchEvent(new MessageCreateEvent(
|
||||||
SharpId.Next(),
|
SharpId.Next(),
|
||||||
ChatUser.GetDMChannelName(ctx.User, whisperUser),
|
UserInfo.GetDMChannelName(ctx.User, whisperUser),
|
||||||
ctx.User,
|
ctx.User,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
string.Join(' ', ctx.Args.Skip(1)),
|
string.Join(' ', ctx.Args.Skip(1)),
|
||||||
|
|
|
@ -6,21 +6,21 @@ using System.Net;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class PardonAddressCommand : IChatCommand {
|
public class PardonAddressCommand : IUserCommand {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public PardonAddressCommand(MisuzuClient msz) {
|
public PardonAddressCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz;
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("pardonip")
|
return ctx.NameEquals("pardonip")
|
||||||
|| ctx.NameEquals("unbanip");
|
|| ctx.NameEquals("unbanip");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.KickUser)
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.KickUser)
|
||||||
&& !ctx.User.Permissions.HasFlag(ChatUserPermissions.BanUser)) {
|
&& !ctx.User.Permissions.HasFlag(UserPermissions.BanUser)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,21 +5,21 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class PardonUserCommand : IChatCommand {
|
public class PardonUserCommand : IUserCommand {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
public PardonUserCommand(MisuzuClient msz) {
|
public PardonUserCommand(MisuzuClient msz) {
|
||||||
Misuzu = msz;
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("pardon")
|
return ctx.NameEquals("pardon")
|
||||||
|| ctx.NameEquals("unban");
|
|| ctx.NameEquals("unban");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.KickUser)
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.KickUser)
|
||||||
&& !ctx.User.Permissions.HasFlag(ChatUserPermissions.BanUser)) {
|
&& !ctx.User.Permissions.HasFlag(UserPermissions.BanUser)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -31,7 +31,7 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatUser? unbanUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(unbanUserTarget));
|
UserInfo? unbanUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(unbanUserTarget));
|
||||||
if(unbanUser == null && long.TryParse(unbanUserTarget, out long unbanUserId)) {
|
if(unbanUser == null && long.TryParse(unbanUserTarget, out long unbanUserId)) {
|
||||||
unbanUserTargetIsName = false;
|
unbanUserTargetIsName = false;
|
||||||
unbanUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == unbanUserId);
|
unbanUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == unbanUserId);
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class ShutdownRestartCommand : IChatCommand {
|
public class ShutdownRestartCommand : IUserCommand {
|
||||||
private readonly ManualResetEvent WaitHandle;
|
private readonly ManualResetEvent WaitHandle;
|
||||||
private readonly Func<bool> ShutdownCheck;
|
private readonly Func<bool> ShutdownCheck;
|
||||||
|
|
||||||
|
@ -12,12 +12,12 @@ namespace SharpChat.Commands {
|
||||||
ShutdownCheck = shutdownCheck;
|
ShutdownCheck = shutdownCheck;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("shutdown")
|
return ctx.NameEquals("shutdown")
|
||||||
|| ctx.NameEquals("restart");
|
|| ctx.NameEquals("restart");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(ctx.User.UserId != 1) {
|
if(ctx.User.UserId != 1) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
|
@ -27,7 +27,7 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ctx.NameEquals("restart"))
|
if(ctx.NameEquals("restart"))
|
||||||
foreach(ChatConnection conn in ctx.Chat.Connections)
|
foreach(ConnectionInfo conn in ctx.Chat.Connections)
|
||||||
conn.PrepareForRestart();
|
conn.PrepareForRestart();
|
||||||
|
|
||||||
ctx.Chat.Update();
|
ctx.Chat.Update();
|
||||||
|
|
|
@ -2,15 +2,15 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class UserAFKCommand : IChatCommand {
|
public class UserAFKCommand : IUserCommand {
|
||||||
private const string DEFAULT = "AFK";
|
private const string DEFAULT = "AFK";
|
||||||
private const int MAX_LENGTH = 5;
|
private const int MAX_LENGTH = 5;
|
||||||
|
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("afk");
|
return ctx.NameEquals("afk");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
string? statusText = ctx.Args.FirstOrDefault();
|
string? statusText = ctx.Args.FirstOrDefault();
|
||||||
if(string.IsNullOrWhiteSpace(statusText))
|
if(string.IsNullOrWhiteSpace(statusText))
|
||||||
statusText = DEFAULT;
|
statusText = DEFAULT;
|
||||||
|
@ -22,7 +22,7 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
ctx.Chat.UpdateUser(
|
ctx.Chat.UpdateUser(
|
||||||
ctx.User,
|
ctx.User,
|
||||||
status: ChatUserStatus.Away,
|
status: UserStatus.Away,
|
||||||
statusText: statusText
|
statusText: statusText
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,20 +2,20 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class UserNickCommand : IChatCommand {
|
public class UserNickCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("nick");
|
return ctx.NameEquals("nick");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
bool setOthersNick = ctx.User.Permissions.HasFlag(ChatUserPermissions.SetOthersNickname);
|
bool setOthersNick = ctx.User.Permissions.HasFlag(UserPermissions.SetOthersNickname);
|
||||||
|
|
||||||
if(!setOthersNick && !ctx.User.Permissions.HasFlag(ChatUserPermissions.SetOwnNickname)) {
|
if(!setOthersNick && !ctx.User.Permissions.HasFlag(UserPermissions.SetOwnNickname)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatUser? targetUser = null;
|
UserInfo? targetUser = null;
|
||||||
int offset = 0;
|
int offset = 0;
|
||||||
|
|
||||||
if(setOthersNick && long.TryParse(ctx.Args.FirstOrDefault(), out long targetUserId) && targetUserId > 0) {
|
if(setOthersNick && long.TryParse(ctx.Args.FirstOrDefault(), out long targetUserId) && targetUserId > 0) {
|
||||||
|
|
|
@ -2,12 +2,12 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class WhoCommand : IChatCommand {
|
public class WhoCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("who");
|
return ctx.NameEquals("who");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
string? channelName = ctx.Args.FirstOrDefault();
|
string? channelName = ctx.Args.FirstOrDefault();
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(channelName)) {
|
if(string.IsNullOrEmpty(channelName)) {
|
||||||
|
@ -18,14 +18,14 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatChannel? channel = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(channelName));
|
ChannelInfo? channel = ctx.Chat.Channels.Values.FirstOrDefault(c => c.NameEquals(channelName));
|
||||||
|
|
||||||
if(channel == null) {
|
if(channel == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(channelName));
|
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(channelName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(channel.Rank > ctx.User.Rank || (channel.HasPassword && !ctx.User.Permissions.HasFlag(ChatUserPermissions.JoinAnyChannel))) {
|
if(channel.Rank > ctx.User.Rank || (channel.HasPassword && !ctx.User.Permissions.HasFlag(UserPermissions.JoinAnyChannel))) {
|
||||||
ctx.Chat.SendTo(ctx.User, new WhoChannelNotFoundErrorPacket(channelName));
|
ctx.Chat.SendTo(ctx.User, new WhoChannelNotFoundErrorPacket(channelName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,20 +3,20 @@ using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace SharpChat.Commands {
|
namespace SharpChat.Commands {
|
||||||
public class WhoisCommand : IChatCommand {
|
public class WhoisCommand : IUserCommand {
|
||||||
public bool IsMatch(ChatCommandContext ctx) {
|
public bool IsMatch(UserCommandContext ctx) {
|
||||||
return ctx.NameEquals("ip")
|
return ctx.NameEquals("ip")
|
||||||
|| ctx.NameEquals("whois");
|
|| ctx.NameEquals("whois");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(UserCommandContext ctx) {
|
||||||
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.SeeIPAddress)) {
|
if(!ctx.User.Permissions.HasFlag(UserPermissions.SeeIPAddress)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string ipUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
string ipUserStr = ctx.Args.FirstOrDefault() ?? string.Empty;
|
||||||
ChatUser? ipUser;
|
UserInfo? ipUser;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) {
|
if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(ipUserStr));
|
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(ipUserStr));
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatConnection : IDisposable {
|
public class ConnectionInfo : IDisposable {
|
||||||
public const int ID_LENGTH = 20;
|
public const int ID_LENGTH = 20;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -17,7 +17,7 @@ namespace SharpChat {
|
||||||
public string Id { get; }
|
public string Id { get; }
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.Now;
|
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.Now;
|
||||||
public ChatUser? User { get; set; }
|
public UserInfo? User { get; set; }
|
||||||
|
|
||||||
private int CloseCode { get; set; } = 1000;
|
private int CloseCode { get; set; } = 1000;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ namespace SharpChat {
|
||||||
|
|
||||||
public bool IsAuthed => IsAlive && User is not null;
|
public bool IsAuthed => IsAlive && User is not null;
|
||||||
|
|
||||||
public ChatConnection(IWebSocketConnection sock) {
|
public ConnectionInfo(IWebSocketConnection sock) {
|
||||||
Socket = sock;
|
Socket = sock;
|
||||||
Id = RNG.SecureRandomString(ID_LENGTH);
|
Id = RNG.SecureRandomString(ID_LENGTH);
|
||||||
|
|
||||||
|
@ -64,7 +64,7 @@ namespace SharpChat {
|
||||||
CloseCode = 1012;
|
CloseCode = 1012;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ChatConnection() {
|
~ConnectionInfo() {
|
||||||
DoDispose();
|
DoDispose();
|
||||||
}
|
}
|
||||||
|
|
|
@ -16,19 +16,19 @@ namespace SharpChat.EventStorage
|
||||||
);
|
);
|
||||||
void AddEvent(
|
void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
long senderId, string? senderName, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
long senderId, string? senderName, Colour senderColour, int senderRank, string? senderNick, UserPermissions senderPerms,
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
);
|
);
|
||||||
void AddEvent(
|
void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
string? channelName,
|
string? channelName,
|
||||||
long senderId, string? senderName, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
long senderId, string? senderName, Colour senderColour, int senderRank, string? senderNick, UserPermissions senderPerms,
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
);
|
);
|
||||||
|
|
||||||
long AddEvent(string type, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None);
|
long AddEvent(string type, UserInfo user, ChannelInfo channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None);
|
||||||
void RemoveEvent(StoredEventInfo evt);
|
void RemoveEvent(StoredEventInfo evt);
|
||||||
StoredEventInfo? GetEvent(long seqId);
|
StoredEventInfo? GetEvent(long seqId);
|
||||||
IEnumerable<StoredEventInfo> GetChannelEventLog(string channelName, int amount = 20, int offset = 0);
|
IEnumerable<StoredEventInfo> GetChannelEventLog(string channelName, int amount = 20, int offset = 0);
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SharpChat.EventStorage {
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
AddEvent(id, type, null, 0, null, ChatColour.None, 0, null, 0, data, flags);
|
AddEvent(id, type, null, 0, null, Colour.None, 0, null, 0, data, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
|
@ -26,12 +26,12 @@ namespace SharpChat.EventStorage {
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
AddEvent(id, type, channelName, 0, null, ChatColour.None, 0, null, 0, data, flags);
|
AddEvent(id, type, channelName, 0, null, Colour.None, 0, null, 0, data, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
long senderId, string? senderName, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
long senderId, string? senderName, Colour senderColour, int senderRank, string? senderNick, UserPermissions senderPerms,
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
|
@ -41,7 +41,7 @@ namespace SharpChat.EventStorage {
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
string? channelName,
|
string? channelName,
|
||||||
long senderId, string? senderName, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
long senderId, string? senderName, Colour senderColour, int senderRank, string? senderNick, UserPermissions senderPerms,
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
|
@ -64,7 +64,7 @@ namespace SharpChat.EventStorage {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public long AddEvent(string type, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
public long AddEvent(string type, UserInfo user, ChannelInfo channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
||||||
long id = SharpId.Next();
|
long id = SharpId.Next();
|
||||||
|
|
||||||
AddEvent(
|
AddEvent(
|
||||||
|
@ -72,7 +72,7 @@ namespace SharpChat.EventStorage {
|
||||||
channel?.Name,
|
channel?.Name,
|
||||||
user?.UserId ?? 0,
|
user?.UserId ?? 0,
|
||||||
user?.UserName ?? string.Empty,
|
user?.UserName ?? string.Empty,
|
||||||
user?.Colour ?? ChatColour.None,
|
user?.Colour ?? Colour.None,
|
||||||
user?.Rank ?? 0,
|
user?.Rank ?? 0,
|
||||||
user?.NickName,
|
user?.NickName,
|
||||||
user?.Permissions ?? 0,
|
user?.Permissions ?? 0,
|
||||||
|
@ -112,12 +112,12 @@ namespace SharpChat.EventStorage {
|
||||||
return new StoredEventInfo(
|
return new StoredEventInfo(
|
||||||
reader.GetInt64("event_id"),
|
reader.GetInt64("event_id"),
|
||||||
Encoding.ASCII.GetString((byte[])reader["event_type"]),
|
Encoding.ASCII.GetString((byte[])reader["event_type"]),
|
||||||
reader.IsDBNull(reader.GetOrdinal("event_sender")) ? null : new ChatUser(
|
reader.IsDBNull(reader.GetOrdinal("event_sender")) ? null : new UserInfo(
|
||||||
reader.GetInt64("event_sender"),
|
reader.GetInt64("event_sender"),
|
||||||
reader.IsDBNull(reader.GetOrdinal("event_sender_name")) ? string.Empty : reader.GetString("event_sender_name"),
|
reader.IsDBNull(reader.GetOrdinal("event_sender_name")) ? string.Empty : reader.GetString("event_sender_name"),
|
||||||
ChatColour.FromMisuzu(reader.GetInt32("event_sender_colour")),
|
Colour.FromMisuzu(reader.GetInt32("event_sender_colour")),
|
||||||
reader.GetInt32("event_sender_rank"),
|
reader.GetInt32("event_sender_rank"),
|
||||||
(ChatUserPermissions)reader.GetInt32("event_sender_perms"),
|
(UserPermissions)reader.GetInt32("event_sender_perms"),
|
||||||
reader.IsDBNull(reader.GetOrdinal("event_sender_nick")) ? null : reader.GetString("event_sender_nick")
|
reader.IsDBNull(reader.GetOrdinal("event_sender_nick")) ? null : reader.GetString("event_sender_nick")
|
||||||
),
|
),
|
||||||
DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created")),
|
DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created")),
|
||||||
|
|
|
@ -5,7 +5,7 @@ namespace SharpChat.EventStorage {
|
||||||
public class StoredEventInfo {
|
public class StoredEventInfo {
|
||||||
public long Id { get; set; }
|
public long Id { get; set; }
|
||||||
public string Type { get; set; }
|
public string Type { get; set; }
|
||||||
public ChatUser? Sender { get; set; }
|
public UserInfo? Sender { get; set; }
|
||||||
public DateTimeOffset Created { get; set; }
|
public DateTimeOffset Created { get; set; }
|
||||||
public DateTimeOffset? Deleted { get; set; }
|
public DateTimeOffset? Deleted { get; set; }
|
||||||
public string? ChannelName { get; set; }
|
public string? ChannelName { get; set; }
|
||||||
|
@ -15,7 +15,7 @@ namespace SharpChat.EventStorage {
|
||||||
public StoredEventInfo(
|
public StoredEventInfo(
|
||||||
long id,
|
long id,
|
||||||
string type,
|
string type,
|
||||||
ChatUser? sender,
|
UserInfo? sender,
|
||||||
DateTimeOffset created,
|
DateTimeOffset created,
|
||||||
DateTimeOffset? deleted,
|
DateTimeOffset? deleted,
|
||||||
string? channelName,
|
string? channelName,
|
||||||
|
|
|
@ -12,7 +12,7 @@ namespace SharpChat.EventStorage {
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
AddEvent(id, type, null, 0, null, ChatColour.None, 0, null, 0, data, flags);
|
AddEvent(id, type, null, 0, null, Colour.None, 0, null, 0, data, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
|
@ -21,12 +21,12 @@ namespace SharpChat.EventStorage {
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
AddEvent(id, type, channelName, 0, null, ChatColour.None, 0, null, 0, data, flags);
|
AddEvent(id, type, channelName, 0, null, Colour.None, 0, null, 0, data, flags);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
long senderId, string? senderName, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
long senderId, string? senderName, Colour senderColour, int senderRank, string? senderNick, UserPermissions senderPerms,
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
|
@ -36,13 +36,13 @@ namespace SharpChat.EventStorage {
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
string? channelName,
|
string? channelName,
|
||||||
long senderId, string? senderName, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
long senderId, string? senderName, Colour senderColour, int senderRank, string? senderNick, UserPermissions senderPerms,
|
||||||
object? data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
// VES is meant as an emergency fallback but this is something else
|
// VES is meant as an emergency fallback but this is something else
|
||||||
JsonDocument hack = JsonDocument.Parse(data == null ? "{}" : JsonSerializer.Serialize(data));
|
JsonDocument hack = JsonDocument.Parse(data == null ? "{}" : JsonSerializer.Serialize(data));
|
||||||
Events.Add(id, new(id, type, senderId < 1 ? null : new ChatUser(
|
Events.Add(id, new(id, type, senderId < 1 ? null : new UserInfo(
|
||||||
senderId,
|
senderId,
|
||||||
senderName ?? string.Empty,
|
senderName ?? string.Empty,
|
||||||
senderColour,
|
senderColour,
|
||||||
|
@ -52,7 +52,7 @@ namespace SharpChat.EventStorage {
|
||||||
), DateTimeOffset.Now, null, channelName, hack, flags));
|
), DateTimeOffset.Now, null, channelName, hack, flags));
|
||||||
}
|
}
|
||||||
|
|
||||||
public long AddEvent(string type, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
public long AddEvent(string type, UserInfo user, ChannelInfo channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
||||||
long id = SharpId.Next();
|
long id = SharpId.Next();
|
||||||
|
|
||||||
AddEvent(
|
AddEvent(
|
||||||
|
@ -60,7 +60,7 @@ namespace SharpChat.EventStorage {
|
||||||
channel?.Name,
|
channel?.Name,
|
||||||
user?.UserId ?? 0,
|
user?.UserId ?? 0,
|
||||||
user?.UserName,
|
user?.UserName,
|
||||||
user?.Colour ?? ChatColour.None,
|
user?.Colour ?? Colour.None,
|
||||||
user?.Rank ?? 0,
|
user?.Rank ?? 0,
|
||||||
user?.NickName,
|
user?.NickName,
|
||||||
user?.Permissions ?? 0,
|
user?.Permissions ?? 0,
|
||||||
|
|
|
@ -6,10 +6,10 @@ namespace SharpChat.Events {
|
||||||
public string? ChannelName { get; }
|
public string? ChannelName { get; }
|
||||||
public long SenderId { get; }
|
public long SenderId { get; }
|
||||||
public string? SenderName { get; }
|
public string? SenderName { get; }
|
||||||
public ChatColour SenderColour { get; }
|
public Colour SenderColour { get; }
|
||||||
public int SenderRank { get; }
|
public int SenderRank { get; }
|
||||||
public string? SenderNickName { get; }
|
public string? SenderNickName { get; }
|
||||||
public ChatUserPermissions SenderPerms { get; }
|
public UserPermissions SenderPerms { get; }
|
||||||
public DateTimeOffset MessageCreated { get; }
|
public DateTimeOffset MessageCreated { get; }
|
||||||
public string MessageText { get; }
|
public string MessageText { get; }
|
||||||
public bool IsPrivate { get; }
|
public bool IsPrivate { get; }
|
||||||
|
@ -21,10 +21,10 @@ namespace SharpChat.Events {
|
||||||
string? channelName,
|
string? channelName,
|
||||||
long senderId,
|
long senderId,
|
||||||
string? senderName,
|
string? senderName,
|
||||||
ChatColour senderColour,
|
Colour senderColour,
|
||||||
int senderRank,
|
int senderRank,
|
||||||
string? senderNickName,
|
string? senderNickName,
|
||||||
ChatUserPermissions senderPerms,
|
UserPermissions senderPerms,
|
||||||
DateTimeOffset msgCreated,
|
DateTimeOffset msgCreated,
|
||||||
string msgText,
|
string msgText,
|
||||||
bool isPrivate,
|
bool isPrivate,
|
||||||
|
@ -49,7 +49,7 @@ namespace SharpChat.Events {
|
||||||
public MessageCreateEvent(
|
public MessageCreateEvent(
|
||||||
long msgId,
|
long msgId,
|
||||||
string? channelName,
|
string? channelName,
|
||||||
ChatUser? sender,
|
UserInfo? sender,
|
||||||
DateTimeOffset msgCreated,
|
DateTimeOffset msgCreated,
|
||||||
string msgText,
|
string msgText,
|
||||||
bool isPrivate,
|
bool isPrivate,
|
||||||
|
@ -60,7 +60,7 @@ namespace SharpChat.Events {
|
||||||
channelName,
|
channelName,
|
||||||
sender?.UserId ?? -1,
|
sender?.UserId ?? -1,
|
||||||
sender?.UserName ?? null,
|
sender?.UserName ?? null,
|
||||||
sender?.Colour ?? ChatColour.None,
|
sender?.Colour ?? Colour.None,
|
||||||
sender?.Rank ?? 0,
|
sender?.Rank ?? 0,
|
||||||
sender?.NickName ?? null,
|
sender?.NickName ?? null,
|
||||||
sender?.Permissions ?? 0,
|
sender?.Permissions ?? 0,
|
||||||
|
@ -73,8 +73,8 @@ namespace SharpChat.Events {
|
||||||
|
|
||||||
public MessageCreateEvent(
|
public MessageCreateEvent(
|
||||||
long msgId,
|
long msgId,
|
||||||
ChatChannel channel,
|
ChannelInfo channel,
|
||||||
ChatUser sender,
|
UserInfo sender,
|
||||||
DateTimeOffset msgCreated,
|
DateTimeOffset msgCreated,
|
||||||
string msgText,
|
string msgText,
|
||||||
bool isPrivate,
|
bool isPrivate,
|
||||||
|
|
|
@ -1,6 +0,0 @@
|
||||||
namespace SharpChat {
|
|
||||||
public interface IChatCommand {
|
|
||||||
bool IsMatch(ChatCommandContext ctx);
|
|
||||||
void Dispatch(ChatCommandContext ctx);
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,6 +0,0 @@
|
||||||
namespace SharpChat {
|
|
||||||
public interface IChatPacketHandler {
|
|
||||||
bool IsMatch(ChatPacketHandlerContext ctx);
|
|
||||||
void Handle(ChatPacketHandlerContext ctx);
|
|
||||||
}
|
|
||||||
}
|
|
6
SharpChat/IPacketHandler.cs
Normal file
6
SharpChat/IPacketHandler.cs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
namespace SharpChat {
|
||||||
|
public interface IPacketHandler {
|
||||||
|
bool IsMatch(PacketHandlerContext ctx);
|
||||||
|
void Handle(PacketHandlerContext ctx);
|
||||||
|
}
|
||||||
|
}
|
6
SharpChat/IUserCommand.cs
Normal file
6
SharpChat/IUserCommand.cs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
namespace SharpChat {
|
||||||
|
public interface IUserCommand {
|
||||||
|
bool IsMatch(UserCommandContext ctx);
|
||||||
|
void Dispatch(UserCommandContext ctx);
|
||||||
|
}
|
||||||
|
}
|
|
@ -18,13 +18,13 @@ namespace SharpChat.Misuzu {
|
||||||
[JsonPropertyName("colour_raw")]
|
[JsonPropertyName("colour_raw")]
|
||||||
public int ColourRaw { get; set; }
|
public int ColourRaw { get; set; }
|
||||||
|
|
||||||
public ChatColour Colour => ChatColour.FromMisuzu(ColourRaw);
|
public Colour Colour => Colour.FromMisuzu(ColourRaw);
|
||||||
|
|
||||||
[JsonPropertyName("hierarchy")]
|
[JsonPropertyName("hierarchy")]
|
||||||
public int Rank { get; set; }
|
public int Rank { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("perms")]
|
[JsonPropertyName("perms")]
|
||||||
public ChatUserPermissions Permissions { get; set; }
|
public UserPermissions Permissions { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("super")]
|
[JsonPropertyName("super")]
|
||||||
public bool IsSuper { get; set; }
|
public bool IsSuper { get; set; }
|
||||||
|
|
|
@ -27,6 +27,6 @@ namespace SharpChat.Misuzu {
|
||||||
|
|
||||||
public bool HasExpired => !IsPermanent && DateTimeOffset.UtcNow >= ExpiresAt;
|
public bool HasExpired => !IsPermanent && DateTimeOffset.UtcNow >= ExpiresAt;
|
||||||
|
|
||||||
public ChatColour UserColour => ChatColour.FromMisuzu(UserColourRaw);
|
public Colour UserColour => Colour.FromMisuzu(UserColourRaw);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,18 +4,18 @@ namespace SharpChat.Packet {
|
||||||
public class AuthSuccessPacket : ServerPacket {
|
public class AuthSuccessPacket : ServerPacket {
|
||||||
private readonly long UserId;
|
private readonly long UserId;
|
||||||
private readonly string UserName;
|
private readonly string UserName;
|
||||||
private readonly ChatColour UserColour;
|
private readonly Colour UserColour;
|
||||||
private readonly int UserRank;
|
private readonly int UserRank;
|
||||||
private readonly ChatUserPermissions UserPerms;
|
private readonly UserPermissions UserPerms;
|
||||||
private readonly string ChannelName;
|
private readonly string ChannelName;
|
||||||
private readonly int MaxMessageLength;
|
private readonly int MaxMessageLength;
|
||||||
|
|
||||||
public AuthSuccessPacket(
|
public AuthSuccessPacket(
|
||||||
long userId,
|
long userId,
|
||||||
string userName,
|
string userName,
|
||||||
ChatColour userColour,
|
Colour userColour,
|
||||||
int userRank,
|
int userRank,
|
||||||
ChatUserPermissions userPerms,
|
UserPermissions userPerms,
|
||||||
string channelName,
|
string channelName,
|
||||||
int maxMsgLength
|
int maxMsgLength
|
||||||
) {
|
) {
|
||||||
|
@ -35,11 +35,11 @@ namespace SharpChat.Packet {
|
||||||
UserName,
|
UserName,
|
||||||
UserColour,
|
UserColour,
|
||||||
UserRank,
|
UserRank,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
|
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
|
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
|
||||||
) : 0,
|
) : 0,
|
||||||
ChannelName,
|
ChannelName,
|
||||||
MaxMessageLength
|
MaxMessageLength
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace SharpChat.Packet {
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
return string.Format(
|
return string.Format(
|
||||||
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\fsay\f{1}\twelcome\t0\t10010",
|
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\fsay\f{1}\twelcome\t0\t10010",
|
||||||
Timestamp, SharpUtil.Sanitise(Body)
|
Timestamp, Utility.Sanitise(Body)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,7 +24,7 @@ namespace SharpChat.Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
string body = SharpUtil.Sanitise(Body);
|
string body = Utility.Sanitise(Body);
|
||||||
if(IsAction)
|
if(IsAction)
|
||||||
body = string.Format("<i>{0}</i>", body);
|
body = string.Format("<i>{0}</i>", body);
|
||||||
|
|
||||||
|
|
|
@ -14,7 +14,7 @@ namespace SharpChat.Packet {
|
||||||
return string.Format(
|
return string.Format(
|
||||||
"2\t{0}\t-1\t0\fsay\f{1}\t{2}\t10010",
|
"2\t{0}\t-1\t0\fsay\f{1}\t{2}\t10010",
|
||||||
Timestamp,
|
Timestamp,
|
||||||
SharpUtil.Sanitise(Body),
|
Utility.Sanitise(Body),
|
||||||
SequenceId
|
SequenceId
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -35,11 +35,11 @@ namespace SharpChat.Packet {
|
||||||
Event.Sender?.LegacyNameWithStatus,
|
Event.Sender?.LegacyNameWithStatus,
|
||||||
Event.Sender?.Colour,
|
Event.Sender?.Colour,
|
||||||
Event.Sender?.Rank,
|
Event.Sender?.Rank,
|
||||||
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.KickUser) == true ? 1 : 0,
|
Event.Sender?.Permissions.HasFlag(UserPermissions.KickUser) == true ? 1 : 0,
|
||||||
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.ViewLogs) == true ? 1 : 0,
|
Event.Sender?.Permissions.HasFlag(UserPermissions.ViewLogs) == true ? 1 : 0,
|
||||||
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.SetOwnNickname) == true ? 1 : 0,
|
Event.Sender?.Permissions.HasFlag(UserPermissions.SetOwnNickname) == true ? 1 : 0,
|
||||||
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.CreateChannel) == true ? (
|
Event.Sender?.Permissions.HasFlag(UserPermissions.CreateChannel) == true ? (
|
||||||
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.SetChannelPermanent) == true ? 2 : 1
|
Event.Sender?.Permissions.HasFlag(UserPermissions.SetChannelPermanent) == true ? 2 : 1
|
||||||
) : 0
|
) : 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace SharpChat.Packet {
|
||||||
if(isBroadcast)
|
if(isBroadcast)
|
||||||
sb.Append("0\fsay\f");
|
sb.Append("0\fsay\f");
|
||||||
|
|
||||||
string body = SharpUtil.Sanitise(Event.Data.RootElement.GetProperty("text").GetString());
|
string body = Utility.Sanitise(Event.Data.RootElement.GetProperty("text").GetString());
|
||||||
if(isAction)
|
if(isAction)
|
||||||
body = string.Format("<i>{0}</i>", body);
|
body = string.Format("<i>{0}</i>", body);
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,16 @@ namespace SharpChat.Packet {
|
||||||
public class UserChannelJoinPacket : ServerPacket {
|
public class UserChannelJoinPacket : ServerPacket {
|
||||||
private readonly long UserId;
|
private readonly long UserId;
|
||||||
private readonly string UserName;
|
private readonly string UserName;
|
||||||
private readonly ChatColour UserColour;
|
private readonly Colour UserColour;
|
||||||
private readonly int UserRank;
|
private readonly int UserRank;
|
||||||
private readonly ChatUserPermissions UserPerms;
|
private readonly UserPermissions UserPerms;
|
||||||
|
|
||||||
public UserChannelJoinPacket(
|
public UserChannelJoinPacket(
|
||||||
long userId,
|
long userId,
|
||||||
string userName,
|
string userName,
|
||||||
ChatColour userColour,
|
Colour userColour,
|
||||||
int userRank,
|
int userRank,
|
||||||
ChatUserPermissions userPerms
|
UserPermissions userPerms
|
||||||
) {
|
) {
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
UserName = userName;
|
UserName = userName;
|
||||||
|
@ -29,11 +29,11 @@ namespace SharpChat.Packet {
|
||||||
UserName,
|
UserName,
|
||||||
UserColour,
|
UserColour,
|
||||||
UserRank,
|
UserRank,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
|
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
|
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
|
||||||
) : 0,
|
) : 0,
|
||||||
SequenceId
|
SequenceId
|
||||||
);
|
);
|
||||||
|
|
|
@ -5,17 +5,17 @@ namespace SharpChat.Packet {
|
||||||
private readonly DateTimeOffset Joined;
|
private readonly DateTimeOffset Joined;
|
||||||
private readonly long UserId;
|
private readonly long UserId;
|
||||||
private readonly string UserName;
|
private readonly string UserName;
|
||||||
private readonly ChatColour UserColour;
|
private readonly Colour UserColour;
|
||||||
private readonly int UserRank;
|
private readonly int UserRank;
|
||||||
private readonly ChatUserPermissions UserPerms;
|
private readonly UserPermissions UserPerms;
|
||||||
|
|
||||||
public UserConnectPacket(
|
public UserConnectPacket(
|
||||||
DateTimeOffset joined,
|
DateTimeOffset joined,
|
||||||
long userId,
|
long userId,
|
||||||
string userName,
|
string userName,
|
||||||
ChatColour userColour,
|
Colour userColour,
|
||||||
int userRank,
|
int userRank,
|
||||||
ChatUserPermissions userPerms
|
UserPermissions userPerms
|
||||||
) {
|
) {
|
||||||
Joined = joined;
|
Joined = joined;
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
|
@ -33,11 +33,11 @@ namespace SharpChat.Packet {
|
||||||
UserName,
|
UserName,
|
||||||
UserColour,
|
UserColour,
|
||||||
UserRank,
|
UserRank,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
|
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
|
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
|
||||||
) : 0,
|
) : 0,
|
||||||
SequenceId
|
SequenceId
|
||||||
);
|
);
|
||||||
|
|
|
@ -4,12 +4,12 @@ namespace SharpChat.Packet {
|
||||||
public class UserDisconnectLogPacket : ServerPacket {
|
public class UserDisconnectLogPacket : ServerPacket {
|
||||||
private readonly long Timestamp;
|
private readonly long Timestamp;
|
||||||
private readonly string UserName;
|
private readonly string UserName;
|
||||||
private readonly ChatUserDisconnectReason Reason;
|
private readonly UserDisconnectReason Reason;
|
||||||
|
|
||||||
public UserDisconnectLogPacket(
|
public UserDisconnectLogPacket(
|
||||||
DateTimeOffset timestamp,
|
DateTimeOffset timestamp,
|
||||||
string userName,
|
string userName,
|
||||||
ChatUserDisconnectReason reason
|
UserDisconnectReason reason
|
||||||
) {
|
) {
|
||||||
Timestamp = timestamp.ToUnixTimeSeconds();
|
Timestamp = timestamp.ToUnixTimeSeconds();
|
||||||
UserName = userName;
|
UserName = userName;
|
||||||
|
@ -21,10 +21,10 @@ namespace SharpChat.Packet {
|
||||||
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\f{1}\f{2}\t{3}\t0\t10010",
|
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\f{1}\f{2}\t{3}\t0\t10010",
|
||||||
Timestamp,
|
Timestamp,
|
||||||
Reason switch {
|
Reason switch {
|
||||||
ChatUserDisconnectReason.Leave => "leave",
|
UserDisconnectReason.Leave => "leave",
|
||||||
ChatUserDisconnectReason.TimeOut => "timeout",
|
UserDisconnectReason.TimeOut => "timeout",
|
||||||
ChatUserDisconnectReason.Kicked => "kick",
|
UserDisconnectReason.Kicked => "kick",
|
||||||
ChatUserDisconnectReason.Flood => "flood",
|
UserDisconnectReason.Flood => "flood",
|
||||||
_ => "leave",
|
_ => "leave",
|
||||||
},
|
},
|
||||||
UserName,
|
UserName,
|
||||||
|
|
|
@ -5,13 +5,13 @@ namespace SharpChat.Packet {
|
||||||
private readonly long Timestamp;
|
private readonly long Timestamp;
|
||||||
private readonly long UserId;
|
private readonly long UserId;
|
||||||
private readonly string UserName;
|
private readonly string UserName;
|
||||||
private readonly ChatUserDisconnectReason Reason;
|
private readonly UserDisconnectReason Reason;
|
||||||
|
|
||||||
public UserDisconnectPacket(
|
public UserDisconnectPacket(
|
||||||
DateTimeOffset timestamp,
|
DateTimeOffset timestamp,
|
||||||
long userId,
|
long userId,
|
||||||
string userName,
|
string userName,
|
||||||
ChatUserDisconnectReason reason
|
UserDisconnectReason reason
|
||||||
) {
|
) {
|
||||||
Timestamp = timestamp.ToUnixTimeSeconds();
|
Timestamp = timestamp.ToUnixTimeSeconds();
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
|
@ -25,10 +25,10 @@ namespace SharpChat.Packet {
|
||||||
UserId,
|
UserId,
|
||||||
UserName,
|
UserName,
|
||||||
Reason switch {
|
Reason switch {
|
||||||
ChatUserDisconnectReason.Leave => "leave",
|
UserDisconnectReason.Leave => "leave",
|
||||||
ChatUserDisconnectReason.TimeOut => "timeout",
|
UserDisconnectReason.TimeOut => "timeout",
|
||||||
ChatUserDisconnectReason.Kicked => "kick",
|
UserDisconnectReason.Kicked => "kick",
|
||||||
ChatUserDisconnectReason.Flood => "flood",
|
UserDisconnectReason.Flood => "flood",
|
||||||
_ => "leave",
|
_ => "leave",
|
||||||
},
|
},
|
||||||
Timestamp,
|
Timestamp,
|
||||||
|
|
|
@ -4,16 +4,16 @@ namespace SharpChat.Packet {
|
||||||
public class UserUpdatePacket : ServerPacket {
|
public class UserUpdatePacket : ServerPacket {
|
||||||
private readonly long UserId;
|
private readonly long UserId;
|
||||||
private readonly string UserName;
|
private readonly string UserName;
|
||||||
private readonly ChatColour UserColour;
|
private readonly Colour UserColour;
|
||||||
private readonly int UserRank;
|
private readonly int UserRank;
|
||||||
private readonly ChatUserPermissions UserPerms;
|
private readonly UserPermissions UserPerms;
|
||||||
|
|
||||||
public UserUpdatePacket(
|
public UserUpdatePacket(
|
||||||
long userId,
|
long userId,
|
||||||
string userName,
|
string userName,
|
||||||
ChatColour userColour,
|
Colour userColour,
|
||||||
int userRank,
|
int userRank,
|
||||||
ChatUserPermissions userPerms
|
UserPermissions userPerms
|
||||||
) {
|
) {
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
UserName = userName;
|
UserName = userName;
|
||||||
|
@ -29,11 +29,11 @@ namespace SharpChat.Packet {
|
||||||
UserName,
|
UserName,
|
||||||
UserColour,
|
UserColour,
|
||||||
UserRank,
|
UserRank,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
|
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
|
||||||
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
|
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
|
||||||
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
|
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
|
||||||
) : 0
|
) : 0
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -3,7 +3,7 @@ using System.Text;
|
||||||
|
|
||||||
namespace SharpChat.Packet {
|
namespace SharpChat.Packet {
|
||||||
public class UsersPopulatePacket : ServerPacket {
|
public class UsersPopulatePacket : ServerPacket {
|
||||||
public record ListEntry(long Id, string Name, ChatColour Colour, int Rank, ChatUserPermissions Perms, bool Visible);
|
public record ListEntry(long Id, string Name, Colour Colour, int Rank, UserPermissions Perms, bool Visible);
|
||||||
|
|
||||||
private readonly ListEntry[] Entries;
|
private readonly ListEntry[] Entries;
|
||||||
|
|
||||||
|
@ -23,11 +23,11 @@ namespace SharpChat.Packet {
|
||||||
entry.Name,
|
entry.Name,
|
||||||
entry.Colour,
|
entry.Colour,
|
||||||
entry.Rank,
|
entry.Rank,
|
||||||
entry.Perms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
|
entry.Perms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
|
||||||
entry.Perms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
|
entry.Perms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
|
||||||
entry.Perms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
|
entry.Perms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
|
||||||
entry.Perms.HasFlag(ChatUserPermissions.CreateChannel) ? (
|
entry.Perms.HasFlag(UserPermissions.CreateChannel) ? (
|
||||||
entry.Perms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
|
entry.Perms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
|
||||||
) : 0,
|
) : 0,
|
||||||
entry.Visible ? 1 : 0
|
entry.Visible ? 1 : 0
|
||||||
);
|
);
|
||||||
|
|
|
@ -1,15 +1,15 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatPacketHandlerContext {
|
public class PacketHandlerContext {
|
||||||
public string Text { get; }
|
public string Text { get; }
|
||||||
public ChatContext Chat { get; }
|
public ChatContext Chat { get; }
|
||||||
public ChatConnection Connection { get; }
|
public ConnectionInfo Connection { get; }
|
||||||
|
|
||||||
public ChatPacketHandlerContext(
|
public PacketHandlerContext(
|
||||||
string text,
|
string text,
|
||||||
ChatContext chat,
|
ChatContext chat,
|
||||||
ChatConnection connection
|
ConnectionInfo connection
|
||||||
) {
|
) {
|
||||||
Text = text;
|
Text = text;
|
||||||
Chat = chat;
|
Chat = chat;
|
|
@ -8,15 +8,15 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.PacketHandlers {
|
namespace SharpChat.PacketHandlers {
|
||||||
public class AuthHandler : IChatPacketHandler {
|
public class AuthHandler : IPacketHandler {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
private readonly ChatChannel DefaultChannel;
|
private readonly ChannelInfo DefaultChannel;
|
||||||
private readonly CachedValue<int> MaxMessageLength;
|
private readonly CachedValue<int> MaxMessageLength;
|
||||||
private readonly CachedValue<int> MaxConnections;
|
private readonly CachedValue<int> MaxConnections;
|
||||||
|
|
||||||
public AuthHandler(
|
public AuthHandler(
|
||||||
MisuzuClient msz,
|
MisuzuClient msz,
|
||||||
ChatChannel defaultChannel,
|
ChannelInfo defaultChannel,
|
||||||
CachedValue<int> maxMsgLength,
|
CachedValue<int> maxMsgLength,
|
||||||
CachedValue<int> maxConns
|
CachedValue<int> maxConns
|
||||||
) {
|
) {
|
||||||
|
@ -26,11 +26,11 @@ namespace SharpChat.PacketHandlers {
|
||||||
MaxConnections = maxConns;
|
MaxConnections = maxConns;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
public bool IsMatch(PacketHandlerContext ctx) {
|
||||||
return ctx.CheckPacketId("1");
|
return ctx.CheckPacketId("1");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(ChatPacketHandlerContext ctx) {
|
public void Handle(PacketHandlerContext ctx) {
|
||||||
string[] args = ctx.SplitText(3);
|
string[] args = ctx.SplitText(3);
|
||||||
|
|
||||||
string? authMethod = args.ElementAtOrDefault(1);
|
string? authMethod = args.ElementAtOrDefault(1);
|
||||||
|
@ -114,10 +114,10 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
await ctx.Chat.ContextAccess.WaitAsync();
|
await ctx.Chat.ContextAccess.WaitAsync();
|
||||||
try {
|
try {
|
||||||
ChatUser? user = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == fai.UserId);
|
UserInfo? user = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == fai.UserId);
|
||||||
|
|
||||||
if(user == null)
|
if(user == null)
|
||||||
user = new ChatUser(
|
user = new UserInfo(
|
||||||
fai.UserId,
|
fai.UserId,
|
||||||
fai.UserName ?? string.Empty,
|
fai.UserName ?? string.Empty,
|
||||||
fai.Colour,
|
fai.Colour,
|
||||||
|
|
|
@ -5,7 +5,7 @@ using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.PacketHandlers {
|
namespace SharpChat.PacketHandlers {
|
||||||
public class PingHandler : IChatPacketHandler {
|
public class PingHandler : IPacketHandler {
|
||||||
private readonly MisuzuClient Misuzu;
|
private readonly MisuzuClient Misuzu;
|
||||||
|
|
||||||
private readonly TimeSpan BumpInterval = TimeSpan.FromMinutes(1);
|
private readonly TimeSpan BumpInterval = TimeSpan.FromMinutes(1);
|
||||||
|
@ -15,11 +15,11 @@ namespace SharpChat.PacketHandlers {
|
||||||
Misuzu = msz;
|
Misuzu = msz;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
public bool IsMatch(PacketHandlerContext ctx) {
|
||||||
return ctx.CheckPacketId("0");
|
return ctx.CheckPacketId("0");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(ChatPacketHandlerContext ctx) {
|
public void Handle(PacketHandlerContext ctx) {
|
||||||
string[] parts = ctx.SplitText(2);
|
string[] parts = ctx.SplitText(2);
|
||||||
|
|
||||||
if(!int.TryParse(parts.FirstOrDefault(), out int pTime))
|
if(!int.TryParse(parts.FirstOrDefault(), out int pTime))
|
||||||
|
@ -32,7 +32,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
try {
|
try {
|
||||||
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
|
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
|
||||||
(string, string)[] bumpList = ctx.Chat.Users.Values
|
(string, string)[] bumpList = ctx.Chat.Users.Values
|
||||||
.Where(u => u.Status == ChatUserStatus.Online && ctx.Chat.Connections.Any(c => c.User == u))
|
.Where(u => u.Status == UserStatus.Online && ctx.Chat.Connections.Any(c => c.User == u))
|
||||||
.Select(u => (u.UserId.ToString(), ctx.Chat.GetRemoteAddresses(u).FirstOrDefault()?.ToString() ?? string.Empty))
|
.Select(u => (u.UserId.ToString(), ctx.Chat.GetRemoteAddresses(u).FirstOrDefault()?.ToString() ?? string.Empty))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
|
|
@ -9,36 +9,36 @@ using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat.PacketHandlers
|
namespace SharpChat.PacketHandlers
|
||||||
{
|
{
|
||||||
public class SendMessageHandler : IChatPacketHandler {
|
public class SendMessageHandler : IPacketHandler {
|
||||||
private readonly CachedValue<int> MaxMessageLength;
|
private readonly CachedValue<int> MaxMessageLength;
|
||||||
|
|
||||||
private List<IChatCommand> Commands { get; } = new();
|
private List<IUserCommand> Commands { get; } = new();
|
||||||
|
|
||||||
public SendMessageHandler(CachedValue<int> maxMsgLength) {
|
public SendMessageHandler(CachedValue<int> maxMsgLength) {
|
||||||
MaxMessageLength = maxMsgLength;
|
MaxMessageLength = maxMsgLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommand(IChatCommand command) {
|
public void AddCommand(IUserCommand command) {
|
||||||
Commands.Add(command);
|
Commands.Add(command);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddCommands(IEnumerable<IChatCommand> commands) {
|
public void AddCommands(IEnumerable<IUserCommand> commands) {
|
||||||
Commands.AddRange(commands);
|
Commands.AddRange(commands);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMatch(ChatPacketHandlerContext ctx) {
|
public bool IsMatch(PacketHandlerContext ctx) {
|
||||||
return ctx.CheckPacketId("2");
|
return ctx.CheckPacketId("2");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Handle(ChatPacketHandlerContext ctx) {
|
public void Handle(PacketHandlerContext ctx) {
|
||||||
string[] args = ctx.SplitText(3);
|
string[] args = ctx.SplitText(3);
|
||||||
|
|
||||||
ChatUser? user = ctx.Connection.User;
|
UserInfo? user = ctx.Connection.User;
|
||||||
|
|
||||||
// No longer concats everything after index 1 with \t, no previous implementation did that either
|
// No longer concats everything after index 1 with \t, no previous implementation did that either
|
||||||
string? messageText = args.ElementAtOrDefault(2);
|
string? messageText = args.ElementAtOrDefault(2);
|
||||||
|
|
||||||
if(user == null || !user.Permissions.HasFlag(ChatUserPermissions.SendMessage) || string.IsNullOrWhiteSpace(messageText))
|
if(user == null || !user.Permissions.HasFlag(UserPermissions.SendMessage) || string.IsNullOrWhiteSpace(messageText))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
// Extra validation step, not necessary at all but enforces proper formatting in SCv1.
|
// Extra validation step, not necessary at all but enforces proper formatting in SCv1.
|
||||||
|
@ -47,12 +47,12 @@ namespace SharpChat.PacketHandlers
|
||||||
|
|
||||||
ctx.Chat.ContextAccess.Wait();
|
ctx.Chat.ContextAccess.Wait();
|
||||||
try {
|
try {
|
||||||
if(!ctx.Chat.UserLastChannel.TryGetValue(user.UserId, out ChatChannel? channel)
|
if(!ctx.Chat.UserLastChannel.TryGetValue(user.UserId, out ChannelInfo? channel)
|
||||||
|| !ctx.Chat.IsInChannel(user, channel))
|
|| !ctx.Chat.IsInChannel(user, channel))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(user.Status != ChatUserStatus.Online)
|
if(user.Status != UserStatus.Online)
|
||||||
ctx.Chat.UpdateUser(user, status: ChatUserStatus.Online);
|
ctx.Chat.UpdateUser(user, status: UserStatus.Online);
|
||||||
|
|
||||||
int maxMsgLength = MaxMessageLength;
|
int maxMsgLength = MaxMessageLength;
|
||||||
if(messageText.Length > maxMsgLength)
|
if(messageText.Length > maxMsgLength)
|
||||||
|
@ -65,11 +65,11 @@ namespace SharpChat.PacketHandlers
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if(messageText.StartsWith("/")) {
|
if(messageText.StartsWith("/")) {
|
||||||
ChatCommandContext context = new(messageText, ctx.Chat, user, ctx.Connection, channel);
|
UserCommandContext context = new(messageText, ctx.Chat, user, ctx.Connection, channel);
|
||||||
|
|
||||||
IChatCommand? command = null;
|
IUserCommand? command = null;
|
||||||
|
|
||||||
foreach(IChatCommand cmd in Commands)
|
foreach(IUserCommand cmd in Commands)
|
||||||
if(cmd.IsMatch(context)) {
|
if(cmd.IsMatch(context)) {
|
||||||
command = cmd;
|
command = cmd;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -18,13 +18,13 @@ namespace SharpChat {
|
||||||
Console.WriteLine(@" ___/ / / / / /_/ / / / /_/ / /___/ / / / /_/ / /_ ");
|
Console.WriteLine(@" ___/ / / / / /_/ / / / /_/ / /___/ / / / /_/ / /_ ");
|
||||||
Console.WriteLine(@"/____/_/ /_/\__,_/_/ / .___/\____/_/ /_/\__,_/\__/ ");
|
Console.WriteLine(@"/____/_/ /_/\__,_/_/ / .___/\____/_/ /_/\__,_/\__/ ");
|
||||||
/**/Console.Write(@" /__/");
|
/**/Console.Write(@" /__/");
|
||||||
if(SharpInfo.IsDebugBuild) {
|
if(BuildInfo.IsDebugBuild) {
|
||||||
Console.WriteLine();
|
Console.WriteLine();
|
||||||
Console.Write(@"== ");
|
Console.Write(@"== ");
|
||||||
Console.Write(SharpInfo.VersionString);
|
Console.Write(BuildInfo.VersionString);
|
||||||
Console.WriteLine(@" == DBG ==");
|
Console.WriteLine(@" == DBG ==");
|
||||||
} else
|
} else
|
||||||
Console.WriteLine(SharpInfo.VersionStringShort.PadLeft(28, ' '));
|
Console.WriteLine(BuildInfo.VersionStringShort.PadLeft(28, ' '));
|
||||||
|
|
||||||
using ManualResetEvent mre = new(false);
|
using ManualResetEvent mre = new(false);
|
||||||
bool hasCancelled = false;
|
bool hasCancelled = false;
|
||||||
|
@ -52,7 +52,7 @@ namespace SharpChat {
|
||||||
using HttpClient httpClient = new(new HttpClientHandler() {
|
using HttpClient httpClient = new(new HttpClientHandler() {
|
||||||
UseProxy = false,
|
UseProxy = false,
|
||||||
});
|
});
|
||||||
httpClient.DefaultRequestHeaders.Add("User-Agent", SharpInfo.ProgramName);
|
httpClient.DefaultRequestHeaders.Add("User-Agent", BuildInfo.ProgramName);
|
||||||
|
|
||||||
if(hasCancelled) return;
|
if(hasCancelled) return;
|
||||||
|
|
||||||
|
|
|
@ -30,13 +30,13 @@ namespace SharpChat {
|
||||||
private readonly CachedValue<int> FloodKickLength;
|
private readonly CachedValue<int> FloodKickLength;
|
||||||
private readonly CachedValue<int> FloodKickExemptRank;
|
private readonly CachedValue<int> FloodKickExemptRank;
|
||||||
|
|
||||||
private readonly List<IChatPacketHandler> GuestHandlers = new();
|
private readonly List<IPacketHandler> GuestHandlers = new();
|
||||||
private readonly List<IChatPacketHandler> AuthedHandlers = new();
|
private readonly List<IPacketHandler> AuthedHandlers = new();
|
||||||
private readonly SendMessageHandler SendMessageHandler;
|
private readonly SendMessageHandler SendMessageHandler;
|
||||||
|
|
||||||
private bool IsShuttingDown = false;
|
private bool IsShuttingDown = false;
|
||||||
|
|
||||||
private ChatChannel DefaultChannel { get; set; }
|
private ChannelInfo DefaultChannel { get; set; }
|
||||||
|
|
||||||
public SockChatServer(HttpClient httpClient, MisuzuClient msz, IEventStorage evtStore, IConfig config) {
|
public SockChatServer(HttpClient httpClient, MisuzuClient msz, IEventStorage evtStore, IConfig config) {
|
||||||
Logger.Write("Initialising Sock Chat server...");
|
Logger.Write("Initialising Sock Chat server...");
|
||||||
|
@ -61,7 +61,7 @@ namespace SharpChat {
|
||||||
if(string.IsNullOrWhiteSpace(name))
|
if(string.IsNullOrWhiteSpace(name))
|
||||||
name = channelName;
|
name = channelName;
|
||||||
|
|
||||||
ChatChannel channelInfo = new(
|
ChannelInfo channelInfo = new(
|
||||||
name,
|
name,
|
||||||
channelCfg.SafeReadValue("password", string.Empty),
|
channelCfg.SafeReadValue("password", string.Empty),
|
||||||
rank: channelCfg.SafeReadValue("minRank", 0)
|
rank: channelCfg.SafeReadValue("minRank", 0)
|
||||||
|
@ -71,18 +71,18 @@ namespace SharpChat {
|
||||||
DefaultChannel ??= channelInfo;
|
DefaultChannel ??= channelInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
DefaultChannel ??= new ChatChannel("Default");
|
DefaultChannel ??= new ChannelInfo("Default");
|
||||||
if(Context.Channels.Count < 1)
|
if(Context.Channels.Count < 1)
|
||||||
Context.Channels.Add(DefaultChannel.Name, DefaultChannel);
|
Context.Channels.Add(DefaultChannel.Name, DefaultChannel);
|
||||||
|
|
||||||
GuestHandlers.Add(new AuthHandler(Misuzu, DefaultChannel, MaxMessageLength, MaxConnections));
|
GuestHandlers.Add(new AuthHandler(Misuzu, DefaultChannel, MaxMessageLength, MaxConnections));
|
||||||
|
|
||||||
AuthedHandlers.AddRange(new IChatPacketHandler[] {
|
AuthedHandlers.AddRange(new IPacketHandler[] {
|
||||||
new PingHandler(Misuzu),
|
new PingHandler(Misuzu),
|
||||||
SendMessageHandler = new SendMessageHandler(MaxMessageLength),
|
SendMessageHandler = new SendMessageHandler(MaxMessageLength),
|
||||||
});
|
});
|
||||||
|
|
||||||
SendMessageHandler.AddCommands(new IChatCommand[] {
|
SendMessageHandler.AddCommands(new IUserCommand[] {
|
||||||
new UserAFKCommand(),
|
new UserAFKCommand(),
|
||||||
new UserNickCommand(),
|
new UserNickCommand(),
|
||||||
new MessageWhisperCommand(),
|
new MessageWhisperCommand(),
|
||||||
|
@ -116,7 +116,7 @@ namespace SharpChat {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatConnection conn = new(sock);
|
ConnectionInfo conn = new(sock);
|
||||||
Context.Connections.Add(conn);
|
Context.Connections.Add(conn);
|
||||||
|
|
||||||
sock.OnOpen = () => OnOpen(conn);
|
sock.OnOpen = () => OnOpen(conn);
|
||||||
|
@ -128,17 +128,17 @@ namespace SharpChat {
|
||||||
Logger.Write("Listening...");
|
Logger.Write("Listening...");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnOpen(ChatConnection conn) {
|
private void OnOpen(ConnectionInfo conn) {
|
||||||
Logger.Write($"Connection opened from {conn.RemoteAddress}:{conn.RemotePort}");
|
Logger.Write($"Connection opened from {conn.RemoteAddress}:{conn.RemotePort}");
|
||||||
Context.SafeUpdate();
|
Context.SafeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnError(ChatConnection conn, Exception ex) {
|
private void OnError(ConnectionInfo conn, Exception ex) {
|
||||||
Logger.Write($"[{conn.Id} {conn.RemoteAddress}] {ex}");
|
Logger.Write($"[{conn.Id} {conn.RemoteAddress}] {ex}");
|
||||||
Context.SafeUpdate();
|
Context.SafeUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClose(ChatConnection conn) {
|
private void OnClose(ConnectionInfo conn) {
|
||||||
Logger.Write($"Connection closed from {conn.RemoteAddress}:{conn.RemotePort}");
|
Logger.Write($"Connection closed from {conn.RemoteAddress}:{conn.RemotePort}");
|
||||||
|
|
||||||
Context.ContextAccess.Wait();
|
Context.ContextAccess.Wait();
|
||||||
|
@ -154,12 +154,12 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMessage(ChatConnection conn, string msg) {
|
private void OnMessage(ConnectionInfo conn, string msg) {
|
||||||
Context.SafeUpdate();
|
Context.SafeUpdate();
|
||||||
|
|
||||||
// this doesn't affect non-authed connections?????
|
// this doesn't affect non-authed connections?????
|
||||||
if(conn.User is not null && conn.User.Rank < FloodKickExemptRank) {
|
if(conn.User is not null && conn.User.Rank < FloodKickExemptRank) {
|
||||||
ChatUser? banUser = null;
|
UserInfo? banUser = null;
|
||||||
string banAddr = string.Empty;
|
string banAddr = string.Empty;
|
||||||
TimeSpan banDuration = TimeSpan.MinValue;
|
TimeSpan banDuration = TimeSpan.MinValue;
|
||||||
|
|
||||||
|
@ -167,9 +167,9 @@ namespace SharpChat {
|
||||||
try {
|
try {
|
||||||
if(!Context.UserRateLimiters.TryGetValue(conn.User.UserId, out RateLimiter? rateLimiter))
|
if(!Context.UserRateLimiters.TryGetValue(conn.User.UserId, out RateLimiter? rateLimiter))
|
||||||
Context.UserRateLimiters.Add(conn.User.UserId, rateLimiter = new RateLimiter(
|
Context.UserRateLimiters.Add(conn.User.UserId, rateLimiter = new RateLimiter(
|
||||||
ChatUser.DEFAULT_SIZE,
|
UserInfo.DEFAULT_SIZE,
|
||||||
ChatUser.DEFAULT_MINIMUM_DELAY,
|
UserInfo.DEFAULT_MINIMUM_DELAY,
|
||||||
ChatUser.DEFAULT_RISKY_OFFSET
|
UserInfo.DEFAULT_RISKY_OFFSET
|
||||||
));
|
));
|
||||||
|
|
||||||
rateLimiter.Update();
|
rateLimiter.Update();
|
||||||
|
@ -186,7 +186,7 @@ namespace SharpChat {
|
||||||
if(banDuration == TimeSpan.MinValue) {
|
if(banDuration == TimeSpan.MinValue) {
|
||||||
Context.SendTo(conn.User, new FloodWarningPacket());
|
Context.SendTo(conn.User, new FloodWarningPacket());
|
||||||
} else {
|
} else {
|
||||||
Context.BanUser(conn.User, banDuration, ChatUserDisconnectReason.Flood);
|
Context.BanUser(conn.User, banDuration, UserDisconnectReason.Flood);
|
||||||
|
|
||||||
if(banDuration > TimeSpan.Zero)
|
if(banDuration > TimeSpan.Zero)
|
||||||
Misuzu.CreateBanAsync(
|
Misuzu.CreateBanAsync(
|
||||||
|
@ -204,8 +204,8 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatPacketHandlerContext context = new(msg, Context, conn);
|
PacketHandlerContext context = new(msg, Context, conn);
|
||||||
IChatPacketHandler? handler = conn.User is null
|
IPacketHandler? handler = conn.User is null
|
||||||
? GuestHandlers.FirstOrDefault(h => h.IsMatch(context))
|
? GuestHandlers.FirstOrDefault(h => h.IsMatch(context))
|
||||||
: AuthedHandlers.FirstOrDefault(h => h.IsMatch(context));
|
: AuthedHandlers.FirstOrDefault(h => h.IsMatch(context));
|
||||||
|
|
||||||
|
@ -229,7 +229,7 @@ namespace SharpChat {
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
IsShuttingDown = true;
|
IsShuttingDown = true;
|
||||||
|
|
||||||
foreach(ChatConnection conn in Context.Connections)
|
foreach(ConnectionInfo conn in Context.Connections)
|
||||||
conn.Dispose();
|
conn.Dispose();
|
||||||
|
|
||||||
Server?.Dispose();
|
Server?.Dispose();
|
||||||
|
|
|
@ -2,20 +2,20 @@
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatCommandContext {
|
public class UserCommandContext {
|
||||||
public string Name { get; }
|
public string Name { get; }
|
||||||
public string[] Args { get; }
|
public string[] Args { get; }
|
||||||
public ChatContext Chat { get; }
|
public ChatContext Chat { get; }
|
||||||
public ChatUser User { get; }
|
public UserInfo User { get; }
|
||||||
public ChatConnection Connection { get; }
|
public ConnectionInfo Connection { get; }
|
||||||
public ChatChannel Channel { get; }
|
public ChannelInfo Channel { get; }
|
||||||
|
|
||||||
public ChatCommandContext(
|
public UserCommandContext(
|
||||||
string text,
|
string text,
|
||||||
ChatContext chat,
|
ChatContext chat,
|
||||||
ChatUser user,
|
UserInfo user,
|
||||||
ChatConnection connection,
|
ConnectionInfo connection,
|
||||||
ChatChannel channel
|
ChannelInfo channel
|
||||||
) {
|
) {
|
||||||
Chat = chat;
|
Chat = chat;
|
||||||
User = user;
|
User = user;
|
|
@ -1,5 +1,5 @@
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public enum ChatUserDisconnectReason {
|
public enum UserDisconnectReason {
|
||||||
Leave,
|
Leave,
|
||||||
TimeOut,
|
TimeOut,
|
||||||
Kicked,
|
Kicked,
|
|
@ -2,19 +2,19 @@
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatUser {
|
public class UserInfo {
|
||||||
public const int DEFAULT_SIZE = 30;
|
public const int DEFAULT_SIZE = 30;
|
||||||
public const int DEFAULT_MINIMUM_DELAY = 10000;
|
public const int DEFAULT_MINIMUM_DELAY = 10000;
|
||||||
public const int DEFAULT_RISKY_OFFSET = 5;
|
public const int DEFAULT_RISKY_OFFSET = 5;
|
||||||
|
|
||||||
public long UserId { get; }
|
public long UserId { get; }
|
||||||
public string UserName { get; set; }
|
public string UserName { get; set; }
|
||||||
public ChatColour Colour { get; set; }
|
public Colour Colour { get; set; }
|
||||||
public int Rank { get; set; }
|
public int Rank { get; set; }
|
||||||
public ChatUserPermissions Permissions { get; set; }
|
public UserPermissions Permissions { get; set; }
|
||||||
public bool IsSuper { get; set; }
|
public bool IsSuper { get; set; }
|
||||||
public string NickName { get; set; }
|
public string NickName { get; set; }
|
||||||
public ChatUserStatus Status { get; set; }
|
public UserStatus Status { get; set; }
|
||||||
public string StatusText { get; set; }
|
public string StatusText { get; set; }
|
||||||
|
|
||||||
public string LegacyName => string.IsNullOrWhiteSpace(NickName) ? UserName : $"~{NickName}";
|
public string LegacyName => string.IsNullOrWhiteSpace(NickName) ? UserName : $"~{NickName}";
|
||||||
|
@ -23,7 +23,7 @@ namespace SharpChat {
|
||||||
get {
|
get {
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
|
|
||||||
if(Status == ChatUserStatus.Away)
|
if(Status == UserStatus.Away)
|
||||||
sb.AppendFormat("<{0}>_", StatusText[..Math.Min(StatusText.Length, 5)].ToUpperInvariant());
|
sb.AppendFormat("<{0}>_", StatusText[..Math.Min(StatusText.Length, 5)].ToUpperInvariant());
|
||||||
|
|
||||||
sb.Append(LegacyName);
|
sb.Append(LegacyName);
|
||||||
|
@ -32,14 +32,14 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatUser(
|
public UserInfo(
|
||||||
long userId,
|
long userId,
|
||||||
string userName,
|
string userName,
|
||||||
ChatColour colour,
|
Colour colour,
|
||||||
int rank,
|
int rank,
|
||||||
ChatUserPermissions perms,
|
UserPermissions perms,
|
||||||
string? nickName = null,
|
string? nickName = null,
|
||||||
ChatUserStatus status = ChatUserStatus.Online,
|
UserStatus status = UserStatus.Online,
|
||||||
string? statusText = null,
|
string? statusText = null,
|
||||||
bool isSuper = false
|
bool isSuper = false
|
||||||
) {
|
) {
|
||||||
|
@ -61,7 +61,7 @@ namespace SharpChat {
|
||||||
|| string.Equals(name, LegacyNameWithStatus, StringComparison.InvariantCultureIgnoreCase);
|
|| string.Equals(name, LegacyNameWithStatus, StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static string GetDMChannelName(ChatUser user1, ChatUser user2) {
|
public static string GetDMChannelName(UserInfo user1, UserInfo user2) {
|
||||||
return user1.UserId < user2.UserId
|
return user1.UserId < user2.UserId
|
||||||
? $"@{user1.UserId}-{user2.UserId}"
|
? $"@{user1.UserId}-{user2.UserId}"
|
||||||
: $"@{user2.UserId}-{user1.UserId}";
|
: $"@{user2.UserId}-{user1.UserId}";
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
[Flags]
|
[Flags]
|
||||||
public enum ChatUserPermissions : int {
|
public enum UserPermissions : int {
|
||||||
KickUser = 0x00000001,
|
KickUser = 0x00000001,
|
||||||
BanUser = 0x00000002,
|
BanUser = 0x00000002,
|
||||||
//SilenceUser = 0x00000004,
|
//SilenceUser = 0x00000004,
|
|
@ -1,5 +1,5 @@
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public enum ChatUserStatus {
|
public enum UserStatus {
|
||||||
Online,
|
Online,
|
||||||
Away,
|
Away,
|
||||||
Offline,
|
Offline,
|
|
@ -1,5 +1,5 @@
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public static class SharpUtil {
|
public static class Utility {
|
||||||
public static string Sanitise(string? body) {
|
public static string Sanitise(string? body) {
|
||||||
if(string.IsNullOrEmpty(body))
|
if(string.IsNullOrEmpty(body))
|
||||||
return string.Empty;
|
return string.Empty;
|
Loading…
Add table
Add a link
Reference in a new issue