122 lines
5.8 KiB
C#
122 lines
5.8 KiB
C#
using SharpChat.Bans;
|
|
using SharpChat.Channels;
|
|
using SharpChat.Messages;
|
|
using SharpChat.Protocol.SockChat.Packets;
|
|
using SharpChat.Sessions;
|
|
using SharpChat.Users;
|
|
using SharpChat.Users.Remote;
|
|
using System;
|
|
using System.Linq;
|
|
|
|
namespace SharpChat.Protocol.SockChat.PacketHandlers {
|
|
public class AuthPacketHandler : IPacketHandler {
|
|
public ClientPacketId PacketId => ClientPacketId.Authenticate;
|
|
|
|
private SockChatServer Server { get; }
|
|
private SessionManager Sessions { get; }
|
|
private UserManager Users { get; }
|
|
private ChannelManager Channels { get; }
|
|
private ChannelUserRelations ChannelUsers { get; }
|
|
private MessageManager Messages { get; }
|
|
private IRemoteUserClient RemoteUserClient { get; }
|
|
private BanManager Bans { get; }
|
|
private IUser Sender { get; }
|
|
private WelcomeMessage WelcomeMessage { get; }
|
|
|
|
public AuthPacketHandler(
|
|
SockChatServer server,
|
|
SessionManager sessions,
|
|
UserManager users,
|
|
ChannelManager channels,
|
|
ChannelUserRelations channelUsers,
|
|
MessageManager messages,
|
|
IRemoteUserClient remoteUserClient,
|
|
BanManager bans,
|
|
IUser sender,
|
|
WelcomeMessage welcomeMessage
|
|
) {
|
|
Server = server ?? throw new ArgumentNullException(nameof(server));
|
|
Sessions = sessions ?? throw new ArgumentNullException(nameof(sessions));
|
|
Users = users ?? throw new ArgumentNullException(nameof(users));
|
|
Channels = channels ?? throw new ArgumentNullException(nameof(channels));
|
|
ChannelUsers = channelUsers ?? throw new ArgumentNullException(nameof(channelUsers));
|
|
Messages = messages ?? throw new ArgumentNullException(nameof(messages));
|
|
RemoteUserClient = remoteUserClient ?? throw new ArgumentNullException(nameof(remoteUserClient));
|
|
Bans = bans ?? throw new ArgumentNullException(nameof(bans));
|
|
Sender = sender ?? throw new ArgumentNullException(nameof(sender));
|
|
WelcomeMessage = welcomeMessage ?? throw new ArgumentNullException(nameof(welcomeMessage));
|
|
}
|
|
|
|
public void HandlePacket(PacketHandlerContext ctx) {
|
|
if(ctx.HasSession)
|
|
return;
|
|
|
|
if(!long.TryParse(ctx.Args.ElementAtOrDefault(1), out long userId) || userId < 1)
|
|
return;
|
|
|
|
string token = ctx.Args.ElementAtOrDefault(2);
|
|
if(string.IsNullOrEmpty(token))
|
|
return;
|
|
|
|
Action<Exception> exceptionHandler = new(ex => {
|
|
Logger.Debug($@"[{ctx.Connection}] Auth fail: {ex.Message}");
|
|
ctx.Connection.SendPacket(new AuthFailPacket(AuthFailReason.AuthInvalid));
|
|
ctx.Connection.Close();
|
|
});
|
|
|
|
RemoteUserClient.AuthenticateUser(
|
|
new UserAuthRequest(userId, token, ctx.Connection.RemoteAddress),
|
|
res => {
|
|
Bans.CheckBan(res, ctx.Connection.RemoteAddress, ban => {
|
|
if(ban.IsPermanent || ban.Expires > DateTimeOffset.Now) {
|
|
ctx.Connection.SendPacket(new AuthFailPacket(AuthFailReason.Banned, ban));
|
|
ctx.Connection.Close();
|
|
return;
|
|
}
|
|
|
|
Users.Connect(res, user => {
|
|
Sessions.HasAvailableSessions(user, available => {
|
|
if(!available) {
|
|
ctx.Connection.SendPacket(new AuthFailPacket(AuthFailReason.MaxSessions));
|
|
ctx.Connection.Close();
|
|
return;
|
|
}
|
|
|
|
Sessions.Create(ctx.Connection, user, session => {
|
|
// TODO: !!!!!!!!!!!!!!!!
|
|
ctx.Connection.Session = session;
|
|
session.Connection = ctx.Connection;
|
|
|
|
string welcome = Server.WelcomeMessage;
|
|
if(!string.IsNullOrWhiteSpace(welcome))
|
|
ctx.Connection.SendPacket(new WelcomeMessagePacket(Sender, welcome.Replace(@"{username}", user.UserName)));
|
|
|
|
if(WelcomeMessage.HasRandom) {
|
|
string line = WelcomeMessage.GetRandomString();
|
|
if(!string.IsNullOrWhiteSpace(line))
|
|
ctx.Connection.SendPacket(new WelcomeMessagePacket(Sender, line));
|
|
}
|
|
|
|
Channels.GetDefaultChannels(channels => {
|
|
if(!channels.Any())
|
|
return; // what do, this is impossible
|
|
|
|
// other channels should be joined if MCHAN has been received
|
|
IChannel firstChan = channels.FirstOrDefault();
|
|
|
|
ctx.Connection.LastChannel = firstChan;
|
|
ctx.Connection.SendPacket(new AuthSuccessPacket(user, firstChan, session, Messages.TextMaxLength));
|
|
|
|
Channels.GetChannels(user.Rank, c => ctx.Connection.SendPacket(new ContextChannelsPacket(c)));
|
|
ChannelUsers.JoinChannel(firstChan, session);
|
|
});
|
|
});
|
|
});
|
|
});
|
|
}, exceptionHandler);
|
|
},
|
|
exceptionHandler
|
|
);
|
|
}
|
|
}
|
|
}
|