Simplified packet building.

This commit is contained in:
flash 2024-05-10 17:28:52 +00:00
parent 1ba94a526c
commit 356409eb16
29 changed files with 234 additions and 431 deletions

4
.editorconfig Normal file
View file

@ -0,0 +1,4 @@
[*.{cs,vb}]
# IDE0046: Convert to conditional expression
dotnet_style_prefer_conditional_expression_over_return = false

View file

@ -127,7 +127,7 @@ Response to client packet `0`: Ping.
<table>
<tr>
<td><code>string</code></td>
<td>Any arbitrary string, do not rely on the data sent here. Original Sock Chat server sent <code>pong</code>, SharpChat currently sends the current Unix epoch timestamp in seconds.</td>
<td>A string containing <code>pong</code>. Previously SharpChat sent the current Unix timestamp here, but has since been updated to conform to the Original Sock Chat server formatting.</td>
</tr>
</table>

View file

@ -7,6 +7,7 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SharpChat", "SharpChat\Shar
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{DF7A7073-A67A-4D93-92C6-F9D0F95E2359}"
ProjectSection(SolutionItems) = preProject
.editorconfig = .editorconfig
.gitattributes = .gitattributes
.gitignore = .gitignore
LICENSE = LICENSE

View file

@ -1,6 +1,5 @@
using System;
using System.Linq;
using System.Text;
namespace SharpChat {
public class ChatChannel {
@ -35,18 +34,6 @@ namespace SharpChat {
OwnerId = ownerId;
}
public string Pack() {
StringBuilder sb = new();
sb.Append(Name);
sb.Append('\t');
sb.Append(string.IsNullOrEmpty(Password) ? '0' : '1');
sb.Append('\t');
sb.Append(IsTemporary ? '1' : '0');
return sb.ToString();
}
public bool NameEquals(string name) {
return string.Equals(name, Name, StringComparison.InvariantCultureIgnoreCase);
}

View file

@ -199,9 +199,9 @@ namespace SharpChat {
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
if(duration > TimeSpan.Zero) {
DateTimeOffset expires = duration >= TimeSpan.MaxValue ? DateTimeOffset.MaxValue : DateTimeOffset.Now + duration;
SendTo(user, new ForceDisconnectPacket(ForceDisconnectReason.Banned, expires));
SendTo(user, new ForceDisconnectPacket(expires));
} else
SendTo(user, new ForceDisconnectPacket(ForceDisconnectReason.Kicked));
SendTo(user, new ForceDisconnectPacket());
foreach(ChatConnection conn in Connections)
if(conn.User == user)

View file

@ -51,6 +51,7 @@ namespace SharpChat {
NickName = nickName ?? string.Empty;
Status = status;
StatusText = statusText ?? string.Empty;
IsSuper = isSuper;
}
public bool Can(ChatUserPermissions perm, bool strict = false) {
@ -58,30 +59,6 @@ namespace SharpChat {
return strict ? perms == perm : perms > 0;
}
public string Pack() {
StringBuilder sb = new();
sb.Append(UserId);
sb.Append('\t');
sb.Append(LegacyNameWithStatus);
sb.Append('\t');
sb.Append(Colour);
sb.Append('\t');
sb.Append(Rank);
sb.Append(' ');
sb.Append(Can(ChatUserPermissions.KickUser) ? '1' : '0');
sb.Append(' ');
sb.Append(Can(ChatUserPermissions.ViewLogs) ? '1' : '0');
sb.Append(' ');
sb.Append(Can(ChatUserPermissions.SetOwnNickname) ? '1' : '0');
sb.Append(' ');
sb.Append(Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? '2' : (
Can(ChatUserPermissions.CreateChannel) ? '1' : '0'
));
return sb.ToString();
}
public bool NameEquals(string name) {
return string.Equals(name, UserName, StringComparison.InvariantCultureIgnoreCase)
|| string.Equals(name, NickName, StringComparison.InvariantCultureIgnoreCase)

View file

@ -1,6 +1,5 @@
using SharpChat.Misuzu;
using System;
using System.Text;
namespace SharpChat.Packet {
public enum AuthFailReason {
@ -21,34 +20,17 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
string packet = string.Format("1\tn\t{0}fail", Reason switch {
AuthFailReason.AuthInvalid => "auth",
AuthFailReason.MaxSessions => "sock",
AuthFailReason.Banned => "join",
_ => "user",
});
sb.Append('1');
sb.Append("\tn\t");
if(Reason == AuthFailReason.Banned)
packet += string.Format("\t{0}", BanInfo.IsPermanent ? -1 : BanInfo.ExpiresAt.ToUnixTimeSeconds());
switch(Reason) {
case AuthFailReason.AuthInvalid:
default:
sb.Append("authfail");
break;
case AuthFailReason.MaxSessions:
sb.Append("sockfail");
break;
case AuthFailReason.Banned:
sb.Append("joinfail");
break;
}
if(Reason == AuthFailReason.Banned) {
sb.Append('\t');
if(BanInfo.IsPermanent)
sb.Append("-1");
else
sb.Append(BanInfo.ExpiresAt.ToUnixTimeSeconds());
}
return sb.ToString();
return packet;
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class AuthSuccessPacket : ServerPacket {
@ -21,17 +20,21 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('1');
sb.Append("\ty\t");
sb.Append(User.Pack());
sb.Append('\t');
sb.Append(Channel.Name);
sb.Append('\t');
sb.Append(MaxMessageLength);
return sb.ToString();
return string.Format(
"1\ty\t{0}\t{1}\t{2}\t{3} {4} {5} {6} {7}\t{8}\t{9}",
User.UserId,
User.LegacyNameWithStatus,
User.Colour,
User.Rank,
User.Can(ChatUserPermissions.KickUser) ? 1 : 0,
User.Can(ChatUserPermissions.ViewLogs) ? 1 : 0,
User.Can(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
User.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? 2 : (
User.Can(ChatUserPermissions.CreateChannel) ? 1 : 0
),
Channel.Name,
MaxMessageLength
);
}
}
}

View file

@ -15,10 +15,7 @@ namespace SharpChat.Packet {
public override string Pack() {
StringBuilder sb = new();
sb.Append('2');
sb.Append('\t');
sb.Append(DateTimeOffset.Now.ToUnixTimeSeconds());
sb.Append("\t-1\t0\fbanlist\f");
sb.AppendFormat("2\t{0}\t-1\t0\fbanlist\f", DateTimeOffset.Now.ToUnixTimeSeconds());
foreach(MisuzuBanInfo ban in Bans) {
string banStr = string.IsNullOrEmpty(ban.UserName) ? ban.RemoteAddress : ban.UserName;
@ -28,9 +25,7 @@ namespace SharpChat.Packet {
if(Bans.Any())
sb.Length -= 2;
sb.Append('\t');
sb.Append(SequenceId);
sb.Append("\t10010");
sb.AppendFormat("\t{0}\t10010", SequenceId);
return sb.ToString();
}

View file

@ -1,6 +1,4 @@
using System.Text;
namespace SharpChat.Packet {
namespace SharpChat.Packet {
public class ChannelCreatePacket : ServerPacket {
public ChatChannel Channel { get; private set; }
@ -9,15 +7,12 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('4');
sb.Append('\t');
sb.Append('0');
sb.Append('\t');
sb.Append(Channel.Pack());
return sb.ToString();
return string.Format(
"4\t0\t{0}\t{1}\t{2}",
Channel.Name,
Channel.HasPassword ? 1 : 0,
Channel.IsTemporary ? 1 : 0
);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class ChannelDeletePacket : ServerPacket {
@ -10,15 +9,7 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('4');
sb.Append('\t');
sb.Append('2');
sb.Append('\t');
sb.Append(Channel.Name);
return sb.ToString();
return string.Format("4\t2\t{0}", Channel.Name);
}
}
}

View file

@ -1,6 +1,4 @@
using System.Text;
namespace SharpChat.Packet {
namespace SharpChat.Packet {
public class ChannelUpdatePacket : ServerPacket {
public string PreviousName { get; private set; }
public ChatChannel Channel { get; private set; }
@ -11,17 +9,13 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('4');
sb.Append('\t');
sb.Append('1');
sb.Append('\t');
sb.Append(PreviousName);
sb.Append('\t');
sb.Append(Channel.Pack());
return sb.ToString();
return string.Format(
"4\t1\t{0}\t{1}\t{2}\t{3}",
PreviousName,
Channel.Name,
Channel.HasPassword ? 1 : 0,
Channel.IsTemporary ? 1 : 0
);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class ChatMessageAddPacket : ServerPacket {
@ -25,40 +24,22 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('2');
sb.Append('\t');
sb.Append(Created.ToUnixTimeSeconds());
sb.Append('\t');
sb.Append(UserId);
sb.Append('\t');
string body = Text.Replace("<", "&lt;").Replace(">", "&gt;").Replace("\n", " <br/> ").Replace("\t", " ");
if(IsAction)
sb.Append("<i>");
body = string.Format("<i>{0}</i>", body);
sb.Append(
Text.Replace("<", "&lt;")
.Replace(">", "&gt;")
.Replace("\n", " <br/> ")
.Replace("\t", " ")
return string.Format(
"2\t{0}\t{1}\t{2}\t{3}\t{4}{5}{6}{7}{8}",
Created.ToUnixTimeSeconds(),
UserId,
body,
SequenceId,
1,
IsAction ? 1 : 0,
0,
IsAction ? 0 : 1,
IsPrivate ? 1 : 0
);
if(IsAction)
sb.Append("</i>");
sb.Append('\t');
sb.Append(SequenceId);
sb.AppendFormat(
"\t1{0}0{1}{2}",
IsAction ? '1' : '0',
IsAction ? '0' : '1',
IsPrivate ? '1' : '0'
);
return sb.ToString();
}
}
}

View file

@ -1,6 +1,4 @@
using System.Text;
namespace SharpChat.Packet {
namespace SharpChat.Packet {
public class ChatMessageDeletePacket : ServerPacket {
public long EventId { get; private set; }
@ -9,13 +7,7 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('6');
sb.Append('\t');
sb.Append(EventId);
return sb.ToString();
return string.Format("6\t{0}", EventId);
}
}
}

View file

@ -14,16 +14,15 @@ namespace SharpChat.Packet {
public override string Pack() {
StringBuilder sb = new();
sb.Append('7');
sb.Append('\t');
sb.Append('2');
sb.Append('\t');
sb.Append(Channels.Count());
sb.AppendFormat("7\t2\t{0}", Channels.Count());
foreach(ChatChannel channel in Channels) {
sb.Append('\t');
sb.Append(channel.Pack());
}
foreach(ChatChannel channel in Channels)
sb.AppendFormat(
"\t{0}\t{1}\t{2}",
channel.Name,
channel.HasPassword ? 1 : 0,
channel.IsTemporary ? 1 : 0
);
return sb.ToString();
}

View file

@ -1,6 +1,4 @@
using System.Text;
namespace SharpChat.Packet {
namespace SharpChat.Packet {
public enum ContextClearMode {
Messages = 0,
Users = 1,
@ -22,13 +20,7 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('8');
sb.Append('\t');
sb.Append((int)Mode);
return sb.ToString();
return string.Format("8\t{0}", (int)Mode);
}
}
}

View file

@ -12,7 +12,7 @@ namespace SharpChat.Packet {
Notify = notify;
}
private const string V1_CHATBOT = "-1\tChatBot\tinherit\t\t";
private const string V1_CHATBOT = "-1\tChatBot\tinherit\t";
public override string Pack() {
bool isAction = Event.Flags.HasFlag(StoredEventFlags.Action);
@ -21,95 +21,82 @@ namespace SharpChat.Packet {
StringBuilder sb = new();
sb.Append('7');
sb.Append('\t');
sb.Append('1');
sb.Append('\t');
sb.Append(Event.Created.ToUnixTimeSeconds());
sb.Append('\t');
sb.AppendFormat("7\t1\t{0}\t", Event.Created.ToUnixTimeSeconds());
switch(Event.Type) {
case "msg:add":
case "SharpChat.Events.ChatMessage":
if(isBroadcast) {
sb.Append(V1_CHATBOT);
sb.Append("0\fsay\f");
} else {
sb.Append(Event.Sender.Pack());
sb.Append('\t');
sb.AppendFormat(
"{0}\t{1}\t{2}\t{3} {4} {5} {6} {7}",
Event.Sender.UserId,
Event.Sender.LegacyNameWithStatus,
Event.Sender.Colour,
Event.Sender.Rank,
Event.Sender.Can(ChatUserPermissions.KickUser) ? 1 : 0,
Event.Sender.Can(ChatUserPermissions.ViewLogs) ? 1 : 0,
Event.Sender.Can(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
Event.Sender.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? 2 : (
Event.Sender.Can(ChatUserPermissions.CreateChannel) ? 1 : 0
)
);
}
if(isAction)
sb.Append("<i>");
sb.Append('\t');
sb.Append(
Event.Data.RootElement.GetProperty("text").GetString()
.Replace("<", "&lt;")
.Replace(">", "&gt;")
.Replace("\n", " <br/> ")
.Replace("\t", " ")
);
if(isBroadcast)
sb.Append("0\fsay\f");
string body = Event.Data.RootElement.GetProperty("text").GetString().Replace("<", "&lt;").Replace(">", "&gt;").Replace("\n", " <br/> ").Replace("\t", " ");
if(isAction)
sb.Append("</i>");
body = string.Format("<i>{0}</i>", body);
sb.Append(body);
break;
case "user:connect":
case "SharpChat.Events.UserConnectEvent":
sb.Append(V1_CHATBOT);
sb.Append("0\fjoin\f");
sb.Append(Event.Sender.LegacyName);
sb.AppendFormat("{0}\t0\fjoin\f{1}", V1_CHATBOT, Event.Sender.LegacyName);
break;
case "chan:join":
case "SharpChat.Events.UserChannelJoinEvent":
sb.Append(V1_CHATBOT);
sb.Append("0\fjchan\f");
sb.Append(Event.Sender.LegacyName);
sb.AppendFormat("{0}\t0\fjchan\f{1}", V1_CHATBOT, Event.Sender.LegacyName);
break;
case "chan:leave":
case "SharpChat.Events.UserChannelLeaveEvent":
sb.Append(V1_CHATBOT);
sb.Append("0\flchan\f");
sb.Append(Event.Sender.LegacyName);
sb.AppendFormat("{0}\t0\flchan\f{1}", V1_CHATBOT, Event.Sender.LegacyName);
break;
case "user:disconnect":
case "SharpChat.Events.UserDisconnectEvent":
sb.Append(V1_CHATBOT);
sb.Append("0\f");
switch((UserDisconnectReason)Event.Data.RootElement.GetProperty("reason").GetByte()) {
case UserDisconnectReason.Flood:
sb.Append("flood");
break;
case UserDisconnectReason.Kicked:
sb.Append("kick");
break;
case UserDisconnectReason.TimeOut:
sb.Append("timeout");
break;
case UserDisconnectReason.Leave:
default:
sb.Append("leave");
break;
}
sb.Append('\f');
sb.Append(Event.Sender.LegacyName);
sb.AppendFormat(
"{0}\t0\f{1}\f{2}",
V1_CHATBOT,
(UserDisconnectReason)Event.Data.RootElement.GetProperty("reason").GetByte() switch {
UserDisconnectReason.Flood => "flood",
UserDisconnectReason.Kicked => "kick",
UserDisconnectReason.TimeOut => "timeout",
UserDisconnectReason.Leave => "leave",
_ => "leave",
},
Event.Sender.LegacyName
);
break;
}
sb.Append('\t');
sb.Append(Event.Id < 1 ? SequenceId : Event.Id);
sb.Append('\t');
sb.Append(Notify ? '1' : '0');
sb.AppendFormat(
"\t1{0}0{1}{2}",
isAction ? '1' : '0',
isAction ? '0' : '1',
isPrivate ? '1' : '0'
"\t{0}\t{1}\t{2}{3}{4}{5}{6}",
Event.Id < 1 ? SequenceId : Event.Id,
Notify ? 1 : 0,
1,
isAction ? 1 : 0,
0,
isAction ? 0 : 1,
isPrivate ? 1 : 0
);
return sb.ToString();

View file

@ -14,18 +14,23 @@ namespace SharpChat.Packet {
public override string Pack() {
StringBuilder sb = new();
sb.Append('7');
sb.Append('\t');
sb.Append('0');
sb.Append('\t');
sb.Append(Users.Count());
sb.AppendFormat("7\t0\t{0}", Users.Count());
foreach(ChatUser user in Users) {
sb.Append('\t');
sb.Append(user.Pack());
sb.Append('\t');
sb.Append('1'); // visibility flag
}
foreach(ChatUser user in Users)
sb.AppendFormat(
"\t{0}\t{1}\t{2}\t{3} {4} {5} {6} {7}\t{8}",
user.UserId,
user.LegacyNameWithStatus,
user.Colour,
user.Rank,
user.Can(ChatUserPermissions.KickUser) ? 1 : 0,
user.Can(ChatUserPermissions.ViewLogs) ? 1 : 0,
user.Can(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
user.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? 2 : (
user.Can(ChatUserPermissions.CreateChannel) ? 1 : 0
),
1 // visibility flag
);
return sb.ToString();
}

View file

@ -1,42 +1,21 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public enum ForceDisconnectReason {
Kicked = 0,
Banned = 1,
}
public class ForceDisconnectPacket : ServerPacket {
public ForceDisconnectReason Reason { get; private set; }
public DateTimeOffset Expires { get; private set; }
public DateTimeOffset? Expires { get; private set; }
public ForceDisconnectPacket(ForceDisconnectReason reason, DateTimeOffset? expires = null) {
Reason = reason;
if(reason == ForceDisconnectReason.Banned) {
if(!expires.HasValue)
throw new ArgumentNullException(nameof(expires));
Expires = expires.Value;
}
public ForceDisconnectPacket(DateTimeOffset? expires = null) {
Expires = expires;
}
public override string Pack() {
StringBuilder sb = new();
if(Expires.HasValue)
return string.Format(
"9\t1\t{0}",
Expires.Value.Year >= 2100 ? -1 : Expires.Value.ToUnixTimeSeconds()
);
sb.Append('9');
sb.Append('\t');
sb.Append((int)Reason);
if(Reason == ForceDisconnectReason.Banned) {
sb.Append('\t');
if(Expires.Year >= 2100)
sb.Append("-1");
else
sb.Append(Expires.ToUnixTimeSeconds());
}
return sb.ToString();
return "9\t0";
}
}
}

View file

@ -22,45 +22,35 @@ namespace SharpChat.Packet {
public override string Pack() {
StringBuilder sb = new();
if(StringId == LCR.WELCOME) {
sb.Append('7');
sb.Append('\t');
sb.Append('1');
sb.Append('\t');
sb.Append(DateTimeOffset.Now.ToUnixTimeSeconds());
sb.Append("\t-1\tChatBot\tinherit\t\t");
} else {
sb.Append('2');
sb.Append('\t');
sb.Append(DateTimeOffset.Now.ToUnixTimeSeconds());
sb.Append("\t-1\t");
}
if(StringId == LCR.WELCOME)
sb.AppendFormat(
"7\t1\t{0}\t-1\tChatBot\tinherit\t\t",
DateTimeOffset.Now.ToUnixTimeSeconds()
);
else
sb.AppendFormat(
"2\t{0}\t-1\t",
DateTimeOffset.Now.ToUnixTimeSeconds()
);
sb.Append(IsError ? '1' : '0');
sb.Append('\f');
sb.Append(StringId == LCR.WELCOME ? LCR.BROADCAST : StringId);
sb.AppendFormat(
"{0}\f{1}",
IsError ? 1 : 0,
StringId == LCR.WELCOME ? LCR.BROADCAST : StringId
);
if(Arguments?.Any() == true)
foreach(object arg in Arguments) {
sb.Append('\f');
sb.Append(arg);
}
foreach(object arg in Arguments)
sb.AppendFormat("\f{0}", arg);
sb.Append('\t');
if(StringId == LCR.WELCOME) {
sb.Append(StringId);
sb.Append("\t0");
} else
if(StringId == LCR.WELCOME)
sb.AppendFormat("{0}\t0", StringId);
else
sb.Append(SequenceId);
sb.Append("\t10010");
/*sb.AppendFormat(
"\t1{0}0{1}{2}",
Flags.HasFlag(ChatMessageFlags.Action) ? '1' : '0',
Flags.HasFlag(ChatMessageFlags.Action) ? '0' : '1',
Flags.HasFlag(ChatMessageFlags.Private) ? '1' : '0'
);*/
return sb.ToString();
}

View file

@ -1,22 +1,7 @@
using System;
using System.Text;
namespace SharpChat.Packet {
namespace SharpChat.Packet {
public class PongPacket : ServerPacket {
public DateTimeOffset PongTime { get; private set; }
public PongPacket(DateTimeOffset dto) {
PongTime = dto;
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('0');
sb.Append('\t');
sb.Append(PongTime.ToUnixTimeSeconds());
return sb.ToString();
return "0\tpong";
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class UserChannelForceJoinPacket : ServerPacket {
@ -10,15 +9,7 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('5');
sb.Append('\t');
sb.Append('2');
sb.Append('\t');
sb.Append(Channel.Name);
return sb.ToString();
return string.Format("5\t2\t{0}", Channel.Name);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class UserChannelJoinPacket : ServerPacket {
@ -10,17 +9,20 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('5');
sb.Append('\t');
sb.Append('0');
sb.Append('\t');
sb.Append(User.Pack());
sb.Append('\t');
sb.Append(SequenceId);
return sb.ToString();
return string.Format(
"5\t0\t{0}\t{1}\t{2}\t{3} {4} {5} {6} {7}\t{8}",
User.UserId,
User.LegacyNameWithStatus,
User.Colour,
User.Rank,
User.Can(ChatUserPermissions.KickUser) ? 1 : 0,
User.Can(ChatUserPermissions.ViewLogs) ? 1 : 0,
User.Can(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
User.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? 2 : (
User.Can(ChatUserPermissions.CreateChannel) ? 1 : 0
),
SequenceId
);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class UserChannelLeavePacket : ServerPacket {
@ -10,17 +9,7 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('5');
sb.Append('\t');
sb.Append('1');
sb.Append('\t');
sb.Append(User.UserId);
sb.Append('\t');
sb.Append(SequenceId);
return sb.ToString();
return string.Format("5\t1\t{0}\t{1}", User.UserId, SequenceId);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class UserConnectPacket : ServerPacket {
@ -12,17 +11,21 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('1');
sb.Append('\t');
sb.Append(Joined.ToUnixTimeSeconds());
sb.Append('\t');
sb.Append(User.Pack());
sb.Append('\t');
sb.Append(SequenceId);
return sb.ToString();
return string.Format(
"1\t{0}\t{1}\t{2}\t{3}\t{4} {5} {6} {7} {8}\t{9}",
Joined.ToUnixTimeSeconds(),
User.UserId,
User.LegacyNameWithStatus,
User.Colour,
User.Rank,
User.Can(ChatUserPermissions.KickUser) ? 1 : 0,
User.Can(ChatUserPermissions.ViewLogs) ? 1 : 0,
User.Can(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
User.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? 2 : (
User.Can(ChatUserPermissions.CreateChannel) ? 1 : 0
),
SequenceId
);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public enum UserDisconnectReason {
@ -21,37 +20,20 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('3');
sb.Append('\t');
sb.Append(User.UserId);
sb.Append('\t');
sb.Append(User.LegacyNameWithStatus);
sb.Append('\t');
switch(Reason) {
case UserDisconnectReason.Leave:
default:
sb.Append("leave");
break;
case UserDisconnectReason.TimeOut:
sb.Append("timeout");
break;
case UserDisconnectReason.Kicked:
sb.Append("kick");
break;
case UserDisconnectReason.Flood:
sb.Append("flood");
break;
}
sb.Append('\t');
sb.Append(Disconnected.ToUnixTimeSeconds());
sb.Append('\t');
sb.Append(SequenceId);
return sb.ToString();
return string.Format(
"3\t{0}\t{1}\t{2}\t{3}\t{4}",
User.UserId,
User.LegacyNameWithStatus,
Reason switch {
UserDisconnectReason.Leave => "leave",
UserDisconnectReason.TimeOut => "timeout",
UserDisconnectReason.Kicked => "kick",
UserDisconnectReason.Flood => "flood",
_ => "leave",
},
Disconnected.ToUnixTimeSeconds(),
SequenceId
);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class UserUpdateNotificationPacket : ServerPacket {
@ -14,20 +13,13 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append('2');
sb.Append('\t');
sb.Append(Timestamp.ToUnixTimeSeconds());
sb.Append("\t-1\t0\fnick\f");
sb.Append(PreviousName);
sb.Append('\f');
sb.Append(NewName);
sb.Append('\t');
sb.Append(SequenceId);
sb.Append("\t10010");
return sb.ToString();
return string.Format(
"2\t{0}\t-1\t0\fnick\f{1}\f{2}\t{3}\t10010",
Timestamp.ToUnixTimeSeconds(),
PreviousName,
NewName,
SequenceId
);
}
}
}

View file

@ -1,5 +1,4 @@
using System;
using System.Text;
namespace SharpChat.Packet {
public class UserUpdatePacket : ServerPacket {
@ -10,13 +9,19 @@ namespace SharpChat.Packet {
}
public override string Pack() {
StringBuilder sb = new();
sb.Append("10");
sb.Append('\t');
sb.Append(User.Pack());
return sb.ToString();
return string.Format(
"10\t{0}\t{1}\t{2}\t{3} {4} {5} {6} {7}",
User.UserId,
User.LegacyNameWithStatus,
User.Colour,
User.Rank,
User.Can(ChatUserPermissions.KickUser) ? 1 : 0,
User.Can(ChatUserPermissions.ViewLogs) ? 1 : 0,
User.Can(ChatUserPermissions.SetOwnNickname) ? 1 : 0,
User.Can(ChatUserPermissions.CreateChannel | ChatUserPermissions.SetChannelPermanent, true) ? 2 : (
User.Can(ChatUserPermissions.CreateChannel) ? 1 : 0
)
);
}
}
}

View file

@ -26,7 +26,7 @@ namespace SharpChat.PacketHandlers {
return;
ctx.Connection.BumpPing();
ctx.Connection.Send(new PongPacket(ctx.Connection.LastPing));
ctx.Connection.Send(new PongPacket());
ctx.Chat.ContextAccess.Wait();
try {