Cleaned up S2C packet classes.
This commit is contained in:
parent
9f283e48fe
commit
b8ec381f3b
19 changed files with 130 additions and 203 deletions
SharpChat
C2SPacketHandlers
ChatContext.csCommands
S2CPackets
AuthFailS2CPacket.csBanListS2CPacket.csChannelDeleteS2CPacket.csChannelUpdateS2CPacket.csChatMessageAddS2CPacket.csChatMessageDeleteS2CPacket.csCommandResponseS2CPacket.csContextChannelsS2CPacket.csContextClearS2CPacket.csContextMessageS2CPacket.csContextUsersS2CPacket.csForceDisconnectS2CPacket.csUserChannelForceJoinS2CPacket.csUserChannelLeaveS2CPacket.csUserDisconnectS2CPacket.cs
SockChatServer.cs
|
@ -23,14 +23,14 @@ namespace SharpChat.C2SPacketHandlers {
|
|||
|
||||
string? authMethod = args.ElementAtOrDefault(1);
|
||||
if(string.IsNullOrWhiteSpace(authMethod)) {
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailReason.AuthInvalid));
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailS2CPacket.Reason.AuthInvalid));
|
||||
ctx.Connection.Dispose();
|
||||
return;
|
||||
}
|
||||
|
||||
string? authToken = args.ElementAtOrDefault(2);
|
||||
if(string.IsNullOrWhiteSpace(authToken)) {
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailReason.AuthInvalid));
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailS2CPacket.Reason.AuthInvalid));
|
||||
ctx.Connection.Dispose();
|
||||
return;
|
||||
}
|
||||
|
@ -49,7 +49,7 @@ namespace SharpChat.C2SPacketHandlers {
|
|||
fai = await Misuzu.AuthVerifyAsync(authMethod, authToken, ipAddr);
|
||||
} catch(Exception ex) {
|
||||
Logger.Write($"<{ctx.Connection.Id}> Failed to authenticate: {ex}");
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailReason.AuthInvalid));
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailS2CPacket.Reason.AuthInvalid));
|
||||
ctx.Connection.Dispose();
|
||||
#if DEBUG
|
||||
throw;
|
||||
|
@ -60,7 +60,7 @@ namespace SharpChat.C2SPacketHandlers {
|
|||
|
||||
if(fai?.Success != true) {
|
||||
Logger.Debug($"<{ctx.Connection.Id}> Auth fail: {fai?.Reason ?? "unknown"}");
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailReason.AuthInvalid));
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailS2CPacket.Reason.AuthInvalid));
|
||||
ctx.Connection.Dispose();
|
||||
return;
|
||||
}
|
||||
|
@ -70,7 +70,7 @@ namespace SharpChat.C2SPacketHandlers {
|
|||
fbi = await Misuzu.CheckBanAsync(fai.UserId.ToString(), ipAddr);
|
||||
} catch(Exception ex) {
|
||||
Logger.Write($"<{ctx.Connection.Id}> Failed auth ban check: {ex}");
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailReason.AuthInvalid));
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailS2CPacket.Reason.AuthInvalid));
|
||||
ctx.Connection.Dispose();
|
||||
#if DEBUG
|
||||
throw;
|
||||
|
@ -81,7 +81,7 @@ namespace SharpChat.C2SPacketHandlers {
|
|||
|
||||
if(fbi?.IsBanned == true && !fbi.HasExpired) {
|
||||
Logger.Write($"<{ctx.Connection.Id}> User is banned.");
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailReason.Banned, fbi));
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailS2CPacket.Reason.Banned, fbi.IsPermanent ? DateTimeOffset.MaxValue : fbi.ExpiresAt));
|
||||
ctx.Connection.Dispose();
|
||||
return;
|
||||
}
|
||||
|
@ -109,7 +109,7 @@ namespace SharpChat.C2SPacketHandlers {
|
|||
|
||||
// Enforce a maximum amount of connections per user
|
||||
if(ctx.Chat.Connections.Count(conn => conn.User == user) >= MaxConnections) {
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailReason.MaxSessions));
|
||||
ctx.Connection.Send(new AuthFailS2CPacket(AuthFailS2CPacket.Reason.MaxSessions));
|
||||
ctx.Connection.Dispose();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -93,7 +93,7 @@ namespace SharpChat {
|
|||
|
||||
foreach(ChatUser user in Users)
|
||||
if(!Connections.Any(conn => conn.User == user)) {
|
||||
HandleDisconnect(user, UserDisconnectReason.TimeOut);
|
||||
HandleDisconnect(user, UserDisconnectS2CPacket.Reason.TimeOut);
|
||||
Logger.Write($"Timed out {user} (no more connections).");
|
||||
}
|
||||
}
|
||||
|
@ -191,12 +191,12 @@ namespace SharpChat {
|
|||
}
|
||||
}
|
||||
|
||||
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectReason reason = UserDisconnectReason.Kicked) {
|
||||
public void BanUser(ChatUser user, TimeSpan duration, UserDisconnectS2CPacket.Reason reason = UserDisconnectS2CPacket.Reason.Kicked) {
|
||||
if(duration > TimeSpan.Zero) {
|
||||
DateTimeOffset expires = duration >= TimeSpan.MaxValue ? DateTimeOffset.MaxValue : DateTimeOffset.Now + duration;
|
||||
SendTo(user, new ForceDisconnectS2CPacket(ForceDisconnectReason.Banned, expires));
|
||||
SendTo(user, new ForceDisconnectS2CPacket(expires));
|
||||
} else
|
||||
SendTo(user, new ForceDisconnectS2CPacket(ForceDisconnectReason.Kicked));
|
||||
SendTo(user, new ForceDisconnectS2CPacket());
|
||||
|
||||
foreach(ChatConnection conn in Connections)
|
||||
if(conn.User == user)
|
||||
|
@ -248,7 +248,7 @@ namespace SharpChat {
|
|||
UserLastChannel[user.UserId] = chan;
|
||||
}
|
||||
|
||||
public void HandleDisconnect(ChatUser user, UserDisconnectReason reason = UserDisconnectReason.Leave) {
|
||||
public void HandleDisconnect(ChatUser user, UserDisconnectS2CPacket.Reason reason = UserDisconnectS2CPacket.Reason.Leave) {
|
||||
UpdateUser(user, status: ChatUserStatus.Offline);
|
||||
Users.Remove(user);
|
||||
UserLastChannel.Remove(user.UserId);
|
||||
|
@ -259,7 +259,7 @@ namespace SharpChat {
|
|||
ChannelUsers.Remove(new ChannelUserAssoc(user.UserId, chan.Name));
|
||||
|
||||
long msgId = RandomSnowflake.Next();
|
||||
SendTo(chan, new UserDisconnectS2CPacket(msgId, DateTimeOffset.Now, user, reason));
|
||||
SendTo(chan, new UserDisconnectS2CPacket(msgId, DateTimeOffset.Now, user.UserId, user.LegacyNameWithStatus, reason));
|
||||
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);
|
||||
|
||||
if(chan.IsTemporary && chan.IsOwner(user))
|
||||
|
@ -297,14 +297,14 @@ namespace SharpChat {
|
|||
ChatChannel oldChan = UserLastChannel[user.UserId];
|
||||
|
||||
long leaveId = RandomSnowflake.Next();
|
||||
SendTo(oldChan, new UserChannelLeaveS2CPacket(leaveId, user));
|
||||
SendTo(oldChan, new UserChannelLeaveS2CPacket(leaveId, user.UserId));
|
||||
Events.AddEvent(leaveId, "chan:leave", oldChan.Name, user.UserId, user.UserName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
|
||||
|
||||
long joinId = RandomSnowflake.Next();
|
||||
SendTo(chan, new UserChannelJoinS2CPacket(joinId, user.UserId, user.LegacyNameWithStatus, user.Colour, user.Rank, user.Permissions));
|
||||
Events.AddEvent(joinId, "chan:join", chan.Name, user.UserId, user.LegacyName, user.Colour, user.Rank, user.NickName, user.Permissions, null, StoredEventFlags.Log);
|
||||
|
||||
SendTo(user, new ContextClearS2CPacket(ContextClearMode.MessagesUsers));
|
||||
SendTo(user, new ContextClearS2CPacket(ContextClearS2CPacket.Mode.MessagesUsers));
|
||||
SendTo(user, new ContextUsersS2CPacket(
|
||||
GetChannelUsers(chan).Except([user]).OrderByDescending(u => u.Rank)
|
||||
.Select(u => new ContextUsersS2CPacket.Entry(
|
||||
|
@ -377,7 +377,7 @@ namespace SharpChat {
|
|||
if(chan == null && !UserLastChannel.TryGetValue(user.UserId, out chan))
|
||||
throw new ArgumentException("no channel???");
|
||||
|
||||
SendTo(user, new UserChannelForceJoinS2CPacket(chan));
|
||||
SendTo(user, new UserChannelForceJoinS2CPacket(chan.Name));
|
||||
}
|
||||
|
||||
public void UpdateChannel(ChatChannel channel, bool? temporary = null, int? hierarchy = null, string? password = null) {
|
||||
|
@ -417,7 +417,7 @@ namespace SharpChat {
|
|||
|
||||
// Broadcast deletion of channel
|
||||
foreach(ChatUser user in Users.Where(u => u.Rank >= channel.Rank))
|
||||
SendTo(user, new ChannelDeleteS2CPacket(channel));
|
||||
SendTo(user, new ChannelDeleteS2CPacket(channel.Name));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -19,12 +19,18 @@ namespace SharpChat.Commands {
|
|||
}
|
||||
|
||||
Task.Run(async () => {
|
||||
MisuzuBanInfo[]? mbi = await Misuzu.GetBanListAsync();
|
||||
|
||||
if(mbi is null)
|
||||
MisuzuBanInfo[]? mbis = await Misuzu.GetBanListAsync();
|
||||
if(mbis is null)
|
||||
ctx.Chat.SendTo(ctx.User, new CommandResponseS2CPacket(msgId, LCR.GENERIC_ERROR, true));
|
||||
else
|
||||
ctx.Chat.SendTo(ctx.User, new BanListS2CPacket(msgId, mbi));
|
||||
ctx.Chat.SendTo(ctx.User, new BanListS2CPacket(
|
||||
msgId,
|
||||
mbis.Where(mbi => mbi.IsBanned && !mbi.HasExpired)
|
||||
.Select(mbi => new BanListS2CPacket.Entry(
|
||||
BanListS2CPacket.Type.UserName, // Misuzu currently only does username bans so we can just do this
|
||||
mbi.UserName ?? $"({mbi.UserId})"
|
||||
))
|
||||
));
|
||||
}).Wait();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,52 +1,38 @@
|
|||
using SharpChat.Misuzu;
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public enum AuthFailReason {
|
||||
AuthInvalid,
|
||||
MaxSessions,
|
||||
Banned,
|
||||
}
|
||||
|
||||
public class AuthFailS2CPacket : S2CPacket {
|
||||
public AuthFailReason Reason { get; private set; }
|
||||
public MisuzuBanInfo? BanInfo { get; private set; }
|
||||
|
||||
public AuthFailS2CPacket(AuthFailReason reason, MisuzuBanInfo? fbi = null) {
|
||||
Reason = reason;
|
||||
|
||||
if(reason == AuthFailReason.Banned)
|
||||
BanInfo = fbi ?? throw new ArgumentNullException(nameof(fbi));
|
||||
public class AuthFailS2CPacket(
|
||||
AuthFailS2CPacket.Reason reason,
|
||||
DateTimeOffset? expiresAt = null
|
||||
) : S2CPacket {
|
||||
public enum Reason {
|
||||
AuthInvalid,
|
||||
MaxSessions,
|
||||
Banned,
|
||||
}
|
||||
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('1');
|
||||
sb.Append("\tn\t");
|
||||
sb.Append("1\tn\t");
|
||||
|
||||
switch(Reason) {
|
||||
case AuthFailReason.AuthInvalid:
|
||||
switch(reason) {
|
||||
case Reason.AuthInvalid:
|
||||
default:
|
||||
sb.Append("authfail");
|
||||
break;
|
||||
case AuthFailReason.MaxSessions:
|
||||
case Reason.MaxSessions:
|
||||
sb.Append("sockfail");
|
||||
break;
|
||||
case AuthFailReason.Banned:
|
||||
sb.Append("joinfail");
|
||||
case Reason.Banned:
|
||||
sb.Append("joinfail\t");
|
||||
if(expiresAt is null || expiresAt == DateTimeOffset.MaxValue)
|
||||
sb.Append("-1");
|
||||
else
|
||||
sb.Append(expiresAt.Value.ToUnixTimeSeconds());
|
||||
break;
|
||||
}
|
||||
|
||||
if(Reason == AuthFailReason.Banned) {
|
||||
sb.Append('\t');
|
||||
|
||||
if(BanInfo?.IsPermanent == true)
|
||||
sb.Append("-1");
|
||||
else
|
||||
sb.Append(BanInfo?.ExpiresAt.ToUnixTimeSeconds() ?? 0);
|
||||
}
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,29 +1,28 @@
|
|||
using SharpChat.Misuzu;
|
||||
using System.Text;
|
||||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public class BanListS2CPacket(
|
||||
long msgId,
|
||||
IEnumerable<MisuzuBanInfo> bans
|
||||
IEnumerable<BanListS2CPacket.Entry> entries
|
||||
) : S2CPacket {
|
||||
public IEnumerable<MisuzuBanInfo> Bans { get; private set; } = bans ?? throw new ArgumentNullException(nameof(bans));
|
||||
public enum Type {
|
||||
UserName,
|
||||
IPAddress,
|
||||
}
|
||||
|
||||
public record Entry(Type type, string value);
|
||||
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('2');
|
||||
sb.Append('\t');
|
||||
sb.Append("2\t");
|
||||
sb.Append(DateTimeOffset.Now.ToUnixTimeSeconds());
|
||||
sb.Append("\t-1\t0\fbanlist\f");
|
||||
|
||||
foreach(MisuzuBanInfo ban in Bans) {
|
||||
string banStr = string.IsNullOrEmpty(ban.UserName) ? (ban.RemoteAddress ?? "::") : (ban.UserName ?? $"({ban.UserId})");
|
||||
sb.AppendFormat(@"<a href=""javascript:void(0);"" onclick=""Chat.SendMessageWrapper('/unban '+ this.innerHTML);"">{0}</a>, ", banStr);
|
||||
}
|
||||
|
||||
if(Bans.Any())
|
||||
sb.Length -= 2;
|
||||
|
||||
sb.Append(string.Join(", ", entries.Select(entry => string.Format(
|
||||
@"<a href=""javascript:void(0);"" onclick=""Chat.SendMessageWrapper('{0} '+ this.innerHTML);"">{1}</a>",
|
||||
entry.type == Type.IPAddress ? "/unbanip" : "/unban",
|
||||
entry.value
|
||||
))));
|
||||
sb.Append('\t');
|
||||
sb.Append(msgId);
|
||||
sb.Append("\t10010");
|
||||
|
|
|
@ -1,17 +1,14 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public class ChannelDeleteS2CPacket(ChatChannel channel) : S2CPacket {
|
||||
public ChatChannel Channel { get; private set; } = channel ?? throw new ArgumentNullException(nameof(channel));
|
||||
|
||||
public class ChannelDeleteS2CPacket(
|
||||
string channelName
|
||||
) : S2CPacket {
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('4');
|
||||
sb.Append('\t');
|
||||
sb.Append('2');
|
||||
sb.Append('\t');
|
||||
sb.Append(Channel.Name);
|
||||
sb.Append("4\t2\t");
|
||||
sb.Append(channelName);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
|
|
@ -10,10 +10,7 @@ namespace SharpChat.S2CPackets {
|
|||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('4');
|
||||
sb.Append('\t');
|
||||
sb.Append('1');
|
||||
sb.Append('\t');
|
||||
sb.Append("4\t1\t");
|
||||
sb.Append(previousName);
|
||||
sb.Append('\t');
|
||||
sb.Append(newName);
|
||||
|
|
|
@ -9,13 +9,10 @@ namespace SharpChat.S2CPackets {
|
|||
bool isAction,
|
||||
bool isPrivate
|
||||
) : S2CPacket {
|
||||
public string Text { get; } = text ?? throw new ArgumentNullException(nameof(text));
|
||||
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('2');
|
||||
sb.Append('\t');
|
||||
sb.Append("2\t");
|
||||
|
||||
sb.Append(created.ToUnixTimeSeconds());
|
||||
sb.Append('\t');
|
||||
|
@ -27,7 +24,7 @@ namespace SharpChat.S2CPackets {
|
|||
sb.Append("<i>");
|
||||
|
||||
sb.Append(
|
||||
Text.Replace("<", "<")
|
||||
text.Replace("<", "<")
|
||||
.Replace(">", ">")
|
||||
.Replace("\n", " <br/> ")
|
||||
.Replace("\t", " ")
|
||||
|
|
|
@ -5,8 +5,7 @@ namespace SharpChat.S2CPackets {
|
|||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('6');
|
||||
sb.Append('\t');
|
||||
sb.Append("6\t");
|
||||
sb.Append(eventId);
|
||||
|
||||
return sb.ToString();
|
||||
|
|
|
@ -7,28 +7,22 @@ namespace SharpChat.S2CPackets {
|
|||
bool isError = true,
|
||||
params object[] args
|
||||
) : S2CPacket {
|
||||
public string StringId { get; private set; } = stringId ?? throw new ArgumentNullException(nameof(stringId));
|
||||
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
if(StringId == LCR.WELCOME) {
|
||||
sb.Append('7');
|
||||
sb.Append('\t');
|
||||
sb.Append('1');
|
||||
sb.Append('\t');
|
||||
if(stringId == LCR.WELCOME) {
|
||||
sb.Append("7\t1\t");
|
||||
sb.Append(DateTimeOffset.Now.ToUnixTimeSeconds());
|
||||
sb.Append("\t-1\tChatBot\tinherit\t\t");
|
||||
} else {
|
||||
sb.Append('2');
|
||||
sb.Append('\t');
|
||||
sb.Append("2\t");
|
||||
sb.Append(DateTimeOffset.Now.ToUnixTimeSeconds());
|
||||
sb.Append("\t-1\t");
|
||||
}
|
||||
|
||||
sb.Append(isError ? '1' : '0');
|
||||
sb.Append('\f');
|
||||
sb.Append(StringId == LCR.WELCOME ? LCR.BROADCAST : StringId);
|
||||
sb.Append(stringId == LCR.WELCOME ? LCR.BROADCAST : stringId);
|
||||
|
||||
if(args.Length > 0)
|
||||
foreach(object arg in args) {
|
||||
|
@ -38,8 +32,8 @@ namespace SharpChat.S2CPackets {
|
|||
|
||||
sb.Append('\t');
|
||||
|
||||
if(StringId == LCR.WELCOME) {
|
||||
sb.Append(StringId);
|
||||
if(stringId == LCR.WELCOME) {
|
||||
sb.Append(stringId);
|
||||
sb.Append("\t0");
|
||||
} else
|
||||
sb.Append(msgId);
|
||||
|
|
|
@ -7,10 +7,7 @@ namespace SharpChat.S2CPackets {
|
|||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('7');
|
||||
sb.Append('\t');
|
||||
sb.Append('2');
|
||||
sb.Append('\t');
|
||||
sb.Append("7\t2\t");
|
||||
sb.Append(entries.Count());
|
||||
|
||||
foreach(Entry entry in entries) {
|
||||
|
|
|
@ -1,20 +1,19 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public enum ContextClearMode {
|
||||
Messages = 0,
|
||||
Users = 1,
|
||||
Channels = 2,
|
||||
MessagesUsers = 3,
|
||||
MessagesUsersChannels = 4,
|
||||
}
|
||||
public class ContextClearS2CPacket(ContextClearS2CPacket.Mode mode) : S2CPacket {
|
||||
public enum Mode {
|
||||
Messages = 0,
|
||||
Users = 1,
|
||||
Channels = 2,
|
||||
MessagesUsers = 3,
|
||||
MessagesUsersChannels = 4,
|
||||
}
|
||||
|
||||
public class ContextClearS2CPacket(ContextClearMode mode) : S2CPacket {
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('8');
|
||||
sb.Append('\t');
|
||||
sb.Append("8\t");
|
||||
sb.Append((int)mode);
|
||||
|
||||
return sb.ToString();
|
||||
|
|
|
@ -6,8 +6,6 @@ namespace SharpChat.S2CPackets
|
|||
public class ContextMessageS2CPacket(StoredEventInfo evt, bool notify = false) : S2CPacket {
|
||||
public StoredEventInfo Event { get; private set; } = evt ?? throw new ArgumentNullException(nameof(evt));
|
||||
|
||||
private const string V1_CHATBOT = "-1\tChatBot\tinherit\t\t";
|
||||
|
||||
public string Pack() {
|
||||
bool isAction = Event.Flags.HasFlag(StoredEventFlags.Action);
|
||||
bool isBroadcast = Event.Flags.HasFlag(StoredEventFlags.Broadcast);
|
||||
|
@ -15,10 +13,7 @@ namespace SharpChat.S2CPackets
|
|||
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('7');
|
||||
sb.Append('\t');
|
||||
sb.Append('1');
|
||||
sb.Append('\t');
|
||||
sb.Append("7\t1\t");
|
||||
sb.Append(Event.Created.ToUnixTimeSeconds());
|
||||
sb.Append('\t');
|
||||
|
||||
|
@ -26,8 +21,7 @@ namespace SharpChat.S2CPackets
|
|||
case "msg:add":
|
||||
case "SharpChat.Events.ChatMessage":
|
||||
if(isBroadcast || Event.Sender is null) {
|
||||
sb.Append(V1_CHATBOT);
|
||||
sb.Append("0\fsay\f");
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\fsay\f");
|
||||
} else {
|
||||
sb.Append(Event.Sender.UserId);
|
||||
sb.Append('\t');
|
||||
|
@ -64,41 +58,37 @@ namespace SharpChat.S2CPackets
|
|||
|
||||
case "user:connect":
|
||||
case "SharpChat.Events.UserConnectEvent":
|
||||
sb.Append(V1_CHATBOT);
|
||||
sb.Append("0\fjoin\f");
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\fjoin\f");
|
||||
sb.Append(Event.Sender?.LegacyName ?? "?????");
|
||||
break;
|
||||
|
||||
case "chan:join":
|
||||
case "SharpChat.Events.UserChannelJoinEvent":
|
||||
sb.Append(V1_CHATBOT);
|
||||
sb.Append("0\fjchan\f");
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\fjchan\f");
|
||||
sb.Append(Event.Sender?.LegacyName ?? "?????");
|
||||
break;
|
||||
|
||||
case "chan:leave":
|
||||
case "SharpChat.Events.UserChannelLeaveEvent":
|
||||
sb.Append(V1_CHATBOT);
|
||||
sb.Append("0\flchan\f");
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\flchan\f");
|
||||
sb.Append(Event.Sender?.LegacyName ?? "?????");
|
||||
break;
|
||||
|
||||
case "user:disconnect":
|
||||
case "SharpChat.Events.UserDisconnectEvent":
|
||||
sb.Append(V1_CHATBOT);
|
||||
sb.Append("0\f");
|
||||
sb.Append("-1\tChatBot\tinherit\t\t0\f");
|
||||
|
||||
switch((UserDisconnectReason)Event.Data.RootElement.GetProperty("reason").GetByte()) {
|
||||
case UserDisconnectReason.Flood:
|
||||
switch((UserDisconnectS2CPacket.Reason)Event.Data.RootElement.GetProperty("reason").GetByte()) {
|
||||
case UserDisconnectS2CPacket.Reason.Flood:
|
||||
sb.Append("flood");
|
||||
break;
|
||||
case UserDisconnectReason.Kicked:
|
||||
case UserDisconnectS2CPacket.Reason.Kicked:
|
||||
sb.Append("kick");
|
||||
break;
|
||||
case UserDisconnectReason.TimeOut:
|
||||
case UserDisconnectS2CPacket.Reason.TimeOut:
|
||||
sb.Append("timeout");
|
||||
break;
|
||||
case UserDisconnectReason.Leave:
|
||||
case UserDisconnectS2CPacket.Reason.Leave:
|
||||
default:
|
||||
sb.Append("leave");
|
||||
break;
|
||||
|
|
|
@ -7,10 +7,7 @@ namespace SharpChat.S2CPackets {
|
|||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('7');
|
||||
sb.Append('\t');
|
||||
sb.Append('0');
|
||||
sb.Append('\t');
|
||||
sb.Append("7\t0\t");
|
||||
sb.Append(entries.Count());
|
||||
|
||||
foreach(Entry entry in entries) {
|
||||
|
|
|
@ -1,40 +1,21 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public enum ForceDisconnectReason {
|
||||
Kicked = 0,
|
||||
Banned = 1,
|
||||
}
|
||||
|
||||
public class ForceDisconnectS2CPacket : S2CPacket {
|
||||
public ForceDisconnectReason Reason { get; private set; }
|
||||
public DateTimeOffset Expires { get; private set; }
|
||||
|
||||
public ForceDisconnectS2CPacket(ForceDisconnectReason reason, DateTimeOffset? expires = null) {
|
||||
Reason = reason;
|
||||
|
||||
if(reason == ForceDisconnectReason.Banned) {
|
||||
if(!expires.HasValue)
|
||||
throw new ArgumentNullException(nameof(expires));
|
||||
Expires = expires.Value;
|
||||
}
|
||||
}
|
||||
|
||||
public class ForceDisconnectS2CPacket(DateTimeOffset? expires = null) : S2CPacket {
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('9');
|
||||
sb.Append('\t');
|
||||
sb.Append((int)Reason);
|
||||
sb.Append("9\t");
|
||||
|
||||
if(Reason == ForceDisconnectReason.Banned) {
|
||||
sb.Append('\t');
|
||||
if(Expires.Year >= 2100)
|
||||
sb.Append("-1");
|
||||
if(expires.HasValue && expires.Value > DateTimeOffset.UtcNow) {
|
||||
sb.Append("1\t");
|
||||
if(expires.Value < DateTimeOffset.MaxValue)
|
||||
sb.Append(expires.Value.ToUnixTimeSeconds());
|
||||
else
|
||||
sb.Append(Expires.ToUnixTimeSeconds());
|
||||
}
|
||||
|
||||
sb.Append("-1");
|
||||
} else
|
||||
sb.Append('0');
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public class UserChannelForceJoinS2CPacket(ChatChannel channel) : S2CPacket {
|
||||
public ChatChannel Channel { get; private set; } = channel ?? throw new ArgumentNullException(nameof(channel));
|
||||
|
||||
public class UserChannelForceJoinS2CPacket(string channelName) : S2CPacket {
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('5');
|
||||
sb.Append('\t');
|
||||
sb.Append('2');
|
||||
sb.Append('\t');
|
||||
sb.Append(Channel.Name);
|
||||
sb.Append("5\t2\t");
|
||||
sb.Append(channelName);
|
||||
|
||||
return sb.ToString();
|
||||
}
|
||||
|
|
|
@ -1,17 +1,12 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public class UserChannelLeaveS2CPacket(long msgId, ChatUser user) : S2CPacket {
|
||||
public ChatUser User { get; private set; } = user ?? throw new ArgumentNullException(nameof(user));
|
||||
|
||||
public class UserChannelLeaveS2CPacket(long msgId, long userId) : S2CPacket {
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('5');
|
||||
sb.Append('\t');
|
||||
sb.Append('1');
|
||||
sb.Append('\t');
|
||||
sb.Append(User.UserId);
|
||||
sb.Append("5\t1\t");
|
||||
sb.Append(userId);
|
||||
sb.Append('\t');
|
||||
sb.Append(msgId);
|
||||
|
||||
|
|
|
@ -1,43 +1,41 @@
|
|||
using System.Text;
|
||||
|
||||
namespace SharpChat.S2CPackets {
|
||||
public enum UserDisconnectReason {
|
||||
Leave,
|
||||
TimeOut,
|
||||
Kicked,
|
||||
Flood,
|
||||
}
|
||||
|
||||
public class UserDisconnectS2CPacket(
|
||||
long msgId,
|
||||
DateTimeOffset disconnected,
|
||||
ChatUser user,
|
||||
UserDisconnectReason reason
|
||||
long userId,
|
||||
string userName,
|
||||
UserDisconnectS2CPacket.Reason reason
|
||||
) : S2CPacket {
|
||||
public ChatUser User { get; private set; } = user ?? throw new ArgumentNullException(nameof(user));
|
||||
public enum Reason {
|
||||
Leave,
|
||||
TimeOut,
|
||||
Kicked,
|
||||
Flood,
|
||||
}
|
||||
|
||||
public string Pack() {
|
||||
StringBuilder sb = new();
|
||||
|
||||
sb.Append('3');
|
||||
sb.Append("3\t");
|
||||
sb.Append(userId);
|
||||
sb.Append('\t');
|
||||
sb.Append(User.UserId);
|
||||
sb.Append('\t');
|
||||
sb.Append(User.LegacyNameWithStatus);
|
||||
sb.Append(userName);
|
||||
sb.Append('\t');
|
||||
|
||||
switch(reason) {
|
||||
case UserDisconnectReason.Leave:
|
||||
case Reason.Leave:
|
||||
default:
|
||||
sb.Append("leave");
|
||||
break;
|
||||
case UserDisconnectReason.TimeOut:
|
||||
case Reason.TimeOut:
|
||||
sb.Append("timeout");
|
||||
break;
|
||||
case UserDisconnectReason.Kicked:
|
||||
case Reason.Kicked:
|
||||
sb.Append("kick");
|
||||
break;
|
||||
case UserDisconnectReason.Flood:
|
||||
case Reason.Flood:
|
||||
sb.Append("flood");
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -181,7 +181,7 @@ namespace SharpChat {
|
|||
if(banDuration == TimeSpan.MinValue) {
|
||||
Context.SendTo(conn.User, new CommandResponseS2CPacket(Context.RandomSnowflake.Next(), LCR.FLOOD_WARN, false));
|
||||
} else {
|
||||
Context.BanUser(conn.User, banDuration, UserDisconnectReason.Flood);
|
||||
Context.BanUser(conn.User, banDuration, UserDisconnectS2CPacket.Reason.Flood);
|
||||
|
||||
if(banDuration > TimeSpan.Zero)
|
||||
Misuzu.CreateBanAsync(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue