Cleaned up the names of some of the base classes.

This commit is contained in:
flash 2024-05-19 02:17:51 +00:00
parent bd23d3aa15
commit 1a8c44a4ba
57 changed files with 336 additions and 336 deletions

View file

@ -2,7 +2,7 @@
using System.Reflection;
namespace SharpChat {
public static class SharpInfo {
public static class BuildInfo {
private const string NAME = @"SharpChat";
private const string UNKNOWN = @"XXXXXXX";
@ -12,7 +12,7 @@ namespace SharpChat {
public static string ProgramName { get; }
static SharpInfo() {
static BuildInfo() {
#if DEBUG
IsDebugBuild = true;
#endif

View file

@ -2,7 +2,7 @@
using System.Linq;
namespace SharpChat {
public class ChatChannel {
public class ChannelInfo {
public string Name { get; }
public string Password { get; set; }
public bool IsTemporary { get; set; }
@ -12,7 +12,7 @@ namespace SharpChat {
public bool HasPassword
=> !string.IsNullOrWhiteSpace(Password);
public ChatChannel(
public ChannelInfo(
string name,
string? password = null,
bool isTemporary = false,
@ -30,7 +30,7 @@ namespace SharpChat {
return string.Equals(name, Name, StringComparison.InvariantCultureIgnoreCase);
}
public bool IsOwner(ChatUser user) {
public bool IsOwner(UserInfo user) {
return OwnerId > 0
&& user != null
&& OwnerId == user.UserId;

View file

@ -13,13 +13,13 @@ namespace SharpChat {
public readonly SemaphoreSlim ContextAccess = new(1, 1);
public Dictionary<string, ChatChannel> Channels { get; } = new();
public List<ChatConnection> Connections { get; } = new();
public Dictionary<long, ChatUser> Users { get; } = new();
public Dictionary<string, ChannelInfo> Channels { get; } = new();
public List<ConnectionInfo> Connections { get; } = new();
public Dictionary<long, UserInfo> Users { get; } = new();
public IEventStorage Events { get; }
public HashSet<ChannelUserAssoc> ChannelUsers { 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) {
Events = evtStore;
@ -41,12 +41,12 @@ namespace SharpChat {
if(targetIds.Length != 2)
return;
ChatUser[] users = Users.Where(kvp => targetIds.Contains(kvp.Key)).Select(kvp => kvp.Value).ToArray();
ChatUser? target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
UserInfo[] users = Users.Where(kvp => targetIds.Contains(kvp.Key)).Select(kvp => kvp.Value).ToArray();
UserInfo? target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
if(target == null)
return;
foreach(ChatUser user in users)
foreach(UserInfo user in users)
SendTo(user, new MessageAddPacket(
mce.MessageId,
DateTimeOffset.Now,
@ -56,7 +56,7 @@ namespace SharpChat {
true
));
} else {
ChatChannel? channel = Channels.Values.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
ChannelInfo? channel = Channels.Values.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
if(channel != null)
SendTo(channel, new MessageAddPacket(
mce.MessageId,
@ -82,7 +82,7 @@ namespace SharpChat {
}
public void Update() {
foreach(ChatConnection conn in Connections)
foreach(ConnectionInfo conn in Connections)
if(!conn.IsDisposed && conn.HasTimedOut) {
conn.Dispose();
Logger.Write($"Nuked connection {conn.Id} associated with {conn.User}.");
@ -92,9 +92,9 @@ namespace SharpChat {
if(removed > 0)
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)) {
HandleDisconnect(user, ChatUserDisconnectReason.TimeOut);
HandleDisconnect(user, UserDisconnectReason.TimeOut);
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
&& channel != null
&& 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();
}
public ChatChannel[] GetUserChannels(ChatUser user) {
public ChannelInfo[] GetUserChannels(UserInfo user) {
string[] names = GetUserChannelNames(user);
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();
}
public ChatUser[] GetChannelUsers(ChatChannel channel) {
public UserInfo[] GetChannelUsers(ChannelInfo channel) {
long[] targetIds = GetChannelUserIds(channel);
return Users.Values.Where(u => targetIds.Contains(u.UserId)).ToArray();
}
public void UpdateUser(
ChatUser user,
UserInfo user,
string? userName = null,
string? nickName = null,
ChatColour? colour = null,
ChatUserStatus? status = null,
Colour? colour = null,
UserStatus? status = null,
string? statusText = null,
int? rank = null,
ChatUserPermissions? perms = null,
UserPermissions? perms = null,
bool? isSuper = null,
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) {
DateTimeOffset expires = duration >= TimeSpan.MaxValue ? DateTimeOffset.MaxValue : DateTimeOffset.Now + duration;
SendTo(user, new ForceDisconnectPacket(expires));
} else
SendTo(user, new ForceDisconnectPacket());
foreach(ChatConnection conn in Connections)
foreach(ConnectionInfo conn in Connections)
if(conn.User == user)
conn.Dispose();
Connections.RemoveAll(conn => conn.IsDisposed);
@ -226,13 +226,13 @@ namespace SharpChat {
"user:disconnect" => new UserDisconnectLogPacket(
msg.Created,
msg.Sender?.LegacyNameWithStatus ?? string.Empty,
(ChatUserDisconnectReason)msg.Data.RootElement.GetProperty("reason").GetByte()
(UserDisconnectReason)msg.Data.RootElement.GetProperty("reason").GetByte()
),
_ => 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)) {
SendTo(chan, new UserConnectPacket(
DateTimeOffset.Now,
@ -270,14 +270,14 @@ namespace SharpChat {
UserLastChannel[user.UserId] = chan;
}
public void HandleDisconnect(ChatUser user, ChatUserDisconnectReason reason = ChatUserDisconnectReason.Leave) {
UpdateUser(user, status: ChatUserStatus.Offline);
public void HandleDisconnect(UserInfo user, UserDisconnectReason reason = UserDisconnectReason.Leave) {
UpdateUser(user, status: UserStatus.Offline);
Users.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));
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) {
if(UserLastChannel.TryGetValue(user.UserId, out ChatChannel? ulc) && chan == ulc) {
public void SwitchChannel(UserInfo user, ChannelInfo chan, string password) {
if(UserLastChannel.TryGetValue(user.UserId, out ChannelInfo? ulc) && chan == ulc) {
ForceChannel(user);
return;
}
if(!user.Permissions.HasFlag(ChatUserPermissions.JoinAnyChannel) && chan.IsOwner(user)) {
if(!user.Permissions.HasFlag(UserPermissions.JoinAnyChannel) && chan.IsOwner(user)) {
if(chan.Rank > user.Rank) {
SendTo(user, new ChannelRankTooLowErrorPacket(chan.Name));
ForceChannel(user);
@ -311,11 +311,11 @@ namespace SharpChat {
ForceChannelSwitch(user, chan);
}
public void ForceChannelSwitch(ChatUser user, ChatChannel chan) {
public void ForceChannelSwitch(UserInfo user, ChannelInfo chan) {
if(!Channels.ContainsValue(chan))
return;
ChatChannel oldChan = UserLastChannel[user.UserId];
ChannelInfo oldChan = UserLastChannel[user.UserId];
SendTo(oldChan, new UserChannelLeavePacket(user.UserId));
Events.AddEvent("chan:leave", user, oldChan, flags: StoredEventFlags.Log);
@ -339,36 +339,36 @@ namespace SharpChat {
}
public void Send(IServerPacket packet) {
foreach(ChatConnection conn in Connections)
foreach(ConnectionInfo conn in Connections)
if(conn.IsAuthed)
conn.Send(packet);
}
public void SendTo(ChatUser user, IServerPacket packet) {
foreach(ChatConnection conn in Connections)
public void SendTo(UserInfo user, IServerPacket packet) {
foreach(ConnectionInfo conn in Connections)
if(conn.IsAlive && conn.User == user)
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
IEnumerable<ChatConnection> conns = Connections.Where(c => c.IsAuthed && IsInChannel(c.User, channel));
foreach(ChatConnection conn in conns)
IEnumerable<ConnectionInfo> conns = Connections.Where(c => c.IsAuthed && IsInChannel(c.User, channel));
foreach(ConnectionInfo conn in conns)
conn.Send(packet);
}
public void SendToUserChannels(ChatUser user, IServerPacket packet) {
IEnumerable<ChatChannel> 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))));
foreach(ChatConnection conn in conns)
public void SendToUserChannels(UserInfo user, IServerPacket packet) {
IEnumerable<ChannelInfo> chans = Channels.Values.Where(c => IsInChannel(user, c));
IEnumerable<ConnectionInfo> conns = Connections.Where(conn => conn.IsAuthed && ChannelUsers.Any(cu => cu.UserId == conn.User?.UserId && chans.Any(chan => chan.NameEquals(cu.ChannelName))));
foreach(ConnectionInfo conn in conns)
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();
}
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))
throw new ArgumentException("no channel???");
@ -376,7 +376,7 @@ namespace SharpChat {
}
public void UpdateChannel(
ChatChannel channel,
ChannelInfo channel,
bool? temporary = null,
int? minRank = null,
string? password = null
@ -396,16 +396,16 @@ namespace SharpChat {
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
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));
}
}
public void RemoveChannel(ChatChannel channel) {
public void RemoveChannel(ChannelInfo channel) {
if(channel == null || !Channels.Any())
return;
ChatChannel? defaultChannel = Channels.Values.FirstOrDefault();
ChannelInfo? defaultChannel = Channels.Values.FirstOrDefault();
if(defaultChannel == null)
return;
@ -414,11 +414,11 @@ namespace SharpChat {
// 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.
foreach(ChatUser user in GetChannelUsers(channel))
foreach(UserInfo user in GetChannelUsers(channel))
SwitchChannel(user, defaultChannel, string.Empty);
// 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));
}
}

View file

@ -1,27 +1,27 @@
namespace SharpChat {
public readonly struct ChatColour {
public readonly struct Colour {
public readonly byte Red;
public readonly byte Green;
public readonly byte Blue;
public readonly bool Inherits;
public static ChatColour None { get; } = new();
public static Colour None { get; } = new();
public ChatColour() {
public Colour() {
Red = 0;
Green = 0;
Blue = 0;
Inherits = true;
}
public ChatColour(byte red, byte green, byte blue) {
public Colour(byte red, byte green, byte blue) {
Red = red;
Green = green;
Blue = blue;
Inherits = false;
}
public bool Equals(ChatColour other) {
public bool Equals(Colour other) {
return Inherits == other.Inherits
&& Red == other.Red
&& Green == other.Green
@ -38,7 +38,7 @@
return (Red << 16) | (Green << 8) | Blue;
}
public static ChatColour FromRawRGB(int rgb) {
public static Colour FromRawRGB(int rgb) {
return new(
(byte)((rgb >> 16) & 0xFF),
(byte)((rgb >> 8) & 0xFF),
@ -52,7 +52,7 @@
return Inherits ? MSZ_INHERIT : ToRawRGB();
}
public static ChatColour FromMisuzu(int raw) {
public static Colour FromMisuzu(int raw) {
return (raw & MSZ_INHERIT) > 0
? None
: FromRawRGB(raw);

View file

@ -5,21 +5,21 @@ using System.Linq;
using System.Threading.Tasks;
namespace SharpChat.Commands {
public class BanListCommand : IChatCommand {
public class BanListCommand : IUserCommand {
private readonly MisuzuClient Misuzu;
public BanListCommand(MisuzuClient msz) {
Misuzu = msz;
}
public bool IsMatch(ChatCommandContext ctx) {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("bans")
|| ctx.NameEquals("banned");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.KickUser)
&& !ctx.User.Permissions.HasFlag(ChatUserPermissions.BanUser)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.KickUser)
&& !ctx.User.Permissions.HasFlag(UserPermissions.BanUser)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}

View file

@ -2,13 +2,13 @@
using System.Linq;
namespace SharpChat.Commands {
public class ChannelCreateCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class ChannelCreateCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("create");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.CreateChannel)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.CreateChannel)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}
@ -33,7 +33,7 @@ namespace SharpChat.Commands {
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());
return;
}
@ -43,15 +43,15 @@ namespace SharpChat.Commands {
return;
}
ChatChannel createChan = new(
ChannelInfo createChan = new(
createChanName,
isTemporary: !ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelPermanent),
isTemporary: !ctx.User.Permissions.HasFlag(UserPermissions.SetChannelPermanent),
rank: createChanHierarchy,
ownerId: ctx.User.UserId
);
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.Channel.Name,
ctx.Channel.HasPassword,

View file

@ -2,29 +2,29 @@
using System.Linq;
namespace SharpChat.Commands {
public class ChannelDeleteCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class ChannelDeleteCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("delchan") || (
ctx.NameEquals("delete")
&& 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())) {
ctx.Chat.SendTo(ctx.User, new CommandFormatErrorPacket());
return;
}
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) {
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(delChanName));
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));
return;
}

View file

@ -2,14 +2,14 @@
using System.Linq;
namespace SharpChat.Commands {
public class ChannelJoinCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class ChannelJoinCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("join");
}
public void Dispatch(ChatCommandContext ctx) {
public void Dispatch(UserCommandContext ctx) {
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) {
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(joinChanStr));

View file

@ -1,14 +1,14 @@
using SharpChat.Packet;
namespace SharpChat.Commands {
public class ChannelPasswordCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class ChannelPasswordCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("pwd")
|| ctx.NameEquals("password");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelPassword) || !ctx.Channel.IsOwner(ctx.User)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelPassword) || !ctx.Channel.IsOwner(ctx.User)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}

View file

@ -2,15 +2,15 @@
using System.Linq;
namespace SharpChat.Commands {
public class ChannelRankCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class ChannelRankCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("rank")
|| ctx.NameEquals("privilege")
|| ctx.NameEquals("priv");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.SetChannelHierarchy) || !ctx.Channel.IsOwner(ctx.User)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelHierarchy) || !ctx.Channel.IsOwner(ctx.User)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}

View file

@ -5,22 +5,22 @@ using System.Linq;
using System.Threading.Tasks;
namespace SharpChat.Commands {
public class KickBanCommand : IChatCommand {
public class KickBanCommand : IUserCommand {
private readonly MisuzuClient Misuzu;
public KickBanCommand(MisuzuClient msz) {
Misuzu = msz;
}
public bool IsMatch(ChatCommandContext ctx) {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("kick")
|| ctx.NameEquals("ban");
}
public void Dispatch(ChatCommandContext ctx) {
public void Dispatch(UserCommandContext ctx) {
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));
return;
}
@ -28,7 +28,7 @@ namespace SharpChat.Commands {
string banUserTarget = ctx.Args.ElementAtOrDefault(0) ?? string.Empty;
string? banDurationStr = ctx.Args.ElementAtOrDefault(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) {
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(banUserTarget));

View file

@ -3,13 +3,13 @@ using System;
using System.Linq;
namespace SharpChat.Commands {
public class MessageActionCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class MessageActionCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("action")
|| ctx.NameEquals("me");
}
public void Dispatch(ChatCommandContext ctx) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.Args.Any())
return;

View file

@ -3,14 +3,14 @@ using SharpChat.Packet;
using System;
namespace SharpChat.Commands {
public class MessageBroadcastCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class MessageBroadcastCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("say")
|| ctx.NameEquals("broadcast");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.Broadcast)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.Broadcast)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}

View file

@ -4,18 +4,18 @@ using System.Linq;
namespace SharpChat.Commands
{
public class MessageDeleteCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class MessageDeleteCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("delmsg") || (
ctx.NameEquals("delete")
&& ctx.Args.FirstOrDefault()?.All(char.IsDigit) == true
);
}
public void Dispatch(ChatCommandContext ctx) {
bool deleteAnyMessage = ctx.User.Permissions.HasFlag(ChatUserPermissions.DeleteAnyMessage);
public void Dispatch(UserCommandContext ctx) {
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));
return;
}

View file

@ -4,20 +4,20 @@ using System;
using System.Linq;
namespace SharpChat.Commands {
public class MessageWhisperCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class MessageWhisperCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("whisper")
|| ctx.NameEquals("msg");
}
public void Dispatch(ChatCommandContext ctx) {
public void Dispatch(UserCommandContext ctx) {
if(ctx.Args.Length < 2) {
ctx.Chat.SendTo(ctx.User, new CommandFormatErrorPacket());
return;
}
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) {
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(whisperUserStr));
@ -29,7 +29,7 @@ namespace SharpChat.Commands {
ctx.Chat.DispatchEvent(new MessageCreateEvent(
SharpId.Next(),
ChatUser.GetDMChannelName(ctx.User, whisperUser),
UserInfo.GetDMChannelName(ctx.User, whisperUser),
ctx.User,
DateTimeOffset.Now,
string.Join(' ', ctx.Args.Skip(1)),

View file

@ -6,21 +6,21 @@ using System.Net;
using System.Threading.Tasks;
namespace SharpChat.Commands {
public class PardonAddressCommand : IChatCommand {
public class PardonAddressCommand : IUserCommand {
private readonly MisuzuClient Misuzu;
public PardonAddressCommand(MisuzuClient msz) {
Misuzu = msz;
}
public bool IsMatch(ChatCommandContext ctx) {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("pardonip")
|| ctx.NameEquals("unbanip");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.KickUser)
&& !ctx.User.Permissions.HasFlag(ChatUserPermissions.BanUser)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.KickUser)
&& !ctx.User.Permissions.HasFlag(UserPermissions.BanUser)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}

View file

@ -5,21 +5,21 @@ using System.Linq;
using System.Threading.Tasks;
namespace SharpChat.Commands {
public class PardonUserCommand : IChatCommand {
public class PardonUserCommand : IUserCommand {
private readonly MisuzuClient Misuzu;
public PardonUserCommand(MisuzuClient msz) {
Misuzu = msz;
}
public bool IsMatch(ChatCommandContext ctx) {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("pardon")
|| ctx.NameEquals("unban");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.KickUser)
&& !ctx.User.Permissions.HasFlag(ChatUserPermissions.BanUser)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.KickUser)
&& !ctx.User.Permissions.HasFlag(UserPermissions.BanUser)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}
@ -31,7 +31,7 @@ namespace SharpChat.Commands {
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)) {
unbanUserTargetIsName = false;
unbanUser = ctx.Chat.Users.Values.FirstOrDefault(u => u.UserId == unbanUserId);

View file

@ -3,7 +3,7 @@ using System;
using System.Threading;
namespace SharpChat.Commands {
public class ShutdownRestartCommand : IChatCommand {
public class ShutdownRestartCommand : IUserCommand {
private readonly ManualResetEvent WaitHandle;
private readonly Func<bool> ShutdownCheck;
@ -12,12 +12,12 @@ namespace SharpChat.Commands {
ShutdownCheck = shutdownCheck;
}
public bool IsMatch(ChatCommandContext ctx) {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("shutdown")
|| ctx.NameEquals("restart");
}
public void Dispatch(ChatCommandContext ctx) {
public void Dispatch(UserCommandContext ctx) {
if(ctx.User.UserId != 1) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
@ -27,7 +27,7 @@ namespace SharpChat.Commands {
return;
if(ctx.NameEquals("restart"))
foreach(ChatConnection conn in ctx.Chat.Connections)
foreach(ConnectionInfo conn in ctx.Chat.Connections)
conn.PrepareForRestart();
ctx.Chat.Update();

View file

@ -2,15 +2,15 @@
using System.Linq;
namespace SharpChat.Commands {
public class UserAFKCommand : IChatCommand {
public class UserAFKCommand : IUserCommand {
private const string DEFAULT = "AFK";
private const int MAX_LENGTH = 5;
public bool IsMatch(ChatCommandContext ctx) {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("afk");
}
public void Dispatch(ChatCommandContext ctx) {
public void Dispatch(UserCommandContext ctx) {
string? statusText = ctx.Args.FirstOrDefault();
if(string.IsNullOrWhiteSpace(statusText))
statusText = DEFAULT;
@ -22,7 +22,7 @@ namespace SharpChat.Commands {
ctx.Chat.UpdateUser(
ctx.User,
status: ChatUserStatus.Away,
status: UserStatus.Away,
statusText: statusText
);
}

View file

@ -2,20 +2,20 @@
using System.Linq;
namespace SharpChat.Commands {
public class UserNickCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class UserNickCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("nick");
}
public void Dispatch(ChatCommandContext ctx) {
bool setOthersNick = ctx.User.Permissions.HasFlag(ChatUserPermissions.SetOthersNickname);
public void Dispatch(UserCommandContext ctx) {
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));
return;
}
ChatUser? targetUser = null;
UserInfo? targetUser = null;
int offset = 0;
if(setOthersNick && long.TryParse(ctx.Args.FirstOrDefault(), out long targetUserId) && targetUserId > 0) {

View file

@ -2,12 +2,12 @@
using System.Linq;
namespace SharpChat.Commands {
public class WhoCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class WhoCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("who");
}
public void Dispatch(ChatCommandContext ctx) {
public void Dispatch(UserCommandContext ctx) {
string? channelName = ctx.Args.FirstOrDefault();
if(string.IsNullOrEmpty(channelName)) {
@ -18,14 +18,14 @@ namespace SharpChat.Commands {
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) {
ctx.Chat.SendTo(ctx.User, new ChannelNotFoundErrorPacket(channelName));
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));
return;
}

View file

@ -3,20 +3,20 @@ using System.Linq;
using System.Net;
namespace SharpChat.Commands {
public class WhoisCommand : IChatCommand {
public bool IsMatch(ChatCommandContext ctx) {
public class WhoisCommand : IUserCommand {
public bool IsMatch(UserCommandContext ctx) {
return ctx.NameEquals("ip")
|| ctx.NameEquals("whois");
}
public void Dispatch(ChatCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(ChatUserPermissions.SeeIPAddress)) {
public void Dispatch(UserCommandContext ctx) {
if(!ctx.User.Permissions.HasFlag(UserPermissions.SeeIPAddress)) {
ctx.Chat.SendTo(ctx.User, new CommandNotAllowedErrorPacket(ctx.Name));
return;
}
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) {
ctx.Chat.SendTo(ctx.User, new UserNotFoundErrorPacket(ipUserStr));

View file

@ -3,7 +3,7 @@ using System;
using System.Net;
namespace SharpChat {
public class ChatConnection : IDisposable {
public class ConnectionInfo : IDisposable {
public const int ID_LENGTH = 20;
#if DEBUG
@ -17,7 +17,7 @@ namespace SharpChat {
public string Id { get; }
public bool IsDisposed { get; private set; }
public DateTimeOffset LastPing { get; set; } = DateTimeOffset.Now;
public ChatUser? User { get; set; }
public UserInfo? User { get; set; }
private int CloseCode { get; set; } = 1000;
@ -28,7 +28,7 @@ namespace SharpChat {
public bool IsAuthed => IsAlive && User is not null;
public ChatConnection(IWebSocketConnection sock) {
public ConnectionInfo(IWebSocketConnection sock) {
Socket = sock;
Id = RNG.SecureRandomString(ID_LENGTH);
@ -64,7 +64,7 @@ namespace SharpChat {
CloseCode = 1012;
}
~ChatConnection() {
~ConnectionInfo() {
DoDispose();
}

View file

@ -16,19 +16,19 @@ namespace SharpChat.EventStorage
);
void AddEvent(
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,
StoredEventFlags flags = StoredEventFlags.None
);
void AddEvent(
long id, string type,
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,
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);
StoredEventInfo? GetEvent(long seqId);
IEnumerable<StoredEventInfo> GetChannelEventLog(string channelName, int amount = 20, int offset = 0);

View file

@ -17,7 +17,7 @@ namespace SharpChat.EventStorage {
object? data = null,
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(
@ -26,12 +26,12 @@ namespace SharpChat.EventStorage {
object? data = null,
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(
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,
StoredEventFlags flags = StoredEventFlags.None
) {
@ -41,7 +41,7 @@ namespace SharpChat.EventStorage {
public void AddEvent(
long id, string type,
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,
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();
AddEvent(
@ -72,7 +72,7 @@ namespace SharpChat.EventStorage {
channel?.Name,
user?.UserId ?? 0,
user?.UserName ?? string.Empty,
user?.Colour ?? ChatColour.None,
user?.Colour ?? Colour.None,
user?.Rank ?? 0,
user?.NickName,
user?.Permissions ?? 0,
@ -112,12 +112,12 @@ namespace SharpChat.EventStorage {
return new StoredEventInfo(
reader.GetInt64("event_id"),
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.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"),
(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")
),
DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created")),

View file

@ -5,7 +5,7 @@ namespace SharpChat.EventStorage {
public class StoredEventInfo {
public long Id { get; set; }
public string Type { get; set; }
public ChatUser? Sender { get; set; }
public UserInfo? Sender { get; set; }
public DateTimeOffset Created { get; set; }
public DateTimeOffset? Deleted { get; set; }
public string? ChannelName { get; set; }
@ -15,7 +15,7 @@ namespace SharpChat.EventStorage {
public StoredEventInfo(
long id,
string type,
ChatUser? sender,
UserInfo? sender,
DateTimeOffset created,
DateTimeOffset? deleted,
string? channelName,

View file

@ -12,7 +12,7 @@ namespace SharpChat.EventStorage {
object? data = null,
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(
@ -21,12 +21,12 @@ namespace SharpChat.EventStorage {
object? data = null,
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(
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,
StoredEventFlags flags = StoredEventFlags.None
) {
@ -36,13 +36,13 @@ namespace SharpChat.EventStorage {
public void AddEvent(
long id, string type,
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,
StoredEventFlags flags = StoredEventFlags.None
) {
// VES is meant as an emergency fallback but this is something else
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,
senderName ?? string.Empty,
senderColour,
@ -52,7 +52,7 @@ namespace SharpChat.EventStorage {
), 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();
AddEvent(
@ -60,7 +60,7 @@ namespace SharpChat.EventStorage {
channel?.Name,
user?.UserId ?? 0,
user?.UserName,
user?.Colour ?? ChatColour.None,
user?.Colour ?? Colour.None,
user?.Rank ?? 0,
user?.NickName,
user?.Permissions ?? 0,

View file

@ -6,10 +6,10 @@ namespace SharpChat.Events {
public string? ChannelName { get; }
public long SenderId { get; }
public string? SenderName { get; }
public ChatColour SenderColour { get; }
public Colour SenderColour { get; }
public int SenderRank { get; }
public string? SenderNickName { get; }
public ChatUserPermissions SenderPerms { get; }
public UserPermissions SenderPerms { get; }
public DateTimeOffset MessageCreated { get; }
public string MessageText { get; }
public bool IsPrivate { get; }
@ -21,10 +21,10 @@ namespace SharpChat.Events {
string? channelName,
long senderId,
string? senderName,
ChatColour senderColour,
Colour senderColour,
int senderRank,
string? senderNickName,
ChatUserPermissions senderPerms,
UserPermissions senderPerms,
DateTimeOffset msgCreated,
string msgText,
bool isPrivate,
@ -49,7 +49,7 @@ namespace SharpChat.Events {
public MessageCreateEvent(
long msgId,
string? channelName,
ChatUser? sender,
UserInfo? sender,
DateTimeOffset msgCreated,
string msgText,
bool isPrivate,
@ -60,7 +60,7 @@ namespace SharpChat.Events {
channelName,
sender?.UserId ?? -1,
sender?.UserName ?? null,
sender?.Colour ?? ChatColour.None,
sender?.Colour ?? Colour.None,
sender?.Rank ?? 0,
sender?.NickName ?? null,
sender?.Permissions ?? 0,
@ -73,8 +73,8 @@ namespace SharpChat.Events {
public MessageCreateEvent(
long msgId,
ChatChannel channel,
ChatUser sender,
ChannelInfo channel,
UserInfo sender,
DateTimeOffset msgCreated,
string msgText,
bool isPrivate,

View file

@ -1,6 +0,0 @@
namespace SharpChat {
public interface IChatCommand {
bool IsMatch(ChatCommandContext ctx);
void Dispatch(ChatCommandContext ctx);
}
}

View file

@ -1,6 +0,0 @@
namespace SharpChat {
public interface IChatPacketHandler {
bool IsMatch(ChatPacketHandlerContext ctx);
void Handle(ChatPacketHandlerContext ctx);
}
}

View file

@ -0,0 +1,6 @@
namespace SharpChat {
public interface IPacketHandler {
bool IsMatch(PacketHandlerContext ctx);
void Handle(PacketHandlerContext ctx);
}
}

View file

@ -0,0 +1,6 @@
namespace SharpChat {
public interface IUserCommand {
bool IsMatch(UserCommandContext ctx);
void Dispatch(UserCommandContext ctx);
}
}

View file

@ -18,13 +18,13 @@ namespace SharpChat.Misuzu {
[JsonPropertyName("colour_raw")]
public int ColourRaw { get; set; }
public ChatColour Colour => ChatColour.FromMisuzu(ColourRaw);
public Colour Colour => Colour.FromMisuzu(ColourRaw);
[JsonPropertyName("hierarchy")]
public int Rank { get; set; }
[JsonPropertyName("perms")]
public ChatUserPermissions Permissions { get; set; }
public UserPermissions Permissions { get; set; }
[JsonPropertyName("super")]
public bool IsSuper { get; set; }

View file

@ -27,6 +27,6 @@ namespace SharpChat.Misuzu {
public bool HasExpired => !IsPermanent && DateTimeOffset.UtcNow >= ExpiresAt;
public ChatColour UserColour => ChatColour.FromMisuzu(UserColourRaw);
public Colour UserColour => Colour.FromMisuzu(UserColourRaw);
}
}

View file

@ -4,18 +4,18 @@ namespace SharpChat.Packet {
public class AuthSuccessPacket : ServerPacket {
private readonly long UserId;
private readonly string UserName;
private readonly ChatColour UserColour;
private readonly Colour UserColour;
private readonly int UserRank;
private readonly ChatUserPermissions UserPerms;
private readonly UserPermissions UserPerms;
private readonly string ChannelName;
private readonly int MaxMessageLength;
public AuthSuccessPacket(
long userId,
string userName,
ChatColour userColour,
Colour userColour,
int userRank,
ChatUserPermissions userPerms,
UserPermissions userPerms,
string channelName,
int maxMsgLength
) {
@ -35,11 +35,11 @@ namespace SharpChat.Packet {
UserName,
UserColour,
UserRank,
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
) : 0,
ChannelName,
MaxMessageLength

View file

@ -13,7 +13,7 @@ namespace SharpChat.Packet {
public override string Pack() {
return string.Format(
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\fsay\f{1}\twelcome\t0\t10010",
Timestamp, SharpUtil.Sanitise(Body)
Timestamp, Utility.Sanitise(Body)
);
}
}

View file

@ -24,7 +24,7 @@ namespace SharpChat.Packet {
}
public override string Pack() {
string body = SharpUtil.Sanitise(Body);
string body = Utility.Sanitise(Body);
if(IsAction)
body = string.Format("<i>{0}</i>", body);

View file

@ -14,7 +14,7 @@ namespace SharpChat.Packet {
return string.Format(
"2\t{0}\t-1\t0\fsay\f{1}\t{2}\t10010",
Timestamp,
SharpUtil.Sanitise(Body),
Utility.Sanitise(Body),
SequenceId
);
}

View file

@ -35,11 +35,11 @@ namespace SharpChat.Packet {
Event.Sender?.LegacyNameWithStatus,
Event.Sender?.Colour,
Event.Sender?.Rank,
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.KickUser) == true ? 1 : 0,
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.ViewLogs) == true ? 1 : 0,
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.SetOwnNickname) == true ? 1 : 0,
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.CreateChannel) == true ? (
Event.Sender?.Permissions.HasFlag(ChatUserPermissions.SetChannelPermanent) == true ? 2 : 1
Event.Sender?.Permissions.HasFlag(UserPermissions.KickUser) == true ? 1 : 0,
Event.Sender?.Permissions.HasFlag(UserPermissions.ViewLogs) == true ? 1 : 0,
Event.Sender?.Permissions.HasFlag(UserPermissions.SetOwnNickname) == true ? 1 : 0,
Event.Sender?.Permissions.HasFlag(UserPermissions.CreateChannel) == true ? (
Event.Sender?.Permissions.HasFlag(UserPermissions.SetChannelPermanent) == true ? 2 : 1
) : 0
);
}
@ -49,7 +49,7 @@ namespace SharpChat.Packet {
if(isBroadcast)
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)
body = string.Format("<i>{0}</i>", body);

View file

@ -4,16 +4,16 @@ namespace SharpChat.Packet {
public class UserChannelJoinPacket : ServerPacket {
private readonly long UserId;
private readonly string UserName;
private readonly ChatColour UserColour;
private readonly Colour UserColour;
private readonly int UserRank;
private readonly ChatUserPermissions UserPerms;
private readonly UserPermissions UserPerms;
public UserChannelJoinPacket(
long userId,
string userName,
ChatColour userColour,
Colour userColour,
int userRank,
ChatUserPermissions userPerms
UserPermissions userPerms
) {
UserId = userId;
UserName = userName;
@ -29,11 +29,11 @@ namespace SharpChat.Packet {
UserName,
UserColour,
UserRank,
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
) : 0,
SequenceId
);

View file

@ -5,17 +5,17 @@ namespace SharpChat.Packet {
private readonly DateTimeOffset Joined;
private readonly long UserId;
private readonly string UserName;
private readonly ChatColour UserColour;
private readonly Colour UserColour;
private readonly int UserRank;
private readonly ChatUserPermissions UserPerms;
private readonly UserPermissions UserPerms;
public UserConnectPacket(
DateTimeOffset joined,
long userId,
string userName,
ChatColour userColour,
Colour userColour,
int userRank,
ChatUserPermissions userPerms
UserPermissions userPerms
) {
Joined = joined;
UserId = userId;
@ -33,11 +33,11 @@ namespace SharpChat.Packet {
UserName,
UserColour,
UserRank,
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
) : 0,
SequenceId
);

View file

@ -4,12 +4,12 @@ namespace SharpChat.Packet {
public class UserDisconnectLogPacket : ServerPacket {
private readonly long Timestamp;
private readonly string UserName;
private readonly ChatUserDisconnectReason Reason;
private readonly UserDisconnectReason Reason;
public UserDisconnectLogPacket(
DateTimeOffset timestamp,
string userName,
ChatUserDisconnectReason reason
UserDisconnectReason reason
) {
Timestamp = timestamp.ToUnixTimeSeconds();
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",
Timestamp,
Reason switch {
ChatUserDisconnectReason.Leave => "leave",
ChatUserDisconnectReason.TimeOut => "timeout",
ChatUserDisconnectReason.Kicked => "kick",
ChatUserDisconnectReason.Flood => "flood",
UserDisconnectReason.Leave => "leave",
UserDisconnectReason.TimeOut => "timeout",
UserDisconnectReason.Kicked => "kick",
UserDisconnectReason.Flood => "flood",
_ => "leave",
},
UserName,

View file

@ -5,13 +5,13 @@ namespace SharpChat.Packet {
private readonly long Timestamp;
private readonly long UserId;
private readonly string UserName;
private readonly ChatUserDisconnectReason Reason;
private readonly UserDisconnectReason Reason;
public UserDisconnectPacket(
DateTimeOffset timestamp,
long userId,
string userName,
ChatUserDisconnectReason reason
UserDisconnectReason reason
) {
Timestamp = timestamp.ToUnixTimeSeconds();
UserId = userId;
@ -25,10 +25,10 @@ namespace SharpChat.Packet {
UserId,
UserName,
Reason switch {
ChatUserDisconnectReason.Leave => "leave",
ChatUserDisconnectReason.TimeOut => "timeout",
ChatUserDisconnectReason.Kicked => "kick",
ChatUserDisconnectReason.Flood => "flood",
UserDisconnectReason.Leave => "leave",
UserDisconnectReason.TimeOut => "timeout",
UserDisconnectReason.Kicked => "kick",
UserDisconnectReason.Flood => "flood",
_ => "leave",
},
Timestamp,

View file

@ -4,16 +4,16 @@ namespace SharpChat.Packet {
public class UserUpdatePacket : ServerPacket {
private readonly long UserId;
private readonly string UserName;
private readonly ChatColour UserColour;
private readonly Colour UserColour;
private readonly int UserRank;
private readonly ChatUserPermissions UserPerms;
private readonly UserPermissions UserPerms;
public UserUpdatePacket(
long userId,
string userName,
ChatColour userColour,
Colour userColour,
int userRank,
ChatUserPermissions userPerms
UserPermissions userPerms
) {
UserId = userId;
UserName = userName;
@ -29,11 +29,11 @@ namespace SharpChat.Packet {
UserName,
UserColour,
UserRank,
UserPerms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(ChatUserPermissions.CreateChannel) ? (
UserPerms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
UserPerms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
UserPerms.HasFlag(UserPermissions.CreateChannel) ? (
UserPerms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
) : 0
);
}

View file

@ -3,7 +3,7 @@ using System.Text;
namespace SharpChat.Packet {
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;
@ -23,11 +23,11 @@ namespace SharpChat.Packet {
entry.Name,
entry.Colour,
entry.Rank,
entry.Perms.HasFlag(ChatUserPermissions.KickUser) ? 1 : 0,
entry.Perms.HasFlag(ChatUserPermissions.ViewLogs) ? 1 : 0,
entry.Perms.HasFlag(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
entry.Perms.HasFlag(ChatUserPermissions.CreateChannel) ? (
entry.Perms.HasFlag(ChatUserPermissions.SetChannelPermanent) ? 2 : 1
entry.Perms.HasFlag(UserPermissions.KickUser) ? 1 : 0,
entry.Perms.HasFlag(UserPermissions.ViewLogs) ? 1 : 0,
entry.Perms.HasFlag(UserPermissions.SetOwnNickname) ? 1 : 0,
entry.Perms.HasFlag(UserPermissions.CreateChannel) ? (
entry.Perms.HasFlag(UserPermissions.SetChannelPermanent) ? 2 : 1
) : 0,
entry.Visible ? 1 : 0
);

View file

@ -1,15 +1,15 @@
using System;
namespace SharpChat {
public class ChatPacketHandlerContext {
public class PacketHandlerContext {
public string Text { get; }
public ChatContext Chat { get; }
public ChatConnection Connection { get; }
public ConnectionInfo Connection { get; }
public ChatPacketHandlerContext(
public PacketHandlerContext(
string text,
ChatContext chat,
ChatConnection connection
ConnectionInfo connection
) {
Text = text;
Chat = chat;

View file

@ -8,15 +8,15 @@ using System.Linq;
using System.Threading.Tasks;
namespace SharpChat.PacketHandlers {
public class AuthHandler : IChatPacketHandler {
public class AuthHandler : IPacketHandler {
private readonly MisuzuClient Misuzu;
private readonly ChatChannel DefaultChannel;
private readonly ChannelInfo DefaultChannel;
private readonly CachedValue<int> MaxMessageLength;
private readonly CachedValue<int> MaxConnections;
public AuthHandler(
MisuzuClient msz,
ChatChannel defaultChannel,
ChannelInfo defaultChannel,
CachedValue<int> maxMsgLength,
CachedValue<int> maxConns
) {
@ -26,11 +26,11 @@ namespace SharpChat.PacketHandlers {
MaxConnections = maxConns;
}
public bool IsMatch(ChatPacketHandlerContext ctx) {
public bool IsMatch(PacketHandlerContext ctx) {
return ctx.CheckPacketId("1");
}
public void Handle(ChatPacketHandlerContext ctx) {
public void Handle(PacketHandlerContext ctx) {
string[] args = ctx.SplitText(3);
string? authMethod = args.ElementAtOrDefault(1);
@ -114,10 +114,10 @@ namespace SharpChat.PacketHandlers {
await ctx.Chat.ContextAccess.WaitAsync();
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)
user = new ChatUser(
user = new UserInfo(
fai.UserId,
fai.UserName ?? string.Empty,
fai.Colour,

View file

@ -5,7 +5,7 @@ using System.Linq;
using System.Threading.Tasks;
namespace SharpChat.PacketHandlers {
public class PingHandler : IChatPacketHandler {
public class PingHandler : IPacketHandler {
private readonly MisuzuClient Misuzu;
private readonly TimeSpan BumpInterval = TimeSpan.FromMinutes(1);
@ -15,11 +15,11 @@ namespace SharpChat.PacketHandlers {
Misuzu = msz;
}
public bool IsMatch(ChatPacketHandlerContext ctx) {
public bool IsMatch(PacketHandlerContext ctx) {
return ctx.CheckPacketId("0");
}
public void Handle(ChatPacketHandlerContext ctx) {
public void Handle(PacketHandlerContext ctx) {
string[] parts = ctx.SplitText(2);
if(!int.TryParse(parts.FirstOrDefault(), out int pTime))
@ -32,7 +32,7 @@ namespace SharpChat.PacketHandlers {
try {
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
(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))
.ToArray();

View file

@ -9,36 +9,36 @@ using System.Linq;
namespace SharpChat.PacketHandlers
{
public class SendMessageHandler : IChatPacketHandler {
public class SendMessageHandler : IPacketHandler {
private readonly CachedValue<int> MaxMessageLength;
private List<IChatCommand> Commands { get; } = new();
private List<IUserCommand> Commands { get; } = new();
public SendMessageHandler(CachedValue<int> maxMsgLength) {
MaxMessageLength = maxMsgLength;
}
public void AddCommand(IChatCommand command) {
public void AddCommand(IUserCommand command) {
Commands.Add(command);
}
public void AddCommands(IEnumerable<IChatCommand> commands) {
public void AddCommands(IEnumerable<IUserCommand> commands) {
Commands.AddRange(commands);
}
public bool IsMatch(ChatPacketHandlerContext ctx) {
public bool IsMatch(PacketHandlerContext ctx) {
return ctx.CheckPacketId("2");
}
public void Handle(ChatPacketHandlerContext ctx) {
public void Handle(PacketHandlerContext ctx) {
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
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;
// Extra validation step, not necessary at all but enforces proper formatting in SCv1.
@ -47,12 +47,12 @@ namespace SharpChat.PacketHandlers
ctx.Chat.ContextAccess.Wait();
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))
return;
if(user.Status != ChatUserStatus.Online)
ctx.Chat.UpdateUser(user, status: ChatUserStatus.Online);
if(user.Status != UserStatus.Online)
ctx.Chat.UpdateUser(user, status: UserStatus.Online);
int maxMsgLength = MaxMessageLength;
if(messageText.Length > maxMsgLength)
@ -65,11 +65,11 @@ namespace SharpChat.PacketHandlers
#endif
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)) {
command = cmd;
break;

View file

@ -18,13 +18,13 @@ namespace SharpChat {
Console.WriteLine(@" ___/ / / / / /_/ / / / /_/ / /___/ / / / /_/ / /_ ");
Console.WriteLine(@"/____/_/ /_/\__,_/_/ / .___/\____/_/ /_/\__,_/\__/ ");
/**/Console.Write(@" /__/");
if(SharpInfo.IsDebugBuild) {
if(BuildInfo.IsDebugBuild) {
Console.WriteLine();
Console.Write(@"== ");
Console.Write(SharpInfo.VersionString);
Console.Write(BuildInfo.VersionString);
Console.WriteLine(@" == DBG ==");
} else
Console.WriteLine(SharpInfo.VersionStringShort.PadLeft(28, ' '));
Console.WriteLine(BuildInfo.VersionStringShort.PadLeft(28, ' '));
using ManualResetEvent mre = new(false);
bool hasCancelled = false;
@ -52,7 +52,7 @@ namespace SharpChat {
using HttpClient httpClient = new(new HttpClientHandler() {
UseProxy = false,
});
httpClient.DefaultRequestHeaders.Add("User-Agent", SharpInfo.ProgramName);
httpClient.DefaultRequestHeaders.Add("User-Agent", BuildInfo.ProgramName);
if(hasCancelled) return;

View file

@ -30,13 +30,13 @@ namespace SharpChat {
private readonly CachedValue<int> FloodKickLength;
private readonly CachedValue<int> FloodKickExemptRank;
private readonly List<IChatPacketHandler> GuestHandlers = new();
private readonly List<IChatPacketHandler> AuthedHandlers = new();
private readonly List<IPacketHandler> GuestHandlers = new();
private readonly List<IPacketHandler> AuthedHandlers = new();
private readonly SendMessageHandler SendMessageHandler;
private bool IsShuttingDown = false;
private ChatChannel DefaultChannel { get; set; }
private ChannelInfo DefaultChannel { get; set; }
public SockChatServer(HttpClient httpClient, MisuzuClient msz, IEventStorage evtStore, IConfig config) {
Logger.Write("Initialising Sock Chat server...");
@ -61,7 +61,7 @@ namespace SharpChat {
if(string.IsNullOrWhiteSpace(name))
name = channelName;
ChatChannel channelInfo = new(
ChannelInfo channelInfo = new(
name,
channelCfg.SafeReadValue("password", string.Empty),
rank: channelCfg.SafeReadValue("minRank", 0)
@ -71,18 +71,18 @@ namespace SharpChat {
DefaultChannel ??= channelInfo;
}
DefaultChannel ??= new ChatChannel("Default");
DefaultChannel ??= new ChannelInfo("Default");
if(Context.Channels.Count < 1)
Context.Channels.Add(DefaultChannel.Name, DefaultChannel);
GuestHandlers.Add(new AuthHandler(Misuzu, DefaultChannel, MaxMessageLength, MaxConnections));
AuthedHandlers.AddRange(new IChatPacketHandler[] {
AuthedHandlers.AddRange(new IPacketHandler[] {
new PingHandler(Misuzu),
SendMessageHandler = new SendMessageHandler(MaxMessageLength),
});
SendMessageHandler.AddCommands(new IChatCommand[] {
SendMessageHandler.AddCommands(new IUserCommand[] {
new UserAFKCommand(),
new UserNickCommand(),
new MessageWhisperCommand(),
@ -116,7 +116,7 @@ namespace SharpChat {
return;
}
ChatConnection conn = new(sock);
ConnectionInfo conn = new(sock);
Context.Connections.Add(conn);
sock.OnOpen = () => OnOpen(conn);
@ -128,17 +128,17 @@ namespace SharpChat {
Logger.Write("Listening...");
}
private void OnOpen(ChatConnection conn) {
private void OnOpen(ConnectionInfo conn) {
Logger.Write($"Connection opened from {conn.RemoteAddress}:{conn.RemotePort}");
Context.SafeUpdate();
}
private void OnError(ChatConnection conn, Exception ex) {
private void OnError(ConnectionInfo conn, Exception ex) {
Logger.Write($"[{conn.Id} {conn.RemoteAddress}] {ex}");
Context.SafeUpdate();
}
private void OnClose(ChatConnection conn) {
private void OnClose(ConnectionInfo conn) {
Logger.Write($"Connection closed from {conn.RemoteAddress}:{conn.RemotePort}");
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();
// this doesn't affect non-authed connections?????
if(conn.User is not null && conn.User.Rank < FloodKickExemptRank) {
ChatUser? banUser = null;
UserInfo? banUser = null;
string banAddr = string.Empty;
TimeSpan banDuration = TimeSpan.MinValue;
@ -167,9 +167,9 @@ namespace SharpChat {
try {
if(!Context.UserRateLimiters.TryGetValue(conn.User.UserId, out RateLimiter? rateLimiter))
Context.UserRateLimiters.Add(conn.User.UserId, rateLimiter = new RateLimiter(
ChatUser.DEFAULT_SIZE,
ChatUser.DEFAULT_MINIMUM_DELAY,
ChatUser.DEFAULT_RISKY_OFFSET
UserInfo.DEFAULT_SIZE,
UserInfo.DEFAULT_MINIMUM_DELAY,
UserInfo.DEFAULT_RISKY_OFFSET
));
rateLimiter.Update();
@ -186,7 +186,7 @@ namespace SharpChat {
if(banDuration == TimeSpan.MinValue) {
Context.SendTo(conn.User, new FloodWarningPacket());
} else {
Context.BanUser(conn.User, banDuration, ChatUserDisconnectReason.Flood);
Context.BanUser(conn.User, banDuration, UserDisconnectReason.Flood);
if(banDuration > TimeSpan.Zero)
Misuzu.CreateBanAsync(
@ -204,8 +204,8 @@ namespace SharpChat {
}
}
ChatPacketHandlerContext context = new(msg, Context, conn);
IChatPacketHandler? handler = conn.User is null
PacketHandlerContext context = new(msg, Context, conn);
IPacketHandler? handler = conn.User is null
? GuestHandlers.FirstOrDefault(h => h.IsMatch(context))
: AuthedHandlers.FirstOrDefault(h => h.IsMatch(context));
@ -229,7 +229,7 @@ namespace SharpChat {
IsDisposed = true;
IsShuttingDown = true;
foreach(ChatConnection conn in Context.Connections)
foreach(ConnectionInfo conn in Context.Connections)
conn.Dispose();
Server?.Dispose();

View file

@ -2,20 +2,20 @@
using System.Linq;
namespace SharpChat {
public class ChatCommandContext {
public class UserCommandContext {
public string Name { get; }
public string[] Args { get; }
public ChatContext Chat { get; }
public ChatUser User { get; }
public ChatConnection Connection { get; }
public ChatChannel Channel { get; }
public UserInfo User { get; }
public ConnectionInfo Connection { get; }
public ChannelInfo Channel { get; }
public ChatCommandContext(
public UserCommandContext(
string text,
ChatContext chat,
ChatUser user,
ChatConnection connection,
ChatChannel channel
UserInfo user,
ConnectionInfo connection,
ChannelInfo channel
) {
Chat = chat;
User = user;

View file

@ -1,5 +1,5 @@
namespace SharpChat {
public enum ChatUserDisconnectReason {
public enum UserDisconnectReason {
Leave,
TimeOut,
Kicked,

View file

@ -2,19 +2,19 @@
using System.Text;
namespace SharpChat {
public class ChatUser {
public class UserInfo {
public const int DEFAULT_SIZE = 30;
public const int DEFAULT_MINIMUM_DELAY = 10000;
public const int DEFAULT_RISKY_OFFSET = 5;
public long UserId { get; }
public string UserName { get; set; }
public ChatColour Colour { get; set; }
public Colour Colour { get; set; }
public int Rank { get; set; }
public ChatUserPermissions Permissions { get; set; }
public UserPermissions Permissions { get; set; }
public bool IsSuper { get; set; }
public string NickName { get; set; }
public ChatUserStatus Status { get; set; }
public UserStatus Status { get; set; }
public string StatusText { get; set; }
public string LegacyName => string.IsNullOrWhiteSpace(NickName) ? UserName : $"~{NickName}";
@ -23,7 +23,7 @@ namespace SharpChat {
get {
StringBuilder sb = new();
if(Status == ChatUserStatus.Away)
if(Status == UserStatus.Away)
sb.AppendFormat("&lt;{0}&gt;_", StatusText[..Math.Min(StatusText.Length, 5)].ToUpperInvariant());
sb.Append(LegacyName);
@ -32,14 +32,14 @@ namespace SharpChat {
}
}
public ChatUser(
public UserInfo(
long userId,
string userName,
ChatColour colour,
Colour colour,
int rank,
ChatUserPermissions perms,
UserPermissions perms,
string? nickName = null,
ChatUserStatus status = ChatUserStatus.Online,
UserStatus status = UserStatus.Online,
string? statusText = null,
bool isSuper = false
) {
@ -61,7 +61,7 @@ namespace SharpChat {
|| 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
? $"@{user1.UserId}-{user2.UserId}"
: $"@{user2.UserId}-{user1.UserId}";

View file

@ -2,7 +2,7 @@
namespace SharpChat {
[Flags]
public enum ChatUserPermissions : int {
public enum UserPermissions : int {
KickUser = 0x00000001,
BanUser = 0x00000002,
//SilenceUser = 0x00000004,

View file

@ -1,5 +1,5 @@
namespace SharpChat {
public enum ChatUserStatus {
public enum UserStatus {
Online,
Away,
Offline,

View file

@ -1,5 +1,5 @@
namespace SharpChat {
public static class SharpUtil {
public static class Utility {
public static string Sanitise(string? body) {
if(string.IsNullOrEmpty(body))
return string.Empty;