Renamed 'Sessions' to 'Connections'
This commit is contained in:
parent
c8a589c1c1
commit
06af94e94f
12 changed files with 134 additions and 135 deletions
|
@ -7,14 +7,14 @@ namespace SharpChat {
|
||||||
public string[] Args { get; }
|
public string[] Args { get; }
|
||||||
public ChatContext Chat { get; }
|
public ChatContext Chat { get; }
|
||||||
public ChatUser User { get; }
|
public ChatUser User { get; }
|
||||||
public ChatUserSession Session { get; }
|
public ChatConnection Connection { get; }
|
||||||
public ChatChannel Channel { get; }
|
public ChatChannel Channel { get; }
|
||||||
|
|
||||||
public ChatCommandContext(
|
public ChatCommandContext(
|
||||||
string text,
|
string text,
|
||||||
ChatContext chat,
|
ChatContext chat,
|
||||||
ChatUser user,
|
ChatUser user,
|
||||||
ChatUserSession session,
|
ChatConnection connection,
|
||||||
ChatChannel channel
|
ChatChannel channel
|
||||||
) {
|
) {
|
||||||
if(text == null)
|
if(text == null)
|
||||||
|
@ -22,7 +22,7 @@ namespace SharpChat {
|
||||||
|
|
||||||
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
||||||
User = user ?? throw new ArgumentNullException(nameof(user));
|
User = user ?? throw new ArgumentNullException(nameof(user));
|
||||||
Session = session ?? throw new ArgumentNullException(nameof(session));
|
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
||||||
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
||||||
|
|
||||||
string[] parts = text[1..].Split(' ');
|
string[] parts = text[1..].Split(' ');
|
||||||
|
@ -35,14 +35,14 @@ namespace SharpChat {
|
||||||
string[] args,
|
string[] args,
|
||||||
ChatContext chat,
|
ChatContext chat,
|
||||||
ChatUser user,
|
ChatUser user,
|
||||||
ChatUserSession session,
|
ChatConnection connection,
|
||||||
ChatChannel channel
|
ChatChannel channel
|
||||||
) {
|
) {
|
||||||
Name = name ?? throw new ArgumentNullException(nameof(name));
|
Name = name ?? throw new ArgumentNullException(nameof(name));
|
||||||
Args = args ?? throw new ArgumentNullException(nameof(args));
|
Args = args ?? throw new ArgumentNullException(nameof(args));
|
||||||
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
||||||
User = user ?? throw new ArgumentNullException(nameof(user));
|
User = user ?? throw new ArgumentNullException(nameof(user));
|
||||||
Session = session ?? throw new ArgumentNullException(nameof(session));
|
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
||||||
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -4,8 +4,8 @@ using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatUserSession : IDisposable {
|
public class ChatConnection : IDisposable {
|
||||||
public const int ID_LENGTH = 32;
|
public const int ID_LENGTH = 20;
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(1);
|
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(1);
|
||||||
|
@ -13,7 +13,7 @@ namespace SharpChat {
|
||||||
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(5);
|
public static TimeSpan SessionTimeOut { get; } = TimeSpan.FromMinutes(5);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
public IWebSocketConnection Connection { get; }
|
public IWebSocketConnection Socket { get; }
|
||||||
|
|
||||||
public string Id { get; private set; }
|
public string Id { get; private set; }
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
@ -27,11 +27,11 @@ namespace SharpChat {
|
||||||
public IPAddress RemoteAddress {
|
public IPAddress RemoteAddress {
|
||||||
get {
|
get {
|
||||||
if(_RemoteAddress == null) {
|
if(_RemoteAddress == null) {
|
||||||
if((Connection.ConnectionInfo.ClientIpAddress == "127.0.0.1" || Connection.ConnectionInfo.ClientIpAddress == "::1")
|
if((Socket.ConnectionInfo.ClientIpAddress == "127.0.0.1" || Socket.ConnectionInfo.ClientIpAddress == "::1")
|
||||||
&& Connection.ConnectionInfo.Headers.ContainsKey("X-Real-IP"))
|
&& Socket.ConnectionInfo.Headers.ContainsKey("X-Real-IP"))
|
||||||
_RemoteAddress = IPAddress.Parse(Connection.ConnectionInfo.Headers["X-Real-IP"]);
|
_RemoteAddress = IPAddress.Parse(Socket.ConnectionInfo.Headers["X-Real-IP"]);
|
||||||
else
|
else
|
||||||
_RemoteAddress = IPAddress.Parse(Connection.ConnectionInfo.ClientIpAddress);
|
_RemoteAddress = IPAddress.Parse(Socket.ConnectionInfo.ClientIpAddress);
|
||||||
}
|
}
|
||||||
|
|
||||||
return _RemoteAddress;
|
return _RemoteAddress;
|
||||||
|
@ -39,13 +39,13 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatUserSession(IWebSocketConnection ws) {
|
public ChatConnection(IWebSocketConnection sock) {
|
||||||
Connection = ws;
|
Socket = sock;
|
||||||
Id = RNG.SecureRandomString(ID_LENGTH);
|
Id = RNG.SecureRandomString(ID_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(IServerPacket packet) {
|
public void Send(IServerPacket packet) {
|
||||||
if(!Connection.IsAvailable)
|
if(!Socket.IsAvailable)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IEnumerable<string> data = packet.Pack();
|
IEnumerable<string> data = packet.Pack();
|
||||||
|
@ -53,7 +53,7 @@ namespace SharpChat {
|
||||||
if(data != null)
|
if(data != null)
|
||||||
foreach(string line in data)
|
foreach(string line in data)
|
||||||
if(!string.IsNullOrWhiteSpace(line))
|
if(!string.IsNullOrWhiteSpace(line))
|
||||||
Connection.Send(line);
|
Socket.Send(line);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BumpPing() {
|
public void BumpPing() {
|
||||||
|
@ -67,7 +67,7 @@ namespace SharpChat {
|
||||||
CloseCode = 1012;
|
CloseCode = 1012;
|
||||||
}
|
}
|
||||||
|
|
||||||
~ChatUserSession() {
|
~ChatConnection() {
|
||||||
DoDispose();
|
DoDispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,7 +81,7 @@ namespace SharpChat {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
Connection.Close(CloseCode);
|
Socket.Close(CloseCode);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override int GetHashCode() {
|
public override int GetHashCode() {
|
|
@ -11,8 +11,8 @@ namespace SharpChat {
|
||||||
public HashSet<ChatChannel> Channels { get; } = new();
|
public HashSet<ChatChannel> Channels { get; } = new();
|
||||||
public readonly object ChannelsAccess = new();
|
public readonly object ChannelsAccess = new();
|
||||||
|
|
||||||
public HashSet<ChatUserSession> Sessions { get; } = new();
|
public HashSet<ChatConnection> Connections { get; } = new();
|
||||||
public readonly object SessionsAccess = new();
|
public readonly object ConnectionsAccess = new();
|
||||||
|
|
||||||
public HashSet<ChatUser> Users { get; } = new();
|
public HashSet<ChatUser> Users { get; } = new();
|
||||||
public readonly object UsersAccess = new();
|
public readonly object UsersAccess = new();
|
||||||
|
@ -27,21 +27,21 @@ namespace SharpChat {
|
||||||
public void Update() {
|
public void Update() {
|
||||||
lock(UsersAccess)
|
lock(UsersAccess)
|
||||||
foreach(ChatUser user in Users) {
|
foreach(ChatUser user in Users) {
|
||||||
IEnumerable<ChatUserSession> timedOut = user.GetDeadSessions();
|
IEnumerable<ChatConnection> timedOut = user.GetDeadConnections();
|
||||||
|
|
||||||
foreach(ChatUserSession sess in timedOut) {
|
foreach(ChatConnection conn in timedOut) {
|
||||||
user.RemoveSession(sess);
|
user.RemoveConnection(conn);
|
||||||
sess.Dispose();
|
conn.Dispose();
|
||||||
Logger.Write($"Nuked session {sess.Id} from {user.Username} (timeout)");
|
Logger.Write($"Nuked session {conn.Id} from {user.Username} (timeout)");
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!user.HasSessions)
|
if(!user.HasConnections)
|
||||||
UserLeave(null, user, UserDisconnectReason.TimeOut);
|
UserLeave(null, user, UserDisconnectReason.TimeOut);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public ChatUserSession GetSession(IWebSocketConnection conn) {
|
public ChatConnection GetConnection(IWebSocketConnection sock) {
|
||||||
return Sessions.FirstOrDefault(s => s.Connection == conn);
|
return Connections.FirstOrDefault(s => s.Socket == sock);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
|
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
|
||||||
|
@ -54,21 +54,21 @@ namespace SharpChat {
|
||||||
UserLeave(user.Channel, user, reason);
|
UserLeave(user.Channel, user, reason);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void HandleJoin(ChatUser user, ChatChannel chan, ChatUserSession sess, int maxMsgLength) {
|
public void HandleJoin(ChatUser user, ChatChannel chan, ChatConnection conn, int maxMsgLength) {
|
||||||
lock(EventsAccess) {
|
lock(EventsAccess) {
|
||||||
if(!chan.HasUser(user)) {
|
if(!chan.HasUser(user)) {
|
||||||
chan.Send(new UserConnectPacket(DateTimeOffset.Now, user));
|
chan.Send(new UserConnectPacket(DateTimeOffset.Now, user));
|
||||||
Events.AddEvent(new UserConnectEvent(DateTimeOffset.Now, user, chan));
|
Events.AddEvent(new UserConnectEvent(DateTimeOffset.Now, user, chan));
|
||||||
}
|
}
|
||||||
|
|
||||||
sess.Send(new AuthSuccessPacket(user, chan, sess, maxMsgLength));
|
conn.Send(new AuthSuccessPacket(user, chan, conn, maxMsgLength));
|
||||||
sess.Send(new ContextUsersPacket(chan.GetUsers(new[] { user })));
|
conn.Send(new ContextUsersPacket(chan.GetUsers(new[] { user })));
|
||||||
|
|
||||||
foreach(IChatEvent msg in Events.GetTargetEventLog(chan.Name))
|
foreach(IChatEvent msg in Events.GetTargetEventLog(chan.Name))
|
||||||
sess.Send(new ContextMessagePacket(msg));
|
conn.Send(new ContextMessagePacket(msg));
|
||||||
|
|
||||||
lock(ChannelsAccess)
|
lock(ChannelsAccess)
|
||||||
sess.Send(new ContextChannelsPacket(Channels.Where(c => c.Rank <= user.Rank)));
|
conn.Send(new ContextChannelsPacket(Channels.Where(c => c.Rank <= user.Rank)));
|
||||||
|
|
||||||
if(!chan.HasUser(user))
|
if(!chan.HasUser(user))
|
||||||
chan.UserJoin(user);
|
chan.UserJoin(user);
|
||||||
|
|
|
@ -4,16 +4,16 @@ namespace SharpChat {
|
||||||
public class ChatPacketHandlerContext {
|
public class ChatPacketHandlerContext {
|
||||||
public string Text { get; }
|
public string Text { get; }
|
||||||
public ChatContext Chat { get; }
|
public ChatContext Chat { get; }
|
||||||
public ChatUserSession Session { get; }
|
public ChatConnection Connection { get; }
|
||||||
|
|
||||||
public ChatPacketHandlerContext(
|
public ChatPacketHandlerContext(
|
||||||
string text,
|
string text,
|
||||||
ChatContext chat,
|
ChatContext chat,
|
||||||
ChatUserSession session
|
ChatConnection connection
|
||||||
) {
|
) {
|
||||||
Text = text ?? throw new ArgumentNullException(nameof(text));
|
Text = text ?? throw new ArgumentNullException(nameof(text));
|
||||||
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
Chat = chat ?? throw new ArgumentNullException(nameof(chat));
|
||||||
Session = session ?? throw new ArgumentNullException(nameof(session));
|
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CheckPacketId(string packetId) {
|
public bool CheckPacketId(string packetId) {
|
||||||
|
|
|
@ -83,7 +83,7 @@ namespace SharpChat {
|
||||||
public class ChatUser : BasicUser, IPacketTarget {
|
public class ChatUser : BasicUser, IPacketTarget {
|
||||||
public DateTimeOffset SilencedUntil { get; set; }
|
public DateTimeOffset SilencedUntil { get; set; }
|
||||||
|
|
||||||
private readonly List<ChatUserSession> Sessions = new();
|
private readonly List<ChatConnection> Connections = new();
|
||||||
private readonly List<ChatChannel> Channels = new();
|
private readonly List<ChatChannel> Channels = new();
|
||||||
|
|
||||||
public readonly ChatRateLimiter RateLimiter = new();
|
public readonly ChatRateLimiter RateLimiter = new();
|
||||||
|
@ -98,14 +98,13 @@ namespace SharpChat {
|
||||||
public bool IsSilenced
|
public bool IsSilenced
|
||||||
=> DateTimeOffset.UtcNow - SilencedUntil <= TimeSpan.Zero;
|
=> DateTimeOffset.UtcNow - SilencedUntil <= TimeSpan.Zero;
|
||||||
|
|
||||||
public bool HasSessions => Sessions.Where(c => !c.HasTimedOut && !c.IsDisposed).Any();
|
public bool HasConnections => Connections.Where(c => !c.HasTimedOut && !c.IsDisposed).Any();
|
||||||
|
|
||||||
public int SessionCount => Sessions.Where(c => !c.HasTimedOut && !c.IsDisposed).Count();
|
public int ConnectionCount => Connections.Where(c => !c.HasTimedOut && !c.IsDisposed).Count();
|
||||||
|
|
||||||
public IEnumerable<IPAddress> RemoteAddresses => Sessions.Select(c => c.RemoteAddress);
|
public IEnumerable<IPAddress> RemoteAddresses => Connections.Select(c => c.RemoteAddress);
|
||||||
|
|
||||||
public ChatUser() {
|
public ChatUser() {}
|
||||||
}
|
|
||||||
|
|
||||||
public ChatUser(MisuzuAuthInfo auth) {
|
public ChatUser(MisuzuAuthInfo auth) {
|
||||||
UserId = auth.UserId;
|
UserId = auth.UserId;
|
||||||
|
@ -127,14 +126,14 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Send(IServerPacket packet) {
|
public void Send(IServerPacket packet) {
|
||||||
foreach(ChatUserSession conn in Sessions)
|
foreach(ChatConnection conn in Connections)
|
||||||
conn.Send(packet);
|
conn.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Close() {
|
public void Close() {
|
||||||
foreach(ChatUserSession conn in Sessions)
|
foreach(ChatConnection conn in Connections)
|
||||||
conn.Dispose();
|
conn.Dispose();
|
||||||
Sessions.Clear();
|
Connections.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ForceChannel(ChatChannel chan = null) {
|
public void ForceChannel(ChatChannel chan = null) {
|
||||||
|
@ -166,25 +165,25 @@ namespace SharpChat {
|
||||||
return Channels.ToList();
|
return Channels.ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void AddSession(ChatUserSession sess) {
|
public void AddConnection(ChatConnection conn) {
|
||||||
if(sess == null)
|
if(conn == null)
|
||||||
return;
|
return;
|
||||||
sess.User = this;
|
conn.User = this;
|
||||||
|
|
||||||
Sessions.Add(sess);
|
Connections.Add(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RemoveSession(ChatUserSession sess) {
|
public void RemoveConnection(ChatConnection conn) {
|
||||||
if(sess == null)
|
if(conn == null)
|
||||||
return;
|
return;
|
||||||
if(!sess.IsDisposed) // this could be possible
|
if(!conn.IsDisposed) // this could be possible
|
||||||
sess.User = null;
|
conn.User = null;
|
||||||
|
|
||||||
Sessions.Remove(sess);
|
Connections.Remove(conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<ChatUserSession> GetDeadSessions() {
|
public IEnumerable<ChatConnection> GetDeadConnections() {
|
||||||
return Sessions.Where(x => x.HasTimedOut || x.IsDisposed).ToList();
|
return Connections.Where(x => x.HasTimedOut || x.IsDisposed).ToList();
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool NameEquals(string name) {
|
public bool NameEquals(string name) {
|
||||||
|
|
|
@ -72,7 +72,7 @@ namespace SharpChat.Commands {
|
||||||
|
|
||||||
await Misuzu.CreateBanAsync(
|
await Misuzu.CreateBanAsync(
|
||||||
banUser.UserId.ToString(), banUser.RemoteAddresses.First().ToString(),
|
banUser.UserId.ToString(), banUser.RemoteAddresses.First().ToString(),
|
||||||
ctx.User.UserId.ToString(), ctx.Session.RemoteAddress.ToString(),
|
ctx.User.UserId.ToString(), ctx.Connection.RemoteAddress.ToString(),
|
||||||
duration, banReason
|
duration, banReason
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|
|
@ -27,9 +27,9 @@ namespace SharpChat.Commands {
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if(ctx.NameEquals("restart"))
|
if(ctx.NameEquals("restart"))
|
||||||
lock(ctx.Chat.SessionsAccess)
|
lock(ctx.Chat.ConnectionsAccess)
|
||||||
foreach(ChatUserSession sess in ctx.Chat.Sessions)
|
foreach(ChatConnection conn in ctx.Chat.Connections)
|
||||||
sess.PrepareForRestart();
|
conn.PrepareForRestart();
|
||||||
|
|
||||||
ctx.Chat.Update();
|
ctx.Chat.Update();
|
||||||
WaitHandle?.Set();
|
WaitHandle?.Set();
|
||||||
|
|
|
@ -6,18 +6,18 @@ namespace SharpChat.Packet {
|
||||||
public class AuthSuccessPacket : ServerPacket {
|
public class AuthSuccessPacket : ServerPacket {
|
||||||
public ChatUser User { get; private set; }
|
public ChatUser User { get; private set; }
|
||||||
public ChatChannel Channel { get; private set; }
|
public ChatChannel Channel { get; private set; }
|
||||||
public ChatUserSession Session { get; private set; }
|
public ChatConnection Connection { get; private set; }
|
||||||
public int MaxMessageLength { get; private set; }
|
public int MaxMessageLength { get; private set; }
|
||||||
|
|
||||||
public AuthSuccessPacket(
|
public AuthSuccessPacket(
|
||||||
ChatUser user,
|
ChatUser user,
|
||||||
ChatChannel channel,
|
ChatChannel channel,
|
||||||
ChatUserSession sess,
|
ChatConnection connection,
|
||||||
int maxMsgLength
|
int maxMsgLength
|
||||||
) {
|
) {
|
||||||
User = user ?? throw new ArgumentNullException(nameof(user));
|
User = user ?? throw new ArgumentNullException(nameof(user));
|
||||||
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
Channel = channel ?? throw new ArgumentNullException(nameof(channel));
|
||||||
Session = sess ?? throw new ArgumentNullException(nameof(channel));
|
Connection = connection ?? throw new ArgumentNullException(nameof(connection));
|
||||||
MaxMessageLength = maxMsgLength;
|
MaxMessageLength = maxMsgLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -35,15 +35,15 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
string authMethod = args.ElementAtOrDefault(1);
|
string authMethod = args.ElementAtOrDefault(1);
|
||||||
if(string.IsNullOrWhiteSpace(authMethod)) {
|
if(string.IsNullOrWhiteSpace(authMethod)) {
|
||||||
ctx.Session.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
ctx.Session.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.Session.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
ctx.Session.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,14 +55,14 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
MisuzuAuthInfo fai;
|
MisuzuAuthInfo fai;
|
||||||
string ipAddr = ctx.Session.RemoteAddress.ToString();
|
string ipAddr = ctx.Connection.RemoteAddress.ToString();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
fai = await Misuzu.AuthVerifyAsync(authMethod, authToken, ipAddr);
|
fai = await Misuzu.AuthVerifyAsync(authMethod, authToken, ipAddr);
|
||||||
} catch(Exception ex) {
|
} catch(Exception ex) {
|
||||||
Logger.Write($"<{ctx.Session.Id}> Failed to authenticate: {ex}");
|
Logger.Write($"<{ctx.Connection.Id}> Failed to authenticate: {ex}");
|
||||||
ctx.Session.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
ctx.Session.Dispose();
|
ctx.Connection.Dispose();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw;
|
throw;
|
||||||
#else
|
#else
|
||||||
|
@ -71,9 +71,9 @@ namespace SharpChat.PacketHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fai.Success) {
|
if(!fai.Success) {
|
||||||
Logger.Debug($"<{ctx.Session.Id}> Auth fail: {fai.Reason}");
|
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: {fai.Reason}");
|
||||||
ctx.Session.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
ctx.Session.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -81,9 +81,9 @@ namespace SharpChat.PacketHandlers {
|
||||||
try {
|
try {
|
||||||
fbi = await Misuzu.CheckBanAsync(fai.UserId.ToString(), ipAddr);
|
fbi = await Misuzu.CheckBanAsync(fai.UserId.ToString(), ipAddr);
|
||||||
} catch(Exception ex) {
|
} catch(Exception ex) {
|
||||||
Logger.Write($"<{ctx.Session.Id}> Failed auth ban check: {ex}");
|
Logger.Write($"<{ctx.Connection.Id}> Failed auth ban check: {ex}");
|
||||||
ctx.Session.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
ctx.Session.Dispose();
|
ctx.Connection.Dispose();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw;
|
throw;
|
||||||
#else
|
#else
|
||||||
|
@ -92,9 +92,9 @@ namespace SharpChat.PacketHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(fbi.IsBanned && !fbi.HasExpired) {
|
if(fbi.IsBanned && !fbi.HasExpired) {
|
||||||
Logger.Write($"<{ctx.Session.Id}> User is banned.");
|
Logger.Write($"<{ctx.Connection.Id}> User is banned.");
|
||||||
ctx.Session.Send(new AuthFailPacket(AuthFailReason.Banned, fbi));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.Banned, fbi));
|
||||||
ctx.Session.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -109,28 +109,28 @@ namespace SharpChat.PacketHandlers {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Enforce a maximum amount of connections per user
|
// Enforce a maximum amount of connections per user
|
||||||
if(aUser.SessionCount >= MaxConnections) {
|
if(aUser.ConnectionCount >= MaxConnections) {
|
||||||
ctx.Session.Send(new AuthFailPacket(AuthFailReason.MaxSessions));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.MaxSessions));
|
||||||
ctx.Session.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Bumping the ping to prevent upgrading
|
// Bumping the ping to prevent upgrading
|
||||||
ctx.Session.BumpPing();
|
ctx.Connection.BumpPing();
|
||||||
|
|
||||||
aUser.AddSession(ctx.Session);
|
aUser.AddConnection(ctx.Connection);
|
||||||
|
|
||||||
ctx.Session.Send(new LegacyCommandResponse(LCR.WELCOME, false, $"Welcome to Flashii Chat, {aUser.Username}!"));
|
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, $"Welcome to Flashii Chat, {aUser.Username}!"));
|
||||||
|
|
||||||
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.Session.Send(new LegacyCommandResponse(LCR.WELCOME, false, line));
|
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, line));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Chat.HandleJoin(aUser, DefaultChannel, ctx.Session, MaxMessageLength);
|
ctx.Chat.HandleJoin(aUser, DefaultChannel, ctx.Connection, MaxMessageLength);
|
||||||
}
|
}
|
||||||
}).Wait();
|
}).Wait();
|
||||||
}
|
}
|
||||||
|
|
|
@ -26,15 +26,15 @@ namespace SharpChat.PacketHandlers {
|
||||||
if(!int.TryParse(parts.FirstOrDefault(), out int pTime))
|
if(!int.TryParse(parts.FirstOrDefault(), out int pTime))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
ctx.Session.BumpPing();
|
ctx.Connection.BumpPing();
|
||||||
ctx.Session.Send(new PongPacket(ctx.Session.LastPing));
|
ctx.Connection.Send(new PongPacket(ctx.Connection.LastPing));
|
||||||
|
|
||||||
lock(BumpAccess) {
|
lock(BumpAccess) {
|
||||||
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
|
if(LastBump < DateTimeOffset.UtcNow - BumpInterval) {
|
||||||
(string, string)[] bumpList;
|
(string, string)[] bumpList;
|
||||||
lock(ctx.Chat.UsersAccess)
|
lock(ctx.Chat.UsersAccess)
|
||||||
bumpList = ctx.Chat.Users
|
bumpList = ctx.Chat.Users
|
||||||
.Where(u => u.HasSessions && u.Status == ChatUserStatus.Online)
|
.Where(u => u.HasConnections && u.Status == ChatUserStatus.Online)
|
||||||
.Select(u => (u.UserId.ToString(), u.RemoteAddresses.FirstOrDefault()?.ToString() ?? string.Empty))
|
.Select(u => (u.UserId.ToString(), u.RemoteAddresses.FirstOrDefault()?.ToString() ?? string.Empty))
|
||||||
.ToArray();
|
.ToArray();
|
||||||
|
|
||||||
|
|
|
@ -31,7 +31,7 @@ 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.Session.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);
|
||||||
|
@ -61,13 +61,13 @@ namespace SharpChat.PacketHandlers {
|
||||||
messageText = messageText.Trim();
|
messageText = messageText.Trim();
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
Logger.Write($"<{ctx.Session.Id} {user.Username}> {messageText}");
|
Logger.Write($"<{ctx.Connection.Id} {user.Username}> {messageText}");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
IChatMessage message = null;
|
IChatMessage message = null;
|
||||||
|
|
||||||
if(messageText.StartsWith("/")) {
|
if(messageText.StartsWith("/")) {
|
||||||
ChatCommandContext context = new(messageText, ctx.Chat, user, ctx.Session, channel);
|
ChatCommandContext context = new(messageText, ctx.Chat, user, ctx.Connection, channel);
|
||||||
|
|
||||||
IChatCommand command = null;
|
IChatCommand command = null;
|
||||||
|
|
||||||
|
|
|
@ -129,32 +129,32 @@ namespace SharpChat {
|
||||||
Logger.Write("Listening...");
|
Logger.Write("Listening...");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnOpen(IWebSocketConnection conn) {
|
private void OnOpen(IWebSocketConnection sock) {
|
||||||
Logger.Write($"Connection opened from {conn.ConnectionInfo.ClientIpAddress}:{conn.ConnectionInfo.ClientPort}");
|
Logger.Write($"Connection opened from {sock.ConnectionInfo.ClientIpAddress}:{sock.ConnectionInfo.ClientPort}");
|
||||||
|
|
||||||
lock(Context.SessionsAccess) {
|
lock(Context.ConnectionsAccess) {
|
||||||
if(!Context.Sessions.Any(x => x.Connection == conn))
|
if(!Context.Connections.Any(x => x.Socket == sock))
|
||||||
Context.Sessions.Add(new ChatUserSession(conn));
|
Context.Connections.Add(new ChatConnection(sock));
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.Update();
|
Context.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnClose(IWebSocketConnection conn) {
|
private void OnClose(IWebSocketConnection sock) {
|
||||||
Logger.Write($"Connection closed from {conn.ConnectionInfo.ClientIpAddress}:{conn.ConnectionInfo.ClientPort}");
|
Logger.Write($"Connection closed from {sock.ConnectionInfo.ClientIpAddress}:{sock.ConnectionInfo.ClientPort}");
|
||||||
|
|
||||||
ChatUserSession sess;
|
ChatConnection conn;
|
||||||
lock(Context.SessionsAccess)
|
lock(Context.ConnectionsAccess)
|
||||||
sess = Context.GetSession(conn);
|
conn = Context.GetConnection(sock);
|
||||||
|
|
||||||
// Remove connection from user
|
// Remove connection from user
|
||||||
if(sess?.User != null) {
|
if(conn?.User != null) {
|
||||||
// RemoveConnection sets conn.User to null so we must grab a local copy.
|
// RemoveConnection sets conn.User to null so we must grab a local copy.
|
||||||
ChatUser user = sess.User;
|
ChatUser user = conn.User;
|
||||||
|
|
||||||
user.RemoveSession(sess);
|
user.RemoveConnection(conn);
|
||||||
|
|
||||||
if(!user.HasSessions)
|
if(!user.HasConnections)
|
||||||
Context.UserLeave(null, user);
|
Context.UserLeave(null, user);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -162,59 +162,59 @@ namespace SharpChat {
|
||||||
Context.Update();
|
Context.Update();
|
||||||
|
|
||||||
// Remove connection from server
|
// Remove connection from server
|
||||||
lock(Context.SessionsAccess)
|
lock(Context.ConnectionsAccess)
|
||||||
Context.Sessions.Remove(sess);
|
Context.Connections.Remove(conn);
|
||||||
|
|
||||||
sess?.Dispose();
|
conn?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnError(IWebSocketConnection conn, Exception ex) {
|
private void OnError(IWebSocketConnection sock, Exception ex) {
|
||||||
string sessId;
|
string connId;
|
||||||
lock(Context.SessionsAccess) {
|
lock(Context.ConnectionsAccess) {
|
||||||
ChatUserSession sess = Context.GetSession(conn);
|
ChatConnection conn = Context.GetConnection(sock);
|
||||||
sessId = sess?.Id ?? new string('0', ChatUserSession.ID_LENGTH);
|
connId = conn?.Id ?? new string('0', ChatConnection.ID_LENGTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
Logger.Write($"[{sessId} {conn.ConnectionInfo.ClientIpAddress}] {ex}");
|
Logger.Write($"[{connId} {sock.ConnectionInfo.ClientIpAddress}] {ex}");
|
||||||
Context.Update();
|
Context.Update();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnMessage(IWebSocketConnection conn, string msg) {
|
private void OnMessage(IWebSocketConnection sock, string msg) {
|
||||||
Context.Update();
|
Context.Update();
|
||||||
|
|
||||||
ChatUserSession sess;
|
ChatConnection conn;
|
||||||
lock(Context.SessionsAccess)
|
lock(Context.ConnectionsAccess)
|
||||||
sess = Context.GetSession(conn);
|
conn = Context.GetConnection(sock);
|
||||||
|
|
||||||
if(sess == null) {
|
if(conn == null) {
|
||||||
conn.Close();
|
sock.Close();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// this doesn't affect non-authed connections?????
|
// this doesn't affect non-authed connections?????
|
||||||
if(sess.User is not null && sess.User.HasFloodProtection) {
|
if(conn.User is not null && conn.User.HasFloodProtection) {
|
||||||
sess.User.RateLimiter.AddTimePoint();
|
conn.User.RateLimiter.AddTimePoint();
|
||||||
|
|
||||||
if(sess.User.RateLimiter.State == ChatRateLimitState.Kick) {
|
if(conn.User.RateLimiter.State == ChatRateLimitState.Kick) {
|
||||||
Task.Run(async () => {
|
Task.Run(async () => {
|
||||||
TimeSpan duration = TimeSpan.FromSeconds(FloodKickLength);
|
TimeSpan duration = TimeSpan.FromSeconds(FloodKickLength);
|
||||||
|
|
||||||
await Misuzu.CreateBanAsync(
|
await Misuzu.CreateBanAsync(
|
||||||
sess.User.UserId.ToString(), sess.RemoteAddress.ToString(),
|
conn.User.UserId.ToString(), conn.RemoteAddress.ToString(),
|
||||||
string.Empty, "::1",
|
string.Empty, "::1",
|
||||||
duration,
|
duration,
|
||||||
"Kicked from chat for flood protection."
|
"Kicked from chat for flood protection."
|
||||||
);
|
);
|
||||||
|
|
||||||
Context.BanUser(sess.User, duration, UserDisconnectReason.Flood);
|
Context.BanUser(conn.User, duration, UserDisconnectReason.Flood);
|
||||||
}).Wait();
|
}).Wait();
|
||||||
return;
|
return;
|
||||||
} else if(sess.User.RateLimiter.State == ChatRateLimitState.Warning)
|
} else if(conn.User.RateLimiter.State == ChatRateLimitState.Warning)
|
||||||
sess.User.Send(new FloodWarningPacket());
|
conn.User.Send(new FloodWarningPacket());
|
||||||
}
|
}
|
||||||
|
|
||||||
ChatPacketHandlerContext context = new(msg, Context, sess);
|
ChatPacketHandlerContext context = new(msg, Context, conn);
|
||||||
IChatPacketHandler handler = sess.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));
|
||||||
|
|
||||||
|
@ -235,9 +235,9 @@ namespace SharpChat {
|
||||||
return;
|
return;
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
|
||||||
lock(Context.SessionsAccess)
|
lock(Context.ConnectionsAccess)
|
||||||
foreach(ChatUserSession sess in Context.Sessions)
|
foreach(ChatConnection conn in Context.Connections)
|
||||||
sess.Dispose();
|
conn.Dispose();
|
||||||
|
|
||||||
Server?.Dispose();
|
Server?.Dispose();
|
||||||
HttpClient?.Dispose();
|
HttpClient?.Dispose();
|
||||||
|
|
Loading…
Reference in a new issue