Split some packets out of LegacyCommandResponse.
This commit is contained in:
parent
8cc00fe1a8
commit
907711e753
|
@ -28,7 +28,7 @@ namespace SharpChat {
|
||||||
public void DispatchEvent(IChatEvent eventInfo) {
|
public void DispatchEvent(IChatEvent eventInfo) {
|
||||||
if(eventInfo is MessageCreateEvent mce) {
|
if(eventInfo is MessageCreateEvent mce) {
|
||||||
if(mce.IsBroadcast) {
|
if(mce.IsBroadcast) {
|
||||||
Send(new LegacyCommandResponse(LCR.BROADCAST, false, mce.MessageText));
|
Send(new BroadcastPacket(mce.MessageText));
|
||||||
} else if(mce.IsPrivate) {
|
} else if(mce.IsPrivate) {
|
||||||
// The channel name returned by GetDMChannelName should not be exposed to the user, instead @<Target User> should be displayed
|
// The channel name returned by GetDMChannelName should not be exposed to the user, instead @<Target User> should be displayed
|
||||||
// e.g. nook sees @Arysil and Arysil sees @nook
|
// e.g. nook sees @Arysil and Arysil sees @nook
|
||||||
|
@ -311,7 +311,7 @@ namespace SharpChat {
|
||||||
SendTo(chan, new UserChannelJoinPacket(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions));
|
SendTo(chan, new UserChannelJoinPacket(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions));
|
||||||
Events.AddEvent("chan:join", user, oldChan, flags: StoredEventFlags.Log);
|
Events.AddEvent("chan:join", user, oldChan, flags: StoredEventFlags.Log);
|
||||||
|
|
||||||
SendTo(user, new ContextClearPacket(ContextClearMode.MessagesUsers));
|
SendTo(user, new ContextClearPacket(ContextClearPacket.ClearMode.MessagesUsers));
|
||||||
SendTo(user, new ContextUsersPacket(GetChannelUsers(chan).Except(new[] { user }).Select(
|
SendTo(user, new ContextUsersPacket(GetChannelUsers(chan).Except(new[] { user }).Select(
|
||||||
user => new ContextUsersPacket.ListEntry(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions, true)
|
user => new ContextUsersPacket.ListEntry(user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions, true)
|
||||||
).OrderByDescending(u => u.Rank).ToArray()));
|
).OrderByDescending(u => u.Rank).ToArray()));
|
||||||
|
|
|
@ -1,35 +1,35 @@
|
||||||
using System;
|
using System;
|
||||||
|
|
||||||
namespace SharpChat.Packet {
|
namespace SharpChat.Packet {
|
||||||
public enum AuthFailReason {
|
public class AuthFailPacket : ServerPacket {
|
||||||
|
public enum FailReason {
|
||||||
AuthInvalid,
|
AuthInvalid,
|
||||||
MaxSessions,
|
MaxSessions,
|
||||||
Banned,
|
Banned,
|
||||||
Null,
|
Null,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class AuthFailPacket : ServerPacket {
|
private readonly FailReason Reason;
|
||||||
private readonly AuthFailReason Reason;
|
|
||||||
private readonly DateTimeOffset Expires;
|
private readonly DateTimeOffset Expires;
|
||||||
|
|
||||||
public AuthFailPacket(AuthFailReason reason) {
|
public AuthFailPacket(FailReason reason) {
|
||||||
Reason = reason;
|
Reason = reason;
|
||||||
}
|
}
|
||||||
|
|
||||||
public AuthFailPacket(DateTimeOffset expires) {
|
public AuthFailPacket(DateTimeOffset expires) {
|
||||||
Reason = AuthFailReason.Banned;
|
Reason = FailReason.Banned;
|
||||||
Expires = expires;
|
Expires = expires;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
string packet = string.Format("1\tn\t{0}fail", Reason switch {
|
string packet = string.Format("1\tn\t{0}fail", Reason switch {
|
||||||
AuthFailReason.AuthInvalid => "auth",
|
FailReason.AuthInvalid => "auth",
|
||||||
AuthFailReason.MaxSessions => "sock",
|
FailReason.MaxSessions => "sock",
|
||||||
AuthFailReason.Banned => "join",
|
FailReason.Banned => "join",
|
||||||
_ => "user",
|
_ => "user",
|
||||||
});
|
});
|
||||||
|
|
||||||
if(Reason == AuthFailReason.Banned)
|
if(Reason == FailReason.Banned)
|
||||||
packet += string.Format("\t{0}", Expires.Year >= 2100 ? -1 : Expires.ToUnixTimeSeconds());
|
packet += string.Format("\t{0}", Expires.Year >= 2100 ? -1 : Expires.ToUnixTimeSeconds());
|
||||||
|
|
||||||
return packet;
|
return packet;
|
||||||
|
|
22
SharpChat/Packet/BroadcastPacket.cs
Normal file
22
SharpChat/Packet/BroadcastPacket.cs
Normal file
|
@ -0,0 +1,22 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SharpChat.Packet {
|
||||||
|
public class BroadcastPacket : ServerPacket {
|
||||||
|
private readonly long Timestamp;
|
||||||
|
private readonly string Body;
|
||||||
|
|
||||||
|
public BroadcastPacket(string body) {
|
||||||
|
Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||||
|
Body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Pack() {
|
||||||
|
return string.Format(
|
||||||
|
"2\t{0}\t-1\t0\fsay\f{1}\t{2}\t10010",
|
||||||
|
Timestamp,
|
||||||
|
SharpUtil.Sanitise(Body),
|
||||||
|
SequenceId
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -24,7 +24,7 @@ namespace SharpChat.Packet {
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
string body = Body.Replace("<", "<").Replace(">", ">").Replace("\n", " <br/> ").Replace("\t", " ");
|
string body = SharpUtil.Sanitise(Body);
|
||||||
if(IsAction)
|
if(IsAction)
|
||||||
body = string.Format("<i>{0}</i>", body);
|
body = string.Format("<i>{0}</i>", body);
|
||||||
|
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
namespace SharpChat.Packet {
|
namespace SharpChat.Packet {
|
||||||
public class ChatMessageDeletePacket : ServerPacket {
|
public class ChatMessageDeletePacket : ServerPacket {
|
||||||
private readonly long EventId;
|
private readonly long MessageId;
|
||||||
|
|
||||||
public ChatMessageDeletePacket(long eventId) {
|
public ChatMessageDeletePacket(long msgId) {
|
||||||
EventId = eventId;
|
MessageId = msgId;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
return string.Format("6\t{0}", EventId);
|
return string.Format("6\t{0}", MessageId);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
namespace SharpChat.Packet {
|
namespace SharpChat.Packet {
|
||||||
public enum ContextClearMode {
|
public class ContextClearPacket : ServerPacket {
|
||||||
|
public enum ClearMode {
|
||||||
Messages = 0,
|
Messages = 0,
|
||||||
Users = 1,
|
Users = 1,
|
||||||
Channels = 2,
|
Channels = 2,
|
||||||
|
@ -7,10 +8,9 @@
|
||||||
MessagesUsersChannels = 4,
|
MessagesUsersChannels = 4,
|
||||||
}
|
}
|
||||||
|
|
||||||
public class ContextClearPacket : ServerPacket {
|
private readonly ClearMode Mode;
|
||||||
private readonly ContextClearMode Mode;
|
|
||||||
|
|
||||||
public ContextClearPacket(ContextClearMode mode) {
|
public ContextClearPacket(ClearMode mode) {
|
||||||
Mode = mode;
|
Mode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -49,7 +49,7 @@ namespace SharpChat.Packet {
|
||||||
if(isBroadcast)
|
if(isBroadcast)
|
||||||
sb.Append("0\fsay\f");
|
sb.Append("0\fsay\f");
|
||||||
|
|
||||||
string body = Event.Data.RootElement.GetProperty("text").GetString()?.Replace("<", "<").Replace(">", ">").Replace("\n", " <br/> ").Replace("\t", " ") ?? string.Empty;
|
string body = SharpUtil.Sanitise(Event.Data.RootElement.GetProperty("text").GetString());
|
||||||
if(isAction)
|
if(isAction)
|
||||||
body = string.Format("<i>{0}</i>", body);
|
body = string.Format("<i>{0}</i>", body);
|
||||||
|
|
||||||
|
|
|
@ -20,34 +20,17 @@ namespace SharpChat.Packet {
|
||||||
public override string Pack() {
|
public override string Pack() {
|
||||||
StringBuilder sb = new();
|
StringBuilder sb = new();
|
||||||
|
|
||||||
if(StringId == LCR.WELCOME)
|
|
||||||
sb.AppendFormat(
|
sb.AppendFormat(
|
||||||
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t",
|
"2\t{0}\t-1\t{1}\f{2}",
|
||||||
DateTimeOffset.Now.ToUnixTimeSeconds()
|
DateTimeOffset.Now.ToUnixTimeSeconds(),
|
||||||
);
|
|
||||||
else
|
|
||||||
sb.AppendFormat(
|
|
||||||
"2\t{0}\t-1\t",
|
|
||||||
DateTimeOffset.Now.ToUnixTimeSeconds()
|
|
||||||
);
|
|
||||||
|
|
||||||
sb.AppendFormat(
|
|
||||||
"{0}\f{1}",
|
|
||||||
IsError ? 1 : 0,
|
IsError ? 1 : 0,
|
||||||
StringId == LCR.WELCOME ? LCR.BROADCAST : StringId
|
StringId
|
||||||
);
|
);
|
||||||
|
|
||||||
foreach(object arg in Arguments)
|
foreach(object arg in Arguments)
|
||||||
sb.AppendFormat("\f{0}", arg);
|
sb.AppendFormat("\f{0}", arg);
|
||||||
|
|
||||||
sb.Append('\t');
|
sb.AppendFormat("\t{0}\t10010", SequenceId);
|
||||||
|
|
||||||
if(StringId == LCR.WELCOME)
|
|
||||||
sb.AppendFormat("{0}\t0", StringId);
|
|
||||||
else
|
|
||||||
sb.Append(SequenceId);
|
|
||||||
|
|
||||||
sb.Append("\t10010");
|
|
||||||
|
|
||||||
return sb.ToString();
|
return sb.ToString();
|
||||||
}
|
}
|
||||||
|
@ -55,12 +38,8 @@ namespace SharpChat.Packet {
|
||||||
|
|
||||||
// Abbreviated class name because otherwise shit gets wide
|
// Abbreviated class name because otherwise shit gets wide
|
||||||
public static class LCR {
|
public static class LCR {
|
||||||
public const string GENERIC_ERROR = "generr";
|
|
||||||
public const string COMMAND_NOT_FOUND = "nocmd";
|
|
||||||
public const string COMMAND_NOT_ALLOWED = "cmdna";
|
public const string COMMAND_NOT_ALLOWED = "cmdna";
|
||||||
public const string COMMAND_FORMAT_ERROR = "cmderr";
|
public const string COMMAND_FORMAT_ERROR = "cmderr";
|
||||||
public const string WELCOME = "welcome";
|
|
||||||
public const string BROADCAST = "say";
|
|
||||||
public const string IP_ADDRESS = "ipaddr";
|
public const string IP_ADDRESS = "ipaddr";
|
||||||
public const string USER_NOT_FOUND = "usernf";
|
public const string USER_NOT_FOUND = "usernf";
|
||||||
public const string NAME_IN_USE = "nameinuse";
|
public const string NAME_IN_USE = "nameinuse";
|
||||||
|
|
20
SharpChat/Packet/MOTDPacket.cs
Normal file
20
SharpChat/Packet/MOTDPacket.cs
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
using System;
|
||||||
|
|
||||||
|
namespace SharpChat.Packet {
|
||||||
|
public class MOTDPacket : ServerPacket {
|
||||||
|
private readonly long Timestamp;
|
||||||
|
private readonly string Body;
|
||||||
|
|
||||||
|
public MOTDPacket(string body) {
|
||||||
|
Timestamp = DateTimeOffset.Now.ToUnixTimeSeconds();
|
||||||
|
Body = body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override string Pack() {
|
||||||
|
return string.Format(
|
||||||
|
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t0\fsay\f{1}\twelcome\t0\t10010",
|
||||||
|
Timestamp, SharpUtil.Sanitise(Body)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -35,14 +35,14 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
string? authMethod = args.ElementAtOrDefault(1);
|
string? authMethod = args.ElementAtOrDefault(1);
|
||||||
if(string.IsNullOrWhiteSpace(authMethod)) {
|
if(string.IsNullOrWhiteSpace(authMethod)) {
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.AuthInvalid));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
string? authToken = args.ElementAtOrDefault(2);
|
string? authToken = args.ElementAtOrDefault(2);
|
||||||
if(string.IsNullOrWhiteSpace(authToken)) {
|
if(string.IsNullOrWhiteSpace(authToken)) {
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.AuthInvalid));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -61,7 +61,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
fai = await Misuzu.AuthVerifyAsync(authMethod, authToken, ipAddr);
|
fai = await Misuzu.AuthVerifyAsync(authMethod, authToken, ipAddr);
|
||||||
} catch(Exception ex) {
|
} catch(Exception ex) {
|
||||||
Logger.Write($"<{ctx.Connection.Id}> Failed to authenticate: {ex}");
|
Logger.Write($"<{ctx.Connection.Id}> Failed to authenticate: {ex}");
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.AuthInvalid));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw;
|
throw;
|
||||||
|
@ -72,14 +72,14 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
if(fai == null) {
|
if(fai == null) {
|
||||||
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: <null>");
|
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: <null>");
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.Null));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.Null));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!fai.Success) {
|
if(!fai.Success) {
|
||||||
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: {fai.Reason}");
|
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: {fai.Reason}");
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.AuthInvalid));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -89,7 +89,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
fbi = await Misuzu.CheckBanAsync(fai.UserId.ToString(), ipAddr);
|
fbi = await Misuzu.CheckBanAsync(fai.UserId.ToString(), ipAddr);
|
||||||
} catch(Exception ex) {
|
} catch(Exception ex) {
|
||||||
Logger.Write($"<{ctx.Connection.Id}> Failed auth ban check: {ex}");
|
Logger.Write($"<{ctx.Connection.Id}> Failed auth ban check: {ex}");
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.AuthInvalid));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
throw;
|
throw;
|
||||||
|
@ -100,7 +100,7 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
if(fbi == null) {
|
if(fbi == null) {
|
||||||
Logger.Debug($"<{ctx.Connection.Id}> Ban check fail: <null>");
|
Logger.Debug($"<{ctx.Connection.Id}> Ban check fail: <null>");
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.Null));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.Null));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -137,21 +137,21 @@ namespace SharpChat.PacketHandlers {
|
||||||
|
|
||||||
// Enforce a maximum amount of connections per user
|
// Enforce a maximum amount of connections per user
|
||||||
if(ctx.Chat.Connections.Count(conn => conn.User == user) >= MaxConnections) {
|
if(ctx.Chat.Connections.Count(conn => conn.User == user) >= MaxConnections) {
|
||||||
ctx.Connection.Send(new AuthFailPacket(AuthFailReason.MaxSessions));
|
ctx.Connection.Send(new AuthFailPacket(AuthFailPacket.FailReason.MaxSessions));
|
||||||
ctx.Connection.Dispose();
|
ctx.Connection.Dispose();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Connection.BumpPing();
|
ctx.Connection.BumpPing();
|
||||||
ctx.Connection.User = user;
|
ctx.Connection.User = user;
|
||||||
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, $"Welcome to Flashii Chat, {user.UserName}!"));
|
ctx.Connection.Send(new MOTDPacket($"Welcome to Flashii Chat, {user.UserName}!"));
|
||||||
|
|
||||||
if(File.Exists("welcome.txt")) {
|
if(File.Exists("welcome.txt")) {
|
||||||
IEnumerable<string> lines = File.ReadAllLines("welcome.txt").Where(x => !string.IsNullOrWhiteSpace(x));
|
IEnumerable<string> lines = File.ReadAllLines("welcome.txt").Where(x => !string.IsNullOrWhiteSpace(x));
|
||||||
string? line = lines.ElementAtOrDefault(RNG.Next(lines.Count()));
|
string? line = lines.ElementAtOrDefault(RNG.Next(lines.Count()));
|
||||||
|
|
||||||
if(!string.IsNullOrWhiteSpace(line))
|
if(!string.IsNullOrWhiteSpace(line))
|
||||||
ctx.Connection.Send(new LegacyCommandResponse(LCR.WELCOME, false, line));
|
ctx.Connection.Send(new MOTDPacket(line));
|
||||||
}
|
}
|
||||||
|
|
||||||
ctx.Chat.HandleJoin(user, DefaultChannel, ctx.Connection, MaxMessageLength);
|
ctx.Chat.HandleJoin(user, DefaultChannel, ctx.Connection, MaxMessageLength);
|
||||||
|
|
|
@ -6,9 +6,11 @@ namespace SharpChat {
|
||||||
private const long EPOCH = 1588377600000;
|
private const long EPOCH = 1588377600000;
|
||||||
private static int Counter = 0;
|
private static int Counter = 0;
|
||||||
|
|
||||||
public static long Next()
|
public static long Next() {
|
||||||
=> ((DateTimeOffset.Now.ToUnixTimeMilliseconds() - EPOCH) << 8)
|
long num = DateTimeOffset.Now.ToUnixTimeMilliseconds() - EPOCH;
|
||||||
| (ushort)(Interlocked.Increment(ref Counter) & 0xFFFF);
|
num <<= 8;
|
||||||
|
num |= (ushort)(Interlocked.Increment(ref Counter) & 0xFFFF);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
10
SharpChat/SharpUtil.cs
Normal file
10
SharpChat/SharpUtil.cs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
namespace SharpChat {
|
||||||
|
public static class SharpUtil {
|
||||||
|
public static string Sanitise(string? body) {
|
||||||
|
if(string.IsNullOrEmpty(body))
|
||||||
|
return string.Empty;
|
||||||
|
|
||||||
|
return body.Replace("<", "<").Replace(">", ">").Replace("\n", " <br/> ").Replace("\t", " ");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in a new issue