Enabled explicit nullable.
This commit is contained in:
parent
b95cd06cb1
commit
a6569815af
40 changed files with 254 additions and 227 deletions
|
@ -15,14 +15,14 @@ namespace SharpChat {
|
||||||
public ChatChannel(
|
public ChatChannel(
|
||||||
ChatUser owner,
|
ChatUser owner,
|
||||||
string name,
|
string name,
|
||||||
string password = null,
|
string? password = null,
|
||||||
bool isTemporary = false,
|
bool isTemporary = false,
|
||||||
int rank = 0
|
int rank = 0
|
||||||
) : this(name, password, isTemporary, rank, owner?.UserId ?? 0) {}
|
) : this(name, password, isTemporary, rank, owner?.UserId ?? 0) {}
|
||||||
|
|
||||||
public ChatChannel(
|
public ChatChannel(
|
||||||
string name,
|
string name,
|
||||||
string password = null,
|
string? password = null,
|
||||||
bool isTemporary = false,
|
bool isTemporary = false,
|
||||||
int rank = 0,
|
int rank = 0,
|
||||||
long ownerId = 0
|
long ownerId = 0
|
||||||
|
@ -34,7 +34,7 @@ namespace SharpChat {
|
||||||
OwnerId = ownerId;
|
OwnerId = ownerId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool NameEquals(string name) {
|
public bool NameEquals(string? name) {
|
||||||
return string.Equals(name, Name, StringComparison.InvariantCultureIgnoreCase);
|
return string.Equals(name, Name, StringComparison.InvariantCultureIgnoreCase);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,4 @@
|
||||||
using System.Diagnostics.CodeAnalysis;
|
namespace SharpChat {
|
||||||
|
|
||||||
namespace SharpChat {
|
|
||||||
public readonly struct ChatColour {
|
public readonly struct ChatColour {
|
||||||
public readonly byte Red;
|
public readonly byte Red;
|
||||||
public readonly byte Green;
|
public readonly byte Green;
|
||||||
|
@ -23,7 +21,7 @@ namespace SharpChat {
|
||||||
Inherits = false;
|
Inherits = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals([NotNullWhen(true)] object obj) {
|
public override bool Equals(object? obj) {
|
||||||
return obj is ChatColour colour && Equals(colour);
|
return obj is ChatColour colour && Equals(colour);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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 ChatUser? User { get; set; }
|
||||||
|
|
||||||
private int CloseCode { get; set; } = 1000;
|
private int CloseCode { get; set; } = 1000;
|
||||||
|
|
||||||
|
@ -32,12 +32,12 @@ namespace SharpChat {
|
||||||
Socket = sock;
|
Socket = sock;
|
||||||
Id = RNG.SecureRandomString(ID_LENGTH);
|
Id = RNG.SecureRandomString(ID_LENGTH);
|
||||||
|
|
||||||
if(!IPAddress.TryParse(sock.ConnectionInfo.ClientIpAddress, out IPAddress addr))
|
if(!IPAddress.TryParse(sock.ConnectionInfo.ClientIpAddress, out IPAddress? addr))
|
||||||
throw new Exception("Unable to parse remote address?????");
|
throw new Exception("Unable to parse remote address?????");
|
||||||
|
|
||||||
if(IPAddress.IsLoopback(addr)
|
if(IPAddress.IsLoopback(addr)
|
||||||
&& sock.ConnectionInfo.Headers.ContainsKey("X-Real-IP")
|
&& sock.ConnectionInfo.Headers.ContainsKey("X-Real-IP")
|
||||||
&& IPAddress.TryParse(sock.ConnectionInfo.Headers["X-Real-IP"], out IPAddress realAddr))
|
&& IPAddress.TryParse(sock.ConnectionInfo.Headers["X-Real-IP"], out IPAddress? realAddr))
|
||||||
addr = realAddr;
|
addr = realAddr;
|
||||||
|
|
||||||
RemoteAddress = addr;
|
RemoteAddress = addr;
|
||||||
|
|
|
@ -34,7 +34,7 @@ namespace SharpChat {
|
||||||
// e.g. nook sees @Arysil and Arysil sees @nook
|
// e.g. nook sees @Arysil and Arysil sees @nook
|
||||||
|
|
||||||
// this entire routine is garbage, channels should probably in the db
|
// this entire routine is garbage, channels should probably in the db
|
||||||
if(!mce.ChannelName.StartsWith("@"))
|
if(mce.ChannelName?.StartsWith("@") != true)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IEnumerable<long> uids = mce.ChannelName[1..].Split('-', 3).Select(u => long.TryParse(u, out long up) ? up : -1);
|
IEnumerable<long> uids = mce.ChannelName[1..].Split('-', 3).Select(u => long.TryParse(u, out long up) ? up : -1);
|
||||||
|
@ -42,7 +42,7 @@ namespace SharpChat {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IEnumerable<ChatUser> users = Users.Where(u => uids.Any(uid => uid == u.UserId));
|
IEnumerable<ChatUser> users = Users.Where(u => uids.Any(uid => uid == u.UserId));
|
||||||
ChatUser target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
|
ChatUser? target = users.FirstOrDefault(u => u.UserId != mce.SenderId);
|
||||||
if(target == null)
|
if(target == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -56,7 +56,8 @@ namespace SharpChat {
|
||||||
true
|
true
|
||||||
));
|
));
|
||||||
} else {
|
} else {
|
||||||
ChatChannel channel = Channels.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
|
ChatChannel? channel = Channels.FirstOrDefault(c => c.NameEquals(mce.ChannelName));
|
||||||
|
if(channel != null)
|
||||||
SendTo(channel, new ChatMessageAddPacket(
|
SendTo(channel, new ChatMessageAddPacket(
|
||||||
mce.MessageId,
|
mce.MessageId,
|
||||||
DateTimeOffset.Now,
|
DateTimeOffset.Now,
|
||||||
|
@ -105,8 +106,10 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsInChannel(ChatUser user, ChatChannel channel) {
|
public bool IsInChannel(ChatUser? user, ChatChannel? channel) {
|
||||||
return ChannelUsers.Contains(new ChannelUserAssoc(user.UserId, channel.Name));
|
return user != null
|
||||||
|
&& channel != null
|
||||||
|
&& ChannelUsers.Contains(new ChannelUserAssoc(user.UserId, channel.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public string[] GetUserChannelNames(ChatUser user) {
|
public string[] GetUserChannelNames(ChatUser user) {
|
||||||
|
@ -129,11 +132,11 @@ namespace SharpChat {
|
||||||
|
|
||||||
public void UpdateUser(
|
public void UpdateUser(
|
||||||
ChatUser user,
|
ChatUser user,
|
||||||
string userName = null,
|
string? userName = null,
|
||||||
string nickName = null,
|
string? nickName = null,
|
||||||
ChatColour? colour = null,
|
ChatColour? colour = null,
|
||||||
ChatUserStatus? status = null,
|
ChatUserStatus? status = null,
|
||||||
string statusText = null,
|
string? statusText = null,
|
||||||
int? rank = null,
|
int? rank = null,
|
||||||
ChatUserPermissions? perms = null,
|
ChatUserPermissions? perms = null,
|
||||||
bool? isSuper = null,
|
bool? isSuper = null,
|
||||||
|
@ -143,7 +146,7 @@ namespace SharpChat {
|
||||||
throw new ArgumentNullException(nameof(user));
|
throw new ArgumentNullException(nameof(user));
|
||||||
|
|
||||||
bool hasChanged = false;
|
bool hasChanged = false;
|
||||||
string previousName = null;
|
string? previousName = null;
|
||||||
|
|
||||||
if(userName != null && !user.UserName.Equals(userName)) {
|
if(userName != null && !user.UserName.Equals(userName)) {
|
||||||
user.UserName = userName;
|
user.UserName = userName;
|
||||||
|
@ -275,7 +278,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SwitchChannel(ChatUser user, ChatChannel chan, string password) {
|
public void SwitchChannel(ChatUser user, ChatChannel chan, string password) {
|
||||||
if(UserLastChannel.TryGetValue(user.UserId, out ChatChannel ulc) && chan == ulc) {
|
if(UserLastChannel.TryGetValue(user.UserId, out ChatChannel? ulc) && chan == ulc) {
|
||||||
ForceChannel(user);
|
ForceChannel(user);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -365,7 +368,7 @@ namespace SharpChat {
|
||||||
throw new ArgumentNullException(nameof(packet));
|
throw new ArgumentNullException(nameof(packet));
|
||||||
|
|
||||||
IEnumerable<ChatChannel> chans = Channels.Where(c => IsInChannel(user, c));
|
IEnumerable<ChatChannel> chans = Channels.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<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)
|
foreach(ChatConnection conn in conns)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
@ -374,7 +377,7 @@ namespace SharpChat {
|
||||||
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(ChatUser user, ChatChannel? chan = null) {
|
||||||
if(user == null)
|
if(user == null)
|
||||||
throw new ArgumentNullException(nameof(user));
|
throw new ArgumentNullException(nameof(user));
|
||||||
|
|
||||||
|
@ -384,7 +387,12 @@ namespace SharpChat {
|
||||||
SendTo(user, new UserChannelForceJoinPacket(chan.Name));
|
SendTo(user, new UserChannelForceJoinPacket(chan.Name));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void UpdateChannel(ChatChannel channel, bool? temporary = null, int? minRank = null, string password = null) {
|
public void UpdateChannel(
|
||||||
|
ChatChannel channel,
|
||||||
|
bool? temporary = null,
|
||||||
|
int? minRank = null,
|
||||||
|
string? password = null
|
||||||
|
) {
|
||||||
if(channel == null)
|
if(channel == null)
|
||||||
throw new ArgumentNullException(nameof(channel));
|
throw new ArgumentNullException(nameof(channel));
|
||||||
if(!Channels.Contains(channel))
|
if(!Channels.Contains(channel))
|
||||||
|
@ -411,7 +419,7 @@ namespace SharpChat {
|
||||||
if(channel == null || !Channels.Any())
|
if(channel == null || !Channels.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ChatChannel defaultChannel = Channels.FirstOrDefault();
|
ChatChannel? defaultChannel = Channels.FirstOrDefault();
|
||||||
if(defaultChannel == null)
|
if(defaultChannel == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
|
@ -34,13 +34,13 @@ namespace SharpChat {
|
||||||
|
|
||||||
public ChatUser(
|
public ChatUser(
|
||||||
long userId,
|
long userId,
|
||||||
string userName,
|
string? userName,
|
||||||
ChatColour colour,
|
ChatColour colour,
|
||||||
int rank,
|
int rank,
|
||||||
ChatUserPermissions perms,
|
ChatUserPermissions perms,
|
||||||
string nickName = null,
|
string? nickName = null,
|
||||||
ChatUserStatus status = ChatUserStatus.Online,
|
ChatUserStatus status = ChatUserStatus.Online,
|
||||||
string statusText = null,
|
string? statusText = null,
|
||||||
bool isSuper = false
|
bool isSuper = false
|
||||||
) {
|
) {
|
||||||
UserId = userId;
|
UserId = userId;
|
||||||
|
@ -59,7 +59,7 @@ namespace SharpChat {
|
||||||
return strict ? perms == perm : perms > 0;
|
return strict ? perms == perm : perms > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool NameEquals(string name) {
|
public bool NameEquals(string? name) {
|
||||||
return string.Equals(name, UserName, StringComparison.InvariantCultureIgnoreCase)
|
return string.Equals(name, UserName, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|| string.Equals(name, NickName, StringComparison.InvariantCultureIgnoreCase)
|
|| string.Equals(name, NickName, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|| string.Equals(name, LegacyName, StringComparison.InvariantCultureIgnoreCase)
|
|| string.Equals(name, LegacyName, StringComparison.InvariantCultureIgnoreCase)
|
||||||
|
@ -70,11 +70,11 @@ namespace SharpChat {
|
||||||
return UserId.GetHashCode();
|
return UserId.GetHashCode();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool Equals(object obj) {
|
public override bool Equals(object? obj) {
|
||||||
return Equals(obj as ChatUser);
|
return Equals(obj as ChatUser);
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(ChatUser other) {
|
public bool Equals(ChatUser? other) {
|
||||||
return UserId == other?.UserId;
|
return UserId == other?.UserId;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -11,7 +11,7 @@ namespace SharpChat.Commands {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(ChatCommandContext ctx) {
|
||||||
string statusText = ctx.Args.FirstOrDefault();
|
string? statusText = ctx.Args.FirstOrDefault();
|
||||||
if(string.IsNullOrWhiteSpace(statusText))
|
if(string.IsNullOrWhiteSpace(statusText))
|
||||||
statusText = DEFAULT;
|
statusText = DEFAULT;
|
||||||
else {
|
else {
|
||||||
|
|
|
@ -25,8 +25,8 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
ctx.Chat.SendTo(ctx.User, new BanListPacket(
|
ctx.Chat.SendTo(ctx.User, new BanListPacket(
|
||||||
(await Misuzu.GetBanListAsync()).Select(
|
(await Misuzu.GetBanListAsync() ?? Array.Empty<MisuzuBanInfo>()).Select(
|
||||||
ban => string.IsNullOrEmpty(ban.UserName) ? ban.RemoteAddress : ban.UserName
|
ban => string.IsNullOrEmpty(ban.UserName) ? (string.IsNullOrEmpty(ban.RemoteAddress) ? string.Empty : ban.RemoteAddress) : ban.UserName
|
||||||
).ToArray()
|
).ToArray()
|
||||||
));
|
));
|
||||||
}).Wait();
|
}).Wait();
|
||||||
|
|
|
@ -17,7 +17,7 @@ namespace SharpChat.Commands {
|
||||||
}
|
}
|
||||||
|
|
||||||
string delChanName = string.Join('_', ctx.Args);
|
string delChanName = string.Join('_', ctx.Args);
|
||||||
ChatChannel delChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(delChanName));
|
ChatChannel? delChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(delChanName));
|
||||||
|
|
||||||
if(delChan == null) {
|
if(delChan == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, delChanName));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, delChanName));
|
||||||
|
|
|
@ -20,16 +20,16 @@ namespace SharpChat.Commands
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string firstArg = ctx.Args.FirstOrDefault();
|
string? firstArg = ctx.Args.FirstOrDefault();
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(firstArg) || !firstArg.All(char.IsDigit) || !long.TryParse(firstArg, out long delSeqId)) {
|
if(string.IsNullOrWhiteSpace(firstArg) || !firstArg.All(char.IsDigit) || !long.TryParse(firstArg, out long delSeqId)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
StoredEventInfo delMsg = ctx.Chat.Events.GetEvent(delSeqId);
|
StoredEventInfo? delMsg = ctx.Chat.Events.GetEvent(delSeqId);
|
||||||
|
|
||||||
if(delMsg == null || delMsg.Sender.Rank > ctx.User.Rank || (!deleteAnyMessage && delMsg.Sender.UserId != ctx.User.UserId)) {
|
if(delMsg == null || delMsg.Sender?.Rank > ctx.User.Rank || (!deleteAnyMessage && delMsg.Sender?.UserId != ctx.User.UserId)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.MESSAGE_DELETE_ERROR));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.MESSAGE_DELETE_ERROR));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,11 +8,11 @@ namespace SharpChat.Commands {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(ChatCommandContext ctx) {
|
||||||
string joinChanStr = ctx.Args.FirstOrDefault();
|
string? joinChanStr = ctx.Args.FirstOrDefault();
|
||||||
ChatChannel joinChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(joinChanStr));
|
ChatChannel? joinChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(joinChanStr));
|
||||||
|
|
||||||
if(joinChan == null) {
|
if(joinChan == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, joinChanStr));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, joinChanStr ?? string.Empty));
|
||||||
ctx.Chat.ForceChannel(ctx.User);
|
ctx.Chat.ForceChannel(ctx.User);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -25,13 +25,13 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string banUserTarget = ctx.Args.ElementAtOrDefault(0);
|
string? banUserTarget = ctx.Args.ElementAtOrDefault(0);
|
||||||
string banDurationStr = ctx.Args.ElementAtOrDefault(1);
|
string? banDurationStr = ctx.Args.ElementAtOrDefault(1);
|
||||||
int banReasonIndex = 1;
|
int banReasonIndex = 1;
|
||||||
ChatUser banUser = null;
|
ChatUser? banUser = null;
|
||||||
|
|
||||||
if(banUserTarget == null || (banUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) {
|
if(banUserTarget == null || (banUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(banUserTarget))) == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, banUser == null ? "User" : banUserTarget));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, banUserTarget ?? string.Empty));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -63,9 +63,9 @@ namespace SharpChat.Commands {
|
||||||
string userIp = ctx.Chat.GetRemoteAddresses(banUser).FirstOrDefault()?.ToString() ?? string.Empty;
|
string userIp = ctx.Chat.GetRemoteAddresses(banUser).FirstOrDefault()?.ToString() ?? string.Empty;
|
||||||
|
|
||||||
// obviously it makes no sense to only check for one ip address but that's current misuzu limitations
|
// obviously it makes no sense to only check for one ip address but that's current misuzu limitations
|
||||||
MisuzuBanInfo fbi = await Misuzu.CheckBanAsync(userId, userIp);
|
MisuzuBanInfo? fbi = await Misuzu.CheckBanAsync(userId, userIp);
|
||||||
|
|
||||||
if(fbi.IsBanned && !fbi.HasExpired) {
|
if(fbi != null && fbi.IsBanned && !fbi.HasExpired) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.LegacyName));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.KICK_NOT_ALLOWED, true, banUser.LegacyName));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,7 +14,8 @@ namespace SharpChat.Commands {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
ChatUser targetUser = null;
|
|
||||||
|
ChatUser? 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) {
|
||||||
|
@ -46,7 +47,7 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string previousName = targetUser == ctx.User ? (targetUser.NickName ?? targetUser.UserName) : null;
|
string? previousName = targetUser == ctx.User ? (targetUser.NickName ?? targetUser.UserName) : null;
|
||||||
ctx.Chat.UpdateUser(targetUser, nickName: nickStr, silent: previousName == null);
|
ctx.Chat.UpdateUser(targetUser, nickName: nickStr, silent: previousName == null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,8 +24,8 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string unbanAddrTarget = ctx.Args.FirstOrDefault();
|
string? unbanAddrTarget = ctx.Args.FirstOrDefault();
|
||||||
if(string.IsNullOrWhiteSpace(unbanAddrTarget) || !IPAddress.TryParse(unbanAddrTarget, out IPAddress unbanAddr)) {
|
if(string.IsNullOrWhiteSpace(unbanAddrTarget) || !IPAddress.TryParse(unbanAddrTarget, out IPAddress? unbanAddr)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -33,9 +33,9 @@ namespace SharpChat.Commands {
|
||||||
unbanAddrTarget = unbanAddr.ToString();
|
unbanAddrTarget = unbanAddr.ToString();
|
||||||
|
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
MisuzuBanInfo banInfo = await Misuzu.CheckBanAsync(ipAddr: unbanAddrTarget);
|
MisuzuBanInfo? banInfo = await Misuzu.CheckBanAsync(ipAddr: unbanAddrTarget);
|
||||||
|
|
||||||
if(!banInfo.IsBanned || banInfo.HasExpired) {
|
if(banInfo?.IsBanned != true || banInfo.HasExpired) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanAddrTarget));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,13 +24,13 @@ namespace SharpChat.Commands {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool unbanUserTargetIsName = true;
|
bool unbanUserTargetIsName = true;
|
||||||
string unbanUserTarget = ctx.Args.FirstOrDefault();
|
string? unbanUserTarget = ctx.Args.FirstOrDefault();
|
||||||
if(string.IsNullOrWhiteSpace(unbanUserTarget)) {
|
if(string.IsNullOrWhiteSpace(unbanUserTarget)) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatUser unbanUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(unbanUserTarget));
|
ChatUser? unbanUser = ctx.Chat.Users.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.FirstOrDefault(u => u.UserId == unbanUserId);
|
unbanUser = ctx.Chat.Users.FirstOrDefault(u => u.UserId == unbanUserId);
|
||||||
|
@ -40,9 +40,9 @@ namespace SharpChat.Commands {
|
||||||
unbanUserTarget = unbanUser.UserId.ToString();
|
unbanUserTarget = unbanUser.UserId.ToString();
|
||||||
|
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
MisuzuBanInfo banInfo = await Misuzu.CheckBanAsync(unbanUserTarget, userIdIsName: unbanUserTargetIsName);
|
MisuzuBanInfo? banInfo = await Misuzu.CheckBanAsync(unbanUserTarget, userIdIsName: unbanUserTargetIsName);
|
||||||
|
|
||||||
if(!banInfo.IsBanned || banInfo.HasExpired) {
|
if(banInfo?.IsBanned != true || banInfo.HasExpired) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_BANNED, true, unbanUserTarget));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,11 +15,11 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string ipUserStr = ctx.Args.FirstOrDefault();
|
string? ipUserStr = ctx.Args.FirstOrDefault();
|
||||||
ChatUser ipUser;
|
ChatUser? ipUser;
|
||||||
|
|
||||||
if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) {
|
if(string.IsNullOrWhiteSpace(ipUserStr) || (ipUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(ipUserStr))) == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, ipUserStr ?? "User"));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, ipUserStr ?? string.Empty));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -16,11 +16,11 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string whisperUserStr = ctx.Args.FirstOrDefault();
|
string? whisperUserStr = ctx.Args.FirstOrDefault();
|
||||||
ChatUser whisperUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(whisperUserStr));
|
ChatUser? whisperUser = ctx.Chat.Users.FirstOrDefault(u => u.NameEquals(whisperUserStr));
|
||||||
|
|
||||||
if(whisperUser == null) {
|
if(whisperUser == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, whisperUserStr));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USER_NOT_FOUND, true, whisperUserStr ?? string.Empty));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
public void Dispatch(ChatCommandContext ctx) {
|
public void Dispatch(ChatCommandContext ctx) {
|
||||||
StringBuilder whoChanSB = new();
|
StringBuilder whoChanSB = new();
|
||||||
string whoChanStr = ctx.Args.FirstOrDefault();
|
string? whoChanStr = ctx.Args.FirstOrDefault();
|
||||||
|
|
||||||
if(string.IsNullOrEmpty(whoChanStr)) {
|
if(string.IsNullOrEmpty(whoChanStr)) {
|
||||||
foreach(ChatUser whoUser in ctx.Chat.Users) {
|
foreach(ChatUser whoUser in ctx.Chat.Users) {
|
||||||
|
@ -19,9 +19,7 @@ namespace SharpChat.Commands {
|
||||||
if(whoUser == ctx.User)
|
if(whoUser == ctx.User)
|
||||||
whoChanSB.Append(@" style=""font-weight: bold;""");
|
whoChanSB.Append(@" style=""font-weight: bold;""");
|
||||||
|
|
||||||
whoChanSB.Append('>');
|
whoChanSB.AppendFormat(@">{0}</a>, ", whoUser.LegacyName);
|
||||||
whoChanSB.Append(whoUser.LegacyName);
|
|
||||||
whoChanSB.Append("</a>, ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(whoChanSB.Length > 2)
|
if(whoChanSB.Length > 2)
|
||||||
|
@ -29,7 +27,7 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_SERVER, false, whoChanSB));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.USERS_LISTING_SERVER, false, whoChanSB));
|
||||||
} else {
|
} else {
|
||||||
ChatChannel whoChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(whoChanStr));
|
ChatChannel? whoChan = ctx.Chat.Channels.FirstOrDefault(c => c.NameEquals(whoChanStr));
|
||||||
|
|
||||||
if(whoChan == null) {
|
if(whoChan == null) {
|
||||||
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, whoChanStr));
|
ctx.Chat.SendTo(ctx.User, new LegacyCommandResponse(LCR.CHANNEL_NOT_FOUND, true, whoChanStr));
|
||||||
|
@ -47,9 +45,7 @@ namespace SharpChat.Commands {
|
||||||
if(whoUser == ctx.User)
|
if(whoUser == ctx.User)
|
||||||
whoChanSB.Append(@" style=""font-weight: bold;""");
|
whoChanSB.Append(@" style=""font-weight: bold;""");
|
||||||
|
|
||||||
whoChanSB.Append('>');
|
whoChanSB.AppendFormat(@">{0}</a>, ", whoUser.LegacyName);
|
||||||
whoChanSB.Append(whoUser.LegacyName);
|
|
||||||
whoChanSB.Append("</a>, ");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(whoChanSB.Length > 2)
|
if(whoChanSB.Length > 2)
|
||||||
|
|
|
@ -5,13 +5,13 @@ namespace SharpChat.Config {
|
||||||
private IConfig Config { get; }
|
private IConfig Config { get; }
|
||||||
private string Name { get; }
|
private string Name { get; }
|
||||||
private TimeSpan Lifetime { get; }
|
private TimeSpan Lifetime { get; }
|
||||||
private T Fallback { get; }
|
private T? Fallback { get; }
|
||||||
private object ConfigAccess { get; } = new();
|
private object ConfigAccess { get; } = new();
|
||||||
|
|
||||||
private object CurrentValue { get; set; }
|
private object? CurrentValue { get; set; }
|
||||||
private DateTimeOffset LastRead { get; set; }
|
private DateTimeOffset LastRead { get; set; }
|
||||||
|
|
||||||
public T Value {
|
public T? Value {
|
||||||
get {
|
get {
|
||||||
lock(ConfigAccess) { // this lock doesn't really make sense since it doesn't affect other config calls
|
lock(ConfigAccess) { // this lock doesn't really make sense since it doesn't affect other config calls
|
||||||
DateTimeOffset now = DateTimeOffset.Now;
|
DateTimeOffset now = DateTimeOffset.Now;
|
||||||
|
@ -21,13 +21,13 @@ namespace SharpChat.Config {
|
||||||
Logger.Debug($"Read {Name} ({CurrentValue})");
|
Logger.Debug($"Read {Name} ({CurrentValue})");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return (T)CurrentValue;
|
return (T?)CurrentValue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static implicit operator T(CachedValue<T> val) => val.Value;
|
public static implicit operator T?(CachedValue<T> val) => val.Value;
|
||||||
|
|
||||||
public CachedValue(IConfig config, string name, TimeSpan lifetime, T fallback) {
|
public CachedValue(IConfig config, string name, TimeSpan lifetime, T? fallback) {
|
||||||
Config = config ?? throw new ArgumentNullException(nameof(config));
|
Config = config ?? throw new ArgumentNullException(nameof(config));
|
||||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
Name = name ?? throw new ArgumentNullException(nameof(name));
|
||||||
Lifetime = lifetime;
|
Lifetime = lifetime;
|
||||||
|
@ -41,7 +41,7 @@ namespace SharpChat.Config {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string ToString() {
|
public override string ToString() {
|
||||||
return Value.ToString();
|
return Value?.ToString() ?? string.Empty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -14,22 +14,22 @@ namespace SharpChat.Config {
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads a raw (string) value from the config.
|
/// Reads a raw (string) value from the config.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
string ReadValue(string name, string fallback = null);
|
string? ReadValue(string name, string? fallback = null);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads and casts value from the config.
|
/// Reads and casts value from the config.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <exception cref="ConfigTypeException">Type conversion failed.</exception>
|
/// <exception cref="ConfigTypeException">Type conversion failed.</exception>
|
||||||
T ReadValue<T>(string name, T fallback = default);
|
T? ReadValue<T>(string name, T? fallback = default);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Reads and casts a value from the config. Returns fallback when type conversion fails.
|
/// Reads and casts a value from the config. Returns fallback when type conversion fails.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
T SafeReadValue<T>(string name, T fallback);
|
T? SafeReadValue<T>(string name, T fallback);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Creates an object that caches the read value for a certain amount of time, avoiding disk reads for frequently used non-static values.
|
/// Creates an object that caches the read value for a certain amount of time, avoiding disk reads for frequently used non-static values.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
CachedValue<T> ReadCached<T>(string name, T fallback = default, TimeSpan? lifetime = null);
|
CachedValue<T> ReadCached<T>(string name, T? fallback = default, TimeSpan? lifetime = null);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -18,15 +18,15 @@ namespace SharpChat.Config {
|
||||||
return Prefix + name;
|
return Prefix + name;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReadValue(string name, string fallback = null) {
|
public string? ReadValue(string name, string? fallback = null) {
|
||||||
return Config.ReadValue(GetName(name), fallback);
|
return Config.ReadValue(GetName(name), fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T ReadValue<T>(string name, T fallback = default) {
|
public T? ReadValue<T>(string name, T? fallback = default) {
|
||||||
return Config.ReadValue(GetName(name), fallback);
|
return Config.ReadValue(GetName(name), fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
public T SafeReadValue<T>(string name, T fallback) {
|
public T? SafeReadValue<T>(string name, T fallback) {
|
||||||
return Config.SafeReadValue(GetName(name), fallback);
|
return Config.SafeReadValue(GetName(name), fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -34,7 +34,7 @@ namespace SharpChat.Config {
|
||||||
return Config.ScopeTo(GetName(prefix));
|
return Config.ScopeTo(GetName(prefix));
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachedValue<T> ReadCached<T>(string name, T fallback = default, TimeSpan? lifetime = null) {
|
public CachedValue<T> ReadCached<T>(string name, T? fallback = default, TimeSpan? lifetime = null) {
|
||||||
return Config.ReadCached(GetName(name), fallback, lifetime);
|
return Config.ReadCached(GetName(name), fallback, lifetime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -26,14 +26,14 @@ namespace SharpChat.Config {
|
||||||
Lock = new Mutex();
|
Lock = new Mutex();
|
||||||
}
|
}
|
||||||
|
|
||||||
public string ReadValue(string name, string fallback = null) {
|
public string? ReadValue(string name, string? fallback = null) {
|
||||||
if(!Lock.WaitOne(LOCK_TIMEOUT)) // don't catch this, if this happens something is Very Wrong
|
if(!Lock.WaitOne(LOCK_TIMEOUT)) // don't catch this, if this happens something is Very Wrong
|
||||||
throw new ConfigLockException();
|
throw new ConfigLockException();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
Stream.Seek(0, SeekOrigin.Begin);
|
Stream.Seek(0, SeekOrigin.Begin);
|
||||||
|
|
||||||
string line;
|
string? line;
|
||||||
while((line = StreamReader.ReadLine()) != null) {
|
while((line = StreamReader.ReadLine()) != null) {
|
||||||
if(string.IsNullOrWhiteSpace(line))
|
if(string.IsNullOrWhiteSpace(line))
|
||||||
continue;
|
continue;
|
||||||
|
@ -55,8 +55,8 @@ namespace SharpChat.Config {
|
||||||
return fallback;
|
return fallback;
|
||||||
}
|
}
|
||||||
|
|
||||||
public T ReadValue<T>(string name, T fallback = default) {
|
public T? ReadValue<T>(string name, T? fallback = default) {
|
||||||
object value = ReadValue(name);
|
object? value = ReadValue(name);
|
||||||
if(value == null)
|
if(value == null)
|
||||||
return fallback;
|
return fallback;
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ namespace SharpChat.Config {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public T SafeReadValue<T>(string name, T fallback) {
|
public T? SafeReadValue<T>(string name, T fallback) {
|
||||||
try {
|
try {
|
||||||
return ReadValue(name, fallback);
|
return ReadValue(name, fallback);
|
||||||
} catch(ConfigTypeException) {
|
} catch(ConfigTypeException) {
|
||||||
|
@ -88,7 +88,7 @@ namespace SharpChat.Config {
|
||||||
return new ScopedConfig(this, prefix);
|
return new ScopedConfig(this, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
public CachedValue<T> ReadCached<T>(string name, T fallback = default, TimeSpan? lifetime = null) {
|
public CachedValue<T> ReadCached<T>(string name, T? fallback = default, TimeSpan? lifetime = null) {
|
||||||
return new CachedValue<T>(this, name, lifetime ?? CACHE_LIFETIME, fallback);
|
return new CachedValue<T>(this, name, lifetime ?? CACHE_LIFETIME, fallback);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,32 +5,32 @@ namespace SharpChat.EventStorage
|
||||||
public interface IEventStorage {
|
public interface IEventStorage {
|
||||||
void AddEvent(
|
void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
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,
|
||||||
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,
|
||||||
long senderId, string senderName, ChatColour senderColour, int senderRank, string senderNick, ChatUserPermissions senderPerms,
|
long senderId, string? senderName, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions 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, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions 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, ChatUser user, ChatChannel 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
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
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, ChatColour.None, 0, null, 0, data, flags);
|
||||||
|
@ -25,8 +25,8 @@ namespace SharpChat.EventStorage
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
string channelName,
|
string? channelName,
|
||||||
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, ChatColour.None, 0, null, 0, data, flags);
|
||||||
|
@ -34,8 +34,8 @@ namespace SharpChat.EventStorage
|
||||||
|
|
||||||
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, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
||||||
object data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
AddEvent(id, type, null, senderId, senderName, senderColour, senderRank, senderNick, senderPerms, data, flags);
|
AddEvent(id, type, null, senderId, senderName, senderColour, senderRank, senderNick, senderPerms, data, flags);
|
||||||
|
@ -43,9 +43,9 @@ 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, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
||||||
object data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
if(type == null)
|
if(type == null)
|
||||||
|
@ -70,7 +70,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, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
||||||
if(type == null)
|
if(type == null)
|
||||||
throw new ArgumentNullException(nameof(type));
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
|
||||||
|
@ -92,9 +92,9 @@ namespace SharpChat.EventStorage
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StoredEventInfo GetEvent(long seqId) {
|
public StoredEventInfo? GetEvent(long seqId) {
|
||||||
try {
|
try {
|
||||||
using MySqlDataReader reader = RunQuery(
|
using MySqlDataReader? reader = RunQuery(
|
||||||
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
||||||
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`"
|
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`"
|
||||||
+ ", UNIX_TIMESTAMP(`event_created`) AS `event_created`"
|
+ ", UNIX_TIMESTAMP(`event_created`) AS `event_created`"
|
||||||
|
@ -104,6 +104,7 @@ namespace SharpChat.EventStorage
|
||||||
new MySqlParameter("id", seqId)
|
new MySqlParameter("id", seqId)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(reader != null)
|
||||||
while(reader.Read()) {
|
while(reader.Read()) {
|
||||||
StoredEventInfo evt = ReadEvent(reader);
|
StoredEventInfo evt = ReadEvent(reader);
|
||||||
if(evt != null)
|
if(evt != null)
|
||||||
|
@ -140,7 +141,7 @@ namespace SharpChat.EventStorage
|
||||||
List<StoredEventInfo> events = new();
|
List<StoredEventInfo> events = new();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
using MySqlDataReader reader = RunQuery(
|
using MySqlDataReader? reader = RunQuery(
|
||||||
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
||||||
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`"
|
+ ", `event_sender`, `event_sender_name`, `event_sender_colour`, `event_sender_rank`, `event_sender_nick`, `event_sender_perms`"
|
||||||
+ ", UNIX_TIMESTAMP(`event_created`) AS `event_created`"
|
+ ", UNIX_TIMESTAMP(`event_created`) AS `event_created`"
|
||||||
|
@ -155,6 +156,7 @@ namespace SharpChat.EventStorage
|
||||||
new MySqlParameter("offset", offset)
|
new MySqlParameter("offset", offset)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if(reader != null)
|
||||||
while(reader.Read()) {
|
while(reader.Read()) {
|
||||||
StoredEventInfo evt = ReadEvent(reader);
|
StoredEventInfo evt = ReadEvent(reader);
|
||||||
if(evt != null)
|
if(evt != null)
|
||||||
|
|
|
@ -5,10 +5,10 @@ namespace SharpChat.EventStorage {
|
||||||
public partial class MariaDBEventStorage {
|
public partial class MariaDBEventStorage {
|
||||||
public static string BuildConnString(IConfig config) {
|
public static string BuildConnString(IConfig config) {
|
||||||
return BuildConnString(
|
return BuildConnString(
|
||||||
config.ReadValue("host", "localhost"),
|
config.ReadValue("host", "localhost") ?? string.Empty,
|
||||||
config.ReadValue("user", string.Empty),
|
config.ReadValue("user") ?? string.Empty,
|
||||||
config.ReadValue("pass", string.Empty),
|
config.ReadValue("pass") ?? string.Empty,
|
||||||
config.ReadValue("db", "sharpchat")
|
config.ReadValue("db", "sharpchat") ?? string.Empty
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -48,7 +48,7 @@ namespace SharpChat.EventStorage {
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private MySqlDataReader RunQuery(string command, params MySqlParameter[] parameters) {
|
private MySqlDataReader? RunQuery(string command, params MySqlParameter[] parameters) {
|
||||||
try {
|
try {
|
||||||
MySqlConnection conn = GetConnection();
|
MySqlConnection conn = GetConnection();
|
||||||
MySqlCommand cmd = conn.CreateCommand();
|
MySqlCommand cmd = conn.CreateCommand();
|
||||||
|
@ -63,7 +63,7 @@ namespace SharpChat.EventStorage {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
private object RunQueryValue(string command, params MySqlParameter[] parameters) {
|
private object? RunQueryValue(string command, params MySqlParameter[] parameters) {
|
||||||
try {
|
try {
|
||||||
using MySqlConnection conn = GetConnection();
|
using MySqlConnection conn = GetConnection();
|
||||||
using MySqlCommand cmd = conn.CreateCommand();
|
using MySqlCommand cmd = conn.CreateCommand();
|
||||||
|
|
|
@ -4,7 +4,7 @@ using System;
|
||||||
namespace SharpChat.EventStorage {
|
namespace SharpChat.EventStorage {
|
||||||
public partial class MariaDBEventStorage {
|
public partial class MariaDBEventStorage {
|
||||||
private void DoMigration(string name, Action action) {
|
private void DoMigration(string name, Action action) {
|
||||||
bool done = (long)RunQueryValue(
|
bool done = (long?)RunQueryValue(
|
||||||
"SELECT COUNT(*) FROM `sqc_migrations` WHERE `migration_name` = @name",
|
"SELECT COUNT(*) FROM `sqc_migrations` WHERE `migration_name` = @name",
|
||||||
new MySqlParameter("name", name)
|
new MySqlParameter("name", name)
|
||||||
) > 0;
|
) > 0;
|
||||||
|
|
|
@ -5,20 +5,20 @@ 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 ChatUser? 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; }
|
||||||
public StoredEventFlags Flags { get; set; }
|
public StoredEventFlags Flags { get; set; }
|
||||||
public JsonDocument Data { get; set; }
|
public JsonDocument Data { get; set; }
|
||||||
|
|
||||||
public StoredEventInfo(
|
public StoredEventInfo(
|
||||||
long id,
|
long id,
|
||||||
string type,
|
string type,
|
||||||
ChatUser sender,
|
ChatUser? sender,
|
||||||
DateTimeOffset created,
|
DateTimeOffset created,
|
||||||
DateTimeOffset? deleted,
|
DateTimeOffset? deleted,
|
||||||
string channelName,
|
string? channelName,
|
||||||
JsonDocument data,
|
JsonDocument data,
|
||||||
StoredEventFlags flags
|
StoredEventFlags flags
|
||||||
) {
|
) {
|
||||||
|
|
|
@ -9,7 +9,7 @@ namespace SharpChat.EventStorage {
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
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, ChatColour.None, 0, null, 0, data, flags);
|
||||||
|
@ -17,8 +17,8 @@ namespace SharpChat.EventStorage {
|
||||||
|
|
||||||
public void AddEvent(
|
public void AddEvent(
|
||||||
long id, string type,
|
long id, string type,
|
||||||
string channelName,
|
string? channelName,
|
||||||
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, ChatColour.None, 0, null, 0, data, flags);
|
||||||
|
@ -26,8 +26,8 @@ namespace SharpChat.EventStorage {
|
||||||
|
|
||||||
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, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
||||||
object data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
AddEvent(id, type, null, senderId, senderName, senderColour, senderRank, senderNick, senderPerms, data, flags);
|
AddEvent(id, type, null, senderId, senderName, senderColour, senderRank, senderNick, senderPerms, data, flags);
|
||||||
|
@ -35,9 +35,9 @@ 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, ChatColour senderColour, int senderRank, string? senderNick, ChatUserPermissions senderPerms,
|
||||||
object data = null,
|
object? data = null,
|
||||||
StoredEventFlags flags = StoredEventFlags.None
|
StoredEventFlags flags = StoredEventFlags.None
|
||||||
) {
|
) {
|
||||||
if(type == null)
|
if(type == null)
|
||||||
|
@ -55,7 +55,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, ChatUser user, ChatChannel channel, object? data = null, StoredEventFlags flags = StoredEventFlags.None) {
|
||||||
if(type == null)
|
if(type == null)
|
||||||
throw new ArgumentNullException(nameof(type));
|
throw new ArgumentNullException(nameof(type));
|
||||||
|
|
||||||
|
@ -77,13 +77,11 @@ namespace SharpChat.EventStorage {
|
||||||
return id;
|
return id;
|
||||||
}
|
}
|
||||||
|
|
||||||
public StoredEventInfo GetEvent(long seqId) {
|
public StoredEventInfo? GetEvent(long seqId) {
|
||||||
return Events.TryGetValue(seqId, out StoredEventInfo evt) ? evt : null;
|
return Events.TryGetValue(seqId, out StoredEventInfo? evt) ? evt : null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveEvent(StoredEventInfo evt) {
|
public void RemoveEvent(StoredEventInfo evt) {
|
||||||
if(evt == null)
|
|
||||||
throw new ArgumentNullException(nameof(evt));
|
|
||||||
Events.Remove(evt.Id);
|
Events.Remove(evt.Id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -3,15 +3,14 @@
|
||||||
namespace SharpChat.Events {
|
namespace SharpChat.Events {
|
||||||
public class MessageCreateEvent : IChatEvent {
|
public class MessageCreateEvent : IChatEvent {
|
||||||
public long MessageId { get; }
|
public long MessageId { get; }
|
||||||
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 ChatColour SenderColour { get; }
|
||||||
public int SenderRank { get; }
|
public int SenderRank { get; }
|
||||||
public string SenderNickName { get; }
|
public string? SenderNickName { get; }
|
||||||
public ChatUserPermissions SenderPerms { get; }
|
public ChatUserPermissions SenderPerms { get; }
|
||||||
public DateTimeOffset MessageCreated { get; }
|
public DateTimeOffset MessageCreated { get; }
|
||||||
public string MessageChannel { get; }
|
|
||||||
public string MessageText { get; }
|
public string MessageText { get; }
|
||||||
public bool IsPrivate { get; }
|
public bool IsPrivate { get; }
|
||||||
public bool IsAction { get; }
|
public bool IsAction { get; }
|
||||||
|
@ -19,12 +18,12 @@ namespace SharpChat.Events {
|
||||||
|
|
||||||
public MessageCreateEvent(
|
public MessageCreateEvent(
|
||||||
long msgId,
|
long msgId,
|
||||||
string channelName,
|
string? channelName,
|
||||||
long senderId,
|
long senderId,
|
||||||
string senderName,
|
string? senderName,
|
||||||
ChatColour senderColour,
|
ChatColour senderColour,
|
||||||
int senderRank,
|
int senderRank,
|
||||||
string senderNickName,
|
string? senderNickName,
|
||||||
ChatUserPermissions senderPerms,
|
ChatUserPermissions senderPerms,
|
||||||
DateTimeOffset msgCreated,
|
DateTimeOffset msgCreated,
|
||||||
string msgText,
|
string msgText,
|
||||||
|
@ -49,8 +48,8 @@ namespace SharpChat.Events {
|
||||||
|
|
||||||
public MessageCreateEvent(
|
public MessageCreateEvent(
|
||||||
long msgId,
|
long msgId,
|
||||||
string channelName,
|
string? channelName,
|
||||||
ChatUser sender,
|
ChatUser? sender,
|
||||||
DateTimeOffset msgCreated,
|
DateTimeOffset msgCreated,
|
||||||
string msgText,
|
string msgText,
|
||||||
bool isPrivate,
|
bool isPrivate,
|
||||||
|
|
|
@ -13,7 +13,7 @@ namespace SharpChat.Misuzu {
|
||||||
public long UserId { get; set; }
|
public long UserId { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("username")]
|
[JsonPropertyName("username")]
|
||||||
public string UserName { get; set; }
|
public string? UserName { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("colour_raw")]
|
[JsonPropertyName("colour_raw")]
|
||||||
public int ColourRaw { get; set; }
|
public int ColourRaw { get; set; }
|
||||||
|
|
|
@ -7,10 +7,10 @@ namespace SharpChat.Misuzu {
|
||||||
public bool IsBanned { get; set; }
|
public bool IsBanned { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("user_id")]
|
[JsonPropertyName("user_id")]
|
||||||
public string UserId { get; set; }
|
public string? UserId { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("ip_addr")]
|
[JsonPropertyName("ip_addr")]
|
||||||
public string RemoteAddress { get; set; }
|
public string? RemoteAddress { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("is_perma")]
|
[JsonPropertyName("is_perma")]
|
||||||
public bool IsPermanent { get; set; }
|
public bool IsPermanent { get; set; }
|
||||||
|
@ -20,7 +20,7 @@ namespace SharpChat.Misuzu {
|
||||||
|
|
||||||
// only populated in list request
|
// only populated in list request
|
||||||
[JsonPropertyName("user_name")]
|
[JsonPropertyName("user_name")]
|
||||||
public string UserName { get; set; }
|
public string? UserName { get; set; }
|
||||||
|
|
||||||
[JsonPropertyName("user_colour")]
|
[JsonPropertyName("user_colour")]
|
||||||
public int UserColourRaw { get; set; }
|
public int UserColourRaw { get; set; }
|
||||||
|
|
|
@ -47,11 +47,11 @@ namespace SharpChat.Misuzu {
|
||||||
}
|
}
|
||||||
|
|
||||||
public string CreateBufferSignature(byte[] bytes) {
|
public string CreateBufferSignature(byte[] bytes) {
|
||||||
using HMACSHA256 algo = new(Encoding.UTF8.GetBytes(SecretKey));
|
using HMACSHA256 algo = new(Encoding.UTF8.GetBytes(SecretKey.Value ?? string.Empty));
|
||||||
return string.Concat(algo.ComputeHash(bytes).Select(c => c.ToString("x2")));
|
return string.Concat(algo.ComputeHash(bytes).Select(c => c.ToString("x2")));
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MisuzuAuthInfo> AuthVerifyAsync(string method, string token, string ipAddr) {
|
public async Task<MisuzuAuthInfo?> AuthVerifyAsync(string method, string token, string ipAddr) {
|
||||||
method ??= string.Empty;
|
method ??= string.Empty;
|
||||||
token ??= string.Empty;
|
token ??= string.Empty;
|
||||||
ipAddr ??= string.Empty;
|
ipAddr ??= string.Empty;
|
||||||
|
@ -114,7 +114,11 @@ namespace SharpChat.Misuzu {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MisuzuBanInfo> CheckBanAsync(string userId = null, string ipAddr = null, bool userIdIsName = false) {
|
public async Task<MisuzuBanInfo?> CheckBanAsync(
|
||||||
|
string? userId = null,
|
||||||
|
string? ipAddr = null,
|
||||||
|
bool userIdIsName = false
|
||||||
|
) {
|
||||||
userId ??= string.Empty;
|
userId ??= string.Empty;
|
||||||
ipAddr ??= string.Empty;
|
ipAddr ??= string.Empty;
|
||||||
|
|
||||||
|
@ -136,7 +140,7 @@ namespace SharpChat.Misuzu {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
public async Task<MisuzuBanInfo[]> GetBanListAsync() {
|
public async Task<MisuzuBanInfo[]?> GetBanListAsync() {
|
||||||
string now = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
|
string now = DateTimeOffset.Now.ToUnixTimeSeconds().ToString();
|
||||||
string url = string.Format(BANS_LIST_URL, BaseURL, Uri.EscapeDataString(now));
|
string url = string.Format(BANS_LIST_URL, BaseURL, Uri.EscapeDataString(now));
|
||||||
string sig = string.Format(BANS_LIST_SIG, now);
|
string sig = string.Format(BANS_LIST_SIG, now);
|
||||||
|
@ -170,8 +174,8 @@ namespace SharpChat.Misuzu {
|
||||||
};
|
};
|
||||||
|
|
||||||
string target = kind switch {
|
string target = kind switch {
|
||||||
BanRevokeKind.UserId => banInfo.UserId,
|
BanRevokeKind.UserId => banInfo?.UserId ?? string.Empty,
|
||||||
BanRevokeKind.RemoteAddress => banInfo.RemoteAddress,
|
BanRevokeKind.RemoteAddress => banInfo?.RemoteAddress ?? string.Empty,
|
||||||
_ => string.Empty,
|
_ => string.Empty,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -5,6 +5,7 @@ namespace SharpChat.Packet {
|
||||||
AuthInvalid,
|
AuthInvalid,
|
||||||
MaxSessions,
|
MaxSessions,
|
||||||
Banned,
|
Banned,
|
||||||
|
Null,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AuthFailPacket : ServerPacket {
|
public class AuthFailPacket : ServerPacket {
|
||||||
|
|
|
@ -32,15 +32,15 @@ namespace SharpChat.Packet {
|
||||||
} else {
|
} else {
|
||||||
sb.AppendFormat(
|
sb.AppendFormat(
|
||||||
"{0}\t{1}\t{2}\t{3} {4} {5} {6} {7}",
|
"{0}\t{1}\t{2}\t{3} {4} {5} {6} {7}",
|
||||||
Event.Sender.UserId,
|
Event.Sender?.UserId,
|
||||||
Event.Sender.LegacyNameWithStatus,
|
Event.Sender?.LegacyNameWithStatus,
|
||||||
Event.Sender.Colour,
|
Event.Sender?.Colour,
|
||||||
Event.Sender.Rank,
|
Event.Sender?.Rank,
|
||||||
Event.Sender.Can(ChatUserPermissions.KickUser) ? 1 : 0,
|
Event.Sender?.Can(ChatUserPermissions.KickUser) == true ? 1 : 0,
|
||||||
Event.Sender.Can(ChatUserPermissions.ViewLogs) ? 1 : 0,
|
Event.Sender?.Can(ChatUserPermissions.ViewLogs) == true ? 1 : 0,
|
||||||
Event.Sender.Can(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
|
Event.Sender?.Can(ChatUserPermissions.SetOwnNickname) == true ? 1 : 0,
|
||||||
Event.Sender.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? 2 : (
|
Event.Sender?.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) == true ? 2 : (
|
||||||
Event.Sender.Can(ChatUserPermissions.CreateChannel) ? 1 : 0
|
Event.Sender?.Can(ChatUserPermissions.CreateChannel) == true ? 1 : 0
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
@ -50,7 +50,7 @@ namespace SharpChat.Packet {
|
||||||
if(isBroadcast)
|
if(isBroadcast)
|
||||||
sb.Append("0\fsay\f");
|
sb.Append("0\fsay\f");
|
||||||
|
|
||||||
string body = Event.Data.RootElement.GetProperty("text").GetString().Replace("<", "<").Replace(">", ">").Replace("\n", " <br/> ").Replace("\t", " ");
|
string body = Event.Data.RootElement.GetProperty("text").GetString()?.Replace("<", "<").Replace(">", ">").Replace("\n", " <br/> ").Replace("\t", " ") ?? string.Empty;
|
||||||
if(isAction)
|
if(isAction)
|
||||||
body = string.Format("<i>{0}</i>", body);
|
body = string.Format("<i>{0}</i>", body);
|
||||||
|
|
||||||
|
@ -59,17 +59,17 @@ namespace SharpChat.Packet {
|
||||||
|
|
||||||
case "user:connect":
|
case "user:connect":
|
||||||
case "SharpChat.Events.UserConnectEvent":
|
case "SharpChat.Events.UserConnectEvent":
|
||||||
sb.AppendFormat("{0}\t0\fjoin\f{1}", V1_CHATBOT, Event.Sender.LegacyName);
|
sb.AppendFormat("{0}\t0\fjoin\f{1}", V1_CHATBOT, Event.Sender?.LegacyName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "chan:join":
|
case "chan:join":
|
||||||
case "SharpChat.Events.UserChannelJoinEvent":
|
case "SharpChat.Events.UserChannelJoinEvent":
|
||||||
sb.AppendFormat("{0}\t0\fjchan\f{1}", V1_CHATBOT, Event.Sender.LegacyName);
|
sb.AppendFormat("{0}\t0\fjchan\f{1}", V1_CHATBOT, Event.Sender?.LegacyName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "chan:leave":
|
case "chan:leave":
|
||||||
case "SharpChat.Events.UserChannelLeaveEvent":
|
case "SharpChat.Events.UserChannelLeaveEvent":
|
||||||
sb.AppendFormat("{0}\t0\flchan\f{1}", V1_CHATBOT, Event.Sender.LegacyName);
|
sb.AppendFormat("{0}\t0\flchan\f{1}", V1_CHATBOT, Event.Sender?.LegacyName);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case "user:disconnect":
|
case "user:disconnect":
|
||||||
|
@ -84,7 +84,7 @@ namespace SharpChat.Packet {
|
||||||
UserDisconnectReason.Leave => "leave",
|
UserDisconnectReason.Leave => "leave",
|
||||||
_ => "leave",
|
_ => "leave",
|
||||||
},
|
},
|
||||||
Event.Sender.LegacyName
|
Event.Sender?.LegacyName
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,14 +33,14 @@ namespace SharpChat.PacketHandlers {
|
||||||
public void Handle(ChatPacketHandlerContext ctx) {
|
public void Handle(ChatPacketHandlerContext ctx) {
|
||||||
string[] args = ctx.SplitText(3);
|
string[] args = ctx.SplitText(3);
|
||||||
|
|
||||||
string authMethod = args.ElementAtOrDefault(1);
|
string? authMethod = args.ElementAtOrDefault(1);
|
||||||
if(string.IsNullOrWhiteSpace(authMethod)) {
|
if(string.IsNullOrWhiteSpace(authMethod)) {
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string authToken = args.ElementAtOrDefault(2);
|
string? authToken = args.ElementAtOrDefault(2);
|
||||||
if(string.IsNullOrWhiteSpace(authToken)) {
|
if(string.IsNullOrWhiteSpace(authToken)) {
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
|
@ -54,7 +54,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
MisuzuAuthInfo fai;
|
MisuzuAuthInfo? fai;
|
||||||
string ipAddr = ctx.Connection.RemoteAddress.ToString();
|
string ipAddr = ctx.Connection.RemoteAddress.ToString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
|
@ -70,6 +70,13 @@ namespace SharpChat.PacketHandlers {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(fai == null) {
|
||||||
|
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: <null>");
|
||||||
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.Null));
|
||||||
|
ctx.Connection.Dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(!fai.Success) {
|
if(!fai.Success) {
|
||||||
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: {fai.Reason}");
|
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: {fai.Reason}");
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
|
@ -77,7 +84,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
MisuzuBanInfo fbi;
|
MisuzuBanInfo? fbi;
|
||||||
try {
|
try {
|
||||||
fbi = await Misuzu.CheckBanAsync(fai.UserId.ToString(), ipAddr);
|
fbi = await Misuzu.CheckBanAsync(fai.UserId.ToString(), ipAddr);
|
||||||
} catch(Exception ex) {
|
} catch(Exception ex) {
|
||||||
|
@ -91,6 +98,13 @@ namespace SharpChat.PacketHandlers {
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if(fbi == null) {
|
||||||
|
Logger.Debug($"<{ctx.Connection.Id}> Ban check fail: <null>");
|
||||||
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.Null));
|
||||||
|
ctx.Connection.Dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(fbi.IsBanned && !fbi.HasExpired) {
|
if(fbi.IsBanned && !fbi.HasExpired) {
|
||||||
Logger.Write($"<{ctx.Connection.Id}> User is banned.");
|
Logger.Write($"<{ctx.Connection.Id}> User is banned.");
|
||||||
ctx.Connection.Send(new AuthFailPacket(fbi.ExpiresAt));
|
ctx.Connection.Send(new AuthFailPacket(fbi.ExpiresAt));
|
||||||
|
@ -100,7 +114,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
await ctx.Chat.ContextAccess.WaitAsync();
|
await ctx.Chat.ContextAccess.WaitAsync();
|
||||||
try {
|
try {
|
||||||
ChatUser user = ctx.Chat.Users.FirstOrDefault(u => u.UserId == fai.UserId);
|
ChatUser? user = ctx.Chat.Users.FirstOrDefault(u => u.UserId == fai.UserId);
|
||||||
|
|
||||||
if(user == null)
|
if(user == null)
|
||||||
user = new ChatUser(
|
user = new ChatUser(
|
||||||
|
@ -134,7 +148,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
if(File.Exists("welcome.txt")) {
|
if(File.Exists("welcome.txt")) {
|
||||||
IEnumerable<string> lines = File.ReadAllLines("welcome.txt").Where(x => !string.IsNullOrWhiteSpace(x));
|
IEnumerable<string> lines = File.ReadAllLines("welcome.txt").Where(x => !string.IsNullOrWhiteSpace(x));
|
||||||
string line = lines.ElementAtOrDefault(RNG.Next(lines.Count()));
|
string? line = lines.ElementAtOrDefault(RNG.Next(lines.Count()));
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(line))
|
if(!string.IsNullOrWhiteSpace(line))
|
||||||
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, line));
|
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, line));
|
||||||
|
|
|
@ -33,10 +33,10 @@ namespace SharpChat.PacketHandlers
|
||||||
public void Handle(ChatPacketHandlerContext ctx) {
|
public void Handle(ChatPacketHandlerContext ctx) {
|
||||||
string[] args = ctx.SplitText(3);
|
string[] args = ctx.SplitText(3);
|
||||||
|
|
||||||
ChatUser user = ctx.Connection.User;
|
ChatUser? 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.Can(ChatUserPermissions.SendMessage) || string.IsNullOrWhiteSpace(messageText))
|
if(user == null || !user.Can(ChatUserPermissions.SendMessage) || string.IsNullOrWhiteSpace(messageText))
|
||||||
return;
|
return;
|
||||||
|
@ -47,8 +47,8 @@ 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 ChatChannel? channel)
|
||||||
&& !ctx.Chat.IsInChannel(user, channel))
|
|| !ctx.Chat.IsInChannel(user, channel))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(user.Status != ChatUserStatus.Online)
|
if(user.Status != ChatUserStatus.Online)
|
||||||
|
@ -67,7 +67,7 @@ namespace SharpChat.PacketHandlers
|
||||||
if(messageText.StartsWith("/")) {
|
if(messageText.StartsWith("/")) {
|
||||||
ChatCommandContext context = new(messageText, ctx.Chat, user, ctx.Connection, channel);
|
ChatCommandContext context = new(messageText, ctx.Chat, user, ctx.Connection, channel);
|
||||||
|
|
||||||
IChatCommand command = null;
|
IChatCommand? command = null;
|
||||||
|
|
||||||
foreach(IChatCommand cmd in Commands)
|
foreach(IChatCommand cmd in Commands)
|
||||||
if(cmd.IsMatch(context)) {
|
if(cmd.IsMatch(context)) {
|
||||||
|
|
|
@ -29,7 +29,7 @@ namespace SharpChat {
|
||||||
using ManualResetEvent mre = new(false);
|
using ManualResetEvent mre = new(false);
|
||||||
bool hasCancelled = false;
|
bool hasCancelled = false;
|
||||||
|
|
||||||
void cancelKeyPressHandler(object sender, ConsoleCancelEventArgs ev) {
|
void cancelKeyPressHandler(object? sender, ConsoleCancelEventArgs ev) {
|
||||||
Console.CancelKeyPress -= cancelKeyPressHandler;
|
Console.CancelKeyPress -= cancelKeyPressHandler;
|
||||||
hasCancelled = true;
|
hasCancelled = true;
|
||||||
ev.Cancel = true;
|
ev.Cancel = true;
|
||||||
|
|
|
@ -3,6 +3,7 @@
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net6.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using Fleck;
|
#nullable disable
|
||||||
|
|
||||||
|
using Fleck;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
|
|
@ -1,6 +1,5 @@
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Text;
|
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public static class SharpInfo {
|
public static class SharpInfo {
|
||||||
|
@ -19,19 +18,18 @@ namespace SharpChat {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
try {
|
try {
|
||||||
using Stream s = Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SharpChat.version.txt");
|
using Stream? s = Assembly.GetExecutingAssembly().GetManifestResourceStream(@"SharpChat.version.txt");
|
||||||
|
if(s != null) {
|
||||||
using StreamReader sr = new(s);
|
using StreamReader sr = new(s);
|
||||||
VersionString = sr.ReadLine().Trim();
|
VersionString = sr.ReadLine()?.Trim() ?? string.Empty;
|
||||||
|
} else
|
||||||
|
VersionString = string.Empty;
|
||||||
VersionStringShort = VersionString.Length > 10 ? VersionString[..10] : VersionString;
|
VersionStringShort = VersionString.Length > 10 ? VersionString[..10] : VersionString;
|
||||||
} catch {
|
} catch {
|
||||||
VersionStringShort = VersionString = UNKNOWN;
|
VersionStringShort = VersionString = UNKNOWN;
|
||||||
}
|
}
|
||||||
|
|
||||||
StringBuilder sb = new();
|
ProgramName = string.Format(@"{0}/{1}", NAME, VersionStringShort);
|
||||||
sb.Append(NAME);
|
|
||||||
sb.Append('/');
|
|
||||||
sb.Append(VersionStringShort);
|
|
||||||
ProgramName = sb.ToString();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -51,12 +51,13 @@ namespace SharpChat {
|
||||||
|
|
||||||
Context = new ChatContext(evtStore);
|
Context = new ChatContext(evtStore);
|
||||||
|
|
||||||
string[] channelNames = config.ReadValue("channels", new[] { "lounge" });
|
string[]? channelNames = config.ReadValue("channels", new[] { "lounge" });
|
||||||
|
|
||||||
|
if(channelNames != null)
|
||||||
foreach(string channelName in channelNames) {
|
foreach(string channelName in channelNames) {
|
||||||
IConfig channelCfg = config.ScopeTo($"channels:{channelName}");
|
IConfig channelCfg = config.ScopeTo($"channels:{channelName}");
|
||||||
|
|
||||||
string name = channelCfg.SafeReadValue("name", string.Empty);
|
string? name = channelCfg.SafeReadValue("name", string.Empty);
|
||||||
if(string.IsNullOrWhiteSpace(name))
|
if(string.IsNullOrWhiteSpace(name))
|
||||||
name = channelName;
|
name = channelName;
|
||||||
|
|
||||||
|
@ -70,6 +71,10 @@ namespace SharpChat {
|
||||||
DefaultChannel ??= channelInfo;
|
DefaultChannel ??= channelInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DefaultChannel ??= new ChatChannel("Default");
|
||||||
|
if(!Context.Channels.Any())
|
||||||
|
Context.Channels.Add(DefaultChannel);
|
||||||
|
|
||||||
GuestHandlers.Add(new AuthHandler(Misuzu, DefaultChannel, MaxMessageLength, MaxConnections));
|
GuestHandlers.Add(new AuthHandler(Misuzu, DefaultChannel, MaxMessageLength, MaxConnections));
|
||||||
|
|
||||||
AuthedHandlers.AddRange(new IChatPacketHandler[] {
|
AuthedHandlers.AddRange(new IChatPacketHandler[] {
|
||||||
|
@ -154,13 +159,13 @@ namespace SharpChat {
|
||||||
|
|
||||||
// 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;
|
ChatUser? banUser = null;
|
||||||
string banAddr = string.Empty;
|
string banAddr = string.Empty;
|
||||||
TimeSpan banDuration = TimeSpan.MinValue;
|
TimeSpan banDuration = TimeSpan.MinValue;
|
||||||
|
|
||||||
Context.ContextAccess.Wait();
|
Context.ContextAccess.Wait();
|
||||||
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,
|
ChatUser.DEFAULT_SIZE,
|
||||||
ChatUser.DEFAULT_MINIMUM_DELAY,
|
ChatUser.DEFAULT_MINIMUM_DELAY,
|
||||||
|
@ -200,7 +205,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatPacketHandlerContext context = new(msg, Context, conn);
|
ChatPacketHandlerContext context = new(msg, Context, conn);
|
||||||
IChatPacketHandler handler = conn.User is null
|
IChatPacketHandler? 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));
|
||||||
|
|
||||||
|
|
Loading…
Add table
Reference in a new issue