Apparently this is what's actually running on the server.
This commit is contained in:
parent
5d2b9f62c1
commit
23f0bd478f
13 changed files with 411 additions and 75 deletions
6
.gitignore
vendored
6
.gitignore
vendored
|
@ -1,6 +1,12 @@
|
||||||
## Ignore Visual Studio temporary files, build results, and
|
## Ignore Visual Studio temporary files, build results, and
|
||||||
## files generated by popular Visual Studio add-ons.
|
## files generated by popular Visual Studio add-ons.
|
||||||
|
|
||||||
|
welcome.txt
|
||||||
|
mariadb.txt
|
||||||
|
login_key.txt
|
||||||
|
http-motd.txt
|
||||||
|
_webdb.txt
|
||||||
|
|
||||||
# User-specific files
|
# User-specific files
|
||||||
*.suo
|
*.suo
|
||||||
*.user
|
*.user
|
||||||
|
|
|
@ -5,7 +5,7 @@ VisualStudioVersion = 16.0.29025.244
|
||||||
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("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Hamakaze", "Hamakaze\Hamakaze.csproj", "{6059200F-141C-42A5-AA3F-E38C9721AEC8}"
|
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpChatTest", "SharpChatTest\SharpChatTest.csproj", "{6CD6DB9D-E0FF-4DEB-8E28-0C3EA6BA26B2}"
|
||||||
EndProject
|
EndProject
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
|
@ -17,10 +17,10 @@ Global
|
||||||
{DDB24C19-B802-4C96-AC15-0449C6FC77F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{DDB24C19-B802-4C96-AC15-0449C6FC77F2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{DDB24C19-B802-4C96-AC15-0449C6FC77F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{DDB24C19-B802-4C96-AC15-0449C6FC77F2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{DDB24C19-B802-4C96-AC15-0449C6FC77F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
{DDB24C19-B802-4C96-AC15-0449C6FC77F2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{6059200F-141C-42A5-AA3F-E38C9721AEC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{6CD6DB9D-E0FF-4DEB-8E28-0C3EA6BA26B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{6059200F-141C-42A5-AA3F-E38C9721AEC8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{6CD6DB9D-E0FF-4DEB-8E28-0C3EA6BA26B2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{6059200F-141C-42A5-AA3F-E38C9721AEC8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{6CD6DB9D-E0FF-4DEB-8E28-0C3EA6BA26B2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{6059200F-141C-42A5-AA3F-E38C9721AEC8}.Release|Any CPU.Build.0 = Release|Any CPU
|
{6CD6DB9D-E0FF-4DEB-8E28-0C3EA6BA26B2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
EndGlobalSection
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
|
@ -144,19 +144,24 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RefreshFlashiiBans() {
|
public void RefreshFlashiiBans() {
|
||||||
FlashiiBan.GetList(bans => {
|
FlashiiBan.GetList(SockChatServer.HttpClient).ContinueWith(x => {
|
||||||
if(!bans.Any())
|
if(x.IsFaulted) {
|
||||||
|
Logger.Write($@"Ban Refresh: {x.Exception}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!x.Result.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
lock(BanList) {
|
lock(BanList) {
|
||||||
foreach(FlashiiBan fb in bans) {
|
foreach(FlashiiBan fb in x.Result) {
|
||||||
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));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}, ex => Logger.Write($@"Ban Refresh: {ex}"));
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IBan> All() {
|
public IEnumerable<IBan> All() {
|
||||||
|
|
|
@ -26,7 +26,7 @@ namespace SharpChat {
|
||||||
Channels = new ChannelManager(this);
|
Channels = new ChannelManager(this);
|
||||||
Events = new ChatEventManager(this);
|
Events = new ChatEventManager(this);
|
||||||
|
|
||||||
BumpTimer = new Timer(e => FlashiiBump.Submit(Users.WithActiveConnections()), null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
|
BumpTimer = new Timer(e => FlashiiBump.Submit(SockChatServer.HttpClient, Users.WithActiveConnections()), null, TimeSpan.Zero, TimeSpan.FromMinutes(1));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void Update() {
|
public void Update() {
|
||||||
|
|
|
@ -15,7 +15,7 @@ namespace SharpChat {
|
||||||
public ChatEventManager(ChatContext context) {
|
public ChatEventManager(ChatContext context) {
|
||||||
Context = context;
|
Context = context;
|
||||||
|
|
||||||
if (!Database.HasDatabase)
|
if (!Database.HasDatabase && !WebDatabase.IsAvailable)
|
||||||
Events = new List<IChatEvent>();
|
Events = new List<IChatEvent>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,9 @@ namespace SharpChat {
|
||||||
lock(Events)
|
lock(Events)
|
||||||
Events.Add(evt);
|
Events.Add(evt);
|
||||||
|
|
||||||
|
if(WebDatabase.IsAvailable)
|
||||||
|
WebDatabase.LogEvent(evt);
|
||||||
|
|
||||||
if(Database.HasDatabase)
|
if(Database.HasDatabase)
|
||||||
Database.LogEvent(evt);
|
Database.LogEvent(evt);
|
||||||
}
|
}
|
||||||
|
@ -39,6 +42,9 @@ namespace SharpChat {
|
||||||
lock (Events)
|
lock (Events)
|
||||||
Events.Remove(evt);
|
Events.Remove(evt);
|
||||||
|
|
||||||
|
if(WebDatabase.IsAvailable)
|
||||||
|
WebDatabase.DeleteEvent(evt);
|
||||||
|
|
||||||
if (Database.HasDatabase)
|
if (Database.HasDatabase)
|
||||||
Database.DeleteEvent(evt);
|
Database.DeleteEvent(evt);
|
||||||
|
|
||||||
|
@ -49,6 +55,9 @@ namespace SharpChat {
|
||||||
if (seqId < 1)
|
if (seqId < 1)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
if(WebDatabase.IsAvailable)
|
||||||
|
return WebDatabase.GetEvent(seqId);
|
||||||
|
|
||||||
if (Database.HasDatabase)
|
if (Database.HasDatabase)
|
||||||
return Database.GetEvent(seqId);
|
return Database.GetEvent(seqId);
|
||||||
|
|
||||||
|
@ -60,6 +69,9 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<IChatEvent> GetTargetLog(IPacketTarget target, int amount = 20, int offset = 0) {
|
public IEnumerable<IChatEvent> GetTargetLog(IPacketTarget target, int amount = 20, int offset = 0) {
|
||||||
|
if(WebDatabase.IsAvailable)
|
||||||
|
return WebDatabase.GetEvents(target, amount, offset);
|
||||||
|
|
||||||
if (Database.HasDatabase)
|
if (Database.HasDatabase)
|
||||||
return Database.GetEvents(target, amount, offset).Reverse();
|
return Database.GetEvents(target, amount, offset).Reverse();
|
||||||
|
|
||||||
|
|
|
@ -94,7 +94,7 @@ namespace SharpChat {
|
||||||
public ChatChannel CurrentChannel { get; private set; }
|
public ChatChannel CurrentChannel { get; private set; }
|
||||||
|
|
||||||
public bool IsSilenced
|
public bool IsSilenced
|
||||||
=> DateTimeOffset.UtcNow - SilencedUntil <= TimeSpan.Zero;
|
=> SilencedUntil != null && DateTimeOffset.UtcNow - SilencedUntil <= TimeSpan.Zero;
|
||||||
|
|
||||||
public bool HasSessions {
|
public bool HasSessions {
|
||||||
get {
|
get {
|
||||||
|
|
|
@ -1,7 +1,9 @@
|
||||||
using Hamakaze;
|
using Microsoft.Win32.SafeHandles;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.Flashii {
|
namespace SharpChat.Flashii {
|
||||||
public class FlashiiAuthRequest {
|
public class FlashiiAuthRequest {
|
||||||
|
@ -47,13 +49,15 @@ namespace SharpChat.Flashii {
|
||||||
[JsonPropertyName(@"perms")]
|
[JsonPropertyName(@"perms")]
|
||||||
public ChatUserPermissions Permissions { get; set; }
|
public ChatUserPermissions Permissions { get; set; }
|
||||||
|
|
||||||
public static void Attempt(FlashiiAuthRequest authRequest, Action<FlashiiAuth> onComplete, Action<Exception> onError) {
|
public static async Task<FlashiiAuth> Attempt(HttpClient httpClient, FlashiiAuthRequest authRequest) {
|
||||||
|
if(httpClient == null)
|
||||||
|
throw new ArgumentNullException(nameof(httpClient));
|
||||||
if(authRequest == null)
|
if(authRequest == null)
|
||||||
throw new ArgumentNullException(nameof(authRequest));
|
throw new ArgumentNullException(nameof(authRequest));
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
if(authRequest.UserId >= 10000) {
|
if (authRequest.UserId >= 10000)
|
||||||
onComplete(new FlashiiAuth {
|
return new FlashiiAuth {
|
||||||
Success = true,
|
Success = true,
|
||||||
UserId = authRequest.UserId,
|
UserId = authRequest.UserId,
|
||||||
Username = @"Misaka-" + (authRequest.UserId - 10000),
|
Username = @"Misaka-" + (authRequest.UserId - 10000),
|
||||||
|
@ -61,21 +65,21 @@ namespace SharpChat.Flashii {
|
||||||
Rank = 0,
|
Rank = 0,
|
||||||
SilencedUntil = DateTimeOffset.MinValue,
|
SilencedUntil = DateTimeOffset.MinValue,
|
||||||
Permissions = ChatUserPermissions.SendMessage | ChatUserPermissions.EditOwnMessage | ChatUserPermissions.DeleteOwnMessage,
|
Permissions = ChatUserPermissions.SendMessage | ChatUserPermissions.EditOwnMessage | ChatUserPermissions.DeleteOwnMessage,
|
||||||
});
|
};
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HttpRequestMessage hrm = new HttpRequestMessage(@"POST", FlashiiUrls.AUTH);
|
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, FlashiiUrls.AUTH) {
|
||||||
hrm.AddHeader(@"X-SharpChat-Signature", authRequest.Hash);
|
Content = new ByteArrayContent(authRequest.GetJSON()),
|
||||||
hrm.SetBody(authRequest.GetJSON());
|
Headers = {
|
||||||
HttpClient.Send(hrm, (t, r) => {
|
{ @"X-SharpChat-Signature", authRequest.Hash },
|
||||||
try {
|
},
|
||||||
onComplete(JsonSerializer.Deserialize<FlashiiAuth>(r.GetBodyBytes()));
|
};
|
||||||
} catch(Exception ex) {
|
|
||||||
onError(ex);
|
using HttpResponseMessage response = await httpClient.SendAsync(request);
|
||||||
}
|
|
||||||
}, (t, e) => onError(e));
|
return JsonSerializer.Deserialize<FlashiiAuth>(
|
||||||
|
await response.Content.ReadAsByteArrayAsync()
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
using Hamakaze;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.Flashii {
|
namespace SharpChat.Flashii {
|
||||||
public class FlashiiBan {
|
public class FlashiiBan {
|
||||||
|
@ -20,21 +21,19 @@ namespace SharpChat.Flashii {
|
||||||
[JsonPropertyName(@"username")]
|
[JsonPropertyName(@"username")]
|
||||||
public string Username { get; set; }
|
public string Username { get; set; }
|
||||||
|
|
||||||
public static void GetList(Action<IEnumerable<FlashiiBan>> onComplete, Action<Exception> onError) {
|
public static async Task<IEnumerable<FlashiiBan>> GetList(HttpClient httpClient) {
|
||||||
if(onComplete == null)
|
if(httpClient == null)
|
||||||
throw new ArgumentNullException(nameof(onComplete));
|
throw new ArgumentNullException(nameof(httpClient));
|
||||||
if(onError == null)
|
|
||||||
throw new ArgumentNullException(nameof(onError));
|
|
||||||
|
|
||||||
HttpRequestMessage hrm = new HttpRequestMessage(@"GET", FlashiiUrls.BANS);
|
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Get, FlashiiUrls.BANS) {
|
||||||
hrm.AddHeader(@"X-SharpChat-Signature", STRING.GetSignedHash());
|
Headers = {
|
||||||
HttpClient.Send(hrm, (t, r) => {
|
{ @"X-SharpChat-Signature", STRING.GetSignedHash() },
|
||||||
try {
|
},
|
||||||
onComplete(JsonSerializer.Deserialize<IEnumerable<FlashiiBan>>(r.GetBodyBytes()));
|
};
|
||||||
} catch(Exception ex) {
|
|
||||||
onError(ex);
|
using HttpResponseMessage response = await httpClient.SendAsync(request);
|
||||||
}
|
|
||||||
}, (t, e) => onError(e));
|
return JsonSerializer.Deserialize<IEnumerable<FlashiiBan>>(await response.Content.ReadAsByteArrayAsync());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,9 +1,10 @@
|
||||||
using Hamakaze;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
using System.Text.Json;
|
using System.Text.Json;
|
||||||
using System.Text.Json.Serialization;
|
using System.Text.Json.Serialization;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
|
||||||
namespace SharpChat.Flashii {
|
namespace SharpChat.Flashii {
|
||||||
public class FlashiiBump {
|
public class FlashiiBump {
|
||||||
|
@ -13,14 +14,16 @@ namespace SharpChat.Flashii {
|
||||||
[JsonPropertyName(@"ip")]
|
[JsonPropertyName(@"ip")]
|
||||||
public string UserIP { get; set; }
|
public string UserIP { get; set; }
|
||||||
|
|
||||||
public static void Submit(IEnumerable<ChatUser> users) {
|
public static void Submit(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();
|
List<FlashiiBump> bups = users.Where(u => u.HasSessions).Select(x => new FlashiiBump { UserId = x.UserId, UserIP = x.RemoteAddresses.First().ToString() }).ToList();
|
||||||
|
|
||||||
if(bups.Any())
|
if (bups.Any())
|
||||||
Submit(bups);
|
Submit(httpClient, bups);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void Submit(IEnumerable<FlashiiBump> users) {
|
public static void Submit(HttpClient httpClient, IEnumerable<FlashiiBump> users) {
|
||||||
|
if(httpClient == null)
|
||||||
|
throw new ArgumentNullException(nameof(httpClient));
|
||||||
if(users == null)
|
if(users == null)
|
||||||
throw new ArgumentNullException(nameof(users));
|
throw new ArgumentNullException(nameof(users));
|
||||||
if(!users.Any())
|
if(!users.Any())
|
||||||
|
@ -28,10 +31,17 @@ namespace SharpChat.Flashii {
|
||||||
|
|
||||||
byte[] data = JsonSerializer.SerializeToUtf8Bytes(users);
|
byte[] data = JsonSerializer.SerializeToUtf8Bytes(users);
|
||||||
|
|
||||||
HttpRequestMessage hrm = new HttpRequestMessage(@"POST", FlashiiUrls.BUMP);
|
using HttpRequestMessage request = new HttpRequestMessage(HttpMethod.Post, FlashiiUrls.BUMP) {
|
||||||
hrm.AddHeader(@"X-SharpChat-Signature", data.GetSignedHash());
|
Content = new ByteArrayContent(data),
|
||||||
hrm.SetBody(data);
|
Headers = {
|
||||||
HttpClient.Send(hrm, onError: (t, e) => Logger.Write($@"Flashii Bump Error: {e}"));
|
{ @"X-SharpChat-Signature", data.GetSignedHash() },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
httpClient.SendAsync(request).ContinueWith(x => {
|
||||||
|
if(x.IsFaulted)
|
||||||
|
Logger.Write($@"Flashii Bump Error: {x.Exception}");
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,7 @@
|
||||||
using Hamakaze;
|
using SharpChat.Flashii;
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
|
@ -17,8 +19,19 @@ namespace SharpChat {
|
||||||
Console.WriteLine(@"============================================ DEBUG ==");
|
Console.WriteLine(@"============================================ DEBUG ==");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
HttpClient.Instance.DefaultUserAgent = @"SharpChat/0.9";
|
#if DEBUG
|
||||||
|
Console.WriteLine(@"HOLD A KEY TO START A TEST NOW");
|
||||||
|
Thread.Sleep(1000);
|
||||||
|
if (Console.KeyAvailable)
|
||||||
|
switch (Console.ReadKey(true).Key) {
|
||||||
|
case ConsoleKey.F:
|
||||||
|
TestMisuzuAuth();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
WebDatabase.ReadConfig();
|
||||||
|
if(!WebDatabase.IsAvailable)
|
||||||
Database.ReadConfig();
|
Database.ReadConfig();
|
||||||
|
|
||||||
using ManualResetEvent mre = new ManualResetEvent(false);
|
using ManualResetEvent mre = new ManualResetEvent(false);
|
||||||
|
@ -26,5 +39,46 @@ namespace SharpChat {
|
||||||
Console.CancelKeyPress += (s, e) => { e.Cancel = true; mre.Set(); };
|
Console.CancelKeyPress += (s, e) => { e.Cancel = true; mre.Set(); };
|
||||||
mre.WaitOne();
|
mre.WaitOne();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if DEBUG
|
||||||
|
private static void TestMisuzuAuth() {
|
||||||
|
Console.WriteLine($@"Enter token found on {FlashiiUrls.BASE_URL}/login:");
|
||||||
|
string[] token = Console.ReadLine().Split(new[] { '_' }, 2);
|
||||||
|
|
||||||
|
System.Net.Http.HttpClient httpClient = new System.Net.Http.HttpClient();
|
||||||
|
httpClient.DefaultRequestHeaders.UserAgent.ParseAdd(@"SharpChat");
|
||||||
|
|
||||||
|
FlashiiAuth authRes = FlashiiAuth.Attempt(httpClient, new FlashiiAuthRequest {
|
||||||
|
UserId = int.Parse(token[0]), Token = token[1], IPAddress = @"1.2.4.8"
|
||||||
|
}).GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
if(authRes.Success) {
|
||||||
|
Console.WriteLine(@"Auth success!");
|
||||||
|
Console.WriteLine($@" User ID: {authRes.UserId}");
|
||||||
|
Console.WriteLine($@" Username: {authRes.Username}");
|
||||||
|
Console.WriteLine($@" Colour: {authRes.ColourRaw:X8}");
|
||||||
|
Console.WriteLine($@" Hierarchy: {authRes.Rank}");
|
||||||
|
Console.WriteLine($@" Silenced: {authRes.SilencedUntil}");
|
||||||
|
Console.WriteLine($@" Perms: {authRes.Permissions}");
|
||||||
|
} else {
|
||||||
|
Console.WriteLine($@"Auth failed: {authRes.Reason}");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
Console.WriteLine(@"Bumping last seen...");
|
||||||
|
FlashiiBump.Submit(httpClient, new[] { new ChatUser(authRes) });
|
||||||
|
|
||||||
|
Console.WriteLine(@"Fetching ban list...");
|
||||||
|
IEnumerable<FlashiiBan> bans = FlashiiBan.GetList(httpClient).GetAwaiter().GetResult();
|
||||||
|
Console.WriteLine($@"{bans.Count()} BANS");
|
||||||
|
foreach(FlashiiBan ban in bans) {
|
||||||
|
Console.WriteLine($@"BAN INFO");
|
||||||
|
Console.WriteLine($@" User ID: {ban.UserId}");
|
||||||
|
Console.WriteLine($@" Username: {ban.Username}");
|
||||||
|
Console.WriteLine($@" IP Address: {ban.UserIP}");
|
||||||
|
Console.WriteLine($@" Expires: {ban.Expires}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,8 +10,4 @@
|
||||||
<PackageReference Include="MySqlConnector" Version="1.3.11" />
|
<PackageReference Include="MySqlConnector" Version="1.3.11" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\Hamakaze\Hamakaze.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
|
|
||||||
</Project>
|
</Project>
|
||||||
|
|
|
@ -8,6 +8,8 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Runtime.CompilerServices;
|
||||||
using System.Text;
|
using System.Text;
|
||||||
|
|
||||||
namespace SharpChat {
|
namespace SharpChat {
|
||||||
|
@ -37,6 +39,8 @@ namespace SharpChat {
|
||||||
public IWebSocketServer Server { get; }
|
public IWebSocketServer Server { get; }
|
||||||
public ChatContext Context { get; }
|
public ChatContext Context { get; }
|
||||||
|
|
||||||
|
public static HttpClient HttpClient { get; }
|
||||||
|
|
||||||
private IReadOnlyCollection<IChatCommand> Commands { get; } = new IChatCommand[] {
|
private IReadOnlyCollection<IChatCommand> Commands { get; } = new IChatCommand[] {
|
||||||
new AFKCommand(),
|
new AFKCommand(),
|
||||||
};
|
};
|
||||||
|
@ -49,6 +53,12 @@ namespace SharpChat {
|
||||||
return Sessions.FirstOrDefault(x => x.Connection == conn);
|
return Sessions.FirstOrDefault(x => x.Connection == conn);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static SockChatServer() {
|
||||||
|
// "fuck it"
|
||||||
|
HttpClient = new HttpClient();
|
||||||
|
HttpClient.DefaultRequestHeaders.UserAgent.ParseAdd(@"SharpChat");
|
||||||
|
}
|
||||||
|
|
||||||
public SockChatServer(ushort port) {
|
public SockChatServer(ushort port) {
|
||||||
Logger.Write("Starting Sock Chat server...");
|
Logger.Write("Starting Sock Chat server...");
|
||||||
|
|
||||||
|
@ -162,11 +172,20 @@ 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(new FlashiiAuthRequest {
|
FlashiiAuth.Attempt(HttpClient, new FlashiiAuthRequest {
|
||||||
UserId = aUserId,
|
UserId = aUserId,
|
||||||
Token = args[2],
|
Token = args[2],
|
||||||
IPAddress = sess.RemoteAddress.ToString(),
|
IPAddress = sess.RemoteAddress.ToString(),
|
||||||
}, auth => {
|
}).ContinueWith(authTask => {
|
||||||
|
if(authTask.IsFaulted) {
|
||||||
|
Logger.Write($@"<{sess.Id}> Auth task fail: {authTask.Exception}");
|
||||||
|
sess.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
|
sess.Dispose();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
FlashiiAuth auth = authTask.Result;
|
||||||
|
|
||||||
if(!auth.Success) {
|
if(!auth.Success) {
|
||||||
Logger.Debug($@"<{sess.Id}> Auth fail: {auth.Reason}");
|
Logger.Debug($@"<{sess.Id}> Auth fail: {auth.Reason}");
|
||||||
sess.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
sess.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
||||||
|
@ -214,10 +233,6 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
Context.HandleJoin(aUser, Context.Channels.DefaultChannel, sess);
|
Context.HandleJoin(aUser, Context.Channels.DefaultChannel, sess);
|
||||||
}, ex => {
|
|
||||||
Logger.Write($@"<{sess.Id}> Auth task fail: {ex}");
|
|
||||||
sess.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
|
||||||
sess.Dispose();
|
|
||||||
});
|
});
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -529,7 +544,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 createChan = new ChatChannel {
|
||||||
Name = createChanName,
|
Name = createChanName,
|
||||||
IsTemporary = !user.Can(ChatUserPermissions.SetChannelPermanent),
|
IsTemporary = !user.Can(ChatUserPermissions.SetChannelPermanent),
|
||||||
Rank = createChanHierarchy,
|
Rank = createChanHierarchy,
|
||||||
|
@ -816,14 +831,12 @@ namespace SharpChat {
|
||||||
}
|
}
|
||||||
|
|
||||||
~SockChatServer()
|
~SockChatServer()
|
||||||
=> DoDispose();
|
=> Dispose(false);
|
||||||
|
|
||||||
public void Dispose() {
|
public void Dispose()
|
||||||
DoDispose();
|
=> Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void DoDispose() {
|
private void Dispose(bool disposing) {
|
||||||
if(IsDisposed)
|
if(IsDisposed)
|
||||||
return;
|
return;
|
||||||
IsDisposed = true;
|
IsDisposed = true;
|
||||||
|
@ -831,6 +844,10 @@ namespace SharpChat {
|
||||||
Sessions?.Clear();
|
Sessions?.Clear();
|
||||||
Server?.Dispose();
|
Server?.Dispose();
|
||||||
Context?.Dispose();
|
Context?.Dispose();
|
||||||
|
HttpClient?.Dispose();
|
||||||
|
|
||||||
|
if(disposing)
|
||||||
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
233
SharpChat/WebDatabase.cs
Normal file
233
SharpChat/WebDatabase.cs
Normal file
|
@ -0,0 +1,233 @@
|
||||||
|
using SharpChat.Events;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Net.Http;
|
||||||
|
using System.Text.Json;
|
||||||
|
using System.Text.Json.Serialization;
|
||||||
|
|
||||||
|
namespace SharpChat {
|
||||||
|
public static class WebDatabase {
|
||||||
|
private static string EndPoint = null;
|
||||||
|
|
||||||
|
public static bool IsAvailable
|
||||||
|
=> !string.IsNullOrWhiteSpace(EndPoint);
|
||||||
|
|
||||||
|
public static void ReadConfig() {
|
||||||
|
if(!File.Exists(@"webdb.txt"))
|
||||||
|
return;
|
||||||
|
string[] config = File.ReadAllLines(@"webdb.txt");
|
||||||
|
if(config.Length < 1 && !string.IsNullOrWhiteSpace(config[0]))
|
||||||
|
return;
|
||||||
|
Init(config[0]);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Init(string endPoint) {
|
||||||
|
EndPoint = endPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void Deinit() {
|
||||||
|
EndPoint = null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void LogEvent(IChatEvent evt) {
|
||||||
|
if(evt.SequenceId < 1)
|
||||||
|
evt.SequenceId = Database.GenerateId();
|
||||||
|
|
||||||
|
string sId = evt.SequenceId.ToString();
|
||||||
|
string sCreated = evt.DateTime.ToUnixTimeSeconds().ToString();
|
||||||
|
string sType = evt.GetType().FullName;
|
||||||
|
string sTarget = evt.Target.TargetName ?? string.Empty;
|
||||||
|
string sFlags = ((byte)evt.Flags).ToString();
|
||||||
|
string sData = JsonSerializer.Serialize(evt, evt.GetType());
|
||||||
|
string sSender = evt.Sender?.UserId < 1 ? string.Empty : evt.Sender.UserId.ToString();
|
||||||
|
string sSenderName = evt.Sender?.Username.ToString() ?? string.Empty;
|
||||||
|
string sSenderColour = evt.Sender?.Colour.Raw.ToString() ?? string.Empty;
|
||||||
|
string sSenderRank = evt.Sender?.Rank.ToString() ?? string.Empty;
|
||||||
|
string sSenderNick = evt.Sender?.Nickname?.ToString() ?? string.Empty;
|
||||||
|
string sSenderPerms = evt.Sender == null ? string.Empty : ((int)evt.Sender.Permissions).ToString();
|
||||||
|
string sHash = string.Join('#', @"crev", sId, sCreated, sType, sTarget, sFlags, sSender, sSenderColour, sSenderRank, sSenderPerms, sSenderName, sSenderNick, sData);
|
||||||
|
|
||||||
|
MultipartFormDataContent mfdc = new();
|
||||||
|
mfdc.Add(new StringContent(sId), @"i");
|
||||||
|
mfdc.Add(new StringContent(sCreated), @"c");
|
||||||
|
mfdc.Add(new StringContent(sType), @"t");
|
||||||
|
mfdc.Add(new StringContent(sTarget), @"l");
|
||||||
|
mfdc.Add(new StringContent(sFlags), @"f");
|
||||||
|
mfdc.Add(new StringContent(sData), @"d");
|
||||||
|
mfdc.Add(new StringContent(sSender), @"s");
|
||||||
|
mfdc.Add(new StringContent(sSenderName), @"su");
|
||||||
|
mfdc.Add(new StringContent(sSenderColour), @"sc");
|
||||||
|
mfdc.Add(new StringContent(sSenderRank), @"sr");
|
||||||
|
mfdc.Add(new StringContent(sSenderNick), @"sn");
|
||||||
|
mfdc.Add(new StringContent(sSenderPerms), @"sp");
|
||||||
|
|
||||||
|
HttpRequestMessage request = new(HttpMethod.Post, EndPoint + @"?m=crev") {
|
||||||
|
Content = mfdc,
|
||||||
|
Headers = {
|
||||||
|
{ @"X-SharpChat-Signature", sHash.GetSignedHash() },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SockChatServer.HttpClient.SendAsync(request).ContinueWith(x => {
|
||||||
|
if(x.IsCompleted) {
|
||||||
|
if(x.Result.Headers.TryGetValues(@"X-SharpChat-Error", out IEnumerable<string> values))
|
||||||
|
Logger.Write($@"DBS - LogEvent: {values.FirstOrDefault()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x.IsFaulted)
|
||||||
|
Logger.Write($@"DBS - LogEvent: {x.Exception}");
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void DeleteEvent(IChatEvent evt) {
|
||||||
|
string msgId = evt.SequenceId.ToString();
|
||||||
|
|
||||||
|
using HttpRequestMessage request = new(HttpMethod.Delete, EndPoint + @"?m=deev&i=" + msgId) {
|
||||||
|
Headers = {
|
||||||
|
{ @"X-SharpChat-Signature", (@"deev#" + msgId).GetSignedHash() },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
SockChatServer.HttpClient.SendAsync(request).ContinueWith(x => {
|
||||||
|
if(x.IsCompleted) {
|
||||||
|
if(x.Result.Headers.TryGetValues(@"X-SharpChat-Error", out IEnumerable<string> values))
|
||||||
|
Logger.Write($@"DBS - DeleteEvent: {values.FirstOrDefault()}");
|
||||||
|
}
|
||||||
|
|
||||||
|
if(x.IsFaulted)
|
||||||
|
Logger.Write($@"DBS - DeleteEvent: {x.Exception}");
|
||||||
|
}).Wait();
|
||||||
|
}
|
||||||
|
|
||||||
|
private class DatabaseRow {
|
||||||
|
[JsonPropertyName(@"i")]
|
||||||
|
public long EventId { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"s")]
|
||||||
|
public long EventSenderId { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"su")]
|
||||||
|
public string EventSenderName { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"sc")]
|
||||||
|
public int EventSenderColour { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"sr")]
|
||||||
|
public int EventSenderRank { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"sn")]
|
||||||
|
public string EventSenderNick { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"sp")]
|
||||||
|
public int EventSenderPerms { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"c")]
|
||||||
|
public int EventCreated { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"t")]
|
||||||
|
public string EventType { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"l")]
|
||||||
|
public string EventTarget { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"f")]
|
||||||
|
public byte EventFlags { get; set; }
|
||||||
|
|
||||||
|
[JsonPropertyName(@"d")]
|
||||||
|
public string EventData { get; set; }
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IChatEvent ReadEvent(DatabaseRow row, IPacketTarget target = null) {
|
||||||
|
Type evtType = Type.GetType(row.EventType);
|
||||||
|
IChatEvent evt = JsonSerializer.Deserialize(row.EventData, evtType) as IChatEvent;
|
||||||
|
evt.SequenceId = row.EventId;
|
||||||
|
evt.Target = target;
|
||||||
|
evt.TargetName = target?.TargetName ?? row.EventTarget;
|
||||||
|
evt.Flags = (ChatMessageFlags)row.EventFlags;
|
||||||
|
evt.DateTime = DateTimeOffset.FromUnixTimeSeconds(row.EventCreated);
|
||||||
|
|
||||||
|
if(row.EventSenderId > 0) {
|
||||||
|
evt.Sender = new BasicUser {
|
||||||
|
UserId = row.EventSenderId,
|
||||||
|
Username = row.EventSenderName,
|
||||||
|
Colour = new ChatColour(row.EventSenderColour),
|
||||||
|
Rank = row.EventSenderRank,
|
||||||
|
Nickname = string.IsNullOrEmpty(row.EventSenderNick) ? null : row.EventSenderNick,
|
||||||
|
Permissions = (ChatUserPermissions)row.EventSenderPerms
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
return evt;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IChatEvent GetEvent(long seqId) {
|
||||||
|
string sSeqId = seqId.ToString();
|
||||||
|
|
||||||
|
using HttpRequestMessage request = new(HttpMethod.Get, EndPoint + @"?m=geev&i=" + sSeqId) {
|
||||||
|
Headers = {
|
||||||
|
{ @"X-SharpChat-Signature", (@"geev#" + sSeqId).GetSignedHash() },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
// jesus christ what is this
|
||||||
|
System.Runtime.CompilerServices.TaskAwaiter<HttpResponseMessage>? awaiter = null;
|
||||||
|
HttpResponseMessage response = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
awaiter = SockChatServer.HttpClient.SendAsync(request).GetAwaiter();
|
||||||
|
response = awaiter.Value.GetResult();
|
||||||
|
|
||||||
|
byte[] garbage = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
return ReadEvent(
|
||||||
|
(DatabaseRow)JsonSerializer.Deserialize(garbage, typeof(DatabaseRow))
|
||||||
|
);
|
||||||
|
} catch(Exception ex) {
|
||||||
|
Logger.Write($@"DBS - GetEvent: {ex}");
|
||||||
|
} finally {
|
||||||
|
if(awaiter.HasValue && awaiter.Value.IsCompleted) {
|
||||||
|
if(response != null && response.Headers.TryGetValues(@"X-SharpChat-Error", out IEnumerable<string> values))
|
||||||
|
Logger.Write($@"DBS - GetEvent: {values.FirstOrDefault()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static IEnumerable<IChatEvent> GetEvents(IPacketTarget target, int amount, int offset) {
|
||||||
|
List<IChatEvent> events = new();
|
||||||
|
|
||||||
|
using HttpRequestMessage request = new(HttpMethod.Get, EndPoint + @"?m=feev&l=" + target.TargetName + @"&a=" + amount + @"&o=" + offset) {
|
||||||
|
Headers = {
|
||||||
|
{ @"X-SharpChat-Signature", string.Join('#', @"feev", amount, offset, target.TargetName).GetSignedHash() },
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
System.Runtime.CompilerServices.TaskAwaiter<HttpResponseMessage>? awaiter = null;
|
||||||
|
HttpResponseMessage response = null;
|
||||||
|
|
||||||
|
try {
|
||||||
|
awaiter = SockChatServer.HttpClient.SendAsync(request).GetAwaiter();
|
||||||
|
response = awaiter.Value.GetResult();
|
||||||
|
|
||||||
|
byte[] trash = response.Content.ReadAsByteArrayAsync().GetAwaiter().GetResult();
|
||||||
|
|
||||||
|
IEnumerable<DatabaseRow> rows = (IEnumerable<DatabaseRow>)JsonSerializer.Deserialize(trash, typeof(IEnumerable<DatabaseRow>));
|
||||||
|
|
||||||
|
foreach(DatabaseRow row in rows)
|
||||||
|
events.Add(ReadEvent(row, target));
|
||||||
|
} catch(Exception ex) {
|
||||||
|
Logger.Write($@"DBS - GetEvents: {ex}");
|
||||||
|
} finally {
|
||||||
|
if(awaiter.HasValue && awaiter.Value.IsCompleted) {
|
||||||
|
if(response != null && response.Headers.TryGetValues(@"X-SharpChat-Error", out IEnumerable<string> values))
|
||||||
|
Logger.Write($@"DBS - GetEvents: {values.FirstOrDefault()}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return events;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue