Switched to file namespace declarations.

This commit is contained in:
flash 2025-04-26 23:15:54 +00:00
parent 6593929827
commit 34e4e9b1a9
Signed by: flash
GPG key ID: 2C9C2C574D47FE3E
93 changed files with 3470 additions and 3471 deletions
.editorconfig
SharpChat.Flashii
SharpChat.SockChat
SharpChat
SharpChatCommon

View file

@ -15,7 +15,7 @@ csharp_indent_labels = one_less_than_current
csharp_using_directive_placement = outside_namespace:silent
csharp_prefer_simple_using_statement = true:suggestion
csharp_prefer_braces = true:silent
csharp_style_namespace_declarations = block_scoped:silent
csharp_style_namespace_declarations = file_scoped:silent
csharp_style_prefer_method_group_conversion = true:silent
csharp_style_prefer_top_level_statements = true:silent
csharp_style_prefer_primary_constructors = true:suggestion

View file

@ -1,8 +1,9 @@
using SharpChat.Auth;
using System.Text.Json.Serialization;
namespace SharpChat.Flashii {
public class FlashiiAuthResult : AuthResult {
namespace SharpChat.Flashii;
public class FlashiiAuthResult : AuthResult {
public string UserId => UserIdRaw.ToString();
public string UserName => UserNameRaw ?? string.Empty;
public ColourInheritable UserColour => ColourInheritable.FromMisuzu(UserColourRaw);
@ -27,5 +28,4 @@ namespace SharpChat.Flashii {
[JsonPropertyName("perms")]
public UserPermissions UserPermissions { get; init; }
}
}

View file

@ -1,13 +1,13 @@
using SharpChat.Bans;
using SharpChat.Bans;
namespace SharpChat.Flashii {
public abstract class FlashiiBanInfo(
namespace SharpChat.Flashii;
public abstract class FlashiiBanInfo(
BanKind kind,
FlashiiRawBanInfo rawBanInfo
) : BanInfo {
) : BanInfo {
public BanKind Kind { get; } = kind;
public bool IsPermanent { get; } = rawBanInfo.IsPermanent;
public DateTimeOffset ExpiresAt { get; } = rawBanInfo.ExpiresAt;
public abstract override string ToString();
}
}

View file

@ -6,8 +6,9 @@ using System.Security.Cryptography;
using System.Text;
using System.Text.Json;
namespace SharpChat.Flashii {
public class FlashiiClient(HttpClient httpClient, Config config) : AuthClient, BansClient {
namespace SharpChat.Flashii;
public class FlashiiClient(HttpClient httpClient, Config config) : AuthClient, BansClient {
private const string DEFAULT_BASE_URL = "https://flashii.net/_sockchat";
private readonly CachedValue<string> BaseURL = config.ReadCached("url", DEFAULT_BASE_URL);
@ -236,5 +237,4 @@ namespace SharpChat.Flashii {
? new FlashiiUserBanInfo(b) : new FlashiiIPAddressBanInfo(b));
})];
}
}
}

View file

@ -1,9 +1,9 @@
using SharpChat.Bans;
using SharpChat.Bans;
using System.Net;
namespace SharpChat.Flashii {
public class FlashiiIPAddressBanInfo(FlashiiRawBanInfo rawBanInfo) : FlashiiBanInfo(BanKind.IPAddress, rawBanInfo), IPAddressBanInfo {
namespace SharpChat.Flashii;
public class FlashiiIPAddressBanInfo(FlashiiRawBanInfo rawBanInfo) : FlashiiBanInfo(BanKind.IPAddress, rawBanInfo), IPAddressBanInfo {
public IPAddress Address { get; } = IPAddress.TryParse(rawBanInfo.RemoteAddress, out IPAddress? addr) && addr is not null ? addr : IPAddress.IPv6None;
public override string ToString() => Address.ToString();
}
}

View file

@ -1,7 +1,8 @@
using System.Text.Json.Serialization;
using System.Text.Json.Serialization;
namespace SharpChat.Flashii {
public class FlashiiRawBanInfo {
namespace SharpChat.Flashii;
public class FlashiiRawBanInfo {
[JsonPropertyName("is_ban")]
public bool IsBanned { get; set; }
@ -25,5 +26,4 @@ namespace SharpChat.Flashii {
public DateTimeOffset ExpiresAt { get; set; }
public bool HasExpired => !IsPermanent && DateTimeOffset.UtcNow >= ExpiresAt;
}
}

View file

@ -1,10 +1,10 @@
using SharpChat.Bans;
using SharpChat.Bans;
namespace SharpChat.Flashii {
public class FlashiiUserBanInfo(FlashiiRawBanInfo rawBanInfo) : FlashiiBanInfo(BanKind.User, rawBanInfo), UserBanInfo {
namespace SharpChat.Flashii;
public class FlashiiUserBanInfo(FlashiiRawBanInfo rawBanInfo) : FlashiiBanInfo(BanKind.User, rawBanInfo), UserBanInfo {
public string UserId { get; } = rawBanInfo.UserId ?? string.Empty;
public string UserName { get; } = rawBanInfo.UserName ?? $"({rawBanInfo.UserId ?? string.Empty})";
public ColourInheritable UserColour { get; } = ColourInheritable.FromMisuzu(rawBanInfo.UserColourRaw);
public override string ToString() => UserName;
}
}

View file

@ -1,5 +1,5 @@
namespace SharpChat.SockChat {
public interface S2CPacket {
namespace SharpChat.SockChat;
public interface S2CPacket {
string Pack();
}
}

View file

@ -1,10 +1,11 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class AuthFailS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class AuthFailS2CPacket(
AuthFailS2CPacket.Reason reason,
DateTimeOffset? expiresAt = null
) : S2CPacket {
) : S2CPacket {
public enum Reason {
AuthInvalid,
MaxSessions,
@ -39,5 +40,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class AuthSuccessS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class AuthSuccessS2CPacket(
string userId,
string userName,
ColourInheritable userColour,
@ -9,7 +10,7 @@ namespace SharpChat.SockChat.S2CPackets {
UserPermissions userPerms,
string channelName,
int maxMsgLength
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -36,5 +37,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,11 +1,12 @@
using SharpChat.Bans;
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class BanListS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class BanListS2CPacket(
long msgId,
IEnumerable<BanListS2CPacket.Entry> entries
) : S2CPacket {
) : S2CPacket {
public record Entry(BanKind type, string value);
public string Pack() {
@ -25,5 +26,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,11 +1,12 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ChannelCreateS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class ChannelCreateS2CPacket(
string name,
bool hasPassword,
bool isTemporary
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -18,5 +19,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,9 +1,10 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ChannelDeleteS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class ChannelDeleteS2CPacket(
string channelName
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -12,5 +13,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,12 +1,13 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ChannelUpdateS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class ChannelUpdateS2CPacket(
string previousName,
string newName,
bool hasPassword,
bool isTemporary
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -21,5 +22,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,14 +1,15 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ChatMessageAddS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class ChatMessageAddS2CPacket(
long msgId,
DateTimeOffset created,
string userId,
string text,
bool isAction,
bool isPrivate
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -44,5 +45,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ChatMessageDeleteS2CPacket(long eventId) : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class ChatMessageDeleteS2CPacket(long eventId) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -10,5 +11,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,12 +1,13 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class CommandResponseS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class CommandResponseS2CPacket(
long msgId,
string stringId,
bool isError = true,
params object[] args
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -48,10 +49,10 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}
// Abbreviated class name because otherwise shit gets wide
public static class LCR {
// Abbreviated class name because otherwise shit gets wide
public static class LCR {
public const string GENERIC_ERROR = "generr";
public const string COMMAND_NOT_FOUND = "nocmd";
public const string COMMAND_NOT_ALLOWED = "cmdna";
@ -81,5 +82,4 @@ namespace SharpChat.SockChat.S2CPackets {
public const string USER_UNBANNED = "unban";
public const string FLOOD_WARN = "flwarn";
public const string NICKNAME_CHANGE = "nick";
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ContextChannelsS2CPacket(IEnumerable<ContextChannelsS2CPacket.Entry> entries) : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class ContextChannelsS2CPacket(IEnumerable<ContextChannelsS2CPacket.Entry> entries) : S2CPacket {
public record Entry(string name, bool hasPassword, bool isTemporary);
public string Pack() {
@ -21,5 +22,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ContextClearS2CPacket(ContextClearS2CPacket.Mode mode) : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class ContextClearS2CPacket(ContextClearS2CPacket.Mode mode) : S2CPacket {
public enum Mode {
Messages = 0,
Users = 1,
@ -18,5 +19,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ContextUsersS2CPacket(IEnumerable<ContextUsersS2CPacket.Entry> entries) : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class ContextUsersS2CPacket(IEnumerable<ContextUsersS2CPacket.Entry> entries) : S2CPacket {
public record Entry(string id, string name, ColourInheritable colour, int rank, UserPermissions perms, bool visible);
public string Pack() {
@ -33,5 +34,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ForceDisconnectS2CPacket(DateTimeOffset? expires = null) : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class ForceDisconnectS2CPacket(DateTimeOffset? expires = null) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -18,5 +19,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,7 @@
namespace SharpChat.SockChat.S2CPackets {
public class PongS2CPacket : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class PongS2CPacket : S2CPacket {
public string Pack() {
return "0\tpong";
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class UserChannelForceJoinS2CPacket(string channelName) : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class UserChannelForceJoinS2CPacket(string channelName) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -10,5 +11,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,14 +1,15 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class UserChannelJoinS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class UserChannelJoinS2CPacket(
long msgId,
string userId,
string userName,
ColourInheritable userColour,
int userRank,
UserPermissions userPerms
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -33,5 +34,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class UserChannelLeaveS2CPacket(long msgId, string userId) : S2CPacket {
namespace SharpChat.SockChat.S2CPackets;
public class UserChannelLeaveS2CPacket(long msgId, string userId) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -12,5 +13,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class UserConnectS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class UserConnectS2CPacket(
long msgId,
DateTimeOffset joined,
string userId,
@ -9,7 +10,7 @@ namespace SharpChat.SockChat.S2CPackets {
ColourInheritable userColour,
int userRank,
UserPermissions userPerms
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -36,5 +37,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,13 +1,14 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class UserDisconnectS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class UserDisconnectS2CPacket(
long msgId,
DateTimeOffset disconnected,
string userId,
string userName,
UserDisconnectS2CPacket.Reason reason
) : S2CPacket {
) : S2CPacket {
public enum Reason {
Leave,
TimeOut,
@ -47,5 +48,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,13 +1,14 @@
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class UserUpdateS2CPacket(
namespace SharpChat.SockChat.S2CPackets;
public class UserUpdateS2CPacket(
string userId,
string userName,
ColourInheritable userColour,
int userRank,
UserPermissions userPerms
) : S2CPacket {
) : S2CPacket {
public string Pack() {
StringBuilder sb = new();
@ -30,5 +31,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -1,6 +1,6 @@
namespace SharpChat {
public interface C2SPacketHandler {
namespace SharpChat;
public interface C2SPacketHandler {
bool IsMatch(C2SPacketHandlerContext ctx);
Task Handle(C2SPacketHandlerContext ctx);
}
}

View file

@ -1,9 +1,10 @@
namespace SharpChat {
public class C2SPacketHandlerContext(
namespace SharpChat;
public class C2SPacketHandlerContext(
string text,
Context chat,
Connection connection
) {
) {
public string Text { get; } = text ?? throw new ArgumentNullException(nameof(text));
public Context Chat { get; } = chat ?? throw new ArgumentNullException(nameof(chat));
public Connection Connection { get; } = connection ?? throw new ArgumentNullException(nameof(connection));
@ -15,5 +16,4 @@
public string[] SplitText(int expect) {
return Text.Split('\t', expect + 1);
}
}
}

View file

@ -3,14 +3,15 @@ using SharpChat.Bans;
using SharpChat.Configuration;
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.C2SPacketHandlers {
public class AuthC2SPacketHandler(
namespace SharpChat.C2SPacketHandlers;
public class AuthC2SPacketHandler(
AuthClient authClient,
BansClient bansClient,
Channel defaultChannel,
CachedValue<int> maxMsgLength,
CachedValue<int> maxConns
) : C2SPacketHandler {
) : C2SPacketHandler {
private readonly Channel DefaultChannel = defaultChannel ?? throw new ArgumentNullException(nameof(defaultChannel));
private readonly CachedValue<int> MaxMessageLength = maxMsgLength ?? throw new ArgumentNullException(nameof(maxMsgLength));
private readonly CachedValue<int> MaxConnections = maxConns ?? throw new ArgumentNullException(nameof(maxConns));
@ -108,5 +109,4 @@ namespace SharpChat.C2SPacketHandlers {
throw;
}
}
}
}

View file

@ -2,8 +2,9 @@ using SharpChat.Auth;
using SharpChat.SockChat.S2CPackets;
using System.Net;
namespace SharpChat.C2SPacketHandlers {
public class PingC2SPacketHandler(AuthClient authClient) : C2SPacketHandler {
namespace SharpChat.C2SPacketHandlers;
public class PingC2SPacketHandler(AuthClient authClient) : C2SPacketHandler {
private readonly TimeSpan BumpInterval = TimeSpan.FromMinutes(1);
private DateTimeOffset LastBump = DateTimeOffset.MinValue;
@ -36,5 +37,4 @@ namespace SharpChat.C2SPacketHandlers {
ctx.Chat.ContextAccess.Release();
}
}
}
}

View file

@ -4,11 +4,12 @@ using SharpChat.Snowflake;
using System.Globalization;
using System.Text;
namespace SharpChat.C2SPacketHandlers {
public class SendMessageC2SPacketHandler(
namespace SharpChat.C2SPacketHandlers;
public class SendMessageC2SPacketHandler(
RandomSnowflake randomSnowflake,
CachedValue<int> maxMsgLength
) : C2SPacketHandler {
) : C2SPacketHandler {
private readonly CachedValue<int> MaxMessageLength = maxMsgLength ?? throw new ArgumentNullException(nameof(maxMsgLength));
private List<ClientCommand> Commands { get; } = [];
@ -85,5 +86,4 @@ namespace SharpChat.C2SPacketHandlers {
ctx.Chat.ContextAccess.Release();
}
}
}
}

View file

@ -1,11 +1,12 @@
namespace SharpChat {
public class Channel(
namespace SharpChat;
public class Channel(
string name,
string password = "",
bool isTemporary = false,
int rank = 0,
string ownerId = ""
) {
) {
public string Name { get; } = name ?? throw new ArgumentNullException(nameof(name));
public string Password { get; set; } = password ?? string.Empty;
public bool IsTemporary { get; set; } = isTemporary;
@ -36,5 +37,4 @@ namespace SharpChat {
public static bool CheckNameChar(char c) {
return char.IsLetter(c) || char.IsNumber(c) || c == '-' || c == '_';
}
}
}

View file

@ -1,6 +1,6 @@
namespace SharpChat {
public interface ClientCommand {
namespace SharpChat;
public interface ClientCommand {
bool IsMatch(ClientCommandContext ctx);
Task Dispatch(ClientCommandContext ctx);
}
}

View file

@ -1,5 +1,6 @@
namespace SharpChat {
public class ClientCommandContext {
namespace SharpChat;
public class ClientCommandContext {
public string Name { get; }
public string[] Args { get; }
public Context Chat { get; }
@ -45,5 +46,4 @@
public bool NameEquals(string name) {
return Name.Equals(name, StringComparison.InvariantCultureIgnoreCase);
}
}
}

View file

@ -1,8 +1,9 @@
using System.Globalization;
using System.Text;
namespace SharpChat.ClientCommands {
public class AFKClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class AFKClientCommand : ClientCommand {
private const string DEFAULT = "AFK";
public const int MAX_GRAPHEMES = 5;
public const int MAX_BYTES = MAX_GRAPHEMES * 10;
@ -30,5 +31,4 @@ namespace SharpChat.ClientCommands {
statusText: statusText
);
}
}
}

View file

@ -1,7 +1,8 @@
using SharpChat.Events;
namespace SharpChat.ClientCommands {
public class ActionClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class ActionClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("action")
|| ctx.NameEquals("me");
@ -29,5 +30,4 @@ namespace SharpChat.ClientCommands {
false, true, false
));
}
}
}

View file

@ -1,8 +1,9 @@
using SharpChat.Bans;
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class BanListClientCommand(BansClient bansClient) : ClientCommand {
namespace SharpChat.ClientCommands;
public class BanListClientCommand(BansClient bansClient) : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("bans")
|| ctx.NameEquals("banned");
@ -26,5 +27,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.GENERIC_ERROR, true));
}
}
}
}

View file

@ -1,8 +1,9 @@
using SharpChat.Events;
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class BroadcastClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class BroadcastClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("say")
|| ctx.NameEquals("broadcast");
@ -30,5 +31,4 @@ namespace SharpChat.ClientCommands {
false, false, true
));
}
}
}

View file

@ -1,7 +1,8 @@
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class CreateChannelClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class CreateChannelClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("create");
}
@ -58,5 +59,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.SwitchChannel(ctx.User, createChan, createChan.Password);
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.CHANNEL_CREATED, false, createChan.Name));
}
}
}

View file

@ -1,7 +1,8 @@
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class DeleteChannelClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class DeleteChannelClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("delchan") || (
ctx.NameEquals("delete")
@ -33,5 +34,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.RemoveChannel(delChan);
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.CHANNEL_DELETED, false, delChan.Name));
}
}
}

View file

@ -1,9 +1,9 @@
using SharpChat.EventStorage;
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands
{
public class DeleteMessageClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class DeleteMessageClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("delmsg") || (
ctx.NameEquals("delete")
@ -37,5 +37,4 @@ namespace SharpChat.ClientCommands
ctx.Chat.Events.RemoveEvent(delMsg);
await ctx.Chat.Send(new ChatMessageDeleteS2CPacket(delMsg.Id));
}
}
}

View file

@ -1,7 +1,8 @@
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class JoinChannelClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class JoinChannelClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("join");
}
@ -19,5 +20,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.SwitchChannel(ctx.User, joinChan, string.Join(' ', ctx.Args.Skip(1)));
}
}
}

View file

@ -2,8 +2,9 @@ using SharpChat.Bans;
using SharpChat.SockChat.S2CPackets;
using System.Net;
namespace SharpChat.ClientCommands {
public class KickBanClientCommand(BansClient bansClient) : ClientCommand {
namespace SharpChat.ClientCommands;
public class KickBanClientCommand(BansClient bansClient) : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("kick")
|| ctx.NameEquals("ban");
@ -69,5 +70,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.BanUser(banUser, duration);
}
}
}

View file

@ -2,8 +2,9 @@ using SharpChat.SockChat.S2CPackets;
using System.Globalization;
using System.Text;
namespace SharpChat.ClientCommands {
public class NickClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class NickClientCommand : ClientCommand {
private const int MAX_GRAPHEMES = 16;
private const int MAX_BYTES = MAX_GRAPHEMES * 10;
@ -59,5 +60,4 @@ namespace SharpChat.ClientCommands {
string? previousName = targetUser.UserId == ctx.User.UserId ? (targetUser.NickName ?? targetUser.UserName) : null;
await ctx.Chat.UpdateUser(targetUser, nickName: nickStr, silent: previousName == null);
}
}
}

View file

@ -2,8 +2,9 @@ using SharpChat.Bans;
using SharpChat.SockChat.S2CPackets;
using System.Net;
namespace SharpChat.ClientCommands {
public class PardonAddressClientCommand(BansClient bansClient) : ClientCommand {
namespace SharpChat.ClientCommands;
public class PardonAddressClientCommand(BansClient bansClient) : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("pardonip")
|| ctx.NameEquals("unbanip");
@ -36,5 +37,4 @@ namespace SharpChat.ClientCommands {
else
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.USER_NOT_BANNED, true, unbanAddrTarget));
}
}
}

View file

@ -1,8 +1,9 @@
using SharpChat.Bans;
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class PardonUserClientCommand(BansClient bansClient) : ClientCommand {
namespace SharpChat.ClientCommands;
public class PardonUserClientCommand(BansClient bansClient) : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("pardon")
|| ctx.NameEquals("unban");
@ -42,5 +43,4 @@ namespace SharpChat.ClientCommands {
else
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.USER_NOT_BANNED, true, unbanUserDisplay));
}
}
}

View file

@ -1,7 +1,8 @@
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class PasswordChannelClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class PasswordChannelClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("pwd")
|| ctx.NameEquals("password");
@ -23,5 +24,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.UpdateChannel(ctx.Channel, password: chanPass);
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.CHANNEL_PASSWORD_CHANGED, false));
}
}
}

View file

@ -1,7 +1,8 @@
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class RankChannelClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class RankChannelClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("rank")
|| ctx.NameEquals("privilege")
@ -24,5 +25,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.UpdateChannel(ctx.Channel, hierarchy: chanHierarchy);
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.CHANNEL_HIERARCHY_CHANGED, false));
}
}
}

