234 lines
9.4 KiB
C#
234 lines
9.4 KiB
C#
|
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;
|
|||
|
}
|
|||
|
}
|
|||
|
}
|