public async Task HandleClientLogin(ClientLoginInfoPacket packet, Connection connection)
        {
            await using var ctx = new NovaContext();

            var account = await ctx.Accounts.FirstOrDefaultAsync(a => a.Username == packet.Username);

            if (account == default)
            {
                await ctx.Accounts.AddAsync(new Account
                {
                    Username = packet.Username,
                    Hash     = BCrypt.Net.BCrypt.EnhancedHashPassword(packet.Password)
                });

                await ctx.SaveChangesAsync();

                Logger.Information($"Created new account: {packet.Username}");

                connection.Send(new ClientLoginReplyPacket
                {
                    ResultCode    = LoginResultCode.Success,
                    NewServerIp   = "127.0.0.1",
                    NewServerPort = 2002
                });

                return;
            }

            if (!BCrypt.Net.BCrypt.EnhancedVerify(packet.Password, account.Hash))
            {
                connection.Send(new ClientLoginReplyPacket
                {
                    ResultCode    = LoginResultCode.IncorrectInfo,
                    NewServerIp   = "127.0.0.1",
                    NewServerPort = 1001
                });

                Logger.Information($"{packet.Username} failed to login");

                return;
            }

            connection.Send(new ClientLoginReplyPacket
            {
                ResultCode    = LoginResultCode.Success,
                NewServerIp   = "127.0.0.1",
                NewServerPort = 2002
            });
        }
Exemple #2
0
        public async Task LoginRequestHandler(ClientLoginInfoPacket packet, IRakConnection connection)
        {
            await using var ctx = new UchuContext();

            var info = new ServerLoginInfoPacket
            {
                CharacterInstanceAddress = Server.GetHost(),
                CharacterInstancePort    = ushort.MaxValue,
                ChatInstanceAddress      = Server.GetHost(),
                ChatInstancePort         = 2004
            };

            var characterSpecification = await ServerHelper.GetServerByType(ServerType.Character);

            if (characterSpecification == default)
            {
                info.LoginCode = LoginCode.InsufficientPermissions;
                info.Error     = new ServerLoginInfoPacket.ErrorMessage
                {
                    Message = "No character server instance is running. Please try again later."
                };
            }
            else
            {
                info.CharacterInstancePort = (ushort)characterSpecification.Port;

                if (!await ctx.Users.AnyAsync(u => u.Username == packet.Username))
                {
                    info.LoginCode = LoginCode.InsufficientPermissions;
                    info.Error     = new ServerLoginInfoPacket.ErrorMessage
                    {
                        Message = "We have no records of that Username and Password combination. Please try again."
                    };
                }
                else
                {
                    var user = await ctx.Users.SingleAsync(u => u.Username == packet.Username);

                    if (user != null && BCrypt.Net.BCrypt.EnhancedVerify(packet.Password, user.Password))
                    {
                        if (user.Banned)
                        {
                            info.LoginCode = LoginCode.InsufficientPermissions;
                            info.Error     = new ServerLoginInfoPacket.ErrorMessage
                            {
                                Message = $"This account has been banned by an admin. Reason:\n{user.BannedReason ?? "Unknown"}"
                            };
                        }
                        else if (!string.IsNullOrWhiteSpace(user.CustomLockout))
                        {
                            info.LoginCode = LoginCode.InsufficientPermissions;
                            info.Error     = new ServerLoginInfoPacket.ErrorMessage
                            {
                                Message = user.CustomLockout
                            };
                        }
                        else
                        {
                            var key = Server.SessionCache.CreateSession(user.UserId);

                            info.LoginCode = LoginCode.Success;
                            info.UserKey   = key;

                            //
                            // I don't intend, nor do I see anyone else, using these.
                            // Except maybe FirstTimeOnSubscription for the fancy screen.
                            //

                            info.FreeToPlay = user.FreeToPlay;
                            info.FirstLoginWithSubscription = user.FirstTimeOnSubscription;

                            //
                            // No longer the first time on subscription
                            //

                            user.FirstTimeOnSubscription = false;

                            await ctx.SaveChangesAsync();
                        }
                    }
                    else
                    {
                        info.LoginCode = LoginCode.InsufficientPermissions;
                        info.Error     = new ServerLoginInfoPacket.ErrorMessage
                        {
                            Message = "We have no records of that Username and Password combination. Please try again."
                        };
                    }
                }
            }

            connection.Send(info);
        }
Exemple #3
0
        public async Task LoginRequestHandler(ClientLoginInfoPacket packet, IRakConnection connection)
        {
            await using var ctx = new UchuContext();

            var info = new ServerLoginInfoPacket
            {
                CharacterInstanceAddress = UchuServer.Host,
                CharacterInstancePort    = ushort.MaxValue,
                ChatInstanceAddress      = UchuServer.Host,
                ChatInstancePort         = 2004
            };

            var characterSpecification = await UchuServer.Api.RunCommandAsync <InstanceInfoResponse>(
                UchuServer.MasterApi, $"instance/basic?t={(int) ServerType.Character}"
                ).ConfigureAwait(false);

            if (!characterSpecification.Success)
            {
                Logger.Error(characterSpecification.FailedReason);

                info.LoginCode = LoginCode.InsufficientPermissions;
                info.Error     = new ErrorMessage
                {
                    Message = "No character server instance is running. Please try again later."
                };
            }
            else
            {
                info.CharacterInstancePort = (ushort)characterSpecification.Info.Port;

                if (!await ctx.Users.AnyAsync(u => string.Equals(u.Username.ToUpper(), packet.Username.ToUpper()) && !u.Sso))
                {
                    info.LoginCode = LoginCode.InsufficientPermissions;
                    info.Error     = new ErrorMessage
                    {
                        Message = "We have no records of that Username and Password combination. Please try again."
                    };
                }
                else
                {
                    var user = await ctx.Users.FirstAsync(u => string.Equals(u.Username.ToUpper(), packet.Username.ToUpper()) && !u.Sso);

                    if (user != null && BCrypt.Net.BCrypt.EnhancedVerify(packet.Password, user.Password))
                    {
                        if (user.Banned)
                        {
                            info.LoginCode = LoginCode.InsufficientPermissions;
                            info.Error     = new ErrorMessage
                            {
                                Message = $"This account has been banned by an admin. Reason:\n{user.BannedReason ?? "Unknown"}"
                            };
                        }
                        else if (!string.IsNullOrWhiteSpace(user.CustomLockout))
                        {
                            info.LoginCode = LoginCode.InsufficientPermissions;
                            info.Error     = new ErrorMessage
                            {
                                Message = user.CustomLockout
                            };
                        }
                        else
                        {
                            var key = UchuServer.SessionCache.CreateSession(user.Id);

                            info.LoginCode = LoginCode.Success;
                            info.UserKey   = key;

                            //
                            // I don't intend, nor do I see anyone else, using these.
                            // Except maybe FirstTimeOnSubscription for the fancy screen.
                            //

                            info.FreeToPlay = user.FreeToPlay;
                            info.FirstLoginWithSubscription = user.FirstTimeOnSubscription;

                            //
                            // No longer the first time on subscription
                            //

                            user.FirstTimeOnSubscription = false;

                            await ctx.SaveChangesAsync();
                        }
                    }
                    else
                    {
                        info.LoginCode = LoginCode.InsufficientPermissions;
                        info.Error     = new ErrorMessage
                        {
                            Message = "We have no records of that Username and Password combination. Please try again."
                        };
                    }
                }
            }

            connection.Send(info);
        }