View file

@ -1,8 +1,9 @@
using SharpChat.SockChat.S2CPackets;
using System.Net;
namespace SharpChat.ClientCommands {
public class RemoteAddressClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class RemoteAddressClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("ip")
|| ctx.NameEquals("whois");
@ -27,5 +28,4 @@ namespace SharpChat.ClientCommands {
foreach(IPAddress ip in ctx.Chat.GetRemoteAddresses(ipUser))
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.IP_ADDRESS, false, ipUser.UserName, ip));
}
}
}

View file

@ -1,7 +1,8 @@
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class ShutdownRestartClientCommand(ManualResetEvent waitHandle, Func<bool> shutdownCheck) : ClientCommand {
namespace SharpChat.ClientCommands;
public class ShutdownRestartClientCommand(ManualResetEvent waitHandle, Func<bool> shutdownCheck) : ClientCommand {
private readonly ManualResetEvent WaitHandle = waitHandle ?? throw new ArgumentNullException(nameof(waitHandle));
private readonly Func<bool> ShutdownCheck = shutdownCheck ?? throw new ArgumentNullException(nameof(shutdownCheck));
@ -27,5 +28,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.Update();
WaitHandle?.Set();
}
}
}

View file

@ -1,8 +1,9 @@
using SharpChat.Events;
using SharpChat.SockChat.S2CPackets;
namespace SharpChat.ClientCommands {
public class WhisperClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class WhisperClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("whisper")
|| ctx.NameEquals("msg");
@ -41,5 +42,4 @@ namespace SharpChat.ClientCommands {
true, false, false
));
}
}
}

View file

@ -1,8 +1,9 @@
using SharpChat.SockChat.S2CPackets;
using System.Text;
namespace SharpChat.ClientCommands {
public class WhoClientCommand : ClientCommand {
namespace SharpChat.ClientCommands;
public class WhoClientCommand : ClientCommand {
public bool IsMatch(ClientCommandContext ctx) {
return ctx.NameEquals("who");
}
@ -58,5 +59,4 @@ namespace SharpChat.ClientCommands {
await ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.USERS_LISTING_CHANNEL, false, whoChan.Name, whoChanSB));
}
}
}
}

View file

@ -2,8 +2,9 @@ using Fleck;
using SharpChat.SockChat;
using System.Net;
namespace SharpChat {
public class Connection : IDisposable {
namespace SharpChat;
public class Connection : IDisposable {
public const int ID_LENGTH = 20;
#if DEBUG
@ -86,5 +87,4 @@ namespace SharpChat {
public override int GetHashCode() {
return Id.GetHashCode();
}
}
}

View file

@ -5,8 +5,9 @@ using SharpChat.SockChat;
using SharpChat.SockChat.S2CPackets;
using System.Net;
namespace SharpChat {
public class Context {
namespace SharpChat;
public class Context {
public record ChannelUserAssoc(string UserId, string ChannelName);
public readonly SemaphoreSlim ContextAccess = new(1, 1);
@ -409,5 +410,4 @@ namespace SharpChat {
foreach(User user in Users.Where(u => u.Rank >= channel.Rank))
await SendTo(user, new ChannelDeleteS2CPacket(channel.Name));
}
}
}

View file

@ -1,5 +1,6 @@
namespace SharpChat.EventStorage {
public interface EventStorage {
namespace SharpChat.EventStorage;
public interface EventStorage {
void AddEvent(
long id,
string type,
@ -16,5 +17,4 @@ namespace SharpChat.EventStorage {
void RemoveEvent(StoredEventInfo evt);
StoredEventInfo? GetEvent(long seqId);
IEnumerable<StoredEventInfo> GetChannelEventLog(string channelName, int amount = 20, int offset = 0);
}
}

View file

@ -2,8 +2,9 @@ using MySqlConnector;
using System.Text;
using System.Text.Json;
namespace SharpChat.EventStorage {
public partial class MariaDBEventStorage(string connString) : EventStorage {
namespace SharpChat.EventStorage;
public partial class MariaDBEventStorage(string connString) : EventStorage {
private string ConnectionString { get; } = connString ?? throw new ArgumentNullException(nameof(connString));
public void AddEvent(
@ -127,5 +128,4 @@ namespace SharpChat.EventStorage {
new MySqlParameter("id", evt.Id)
);
}
}
}

View file

@ -1,8 +1,9 @@
using MySqlConnector;
using SharpChat.Configuration;
namespace SharpChat.EventStorage {
public partial class MariaDBEventStorage {
namespace SharpChat.EventStorage;
public partial class MariaDBEventStorage {
public static string BuildConnString(Configuration.Config config) {
return BuildConnString(
config.ReadValue("host", "localhost"),
@ -83,5 +84,4 @@ namespace SharpChat.EventStorage {
return default;
}
}
}

View file

@ -1,7 +1,8 @@
using MySqlConnector;
namespace SharpChat.EventStorage {
public partial class MariaDBEventStorage {
namespace SharpChat.EventStorage;
public partial class MariaDBEventStorage {
private void DoMigration(string name, Action action) {
bool done = RunQueryValue<long>(
"SELECT COUNT(*) FROM `sqc_migrations` WHERE `migration_name` = @name",
@ -80,5 +81,4 @@ namespace SharpChat.EventStorage {
+ ") COLLATE='utf8mb4_unicode_ci' ENGINE=InnoDB;"
);
}
}
}

View file

@ -1,10 +1,10 @@
namespace SharpChat.EventStorage {
[Flags]
public enum StoredEventFlags {
namespace SharpChat.EventStorage;
[Flags]
public enum StoredEventFlags {
None = 0,
Action = 1,
Broadcast = 1 << 1,
Log = 1 << 2,
Private = 1 << 3,
}
}

View file

@ -1,7 +1,8 @@
using System.Text.Json;
namespace SharpChat.EventStorage {
public class StoredEventInfo(
namespace SharpChat.EventStorage;
public class StoredEventInfo(
long id,
string type,
User? sender,
@ -10,7 +11,7 @@ namespace SharpChat.EventStorage {
string? channelName,
JsonDocument data,
StoredEventFlags flags
) {
) {
public long Id { get; set; } = id;
public string Type { get; set; } = type;
public User? Sender { get; set; } = sender;
@ -19,5 +20,4 @@ namespace SharpChat.EventStorage {
public string? ChannelName { get; set; } = channelName;
public StoredEventFlags Flags { get; set; } = flags;
public JsonDocument Data { get; set; } = data;
}
}

View file

@ -1,7 +1,8 @@
using System.Text.Json;
namespace SharpChat.EventStorage {
public class VirtualEventStorage : EventStorage {
namespace SharpChat.EventStorage;
public class VirtualEventStorage : EventStorage {
private readonly Dictionary<long, StoredEventInfo> Events = [];
public void AddEvent(
@ -61,5 +62,4 @@ namespace SharpChat.EventStorage {
return [.. subset.Skip(start).Take(amount)];
}
}
}

View file

@ -1,3 +1,3 @@
namespace SharpChat.Events {
public interface ChatEvent {}
}
namespace SharpChat.Events;
public interface ChatEvent {}

View file

@ -1,5 +1,6 @@
namespace SharpChat.Events {
public class MessageCreateEvent(
namespace SharpChat.Events;
public class MessageCreateEvent(
long msgId,
string channelName,
string senderId,
@ -13,7 +14,7 @@ namespace SharpChat.Events {
bool isPrivate,
bool isAction,
bool isBroadcast
) : ChatEvent {
) : ChatEvent {
public long MessageId { get; } = msgId;
public string ChannelName { get; } = channelName;
public string SenderId { get; } = senderId;
@ -27,5 +28,4 @@ namespace SharpChat.Events {
public bool IsPrivate { get; } = isPrivate;
public bool IsAction { get; } = isAction;
public bool IsBroadcast { get; } = isBroadcast;
}
}

View file

@ -3,8 +3,9 @@ using SharpChat.EventStorage;
using SharpChat.Flashii;
using System.Text;
namespace SharpChat {
public class Program {
namespace SharpChat;
public class Program {
public const string CONFIG = "sharpchat.cfg";
public static void Main() {
@ -143,5 +144,4 @@ namespace SharpChat {
sw.Flush();
}
}
}

View file

@ -12,8 +12,9 @@ using System.Text;
// Fleck's Socket wrapper doesn't provide any way to do this with the normally provided APIs
// https://github.com/statianzo/Fleck/blob/1.1.0/src/Fleck/WebSocketServer.cs
namespace SharpChat {
public class SharpChatWebSocketServer : IWebSocketServer {
namespace SharpChat;
public class SharpChatWebSocketServer : IWebSocketServer {
private readonly string _scheme;
private readonly IPAddress _locationIP;
@ -163,5 +164,4 @@ namespace SharpChat {
connection.StartReceiving();
}
}
}
}

View file

@ -1,8 +1,9 @@
using SharpChat.EventStorage;
using System.Text;
namespace SharpChat.SockChat.S2CPackets {
public class ContextMessageS2CPacket(StoredEventInfo evt, bool notify = false) : S2CPacket {
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 string Pack() {
@ -111,5 +112,4 @@ namespace SharpChat.SockChat.S2CPackets {
return sb.ToString();
}
}
}

View file

@ -7,8 +7,9 @@ using SharpChat.Configuration;
using SharpChat.SockChat.S2CPackets;
using System.Net;
namespace SharpChat {
public class SockChatServer : IDisposable {
namespace SharpChat;
public class SockChatServer : IDisposable {
public const ushort DEFAULT_PORT = 6770;
public const int DEFAULT_MSG_LENGTH_MAX = 5000;
public const int DEFAULT_MAX_CONNECTIONS = 5;
@ -236,5 +237,4 @@ namespace SharpChat {
Server?.Dispose();
}
}
}

View file

@ -2,8 +2,9 @@ using SharpChat.ClientCommands;
using System.Globalization;
using System.Text;
namespace SharpChat {
public class User(
namespace SharpChat;
public class User(
string userId,
string userName,
ColourInheritable colour,
@ -12,7 +13,7 @@ namespace SharpChat {
string nickName = "",
UserStatus status = UserStatus.Online,
string statusText = ""
) {
) {
public const int DEFAULT_SIZE = 30;
public const int DEFAULT_MINIMUM_DELAY = 10000;
public const int DEFAULT_RISKY_OFFSET = 5;
@ -69,5 +70,4 @@ namespace SharpChat {
? $"@{user2.UserId}-{user1.UserId}"
: $"@{user1.UserId}-{user2.UserId}";
}
}
}

View file

@ -1,7 +1,7 @@
namespace SharpChat {
public enum UserStatus {
namespace SharpChat;
public enum UserStatus {
Online,
Away,
Offline,
}
}

View file

@ -1,8 +1,8 @@
using System.Net;
namespace SharpChat.Auth {
public interface AuthClient {
namespace SharpChat.Auth;
public interface AuthClient {
Task<AuthResult> AuthVerifyAsync(IPAddress remoteAddr, string scheme, string token);
Task AuthBumpUsersOnlineAsync(IEnumerable<(IPAddress remoteAddr, string userId)> entries);
}
}

View file

@ -1,3 +1,3 @@
namespace SharpChat.Auth {
public class AuthFailedException(string message) : Exception(message) {}
}
namespace SharpChat.Auth;
public class AuthFailedException(string message) : Exception(message) {}

View file

@ -1,9 +1,9 @@
namespace SharpChat.Auth {
public interface AuthResult {
namespace SharpChat.Auth;
public interface AuthResult {
string UserId { get; }
string UserName { get; }
ColourInheritable UserColour { get; }
int UserRank { get; }
UserPermissions UserPermissions { get; }
}
}

View file

@ -1,9 +1,9 @@
namespace SharpChat.Bans {
public interface BanInfo {
namespace SharpChat.Bans;
public interface BanInfo {
BanKind Kind { get; }
bool IsPermanent { get; }
DateTimeOffset ExpiresAt { get; }
public bool HasExpired => !IsPermanent && DateTimeOffset.UtcNow >= ExpiresAt;
string ToString();
}
}

View file

@ -1,6 +1,6 @@
namespace SharpChat.Bans {
public enum BanKind {
namespace SharpChat.Bans;
public enum BanKind {
User,
IPAddress,
}
}

View file

@ -1,7 +1,8 @@
using System.Net;
namespace SharpChat.Bans {
public interface BansClient {
namespace SharpChat.Bans;
public interface BansClient {
Task BanCreateAsync(
BanKind kind,
TimeSpan duration,
@ -14,5 +15,4 @@ namespace SharpChat.Bans {
Task<bool> BanRevokeAsync(BanInfo info);
Task<BanInfo?> BanGetAsync(string? userIdOrName = null, IPAddress? remoteAddr = null);
Task<BanInfo[]> BanGetListAsync();
}
}

View file

@ -1,7 +1,7 @@
using System.Net;
namespace SharpChat.Bans {
public interface IPAddressBanInfo : BanInfo {
namespace SharpChat.Bans;
public interface IPAddressBanInfo : BanInfo {
IPAddress Address { get; }
}
}

View file

@ -1,7 +1,7 @@
namespace SharpChat.Bans {
public interface UserBanInfo : BanInfo {
namespace SharpChat.Bans;
public interface UserBanInfo : BanInfo {
string UserId { get; }
string UserName { get; }
ColourInheritable UserColour { get; }
}
}

View file

@ -1,5 +1,6 @@
namespace SharpChat {
public readonly record struct ColourInheritable(ColourRgb? rgb) {
namespace SharpChat;
public readonly record struct ColourInheritable(ColourRgb? rgb) {
public static readonly ColourInheritable None = new(null);
public override string ToString() => rgb.HasValue ? rgb.Value.ToString() : "inherit";
@ -10,5 +11,4 @@ namespace SharpChat {
private const int MSZ_INHERIT = 0x40000000;
public int ToMisuzu() => rgb.HasValue ? rgb.Value.Raw : MSZ_INHERIT;
public static ColourInheritable FromMisuzu(int msz) => (msz & MSZ_INHERIT) > 0 ? None : new(new ColourRgb(msz & 0xFFFFFF));
}
}

View file

@ -1,9 +1,9 @@
namespace SharpChat {
public readonly record struct ColourRgb(int Raw) {
namespace SharpChat;
public readonly record struct ColourRgb(int Raw) {
public byte Red => (byte)((Raw >> 16) & 0xFF);
public byte Green => (byte)((Raw >> 8) & 0xFF);
public byte Blue => (byte)(Raw & 0xFF);
public override string ToString() => string.Format("#{0:x2}{1:x2}{2:x2}", Red, Green, Blue);
public static ColourRgb FromRgb(byte red, byte green, byte blue) => new(red << 16 | green << 8 | blue);
}
}

View file

@ -1,5 +1,6 @@
namespace SharpChat.Configuration {
public class CachedValue<T>(Config config, string name, TimeSpan lifetime, T? fallback) {
namespace SharpChat.Configuration;
public class CachedValue<T>(Config config, string name, TimeSpan lifetime, T? fallback) {
private Config Config { get; } = config ?? throw new ArgumentNullException(nameof(config));
private string Name { get; } = name ?? throw new ArgumentNullException(nameof(name));
private object ConfigAccess { get; } = new();
@ -30,5 +31,4 @@ namespace SharpChat.Configuration {
public override string ToString() {
return Value?.ToString() ?? string.Empty;
}
}
}

View file

@ -1,5 +1,6 @@
namespace SharpChat.Configuration {
public interface Config : IDisposable {
namespace SharpChat.Configuration;
public interface Config : IDisposable {
/// <summary>
/// Creates a proxy object that forces all names to start with the given prefix.
/// </summary>
@ -25,5 +26,4 @@ namespace SharpChat.Configuration {
/// Creates an object that caches the read value for a certain amount of time, avoiding disk reads for frequently used non-static values.
/// </summary>
CachedValue<T> ReadCached<T>(string name, T? fallback = default, TimeSpan? lifetime = null);
}
}

View file

@ -1,9 +1,9 @@
namespace SharpChat.Configuration {
public abstract class ConfigException : Exception {
namespace SharpChat.Configuration;
public abstract class ConfigException : Exception {
public ConfigException(string message) : base(message) { }
public ConfigException(string message, Exception ex) : base(message, ex) { }
}
public class ConfigLockException() : ConfigException("Unable to acquire lock for reading configuration.") {}
public class ConfigTypeException(Exception ex) : ConfigException("Given type does not match the value in the configuration.", ex) {}
}
public class ConfigLockException() : ConfigException("Unable to acquire lock for reading configuration.") {}
public class ConfigTypeException(Exception ex) : ConfigException("Given type does not match the value in the configuration.", ex) {}

View file

@ -1,5 +1,6 @@
namespace SharpChat.Configuration {
public class ScopedConfig(Config config, string prefix) : Config {
namespace SharpChat.Configuration;
public class ScopedConfig(Config config, string prefix) : Config {
private Config Config { get; } = config ?? throw new ArgumentNullException(nameof(config));
private string Prefix { get; } = prefix ?? throw new ArgumentNullException(nameof(prefix));
@ -30,5 +31,4 @@ namespace SharpChat.Configuration {
public void Dispose() {
GC.SuppressFinalize(this);
}
}
}

View file

@ -1,7 +1,8 @@
using System.Text;
namespace SharpChat.Configuration {
public class StreamConfig : Config {
namespace SharpChat.Configuration;
public class StreamConfig : Config {
private Stream Stream { get; }
private StreamReader StreamReader { get; }
private Mutex Lock { get; }
@ -111,5 +112,4 @@ namespace SharpChat.Configuration {
Stream.Dispose();
Lock.Dispose();
}
}
}

View file

@ -1,8 +1,9 @@
using System.Diagnostics;
using System.Diagnostics;
using System.Text;
namespace SharpChat {
public static class Logger {
namespace SharpChat;
public static class Logger {
public static void Write(string str) {
Console.WriteLine(string.Format("[{1}] {0}", str, DateTime.Now));
}
@ -29,5 +30,4 @@ namespace SharpChat {
public static void Debug(object obj) {
Write(obj);
}
}
}

View file

@ -1,8 +1,9 @@
using System.Buffers;
using System.Buffers;
using System.Security.Cryptography;
namespace SharpChat {
public static class RNG {
namespace SharpChat;
public static class RNG {
public const string CHARS = "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz0123456789";
private static Random NormalRandom { get; } = new();
@ -78,5 +79,4 @@ namespace SharpChat {
public static string SecureRandomString(int length) {
return RandomStringInternal(SecureNext, length);
}
}
}

View file

@ -1,5 +1,6 @@
namespace SharpChat {
public class RateLimiter {
namespace SharpChat;
public class RateLimiter {
private readonly int Size;
private readonly int MinimumDelay;
private readonly int RiskyOffset;
@ -31,5 +32,4 @@
TimePoints[i - 1] = TimePoints[i];
TimePoints[Size - 1] = DateTimeOffset.UtcNow.ToUnixTimeMilliseconds();
}
}
}

View file

@ -1,8 +1,9 @@
using System.Reflection;
using System.Text;
namespace SharpChat {
public static class SharpInfo {
namespace SharpChat;
public static class SharpInfo {
private const string NAME = @"SharpChat";
private const string UNKNOWN = @"XXXXXXXXXX";
@ -32,5 +33,4 @@ namespace SharpChat {
sb.Append(VersionStringShort);
ProgramName = sb.ToString();
}
}
}

View file

@ -1,13 +1,13 @@
using System.Security.Cryptography;
using System.Security.Cryptography;
namespace SharpChat.Snowflake {
public class RandomSnowflake(
namespace SharpChat.Snowflake;
public class RandomSnowflake(
SnowflakeGenerator? generator = null
) {
) {
public readonly SnowflakeGenerator Generator = generator ?? new SnowflakeGenerator();
public long Next(DateTimeOffset? at = null) {
return Generator.Next(Math.Abs(BitConverter.ToInt64(RandomNumberGenerator.GetBytes(8))), at);
}
}
}

View file

@ -1,5 +1,6 @@
namespace SharpChat.Snowflake {
public class SnowflakeGenerator {
namespace SharpChat.Snowflake;
public class SnowflakeGenerator {
public const long MASK = 0x7FFFFFFFFFFFFFFF;
// previous default epoch was 1588377600000, but snowflakes are much larger than SharpIds
public const long EPOCH = 1356998400000;
@ -31,5 +32,4 @@
public long Next(long sequence, DateTimeOffset? at = null) {
return ((Now(at) & TimestampMask) << Shift) | (sequence & SequenceMask);
}
}
}

View file

@ -1,6 +1,7 @@
namespace SharpChat {
[Flags]
public enum UserPermissions : int {
namespace SharpChat;
[Flags]
public enum UserPermissions : int {
KickUser = 0x00000001,
BanUser = 0x00000002,
//SilenceUser = 0x00000004,
@ -20,5 +21,4 @@
EditAnyMessage = 0x00004000,
SeeIPAddress = 0x00008000,
ViewLogs = 0x00040000,
}
}