Split MariaDB message storage out into its own library.
This commit is contained in:
parent
8eff4127b5
commit
f1d4051fb5
23 changed files with 255 additions and 228 deletions
SharpChat.MariaDB
MariaDBMessageStorage.csMariaDBMessageStorage_Database.csMariaDBMessageStorage_Migrations.csMariaDBMessageStorage_Permissions.csMariaDBUserPermissions.csSharpChat.MariaDB.csproj
SharpChat.SockChat/S2CPackets
SharpChat.slnSharpChat
Channel.cs
ClientCommands
DeleteChannelClientCommand.csDeleteMessageClientCommand.csPasswordChannelClientCommand.csRankChannelClientCommand.cs
Context.csEventStorage
Program.csSharpChat.csprojSockChatServer.csSharpChatCommon/Messages
|
@ -1,13 +1,14 @@
|
|||
using MySqlConnector;
|
||||
using SharpChat.Messages;
|
||||
using System.Text;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace SharpChat.EventStorage;
|
||||
namespace SharpChat.MariaDB;
|
||||
|
||||
public partial class MariaDBEventStorage(string connString) : EventStorage {
|
||||
public partial class MariaDBMessageStorage(string connString) : MessageStorage {
|
||||
private string ConnectionString { get; } = connString ?? throw new ArgumentNullException(nameof(connString));
|
||||
|
||||
public async Task AddEvent(
|
||||
public async Task LogMessage(
|
||||
long id,
|
||||
string type,
|
||||
string channelName,
|
||||
|
@ -18,7 +19,7 @@ public partial class MariaDBEventStorage(string connString) : EventStorage {
|
|||
string senderNick,
|
||||
UserPermissions senderPerms,
|
||||
object? data = null,
|
||||
StoredEventFlags flags = StoredEventFlags.None
|
||||
MessageFlags flags = MessageFlags.None
|
||||
) {
|
||||
await RunCommand(
|
||||
"INSERT INTO `sqc_events` (`event_id`, `event_created`, `event_type`, `event_target`, `event_flags`, `event_data`"
|
||||
|
@ -39,7 +40,7 @@ public partial class MariaDBEventStorage(string connString) : EventStorage {
|
|||
);
|
||||
}
|
||||
|
||||
public async Task<StoredEventInfo?> GetEvent(long seqId) {
|
||||
public async Task<Message?> GetMessage(long seqId) {
|
||||
try {
|
||||
using MySqlDataReader? reader = await RunQuery(
|
||||
"SELECT `event_id`, `event_type`, `event_flags`, `event_data`, `event_target`"
|
||||
|
@ -55,7 +56,7 @@ public partial class MariaDBEventStorage(string connString) : EventStorage {
|
|||
return null;
|
||||
|
||||
while(reader.Read()) {
|
||||
StoredEventInfo evt = ReadEvent(reader);
|
||||
Message evt = ReadEvent(reader);
|
||||
if(evt != null)
|
||||
return evt;
|
||||
}
|
||||
|
@ -66,26 +67,26 @@ public partial class MariaDBEventStorage(string connString) : EventStorage {
|
|||
return null;
|
||||
}
|
||||
|
||||
private static StoredEventInfo ReadEvent(MySqlDataReader reader) {
|
||||
return new StoredEventInfo(
|
||||
private static Message ReadEvent(MySqlDataReader reader) {
|
||||
return new Message(
|
||||
reader.GetInt64("event_id"),
|
||||
Encoding.ASCII.GetString((byte[])reader["event_type"]),
|
||||
reader.IsDBNull(reader.GetOrdinal("event_sender")) ? null : reader.GetInt64("event_sender").ToString(),
|
||||
reader.IsDBNull(reader.GetOrdinal("event_sender_name")) ? string.Empty : reader.GetString("event_sender_name"),
|
||||
ColourInheritable.FromMisuzu(reader.GetInt32("event_sender_colour")),
|
||||
reader.GetInt32("event_sender_rank"),
|
||||
FromStoredPermissions((StoredUserPermissions)reader.GetInt32("event_sender_perms")),
|
||||
FromMessagePermissions((MariaDBUserPermissions)reader.GetInt32("event_sender_perms")),
|
||||
reader.IsDBNull(reader.GetOrdinal("event_sender_nick")) ? string.Empty : reader.GetString("event_sender_nick"),
|
||||
DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_created")),
|
||||
reader.IsDBNull(reader.GetOrdinal("event_deleted")) ? null : DateTimeOffset.FromUnixTimeSeconds(reader.GetInt32("event_deleted")),
|
||||
reader.IsDBNull(reader.GetOrdinal("event_target")) ? null : Encoding.ASCII.GetString((byte[])reader["event_target"]),
|
||||
JsonDocument.Parse(Encoding.ASCII.GetString((byte[])reader["event_data"])),
|
||||
(StoredEventFlags)reader.GetByte("event_flags")
|
||||
(MessageFlags)reader.GetByte("event_flags")
|
||||
);
|
||||
}
|
||||
|
||||
public async Task<IEnumerable<StoredEventInfo>> GetChannelEventLog(string channelName, int amount = 20, int offset = 0) {
|
||||
List<StoredEventInfo> events = [];
|
||||
public async Task<IEnumerable<Message>> GetMessages(string channelName, int amount = 20, int offset = 0) {
|
||||
List<Message> events = [];
|
||||
|
||||
try {
|
||||
using MySqlDataReader? reader = await RunQuery(
|
||||
|
@ -106,7 +107,7 @@ public partial class MariaDBEventStorage(string connString) : EventStorage {
|
|||
return events;
|
||||
|
||||
while(reader.Read()) {
|
||||
StoredEventInfo evt = ReadEvent(reader);
|
||||
Message evt = ReadEvent(reader);
|
||||
if(evt != null)
|
||||
events.Add(evt);
|
||||
}
|
||||
|
@ -119,7 +120,7 @@ public partial class MariaDBEventStorage(string connString) : EventStorage {
|
|||
return events;
|
||||
}
|
||||
|
||||
public async Task RemoveEvent(StoredEventInfo evt) {
|
||||
public async Task DeleteMessage(Message evt) {
|
||||
await RunCommand(
|
||||
"UPDATE IGNORE `sqc_events` SET `event_deleted` = NOW() WHERE `event_id` = @id AND `event_deleted` IS NULL",
|
||||
new MySqlParameter("id", evt.Id)
|
|
@ -1,10 +1,10 @@
|
|||
using MySqlConnector;
|
||||
using SharpChat.Configuration;
|
||||
|
||||
namespace SharpChat.EventStorage;
|
||||
namespace SharpChat.MariaDB;
|
||||
|
||||
public partial class MariaDBEventStorage {
|
||||
public static string BuildConnString(Configuration.Config config) {
|
||||
public partial class MariaDBMessageStorage {
|
||||
public static string BuildConnString(Config config) {
|
||||
return BuildConnString(
|
||||
config.ReadValue("host", "localhost"),
|
||||
config.ReadValue("user", string.Empty),
|
|
@ -1,8 +1,8 @@
|
|||
using MySqlConnector;
|
||||
using MySqlConnector;
|
||||
|
||||
namespace SharpChat.EventStorage;
|
||||
namespace SharpChat.MariaDB;
|
||||
|
||||
public partial class MariaDBEventStorage {
|
||||
public partial class MariaDBMessageStorage {
|
||||
private async Task DoMigration(string name, Func<Task> action) {
|
||||
bool done = await RunQueryValue<long>(
|
||||
"SELECT COUNT(*) FROM `sqc_migrations` WHERE `migration_name` = @name",
|
101
SharpChat.MariaDB/MariaDBMessageStorage_Permissions.cs
Normal file
101
SharpChat.MariaDB/MariaDBMessageStorage_Permissions.cs
Normal file
|
@ -0,0 +1,101 @@
|
|||
namespace SharpChat.MariaDB;
|
||||
|
||||
public partial class MariaDBMessageStorage {
|
||||
public static UserPermissions FromMessagePermissions(MariaDBUserPermissions mup) {
|
||||
UserPermissions perms = 0;
|
||||
|
||||
if(mup.HasFlag(MariaDBUserPermissions.KickUser))
|
||||
perms |= UserPermissions.KickUser;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.BanUser))
|
||||
perms |= UserPermissions.BanUser;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.Broadcast))
|
||||
perms |= UserPermissions.SendBroadcast;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.SetOwnNickname))
|
||||
perms |= UserPermissions.SetOwnNickname;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.SetOthersNickname))
|
||||
perms |= UserPermissions.SetOthersNickname;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.CreateChannel))
|
||||
perms |= UserPermissions.CreateChannel;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.DeleteChannel))
|
||||
perms |= UserPermissions.DeleteChannel;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.SetChannelPermanent))
|
||||
perms |= UserPermissions.SetChannelPermanent;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.SetChannelPassword))
|
||||
perms |= UserPermissions.SetChannelPassword;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.SetChannelHierarchy))
|
||||
perms |= UserPermissions.SetChannelMinimumRank;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.JoinAnyChannel))
|
||||
perms |= UserPermissions.JoinAnyChannel;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.SendMessage))
|
||||
perms |= UserPermissions.SendMessage;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.DeleteOwnMessage))
|
||||
perms |= UserPermissions.DeleteOwnMessage;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.DeleteAnyMessage))
|
||||
perms |= UserPermissions.DeleteAnyMessage;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.EditOwnMessage))
|
||||
perms |= UserPermissions.EditOwnMessage;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.EditAnyMessage))
|
||||
perms |= UserPermissions.EditAnyMessage;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.SeeIPAddress))
|
||||
perms |= UserPermissions.ViewIPAddress;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.ViewLogs))
|
||||
perms |= UserPermissions.ViewLogs;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.ViewBanList))
|
||||
perms |= UserPermissions.ViewBanList;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.PardonUser))
|
||||
perms |= UserPermissions.PardonUser;
|
||||
if(mup.HasFlag(MariaDBUserPermissions.PardonIPAddress))
|
||||
perms |= UserPermissions.PardonIPAddress;
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
public static MariaDBUserPermissions ToStoredPermissions(UserPermissions up) {
|
||||
MariaDBUserPermissions perms = 0;
|
||||
|
||||
if(up.HasFlag(UserPermissions.KickUser))
|
||||
perms |= MariaDBUserPermissions.KickUser;
|
||||
if(up.HasFlag(UserPermissions.BanUser))
|
||||
perms |= MariaDBUserPermissions.BanUser;
|
||||
if(up.HasFlag(UserPermissions.SendBroadcast))
|
||||
perms |= MariaDBUserPermissions.Broadcast;
|
||||
if(up.HasFlag(UserPermissions.SetOwnNickname))
|
||||
perms |= MariaDBUserPermissions.SetOwnNickname;
|
||||
if(up.HasFlag(UserPermissions.SetOthersNickname))
|
||||
perms |= MariaDBUserPermissions.SetOthersNickname;
|
||||
if(up.HasFlag(UserPermissions.CreateChannel))
|
||||
perms |= MariaDBUserPermissions.CreateChannel;
|
||||
if(up.HasFlag(UserPermissions.DeleteChannel))
|
||||
perms |= MariaDBUserPermissions.DeleteChannel;
|
||||
if(up.HasFlag(UserPermissions.SetChannelPermanent))
|
||||
perms |= MariaDBUserPermissions.SetChannelPermanent;
|
||||
if(up.HasFlag(UserPermissions.SetChannelPassword))
|
||||
perms |= MariaDBUserPermissions.SetChannelPassword;
|
||||
if(up.HasFlag(UserPermissions.SetChannelMinimumRank))
|
||||
perms |= MariaDBUserPermissions.SetChannelHierarchy;
|
||||
if(up.HasFlag(UserPermissions.JoinAnyChannel))
|
||||
perms |= MariaDBUserPermissions.JoinAnyChannel;
|
||||
if(up.HasFlag(UserPermissions.SendMessage))
|
||||
perms |= MariaDBUserPermissions.SendMessage;
|
||||
if(up.HasFlag(UserPermissions.DeleteOwnMessage))
|
||||
perms |= MariaDBUserPermissions.DeleteOwnMessage;
|
||||
if(up.HasFlag(UserPermissions.DeleteAnyMessage))
|
||||
perms |= MariaDBUserPermissions.DeleteAnyMessage;
|
||||
if(up.HasFlag(UserPermissions.EditOwnMessage))
|
||||
perms |= MariaDBUserPermissions.EditOwnMessage;
|
||||
if(up.HasFlag(UserPermissions.EditAnyMessage))
|
||||
perms |= MariaDBUserPermissions.EditAnyMessage;
|
||||
if(up.HasFlag(UserPermissions.ViewIPAddress))
|
||||
perms |= MariaDBUserPermissions.SeeIPAddress;
|
||||
if(up.HasFlag(UserPermissions.ViewLogs))
|
||||
perms |= MariaDBUserPermissions.ViewLogs;
|
||||
if(up.HasFlag(UserPermissions.ViewBanList))
|
||||
perms |= MariaDBUserPermissions.ViewBanList;
|
||||
if(up.HasFlag(UserPermissions.PardonUser))
|
||||
perms |= MariaDBUserPermissions.PardonUser;
|
||||
if(up.HasFlag(UserPermissions.PardonIPAddress))
|
||||
perms |= MariaDBUserPermissions.PardonIPAddress;
|
||||
|
||||
return perms;
|
||||
}
|
||||
}
|
|
@ -1,7 +1,7 @@
|
|||
namespace SharpChat.EventStorage;
|
||||
namespace SharpChat.MariaDB;
|
||||
|
||||
[Flags]
|
||||
public enum StoredUserPermissions : int {
|
||||
public enum MariaDBUserPermissions : int {
|
||||
KickUser = 0x1,
|
||||
BanUser = 0x2,
|
||||
//SilenceUser = 0x4,
|
17
SharpChat.MariaDB/SharpChat.MariaDB.csproj
Normal file
17
SharpChat.MariaDB/SharpChat.MariaDB.csproj
Normal file
|
@ -0,0 +1,17 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net9.0</TargetFramework>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
<Nullable>enable</Nullable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="MySqlConnector" Version="2.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SharpChatCommon\SharpChatCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
||||
</Project>
|
|
@ -1,43 +1,41 @@
|
|||
using SharpChat.EventStorage;
|
||||
using SharpChat.Messages;
|
||||
using System.Text;
|
||||
|
||||
namespace SharpChat.SockChat.S2CPackets;
|
||||
|
||||
public class ContextMessageS2CPacket(StoredEventInfo evt, bool notify = false) : S2CPacket {
|
||||
public StoredEventInfo Event { get; private set; } = evt ?? throw new ArgumentNullException(nameof(evt));
|
||||
|
||||
public class ContextMessageS2CPacket(Message msg, bool notify = false) : S2CPacket {
|
||||
public string Pack() {
|
||||
bool isAction = Event.Flags.HasFlag(StoredEventFlags.Action);
|
||||
bool isBroadcast = Event.Flags.HasFlag(StoredEventFlags.Broadcast);
|
||||
bool isPrivate = Event.Flags.HasFlag(StoredEventFlags.Private);
|
||||
bool isAction = msg.Flags.HasFlag(MessageFlags.Action);
|
||||
bool isBroadcast = msg.Flags.HasFlag(MessageFlags.Broadcast);
|
||||
bool isPrivate = msg.Flags.HasFlag(MessageFlags.Private);
|
||||
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append("7\t1\t");
|
||||
sb.Append(Event.Created.ToUnixTimeSeconds());
|
||||
sb.Append(msg.Created.ToUnixTimeSeconds());
|
||||
sb.Append('\t');
|
||||
|
||||
switch(Event.Type) {
|
||||
switch(msg.Type) {
|
||||
case "msg:add":
|
||||
case "SharpChat.Events.ChatMessage":
|
||||
if(isBroadcast || Event.SenderId is null) {
|
||||
if(isBroadcast || msg.SenderId is null) {
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\fsay\f");
|
||||
} else {
|
||||
sb.Append(Event.SenderId);
|
||||
sb.Append(msg.SenderId);
|
||||
sb.Append('\t');
|
||||
sb.Append(Event.SenderLegacyName);
|
||||
sb.Append(msg.SenderLegacyName);
|
||||
sb.Append('\t');
|
||||
sb.Append(Event.SenderColour);
|
||||
sb.Append(msg.SenderColour);
|
||||
sb.Append('\t');
|
||||
sb.Append(Event.SenderRank);
|
||||
sb.Append(msg.SenderRank);
|
||||
sb.Append(' ');
|
||||
sb.Append(Event.SenderPermissions.HasFlag(UserPermissions.KickUser) ? '1' : '0');
|
||||
sb.Append(msg.SenderPermissions.HasFlag(UserPermissions.KickUser) ? '1' : '0');
|
||||
sb.Append(' ');
|
||||
sb.Append(Event.SenderPermissions.HasFlag(UserPermissions.ViewLogs) ? '1' : '0');
|
||||
sb.Append(msg.SenderPermissions.HasFlag(UserPermissions.ViewLogs) ? '1' : '0');
|
||||
sb.Append(' ');
|
||||
sb.Append(Event.SenderPermissions.HasFlag(UserPermissions.SetOwnNickname) ? '1' : '0');
|
||||
sb.Append(msg.SenderPermissions.HasFlag(UserPermissions.SetOwnNickname) ? '1' : '0');
|
||||
sb.Append(' ');
|
||||
sb.Append(Event.SenderPermissions.HasFlag(UserPermissions.CreateChannel) ? (Event.SenderPermissions.HasFlag(UserPermissions.SetChannelPermanent) ? '2' : '1') : '0');
|
||||
sb.Append(msg.SenderPermissions.HasFlag(UserPermissions.CreateChannel) ? (msg.SenderPermissions.HasFlag(UserPermissions.SetChannelPermanent) ? '2' : '1') : '0');
|
||||
sb.Append('\t');
|
||||
}
|
||||
|
||||
|
@ -45,7 +43,7 @@ public class ContextMessageS2CPacket(StoredEventInfo evt, bool notify = false) :
|
|||
sb.Append("<i>");
|
||||
|
||||
sb.Append(
|
||||
(Event.Data.RootElement.GetProperty("text").GetString()?
|
||||
(msg.Data.RootElement.GetProperty("text").GetString()?
|
||||
.Replace("<", "<")
|
||||
.Replace(">", ">")
|
||||
.Replace("\n", " <br/> ")
|
||||
|
@ -59,26 +57,26 @@ public class ContextMessageS2CPacket(StoredEventInfo evt, bool notify = false) :
|
|||
case "user:connect":
|
||||
case "SharpChat.Events.UserConnectEvent":
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\fjoin\f");
|
||||
sb.Append(Event.SenderLegacyName);
|
||||
sb.Append(msg.SenderLegacyName);
|
||||
break;
|
||||
|
||||
case "chan:join":
|
||||
case "SharpChat.Events.UserChannelJoinEvent":
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\fjchan\f");
|
||||
sb.Append(Event.SenderLegacyName);
|
||||
sb.Append(msg.SenderLegacyName);
|
||||
break;
|
||||
|
||||
case "chan:leave":
|
||||
case "SharpChat.Events.UserChannelLeaveEvent":
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\flchan\f");
|
||||
sb.Append(Event.SenderLegacyName);
|
||||
sb.Append(msg.SenderLegacyName);
|
||||
break;
|
||||
|
||||
case "user:disconnect":
|
||||
case "SharpChat.Events.UserDisconnectEvent":
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\f");
|
||||
|
||||
switch((UserDisconnectS2CPacket.Reason)Event.Data.RootElement.GetProperty("reason").GetByte()) {
|
||||
switch((UserDisconnectS2CPacket.Reason)msg.Data.RootElement.GetProperty("reason").GetByte()) {
|
||||
case UserDisconnectS2CPacket.Reason.Flood:
|
||||
sb.Append("flood");
|
||||
break;
|
||||
|
@ -95,12 +93,12 @@ public class ContextMessageS2CPacket(StoredEventInfo evt, bool notify = false) :
|
|||
}
|
||||
|
||||
sb.Append('\f');
|
||||
sb.Append(Event.SenderLegacyName);
|
||||
sb.Append(msg.SenderLegacyName);
|
||||
break;
|
||||
}
|
||||
|
||||
sb.Append('\t');
|
||||
sb.Append(Event.Id);
|
||||
sb.Append(msg.Id);
|
||||
sb.Append('\t');
|
||||
sb.Append(notify ? '1' : '0');
|
||||
sb.AppendFormat(
|
|
@ -25,6 +25,10 @@ Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Protos", "Protos", "{02EA68
|
|||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Providers", "Providers", "{5BB7CDAA-06BB-4746-BA07-7EF9090774D8}"
|
||||
EndProject
|
||||
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Storage", "Storage", "{D5EB4BD7-7C69-41F5-9D94-AA5E25B26BDA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "SharpChat.MariaDB", "SharpChat.MariaDB\SharpChat.MariaDB.csproj", "{5B760B2D-F0AD-46E5-B701-8C53D25E2355}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -47,6 +51,10 @@ Global
|
|||
{FEDDC565-B784-4D6F-BEF5-121C383D7AB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{FEDDC565-B784-4D6F-BEF5-121C383D7AB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{FEDDC565-B784-4D6F-BEF5-121C383D7AB2}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{5B760B2D-F0AD-46E5-B701-8C53D25E2355}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{5B760B2D-F0AD-46E5-B701-8C53D25E2355}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{5B760B2D-F0AD-46E5-B701-8C53D25E2355}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{5B760B2D-F0AD-46E5-B701-8C53D25E2355}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
@ -54,6 +62,7 @@ Global
|
|||
GlobalSection(NestedProjects) = preSolution
|
||||
{A9B0B652-C20F-4C62-A96A-EF7ACD2079E9} = {5BB7CDAA-06BB-4746-BA07-7EF9090774D8}
|
||||
{FEDDC565-B784-4D6F-BEF5-121C383D7AB2} = {02EA681E-C7D8-13C7-8484-4AC65E1B71E8}
|
||||
{5B760B2D-F0AD-46E5-B701-8C53D25E2355} = {D5EB4BD7-7C69-41F5-9D94-AA5E25B26BDA}
|
||||
EndGlobalSection
|
||||
GlobalSection(ExtensibilityGlobals) = postSolution
|
||||
SolutionGuid = {42279FE1-5980-440A-87F8-25338DFE54CF}
|
||||
|
|
|
@ -20,10 +20,10 @@ public class Channel(
|
|||
return string.Equals(name, Name, StringComparison.InvariantCultureIgnoreCase);
|
||||
}
|
||||
|
||||
public bool IsOwner(User user) {
|
||||
return string.IsNullOrEmpty(OwnerId)
|
||||
&& user != null
|
||||
&& OwnerId == user.UserId;
|
||||
public bool IsOwner(string userId) {
|
||||
return !string.IsNullOrEmpty(OwnerId)
|
||||
&& !string.IsNullOrEmpty(userId)
|
||||
&& OwnerId == userId;
|
||||
}
|
||||
|
||||
public override int GetHashCode() {
|
||||
|
|
|
@ -26,7 +26,7 @@ public class DeleteChannelClientCommand : ClientCommand {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!ctx.User.Permissions.HasFlag(UserPermissions.DeleteChannel) && delChan.IsOwner(ctx.User)) {
|
||||
if(!ctx.User.Permissions.HasFlag(UserPermissions.DeleteChannel) && delChan.IsOwner(ctx.User.UserId)) {
|
||||
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.CHANNEL_DELETE_FAILED, true, delChan.Name));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
using SharpChat.EventStorage;
|
||||
using SharpChat.Messages;
|
||||
using SharpChat.SockChat.S2CPackets;
|
||||
|
||||
namespace SharpChat.ClientCommands;
|
||||
|
@ -27,14 +27,14 @@ public class DeleteMessageClientCommand : ClientCommand {
|
|||
return;
|
||||
}
|
||||
|
||||
StoredEventInfo? delMsg = await ctx.Chat.Events.GetEvent(delSeqId);
|
||||
Message? delMsg = await ctx.Chat.Messages.GetMessage(delSeqId);
|
||||
|
||||
if(delMsg?.SenderId is null || delMsg.SenderRank > ctx.User.Rank || (!deleteAnyMessage && delMsg.SenderId != ctx.User.UserId)) {
|
||||
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.MESSAGE_DELETE_ERROR));
|
||||
return;
|
||||
}
|
||||
|
||||
await ctx.Chat.Events.RemoveEvent(delMsg);
|
||||
await ctx.Chat.Messages.DeleteMessage(delMsg);
|
||||
await ctx.Chat.Send(new ChatMessageDeleteS2CPacket(delMsg.Id));
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,7 +11,7 @@ public class PasswordChannelClientCommand : ClientCommand {
|
|||
public async Task Dispatch(ClientCommandContext ctx) {
|
||||
long msgId = ctx.Chat.RandomSnowflake.Next();
|
||||
|
||||
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelPassword) || ctx.Channel.IsOwner(ctx.User)) {
|
||||
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelPassword) || ctx.Channel.IsOwner(ctx.User.UserId)) {
|
||||
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -12,7 +12,7 @@ public class RankChannelClientCommand : ClientCommand {
|
|||
public async Task Dispatch(ClientCommandContext ctx) {
|
||||
long msgId = ctx.Chat.RandomSnowflake.Next();
|
||||
|
||||
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelMinimumRank) || ctx.Channel.IsOwner(ctx.User)) {
|
||||
if(!ctx.User.Permissions.HasFlag(UserPermissions.SetChannelMinimumRank) || ctx.Channel.IsOwner(ctx.User.UserId)) {
|
||||
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.COMMAND_NOT_ALLOWED, true, $"/{ctx.Name}"));
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
using SharpChat.Events;
|
||||
using SharpChat.EventStorage;
|
||||
using SharpChat.Messages;
|
||||
using SharpChat.Snowflake;
|
||||
using SharpChat.SockChat;
|
||||
using SharpChat.SockChat.S2CPackets;
|
||||
|
@ -18,13 +18,13 @@ public class Context {
|
|||
public HashSet<Channel> Channels { get; } = [];
|
||||
public HashSet<Connection> Connections { get; } = [];
|
||||
public HashSet<User> Users { get; } = [];
|
||||
public EventStorage.EventStorage Events { get; }
|
||||
public MessageStorage Messages { get; }
|
||||
public HashSet<ChannelUserAssoc> ChannelUsers { get; } = [];
|
||||
public Dictionary<string, RateLimiter> UserRateLimiters { get; } = [];
|
||||
public Dictionary<string, Channel> UserLastChannel { get; } = [];
|
||||
|
||||
public Context(EventStorage.EventStorage evtStore) {
|
||||
Events = evtStore ?? throw new ArgumentNullException(nameof(evtStore));
|
||||
public Context(MessageStorage msgs) {
|
||||
Messages = msgs;
|
||||
RandomSnowflake = new(SnowflakeGenerator);
|
||||
}
|
||||
|
||||
|
@ -71,14 +71,14 @@ public class Context {
|
|||
));
|
||||
}
|
||||
|
||||
await Events.AddEvent(
|
||||
await Messages.LogMessage(
|
||||
mce.MessageId, "msg:add",
|
||||
mce.ChannelName,
|
||||
mce.SenderId, mce.SenderName, mce.SenderColour, mce.SenderRank, mce.SenderNickName, mce.SenderPerms,
|
||||
new { text = mce.MessageText },
|
||||
(mce.IsBroadcast ? StoredEventFlags.Broadcast : 0)
|
||||
| (mce.IsAction ? StoredEventFlags.Action : 0)
|
||||
| (mce.IsPrivate ? StoredEventFlags.Private : 0)
|
||||
(mce.IsBroadcast ? MessageFlags.Broadcast : 0)
|
||||
| (mce.IsAction ? MessageFlags.Action : 0)
|
||||
| (mce.IsPrivate ? MessageFlags.Private : 0)
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
@ -212,7 +212,7 @@ public class Context {
|
|||
if(!IsInChannel(user, chan)) {
|
||||
long msgId = RandomSnowflake.Next();
|
||||
await SendTo(chan, new UserConnectS2CPacket(msgId, DateTimeOffset.Now, user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions));
|
||||
await Events.AddEvent(msgId, "user:connect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
|
||||
await Messages.LogMessage(msgId, "user:connect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, MessageFlags.Log);
|
||||
}
|
||||
|
||||
await conn.Send(new AuthSuccessS2CPacket(
|
||||
|
@ -236,8 +236,8 @@ public class Context {
|
|||
))
|
||||
));
|
||||
|
||||
IEnumerable<StoredEventInfo> msgs = await Events.GetChannelEventLog(chan.Name);
|
||||
foreach(StoredEventInfo msg in msgs)
|
||||
IEnumerable<Message> msgs = await Messages.GetMessages(chan.Name);
|
||||
foreach(Message msg in msgs)
|
||||
await conn.Send(new ContextMessageS2CPacket(msg));
|
||||
|
||||
await conn.Send(new ContextChannelsS2CPacket(
|
||||
|
@ -263,9 +263,9 @@ public class Context {
|
|||
|
||||
long msgId = RandomSnowflake.Next();
|
||||
await SendTo(chan, new UserDisconnectS2CPacket(msgId, DateTimeOffset.Now, user.UserId, user.LegacyNameWithStatus, reason));
|
||||
await Events.AddEvent(msgId, "user:disconnect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, new { reason = (int)reason }, StoredEventFlags.Log);
|
||||
await Messages.LogMessage(msgId, "user:disconnect", chan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, new { reason = (int)reason }, MessageFlags.Log);
|
||||
|
||||
if(chan.IsTemporary && chan.IsOwner(user))
|
||||
if(chan.IsTemporary && chan.IsOwner(user.UserId))
|
||||
await RemoveChannel(chan);
|
||||
}
|
||||
}
|
||||
|
@ -276,7 +276,7 @@ public class Context {
|
|||
return;
|
||||
}
|
||||
|
||||
if(!user.Permissions.HasFlag(UserPermissions.JoinAnyChannel) && chan.IsOwner(user)) {
|
||||
if(!user.Permissions.HasFlag(UserPermissions.JoinAnyChannel) && chan.IsOwner(user.UserId)) {
|
||||
if(chan.Rank > user.Rank) {
|
||||
await SendTo(user, new CommandResponseS2CPacket(RandomSnowflake.Next(), LCR.CHANNEL_INSUFFICIENT_HIERARCHY, true, chan.Name));
|
||||
await ForceChannel(user);
|
||||
|
@ -294,18 +294,18 @@ public class Context {
|
|||
}
|
||||
|
||||
public async Task ForceChannelSwitch(User user, Channel chan) {
|
||||
if(!Channels.Contains(chan))
|
||||
if(!Channels.Any(c => c.NameEquals(chan.Name)))
|
||||
return;
|
||||
|
||||
Channel oldChan = UserLastChannel[user.UserId];
|
||||
|
||||
long leaveId = RandomSnowflake.Next();
|
||||
await SendTo(oldChan, new UserChannelLeaveS2CPacket(leaveId, user.UserId));
|
||||
await Events.AddEvent(leaveId, "chan:leave", oldChan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
|
||||
await Messages.LogMessage(leaveId, "chan:leave", oldChan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, MessageFlags.Log);
|
||||
|
||||
long joinId = RandomSnowflake.Next();
|
||||
await SendTo(chan, new UserChannelJoinS2CPacket(joinId, user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions));
|
||||
await Events.AddEvent(joinId, "chan:join", chan.Name, user.UserId, user.LegacyName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
|
||||
await Messages.LogMessage(joinId, "chan:join", chan.Name, user.UserId, user.LegacyName, user.Colour, user.Rank, user.NickName, user.Permissions, null, MessageFlags.Log);
|
||||
|
||||
await SendTo(user, new ContextClearS2CPacket(ContextClearS2CPacket.Mode.MessagesUsers));
|
||||
await SendTo(user, new ContextUsersS2CPacket(
|
||||
|
@ -320,8 +320,8 @@ public class Context {
|
|||
))
|
||||
));
|
||||
|
||||
IEnumerable<StoredEventInfo> msgs = await Events.GetChannelEventLog(chan.Name);
|
||||
foreach(StoredEventInfo msg in msgs)
|
||||
IEnumerable<Message> msgs = await Messages.GetMessages(chan.Name);
|
||||
foreach(Message msg in msgs)
|
||||
await SendTo(user, new ContextMessageS2CPacket(msg));
|
||||
|
||||
await ForceChannel(user, chan);
|
||||
|
@ -330,7 +330,7 @@ public class Context {
|
|||
ChannelUsers.Add(new ChannelUserAssoc(user.UserId, chan.Name));
|
||||
UserLastChannel[user.UserId] = chan;
|
||||
|
||||
if(oldChan.IsTemporary && oldChan.IsOwner(user))
|
||||
if(oldChan.IsTemporary && oldChan.IsOwner(user.UserId))
|
||||
await RemoveChannel(oldChan);
|
||||
}
|
||||
|
||||
|
@ -374,8 +374,7 @@ public class Context {
|
|||
}
|
||||
|
||||
public async Task UpdateChannel(Channel channel, bool? temporary = null, int? hierarchy = null, string? password = null) {
|
||||
ArgumentNullException.ThrowIfNull(channel);
|
||||
if(!Channels.Contains(channel))
|
||||
if(!Channels.Any(c => c.NameEquals(channel.Name)))
|
||||
throw new ArgumentException("Provided channel is not registered with this manager.", nameof(channel));
|
||||
|
||||
if(temporary.HasValue)
|
||||
|
|
|
@ -1,20 +0,0 @@
|
|||
namespace SharpChat.EventStorage;
|
||||
|
||||
public interface EventStorage {
|
||||
Task AddEvent(
|
||||
long id,
|
||||
string type,
|
||||
string channelName,
|
||||
string senderId,
|
||||
string senderName,
|
||||
ColourInheritable senderColour,
|
||||
int senderRank,
|
||||
string senderNick,
|
||||
UserPermissions senderPerms,
|
||||
object? data = null,
|
||||
StoredEventFlags flags = StoredEventFlags.None
|
||||
);
|
||||
Task RemoveEvent(StoredEventInfo evt);
|
||||
Task<StoredEventInfo?> GetEvent(long seqId);
|
||||
Task<IEnumerable<StoredEventInfo>> GetChannelEventLog(string channelName, int amount = 20, int offset = 0);
|
||||
}
|
|
@ -1,100 +0,0 @@
|
|||
namespace SharpChat.EventStorage;
|
||||
public partial class MariaDBEventStorage {
|
||||
public static UserPermissions FromStoredPermissions(StoredUserPermissions sup) {
|
||||
UserPermissions perms = 0;
|
||||
|
||||
if(sup.HasFlag(StoredUserPermissions.KickUser))
|
||||
perms |= UserPermissions.KickUser;
|
||||
if(sup.HasFlag(StoredUserPermissions.BanUser))
|
||||
perms |= UserPermissions.BanUser;
|
||||
if(sup.HasFlag(StoredUserPermissions.Broadcast))
|
||||
perms |= UserPermissions.SendBroadcast;
|
||||
if(sup.HasFlag(StoredUserPermissions.SetOwnNickname))
|
||||
perms |= UserPermissions.SetOwnNickname;
|
||||
if(sup.HasFlag(StoredUserPermissions.SetOthersNickname))
|
||||
perms |= UserPermissions.SetOthersNickname;
|
||||
if(sup.HasFlag(StoredUserPermissions.CreateChannel))
|
||||
perms |= UserPermissions.CreateChannel;
|
||||
if(sup.HasFlag(StoredUserPermissions.DeleteChannel))
|
||||
perms |= UserPermissions.DeleteChannel;
|
||||
if(sup.HasFlag(StoredUserPermissions.SetChannelPermanent))
|
||||
perms |= UserPermissions.SetChannelPermanent;
|
||||
if(sup.HasFlag(StoredUserPermissions.SetChannelPassword))
|
||||
perms |= UserPermissions.SetChannelPassword;
|
||||
if(sup.HasFlag(StoredUserPermissions.SetChannelHierarchy))
|
||||
perms |= UserPermissions.SetChannelMinimumRank;
|
||||
if(sup.HasFlag(StoredUserPermissions.JoinAnyChannel))
|
||||
perms |= UserPermissions.JoinAnyChannel;
|
||||
if(sup.HasFlag(StoredUserPermissions.SendMessage))
|
||||
perms |= UserPermissions.SendMessage;
|
||||
if(sup.HasFlag(StoredUserPermissions.DeleteOwnMessage))
|
||||
perms |= UserPermissions.DeleteOwnMessage;
|
||||
if(sup.HasFlag(StoredUserPermissions.DeleteAnyMessage))
|
||||
perms |= UserPermissions.DeleteAnyMessage;
|
||||
if(sup.HasFlag(StoredUserPermissions.EditOwnMessage))
|
||||
perms |= UserPermissions.EditOwnMessage;
|
||||
if(sup.HasFlag(StoredUserPermissions.EditAnyMessage))
|
||||
perms |= UserPermissions.EditAnyMessage;
|
||||
if(sup.HasFlag(StoredUserPermissions.SeeIPAddress))
|
||||
perms |= UserPermissions.ViewIPAddress;
|
||||
if(sup.HasFlag(StoredUserPermissions.ViewLogs))
|
||||
perms |= UserPermissions.ViewLogs;
|
||||
if(sup.HasFlag(StoredUserPermissions.ViewBanList))
|
||||
perms |= UserPermissions.ViewBanList;
|
||||
if(sup.HasFlag(StoredUserPermissions.PardonUser))
|
||||
perms |= UserPermissions.PardonUser;
|
||||
if(sup.HasFlag(StoredUserPermissions.PardonIPAddress))
|
||||
perms |= UserPermissions.PardonIPAddress;
|
||||
|
||||
return perms;
|
||||
}
|
||||
|
||||
public static StoredUserPermissions ToStoredPermissions(UserPermissions up) {
|
||||
StoredUserPermissions perms = 0;
|
||||
|
||||
if(up.HasFlag(UserPermissions.KickUser))
|
||||
perms |= StoredUserPermissions.KickUser;
|
||||
if(up.HasFlag(UserPermissions.BanUser))
|
||||
perms |= StoredUserPermissions.BanUser;
|
||||
if(up.HasFlag(UserPermissions.SendBroadcast))
|
||||
perms |= StoredUserPermissions.Broadcast;
|
||||
if(up.HasFlag(UserPermissions.SetOwnNickname))
|
||||
perms |= StoredUserPermissions.SetOwnNickname;
|
||||
if(up.HasFlag(UserPermissions.SetOthersNickname))
|
||||
perms |= StoredUserPermissions.SetOthersNickname;
|
||||
if(up.HasFlag(UserPermissions.CreateChannel))
|
||||
perms |= StoredUserPermissions.CreateChannel;
|
||||
if(up.HasFlag(UserPermissions.DeleteChannel))
|
||||
perms |= StoredUserPermissions.DeleteChannel;
|
||||
if(up.HasFlag(UserPermissions.SetChannelPermanent))
|
||||
perms |= StoredUserPermissions.SetChannelPermanent;
|
||||
if(up.HasFlag(UserPermissions.SetChannelPassword))
|
||||
perms |= StoredUserPermissions.SetChannelPassword;
|
||||
if(up.HasFlag(UserPermissions.SetChannelMinimumRank))
|
||||
perms |= StoredUserPermissions.SetChannelHierarchy;
|
||||
if(up.HasFlag(UserPermissions.JoinAnyChannel))
|
||||
perms |= StoredUserPermissions.JoinAnyChannel;
|
||||
if(up.HasFlag(UserPermissions.SendMessage))
|
||||
perms |= StoredUserPermissions.SendMessage;
|
||||
if(up.HasFlag(UserPermissions.DeleteOwnMessage))
|
||||
perms |= StoredUserPermissions.DeleteOwnMessage;
|
||||
if(up.HasFlag(UserPermissions.DeleteAnyMessage))
|
||||
perms |= StoredUserPermissions.DeleteAnyMessage;
|
||||
if(up.HasFlag(UserPermissions.EditOwnMessage))
|
||||
perms |= StoredUserPermissions.EditOwnMessage;
|
||||
if(up.HasFlag(UserPermissions.EditAnyMessage))
|
||||
perms |= StoredUserPermissions.EditAnyMessage;
|
||||
if(up.HasFlag(UserPermissions.ViewIPAddress))
|
||||
perms |= StoredUserPermissions.SeeIPAddress;
|
||||
if(up.HasFlag(UserPermissions.ViewLogs))
|
||||
perms |= StoredUserPermissions.ViewLogs;
|
||||
if(up.HasFlag(UserPermissions.ViewBanList))
|
||||
perms |= StoredUserPermissions.ViewBanList;
|
||||
if(up.HasFlag(UserPermissions.PardonUser))
|
||||
perms |= StoredUserPermissions.PardonUser;
|
||||
if(up.HasFlag(UserPermissions.PardonIPAddress))
|
||||
perms |= StoredUserPermissions.PardonIPAddress;
|
||||
|
||||
return perms;
|
||||
}
|
||||
}
|
|
@ -1,8 +1,9 @@
|
|||
using SharpChat;
|
||||
using SharpChat.Configuration;
|
||||
using SharpChat.EventStorage;
|
||||
using SharpChat.Messages;
|
||||
using SharpChat.Flashii;
|
||||
using System.Text;
|
||||
using SharpChat.MariaDB;
|
||||
|
||||
const string CONFIG = "sharpchat.cfg";
|
||||
|
||||
|
@ -123,18 +124,18 @@ FlashiiClient flashii = new(httpClient, config.ScopeTo("msz"));
|
|||
|
||||
if(hasCancelled) return;
|
||||
|
||||
EventStorage evtStore;
|
||||
MessageStorage msgStore;
|
||||
if(string.IsNullOrWhiteSpace(config.SafeReadValue("mariadb:host", string.Empty))) {
|
||||
evtStore = new VirtualEventStorage();
|
||||
msgStore = new VirtualMessageStorage();
|
||||
} else {
|
||||
MariaDBEventStorage mdbes = new(MariaDBEventStorage.BuildConnString(config.ScopeTo("mariadb")));
|
||||
evtStore = mdbes;
|
||||
MariaDBMessageStorage mdbes = new(MariaDBMessageStorage.BuildConnString(config.ScopeTo("mariadb")));
|
||||
msgStore = mdbes;
|
||||
await mdbes.RunMigrations();
|
||||
}
|
||||
|
||||
if(hasCancelled) return;
|
||||
|
||||
using SockChatServer scs = new(flashii, flashii, evtStore, config.ScopeTo("chat"));
|
||||
using SockChatServer scs = new(flashii, flashii, msgStore, config.ScopeTo("chat"));
|
||||
scs.Listen(mre);
|
||||
|
||||
mre.WaitOne();
|
||||
|
|
|
@ -17,7 +17,6 @@
|
|||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Fleck" Version="1.2.0" />
|
||||
<PackageReference Include="MySqlConnector" Version="2.4.0" />
|
||||
</ItemGroup>
|
||||
|
||||
<Target Name="PreBuild" BeforeTargets="PreBuildEvent">
|
||||
|
@ -34,6 +33,7 @@
|
|||
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\SharpChat.Flashii\SharpChat.Flashii.csproj" />
|
||||
<ProjectReference Include="..\SharpChat.MariaDB\SharpChat.MariaDB.csproj" />
|
||||
<ProjectReference Include="..\SharpChat.SockChat\SharpChat.SockChat.csproj" />
|
||||
<ProjectReference Include="..\SharpChatCommon\SharpChatCommon.csproj" />
|
||||
</ItemGroup>
|
||||
|
|
|
@ -4,6 +4,7 @@ using SharpChat.Bans;
|
|||
using SharpChat.C2SPacketHandlers;
|
||||
using SharpChat.ClientCommands;
|
||||
using SharpChat.Configuration;
|
||||
using SharpChat.Messages;
|
||||
using SharpChat.SockChat.S2CPackets;
|
||||
using System.Net;
|
||||
|
||||
|
@ -39,7 +40,7 @@ public class SockChatServer : IDisposable {
|
|||
public SockChatServer(
|
||||
AuthClient authClient,
|
||||
BansClient bansClient,
|
||||
EventStorage.EventStorage evtStore,
|
||||
MessageStorage msgStorage,
|
||||
Config config
|
||||
) {
|
||||
Logger.Write("Initialising Sock Chat server...");
|
||||
|
@ -51,7 +52,7 @@ public class SockChatServer : IDisposable {
|
|||
FloodKickLength = config.ReadCached("floodKickLength", DEFAULT_FLOOD_KICK_LENGTH);
|
||||
FloodKickExemptRank = config.ReadCached("floodKickExemptRank", DEFAULT_FLOOD_KICK_EXEMPT_RANK);
|
||||
|
||||
Context = new Context(evtStore);
|
||||
Context = new Context(msgStorage ?? throw new ArgumentNullException(nameof(msgStorage)));
|
||||
|
||||
string[]? channelNames = config.ReadValue("channels", DEFAULT_CHANNELS);
|
||||
if(channelNames is not null)
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
using System.Text.Json;
|
||||
using System.Text.Json;
|
||||
|
||||
namespace SharpChat.EventStorage;
|
||||
namespace SharpChat.Messages;
|
||||
|
||||
public class StoredEventInfo(
|
||||
public class Message(
|
||||
long id,
|
||||
string type,
|
||||
string? senderId,
|
||||
|
@ -15,7 +15,7 @@ public class StoredEventInfo(
|
|||
DateTimeOffset? deleted,
|
||||
string? channelName,
|
||||
JsonDocument data,
|
||||
StoredEventFlags flags
|
||||
MessageFlags flags
|
||||
) {
|
||||
public long Id { get; } = id;
|
||||
public string Type { get; } = type;
|
||||
|
@ -28,7 +28,7 @@ public class StoredEventInfo(
|
|||
public DateTimeOffset Created { get; } = created;
|
||||
public DateTimeOffset? Deleted { get; } = deleted;
|
||||
public string? ChannelName { get; } = channelName;
|
||||
public StoredEventFlags Flags { get; } = flags;
|
||||
public MessageFlags Flags { get; } = flags;
|
||||
public JsonDocument Data { get; } = data;
|
||||
|
||||
public string SenderLegacyName => string.IsNullOrWhiteSpace(SenderNickName) ? SenderName : $"~{SenderNickName}";
|
|
@ -1,7 +1,7 @@
|
|||
namespace SharpChat.EventStorage;
|
||||
namespace SharpChat.Messages;
|
||||
|
||||
[Flags]
|
||||
public enum StoredEventFlags {
|
||||
public enum MessageFlags {
|
||||
None = 0,
|
||||
Action = 1,
|
||||
Broadcast = 1 << 1,
|
20
SharpChatCommon/Messages/MessageStorage.cs
Normal file
20
SharpChatCommon/Messages/MessageStorage.cs
Normal file
|
@ -0,0 +1,20 @@
|
|||
namespace SharpChat.Messages;
|
||||
|
||||
public interface MessageStorage {
|
||||
Task LogMessage(
|
||||
long msgId,
|
||||
string type,
|
||||
string channelName,
|
||||
string senderId,
|
||||
string senderName,
|
||||
ColourInheritable senderColour,
|
||||
int senderRank,
|
||||
string senderNick,
|
||||
UserPermissions senderPerms,
|
||||
object? data = null,
|
||||
MessageFlags flags = MessageFlags.None
|
||||
);
|
||||
Task DeleteMessage(Message evt);
|
||||
Task<Message?> GetMessage(long msgId);
|
||||
Task<IEnumerable<Message>> GetMessages(string channelName, int amount = 20, int offset = 0);
|
||||
}
|
|
@ -1,11 +1,11 @@
|
|||
using System.Text.Json;
|
||||
|
||||
namespace SharpChat.EventStorage;
|
||||
namespace SharpChat.Messages;
|
||||
|
||||
public class VirtualEventStorage : EventStorage {
|
||||
private readonly Dictionary<long, StoredEventInfo> Events = [];
|
||||
public class VirtualMessageStorage : MessageStorage {
|
||||
private readonly Dictionary<long, Message> Messages = [];
|
||||
|
||||
public Task AddEvent(
|
||||
public Task LogMessage(
|
||||
long id,
|
||||
string type,
|
||||
string channelName,
|
||||
|
@ -16,9 +16,9 @@ public class VirtualEventStorage : EventStorage {
|
|||
string senderNick,
|
||||
UserPermissions senderPerms,
|
||||
object? data = null,
|
||||
StoredEventFlags flags = StoredEventFlags.None
|
||||
MessageFlags flags = MessageFlags.None
|
||||
) {
|
||||
Events.Add(
|
||||
Messages.Add(
|
||||
id,
|
||||
new(
|
||||
id,
|
||||
|
@ -40,17 +40,17 @@ public class VirtualEventStorage : EventStorage {
|
|||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<StoredEventInfo?> GetEvent(long seqId) {
|
||||
return Task.FromResult(Events.TryGetValue(seqId, out StoredEventInfo? evt) ? evt : null);
|
||||
public Task<Message?> GetMessage(long seqId) {
|
||||
return Task.FromResult(Messages.TryGetValue(seqId, out Message? evt) ? evt : null);
|
||||
}
|
||||
|
||||
public Task RemoveEvent(StoredEventInfo evt) {
|
||||
Events.Remove(evt.Id);
|
||||
public Task DeleteMessage(Message evt) {
|
||||
Messages.Remove(evt.Id);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
public Task<IEnumerable<StoredEventInfo>> GetChannelEventLog(string channelName, int amount = 20, int offset = 0) {
|
||||
IEnumerable<StoredEventInfo> subset = Events.Values.Where(ev => ev.ChannelName == channelName);
|
||||
public Task<IEnumerable<Message>> GetMessages(string channelName, int amount = 20, int offset = 0) {
|
||||
IEnumerable<Message> subset = Messages.Values.Where(ev => ev.ChannelName == channelName);
|
||||
|
||||
int start = subset.Count() - offset - amount;
|
||||
if(start < 0) {
|
||||
|
@ -58,6 +58,6 @@ public class VirtualEventStorage : EventStorage {
|
|||
start = 0;
|
||||
}
|
||||
|
||||
return Task.FromResult(subset.Skip(start).Take(amount).ToArray() as IEnumerable<StoredEventInfo>);
|
||||
return Task.FromResult(subset.Skip(start).Take(amount).ToArray() as IEnumerable<Message>);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue