Better HttpClient handling.
This commit is contained in:
parent
d2fef02e08
commit
513539319f
11 changed files with 145 additions and 122 deletions
2
LICENSE
2
LICENSE
|
@ -1,6 +1,6 @@
|
||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2019-2022 flashwave
|
Copyright (c) 2019-2023 flashwave
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
|
|
@ -5,6 +5,15 @@ VisualStudioVersion = 17.2.32630.192
|
||||||
MinimumVisualStudioVersion = 10.0.40219.1
|
MinimumVisualStudioVersion = 10.0.40219.1
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpChat", "SharpChat\SharpChat.csproj", "{DDB24C19-B802-4C96-AC15-0449C6FC77F2}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpChat", "SharpChat\SharpChat.csproj", "{DDB24C19-B802-4C96-AC15-0449C6FC77F2}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DF7A7073-A67A-4D93-92C6-F9D0F95E2359}"
|
||||||
|
ProjectSection(SolutionItems) = preProject
|
||||||
|
.gitattributes = .gitattributes
|
||||||
|
.gitignore = .gitignore
|
||||||
|
LICENSE = LICENSE
|
||||||
|
Protocol.md = Protocol.md
|
||||||
|
README.md = README.md
|
||||||
|
EndProjectSection
|
||||||
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
|
@ -3,6 +3,8 @@ using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public interface IBan {
|
public interface IBan {
|
||||||
|
@ -43,15 +45,18 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public class BanManager : IDisposable {
|
public class BanManager : IDisposable {
|
||||||
private readonly List<IBan> BanList = new List<IBan>();
|
private readonly List<IBan> BanList = new();
|
||||||
|
|
||||||
|
private readonly HttpClient HttpClient;
|
||||||
public readonly ChatContext Context;
|
public readonly ChatContext Context;
|
||||||
|
|
||||||
|
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
public BanManager(ChatContext context) {
|
public BanManager(HttpClient httpClient, ChatContext context) {
|
||||||
|
HttpClient = httpClient;
|
||||||
Context = context;
|
Context = context;
|
||||||
RefreshFlashiiBans();
|
RefreshFlashiiBans().Wait();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Add(ChatUser user, DateTimeOffset expires) {
|
public void Add(ChatUser user, DateTimeOffset expires) {
|
||||||
|
@ -143,26 +148,20 @@ namespace SharpChat {
|
||||||
BanList.RemoveAll(x => x.Expires <= DateTimeOffset.Now);
|
BanList.RemoveAll(x => x.Expires <= DateTimeOffset.Now);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshFlashiiBans() {
|
public async Task RefreshFlashiiBans() {
|
||||||
FlashiiBan.GetList(SockChatServer.HttpClient).ContinueWith(x => {
|
IEnumerable<FlashiiBan> bans = await FlashiiBan.GetListAsync(HttpClient);
|
||||||
if(x.IsFaulted) {
|
|
||||||
Logger.Write($@"Ban Refresh: {x.Exception}");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!x.Result.Any())
|
if(!bans.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock(BanList) {
|
lock(BanList)
|
||||||
foreach(FlashiiBan fb in x.Result) {
|
foreach(FlashiiBan fb in bans) {
|
||||||
if(!BanList.OfType<BannedUser>().Any(x => x.UserId == fb.UserId))
|
if(!BanList.OfType<BannedUser>().Any(x => x.UserId == fb.UserId))
|
||||||
Add(new BannedUser(fb));
|
Add(new BannedUser(fb));
|
||||||
if(!BanList.OfType<BannedIPAddress>().Any(x => x.Address.ToString() == fb.UserIP))
|
if(!BanList.OfType<BannedIPAddress>().Any(x => x.Address.ToString() == fb.UserIP))
|
||||||
Add(new BannedIPAddress(fb));
|
Add(new BannedIPAddress(fb));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<IBan> All() {
|
public IEnumerable<IBan> All() {
|
||||||
lock(BanList)
|
lock(BanList)
|
||||||
|
@ -170,20 +169,19 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
~BanManager()
|
~BanManager()
|
||||||
=> Dispose(false);
|
=> DoDispose();
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose() {
|
||||||
=> Dispose(true);
|
DoDispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void Dispose(bool disposing) {
|
private void DoDispose() {
|
||||||
if(IsDisposed)
|
if(IsDisposed)
|
||||||
return;
|
return;
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
|
||||||
BanList.Clear();
|
BanList.Clear();
|
||||||
|
|
||||||
if (disposing)
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,12 +4,15 @@ using SharpChat.Packet;
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
public class ChatContext : IDisposable, IPacketTarget {
|
public class ChatContext : IDisposable, IPacketTarget {
|
||||||
public bool IsDisposed { get; private set; }
|
public bool IsDisposed { get; private set; }
|
||||||
|
|
||||||
|
private readonly HttpClient HttpClient;
|
||||||
|
|
||||||
public SockChatServer Server { get; }
|
public SockChatServer Server { get; }
|
||||||
public Timer BumpTimer { get; }
|
public Timer BumpTimer { get; }
|
||||||
public BanManager Bans { get; }
|
public BanManager Bans { get; }
|
||||||
|
@ -19,14 +22,15 @@ namespace SharpChat {
|
||||||
|
|
||||||
public string TargetName => @"@broadcast";
|
public string TargetName => @"@broadcast";
|
||||||
|
|
||||||
public ChatContext(SockChatServer server) {
|
public ChatContext(HttpClient httpClient, SockChatServer server) {
|
||||||
|
HttpClient = httpClient;
|
||||||
Server = server;
|
Server = server;
|
||||||
Bans = new BanManager(this);
|
Bans = new BanManager(httpClient, this);
|
||||||
Users = new UserManager(this);
|
Users = new UserManager(this);
|
||||||
Channels = new ChannelManager(this);
|
Channels = new ChannelManager(this);
|
||||||
Events = new ChatEventManager(this);
|
Events = new ChatEventManager(this);
|
||||||
|
|
||||||
BumpTimer = new Timer(e => FlashiiBump.Submit(SockChatServer.HttpClient, Users.WithActiveConnections()), null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
|
BumpTimer = new Timer(e => FlashiiBump.SubmitAsync(HttpClient, Users.WithActiveConnections()).Wait(), null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update() {
|
public void Update() {
|
||||||
|
@ -166,13 +170,16 @@ namespace SharpChat {
|
||||||
user.Send(packet);
|
user.Send(packet);
|
||||||
}
|
}
|
||||||
|
|
||||||
~ChatContext()
|
~ChatContext() {
|
||||||
=> Dispose(false);
|
DoDispose();
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose() {
|
||||||
=> Dispose(true);
|
DoDispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void Dispose(bool disposing) {
|
private void DoDispose() {
|
||||||
if (IsDisposed)
|
if (IsDisposed)
|
||||||
return;
|
return;
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
@ -182,9 +189,6 @@ namespace SharpChat {
|
||||||
Channels?.Dispose();
|
Channels?.Dispose();
|
||||||
Users?.Dispose();
|
Users?.Dispose();
|
||||||
Bans?.Dispose();
|
Bans?.Dispose();
|
||||||
|
|
||||||
if (disposing)
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
using Microsoft.Win32.SafeHandles;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
@ -49,7 +48,7 @@ namespace SharpChat.Flashii {
|
||||||
[JsonPropertyName(@"perms")]
|
[JsonPropertyName(@"perms")]
|
||||||
public ChatUserPermissions Permissions { get; set; }
|
public ChatUserPermissions Permissions { get; set; }
|
||||||
|
|
||||||
public static async Task<FlashiiAuth> Attempt(HttpClient httpClient, FlashiiAuthRequest authRequest) {
|
public static async Task<FlashiiAuth> AttemptAsync(HttpClient httpClient, FlashiiAuthRequest authRequest) {
|
||||||
if(httpClient == null)
|
if(httpClient == null)
|
||||||
throw new ArgumentNullException(nameof(httpClient));
|
throw new ArgumentNullException(nameof(httpClient));
|
||||||
if(authRequest == null)
|
if(authRequest == null)
|
||||||
|
@ -68,7 +67,7 @@ namespace SharpChat.Flashii {
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, FlashiiUrls.AuthURL) {
|
HttpRequestMessage request = new(HttpMethod.Post, FlashiiUrls.AuthURL) {
|
||||||
Content = new ByteArrayContent(authRequest.GetJSON()),
|
Content = new ByteArrayContent(authRequest.GetJSON()),
|
||||||
Headers = {
|
Headers = {
|
||||||
{ @"X-SharpChat-Signature", authRequest.Hash },
|
{ @"X-SharpChat-Signature", authRequest.Hash },
|
||||||
|
|
|
@ -21,11 +21,11 @@ namespace SharpChat.Flashii {
|
||||||
[JsonPropertyName(@"username")]
|
[JsonPropertyName(@"username")]
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
public static async Task<IEnumerable<FlashiiBan>> GetList(HttpClient httpClient) {
|
public static async Task<IEnumerable<FlashiiBan>> GetListAsync(HttpClient httpClient) {
|
||||||
if(httpClient == null)
|
if(httpClient == null)
|
||||||
throw new ArgumentNullException(nameof(httpClient));
|
throw new ArgumentNullException(nameof(httpClient));
|
||||||
|
|
||||||
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, FlashiiUrls.BansURL) {
|
HttpRequestMessage request = new(HttpMethod.Get, FlashiiUrls.BansURL) {
|
||||||
Headers = {
|
Headers = {
|
||||||
{ @"X-SharpChat-Signature", STRING.GetSignedHash() },
|
{ @"X-SharpChat-Signature", STRING.GetSignedHash() },
|
||||||
},
|
},
|
||||||
|
|
|
@ -14,14 +14,17 @@ namespace SharpChat.Flashii {
|
||||||
[JsonPropertyName(@"ip")]
|
[JsonPropertyName(@"ip")]
|
||||||
public string UserIP { get; set; }
|
public string UserIP { get; set; }
|
||||||
|
|
||||||
public static void Submit(HttpClient httpClient, IEnumerable<ChatUser> users) {
|
public static async Task SubmitAsync(HttpClient httpClient, IEnumerable<ChatUser> users) {
|
||||||
List<FlashiiBump> bups = users.Where(u => u.HasSessions).Select(x => new FlashiiBump { UserId = x.UserId, UserIP = x.RemoteAddresses.First().ToString() }).ToList();
|
FlashiiBump[] bups = users.Where(u => u.HasSessions).Select(x => new FlashiiBump {
|
||||||
|
UserId = x.UserId,
|
||||||
|
UserIP = x.RemoteAddresses.First().ToString()
|
||||||
|
}).ToArray();
|
||||||
|
|
||||||
if(bups.Any())
|
if(bups.Any())
|
||||||
Submit(httpClient, bups);
|
await SubmitAsync(httpClient, bups);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Submit(HttpClient httpClient, IEnumerable<FlashiiBump> users) {
|
public static async Task SubmitAsync(HttpClient httpClient, IEnumerable<FlashiiBump> users) {
|
||||||
if(httpClient == null)
|
if(httpClient == null)
|
||||||
throw new ArgumentNullException(nameof(httpClient));
|
throw new ArgumentNullException(nameof(httpClient));
|
||||||
if(users == null)
|
if(users == null)
|
||||||
|
@ -31,17 +34,14 @@ namespace SharpChat.Flashii {
|
||||||
|
|
||||||
byte[] data = JsonSerializer.SerializeToUtf8Bytes(users);
|
byte[] data = JsonSerializer.SerializeToUtf8Bytes(users);
|
||||||
|
|
||||||
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, FlashiiUrls.BumpURL) {
|
HttpRequestMessage request = new(HttpMethod.Post, FlashiiUrls.BumpURL) {
|
||||||
Content = new ByteArrayContent(data),
|
Content = new ByteArrayContent(data),
|
||||||
Headers = {
|
Headers = {
|
||||||
{ @"X-SharpChat-Signature", data.GetSignedHash() },
|
{ @"X-SharpChat-Signature", data.GetSignedHash() },
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
httpClient.SendAsync(request).ContinueWith(x => {
|
await httpClient.SendAsync(request);
|
||||||
if(x.IsFaulted)
|
|
||||||
Logger.Write($@"Flashii Bump Error: {x.Exception}");
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -68,6 +68,7 @@ namespace SharpChat.Packet {
|
||||||
|
|
||||||
// Abbreviated class name because otherwise shit gets wide
|
// Abbreviated class name because otherwise shit gets wide
|
||||||
public static class LCR {
|
public static class LCR {
|
||||||
|
public const string GENERIC_ERROR = @"generr";
|
||||||
public const string COMMAND_NOT_FOUND = @"nocmd";
|
public const string COMMAND_NOT_FOUND = @"nocmd";
|
||||||
public const string COMMAND_NOT_ALLOWED = @"cmdna";
|
public const string COMMAND_NOT_ALLOWED = @"cmdna";
|
||||||
public const string COMMAND_FORMAT_ERROR = @"cmderr";
|
public const string COMMAND_FORMAT_ERROR = @"cmderr";
|
||||||
|
|
|
@ -1,7 +1,5 @@
|
||||||
using SharpChat.Flashii;
|
using System;
|
||||||
using System;
|
using System.Net.Http;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
|
@ -21,9 +19,27 @@ namespace SharpChat {
|
||||||
|
|
||||||
Database.ReadConfig();
|
Database.ReadConfig();
|
||||||
|
|
||||||
using ManualResetEvent mre = new ManualResetEvent(false);
|
using ManualResetEvent mre = new(false);
|
||||||
using SockChatServer scs = new SockChatServer(mre, PORT);
|
bool hasCancelled = false;
|
||||||
Console.CancelKeyPress += (s, e) => { e.Cancel = true; mre.Set(); };
|
|
||||||
|
void cancelKeyPressHandler(object sender, ConsoleCancelEventArgs ev) {
|
||||||
|
Console.CancelKeyPress -= cancelKeyPressHandler;
|
||||||
|
hasCancelled = true;
|
||||||
|
ev.Cancel = true;
|
||||||
|
mre.Set();
|
||||||
|
};
|
||||||
|
Console.CancelKeyPress += cancelKeyPressHandler;
|
||||||
|
|
||||||
|
if(hasCancelled) return;
|
||||||
|
|
||||||
|
using HttpClient httpClient = new();
|
||||||
|
httpClient.DefaultRequestHeaders.Add(@"User-Agent", @"SharpChat/20230206");
|
||||||
|
|
||||||
|
if(hasCancelled) return;
|
||||||
|
|
||||||
|
using SockChatServer scs = new(httpClient, PORT);
|
||||||
|
scs.Listen(mre);
|
||||||
|
|
||||||
mre.WaitOne();
|
mre.WaitOne();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<OutputType>Exe</OutputType>
|
<OutputType>Exe</OutputType>
|
||||||
<TargetFramework>net5.0</TargetFramework>
|
<TargetFramework>net6.0</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
|
|
@ -9,7 +9,6 @@ using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Runtime.CompilerServices;
|
|
||||||
using System.Text;
|
using System.Text;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
|
@ -39,7 +38,7 @@ namespace SharpChat {
|
||||||
public IWebSocketServer Server { get; }
|
public IWebSocketServer Server { get; }
|
||||||
public ChatContext Context { get; }
|
public ChatContext Context { get; }
|
||||||
|
|
||||||
public static HttpClient HttpClient { get; }
|
private readonly HttpClient HttpClient;
|
||||||
|
|
||||||
private IReadOnlyCollection<IChatCommand> Commands { get; } = new IChatCommand[] {
|
private IReadOnlyCollection<IChatCommand> Commands { get; } = new IChatCommand[] {
|
||||||
new AFKCommand(),
|
new AFKCommand(),
|
||||||
|
@ -53,21 +52,15 @@ namespace SharpChat {
|
||||||
return Sessions.FirstOrDefault(x => x.Connection == conn);
|
return Sessions.FirstOrDefault(x => x.Connection == conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
static SockChatServer() {
|
private ManualResetEvent Shutdown { get; set; }
|
||||||
// "fuck it"
|
|
||||||
HttpClient = new HttpClient();
|
|
||||||
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(@"SharpChat");
|
|
||||||
}
|
|
||||||
|
|
||||||
private ManualResetEvent Shutdown { get; }
|
|
||||||
private bool IsShuttingDown = false;
|
private bool IsShuttingDown = false;
|
||||||
|
|
||||||
public SockChatServer(ManualResetEvent mre, ushort port) {
|
public SockChatServer(HttpClient httpClient, ushort port) {
|
||||||
Logger.Write("Starting Sock Chat server...");
|
Logger.Write("Starting Sock Chat server...");
|
||||||
|
|
||||||
Shutdown = mre ?? throw new ArgumentNullException(nameof(mre));
|
HttpClient = httpClient;
|
||||||
|
|
||||||
Context = new ChatContext(this);
|
Context = new ChatContext(HttpClient, this);
|
||||||
|
|
||||||
Context.Channels.Add(new ChatChannel(@"Lounge"));
|
Context.Channels.Add(new ChatChannel(@"Lounge"));
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
@ -79,6 +72,10 @@ namespace SharpChat {
|
||||||
Context.Channels.Add(new ChatChannel(@"Staff") { Rank = 5 });
|
Context.Channels.Add(new ChatChannel(@"Staff") { Rank = 5 });
|
||||||
|
|
||||||
Server = new SharpChatWebSocketServer($@"ws://0.0.0.0:{port}");
|
Server = new SharpChatWebSocketServer($@"ws://0.0.0.0:{port}");
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Listen(ManualResetEvent mre) {
|
||||||
|
Shutdown = mre;
|
||||||
|
|
||||||
Server.Start(sock => {
|
Server.Start(sock => {
|
||||||
if(IsShuttingDown || IsDisposed) {
|
if(IsShuttingDown || IsDisposed) {
|
||||||
|
@ -143,7 +140,7 @@ namespace SharpChat {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(sess.User is ChatUser && sess.User.HasFloodProtection) {
|
if(sess.User is not null && sess.User.HasFloodProtection) {
|
||||||
sess.User.RateLimiter.AddTimePoint();
|
sess.User.RateLimiter.AddTimePoint();
|
||||||
|
|
||||||
if(sess.User.RateLimiter.State == ChatRateLimitState.Kick) {
|
if(sess.User.RateLimiter.State == ChatRateLimitState.Kick) {
|
||||||
|
@ -182,7 +179,7 @@ namespace SharpChat {
|
||||||
if(args.Length < 3 || !long.TryParse(args[1], out long aUserId))
|
if(args.Length < 3 || !long.TryParse(args[1], out long aUserId))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
FlashiiAuth.Attempt(HttpClient, new FlashiiAuthRequest {
|
FlashiiAuth.AttemptAsync(HttpClient, new FlashiiAuthRequest {
|
||||||
UserId = aUserId,
|
UserId = aUserId,
|
||||||
Token = args[2],
|
Token = args[2],
|
||||||
IPAddress = sess.RemoteAddress.ToString(),
|
IPAddress = sess.RemoteAddress.ToString(),
|
||||||
|
@ -276,7 +273,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
if(messageText.Length > MSG_LENGTH_MAX)
|
if(messageText.Length > MSG_LENGTH_MAX)
|
||||||
messageText = messageText.Substring(0, MSG_LENGTH_MAX);
|
messageText = messageText[..MSG_LENGTH_MAX];
|
||||||
|
|
||||||
messageText = messageText.Trim();
|
messageText = messageText.Trim();
|
||||||
|
|
||||||
|
@ -293,8 +290,7 @@ namespace SharpChat {
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(message == null)
|
message ??= new ChatMessage {
|
||||||
message = new ChatMessage {
|
|
||||||
Target = mChannel,
|
Target = mChannel,
|
||||||
TargetName = mChannel.TargetName,
|
TargetName = mChannel.TargetName,
|
||||||
DateTime = DateTimeOffset.UtcNow,
|
DateTime = DateTimeOffset.UtcNow,
|
||||||
|
@ -335,7 +331,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IChatMessage HandleV1Command(string message, ChatUser user, ChatChannel channel) {
|
public IChatMessage HandleV1Command(string message, ChatUser user, ChatChannel channel) {
|
||||||
string[] parts = message.Substring(1).Split(' ');
|
string[] parts = message[1..].Split(' ');
|
||||||
string commandName = parts[0].Replace(@".", string.Empty).ToLowerInvariant();
|
string commandName = parts[0].Replace(@".", string.Empty).ToLowerInvariant();
|
||||||
|
|
||||||
for(int i = 1; i < parts.Length; i++)
|
for(int i = 1; i < parts.Length; i++)
|
||||||
|
@ -370,8 +366,7 @@ namespace SharpChat {
|
||||||
offset = 2;
|
offset = 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(targetUser == null)
|
targetUser ??= user;
|
||||||
targetUser = user;
|
|
||||||
|
|
||||||
if(parts.Length < offset) {
|
if(parts.Length < offset) {
|
||||||
user.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
user.Send(new LegacyCommandResponse(LCR.COMMAND_FORMAT_ERROR));
|
||||||
|
@ -389,7 +384,7 @@ namespace SharpChat {
|
||||||
if(nickStr == targetUser.Username)
|
if(nickStr == targetUser.Username)
|
||||||
nickStr = null;
|
nickStr = null;
|
||||||
else if(nickStr.Length > 15)
|
else if(nickStr.Length > 15)
|
||||||
nickStr = nickStr.Substring(0, 15);
|
nickStr = nickStr[..15];
|
||||||
else if(string.IsNullOrEmpty(nickStr))
|
else if(string.IsNullOrEmpty(nickStr))
|
||||||
nickStr = null;
|
nickStr = null;
|
||||||
|
|
||||||
|
@ -454,7 +449,7 @@ namespace SharpChat {
|
||||||
Flags = ChatMessageFlags.Action,
|
Flags = ChatMessageFlags.Action,
|
||||||
};
|
};
|
||||||
case @"who": // gets all online users/online users in a channel if arg
|
case @"who": // gets all online users/online users in a channel if arg
|
||||||
StringBuilder whoChanSB = new StringBuilder();
|
StringBuilder whoChanSB = new();
|
||||||
string whoChanStr = parts.Length > 1 && !string.IsNullOrEmpty(parts[1]) ? parts[1] : string.Empty;
|
string whoChanStr = parts.Length > 1 && !string.IsNullOrEmpty(parts[1]) ? parts[1] : string.Empty;
|
||||||
|
|
||||||
if(!string.IsNullOrEmpty(whoChanStr)) {
|
if(!string.IsNullOrEmpty(whoChanStr)) {
|
||||||
|
@ -476,7 +471,7 @@ namespace SharpChat {
|
||||||
if(whoUser == user)
|
if(whoUser == user)
|
||||||
whoChanSB.Append(@" style=""font-weight: bold;""");
|
whoChanSB.Append(@" style=""font-weight: bold;""");
|
||||||
|
|
||||||
whoChanSB.Append(@">");
|
whoChanSB.Append('>');
|
||||||
whoChanSB.Append(whoUser.DisplayName);
|
whoChanSB.Append(whoUser.DisplayName);
|
||||||
whoChanSB.Append(@"</a>, ");
|
whoChanSB.Append(@"</a>, ");
|
||||||
}
|
}
|
||||||
|
@ -492,7 +487,7 @@ namespace SharpChat {
|
||||||
if(whoUser == user)
|
if(whoUser == user)
|
||||||
whoChanSB.Append(@" style=""font-weight: bold;""");
|
whoChanSB.Append(@" style=""font-weight: bold;""");
|
||||||
|
|
||||||
whoChanSB.Append(@">");
|
whoChanSB.Append('>');
|
||||||
whoChanSB.Append(whoUser.DisplayName);
|
whoChanSB.Append(whoUser.DisplayName);
|
||||||
whoChanSB.Append(@"</a>, ");
|
whoChanSB.Append(@"</a>, ");
|
||||||
}
|
}
|
||||||
|
@ -546,7 +541,8 @@ namespace SharpChat {
|
||||||
|
|
||||||
int createChanHierarchy = 0;
|
int createChanHierarchy = 0;
|
||||||
if(createChanHasHierarchy)
|
if(createChanHasHierarchy)
|
||||||
int.TryParse(parts[1], out createChanHierarchy);
|
if(!int.TryParse(parts[1], out createChanHierarchy))
|
||||||
|
createChanHierarchy = 0;
|
||||||
|
|
||||||
if(createChanHierarchy > user.Rank) {
|
if(createChanHierarchy > user.Rank) {
|
||||||
user.Send(new LegacyCommandResponse(LCR.INSUFFICIENT_HIERARCHY));
|
user.Send(new LegacyCommandResponse(LCR.INSUFFICIENT_HIERARCHY));
|
||||||
|
@ -554,7 +550,7 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
string createChanName = string.Join('_', parts.Skip(createChanHasHierarchy ? 2 : 1));
|
string createChanName = string.Join('_', parts.Skip(createChanHasHierarchy ? 2 : 1));
|
||||||
ChatChannel createChan = new ChatChannel {
|
ChatChannel createChan = new() {
|
||||||
Name = createChanName,
|
Name = createChanName,
|
||||||
IsTemporary = !user.Can(ChatUserPermissions.SetChannelPermanent),
|
IsTemporary = !user.Can(ChatUserPermissions.SetChannelPermanent),
|
||||||
Rank = createChanHierarchy,
|
Rank = createChanHierarchy,
|
||||||
|
@ -848,7 +844,7 @@ namespace SharpChat {
|
||||||
Sessions.ForEach(s => s.PrepareForRestart());
|
Sessions.ForEach(s => s.PrepareForRestart());
|
||||||
|
|
||||||
Context.Update();
|
Context.Update();
|
||||||
Shutdown.Set();
|
Shutdown?.Set();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -859,13 +855,16 @@ namespace SharpChat {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
~SockChatServer()
|
~SockChatServer() {
|
||||||
=> Dispose(false);
|
DoDispose();
|
||||||
|
}
|
||||||
|
|
||||||
public void Dispose()
|
public void Dispose() {
|
||||||
=> Dispose(true);
|
DoDispose();
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
|
}
|
||||||
|
|
||||||
private void Dispose(bool disposing) {
|
private void DoDispose() {
|
||||||
if(IsDisposed)
|
if(IsDisposed)
|
||||||
return;
|
return;
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
@ -876,9 +875,6 @@ namespace SharpChat {
|
||||||
Server?.Dispose();
|
Server?.Dispose();
|
||||||
Context?.Dispose();
|
Context?.Dispose();
|
||||||
HttpClient?.Dispose();
|
HttpClient?.Dispose();
|
||||||
|
|
||||||
if(disposing)
|
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue