Renamed 'Sessions' to 'Connections'

This commit is contained in:
flash 2023-02-16 22:25:41 +01:00
parent c8a589c1c1
commit 06af94e94f
12 changed files with 134 additions and 135 deletions

View file

@ -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));
} }

View file

@ -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() {

View file

@ -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);

View file

@ -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) {

View file

@ -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) {

View file

@ -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
); );

View file

@ -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();

View file

@ -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;
} }

View file

@ -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();
} }

View file

@ -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();

View file

@ -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;

View file

@ -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();