public async Task <LoginCheckerResponse> DoLogin(Login login, string ip) { await semaphore.WaitAsync(); try { var userID = login.UserID; var lobbyVersion = login.LobbyVersion; using (var db = new ZkDataContext()) { if (!VerifyIp(ip)) { return(new LoginCheckerResponse(LoginResponse.Code.BannedTooManyConnectionAttempts)); } SteamWebApi.PlayerInfo info = null; if (!string.IsNullOrEmpty(login.SteamAuthToken)) { info = await server.SteamWebApi.VerifyAndGetAccountInformation(login.SteamAuthToken); if (info == null) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.InvalidSteamToken)); } } Account accBySteamID = null; Account accByLogin = null; if (info != null) { accBySteamID = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.SteamID == info.steamid); } if (!string.IsNullOrEmpty(login.Name)) { var loginToUpper = login.Name.ToUpper(); accByLogin = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name) ?? db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name.ToUpper() == loginToUpper); } if (accBySteamID == null) { if (accByLogin == null) { LogIpFailure(ip); if (!string.IsNullOrEmpty(login.Name)) { return(new LoginCheckerResponse(LoginResponse.Code.InvalidName)); } else { return(new LoginCheckerResponse(LoginResponse.Code.SteamNotLinkedAndLoginMissing)); } } if (string.IsNullOrEmpty(login.PasswordHash) || !accByLogin.VerifyPassword(login.PasswordHash)) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.InvalidPassword)); } } var acc = accBySteamID ?? accByLogin; var ret = new LoginCheckerResponse(LoginResponse.Code.Ok); ret.LoginResponse.Name = acc.Name; var user = ret.User; acc.Country = ResolveCountry(ip); if ((acc.Country == null) || string.IsNullOrEmpty(acc.Country)) { acc.Country = "??"; } acc.LobbyVersion = lobbyVersion; acc.LastLogin = DateTime.UtcNow; if (info != null) { if (db.Accounts.Any(x => x.SteamID == info.steamid && x.Name != acc.Name)) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.SteamLinkedToDifferentAccount)); } acc.SteamID = info.steamid; acc.SteamName = info.personaname; } user.LobbyVersion = login.LobbyVersion; user.IpAddress = ip; UpdateUserFromAccount(user, acc); LogIP(db, acc, ip); LogUserID(db, acc, userID); db.SaveChanges(); ret.LoginResponse.SessionToken = Guid.NewGuid().ToString(); // create session token var banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, x => x.BanLobby); if (banPenalty != null) { return (BlockLogin( $"Banned until {banPenalty.BanExpires} (match to {banPenalty.AccountByAccountID.Name}), reason: {banPenalty.Reason}", acc, ip, userID)); } if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled) { if (HasVpn(ip, acc, db)) { return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID)); } } return(ret); } } finally { semaphore.Release(); } }
public async Task<RegisterResponse> DoRegister(Register register, string ip) { if (!Account.IsValidLobbyName(register.Name)) return new RegisterResponse(RegisterResponse.Code.NameHasInvalidCharacters); if (server.ConnectedUsers.ContainsKey(register.Name)) return new RegisterResponse(RegisterResponse.Code.AlreadyConnected); if (string.IsNullOrEmpty(register.PasswordHash) && string.IsNullOrEmpty(register.SteamAuthToken)) return new RegisterResponse(RegisterResponse.Code.MissingBothPasswordAndToken); if (!VerifyIp(ip)) return new RegisterResponse(RegisterResponse.Code.BannedTooManyAttempts); var banPenalty = Punishment.GetActivePunishment(null, ip, register.UserID, register.InstallID, x => x.BanLobby); if (banPenalty != null) return new RegisterResponse(RegisterResponse.Code.Banned) {BanReason = banPenalty.Reason}; SteamWebApi.PlayerInfo info = null; if (!string.IsNullOrEmpty(register.SteamAuthToken)) { info = await server.SteamWebApi.VerifyAndGetAccountInformation(register.SteamAuthToken); if (info == null) return new RegisterResponse(RegisterResponse.Code.InvalidSteamToken); } using (var db = new ZkDataContext()) { var registerName = register.Name.ToUpper(); var existingByName = db.Accounts.FirstOrDefault(x => x.Name.ToUpper() == registerName); if (existingByName != null) { if (info != null && existingByName.SteamID == info.steamid) return new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisSteamToken); if (info == null && !string.IsNullOrEmpty(register.PasswordHash) && existingByName.VerifyPassword(register.PasswordHash)) return new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisPassword); return new RegisterResponse(RegisterResponse.Code.NameAlreadyTaken); } var acc = new Account() { Name = register.Name }; acc.SetPasswordHashed(register.PasswordHash); acc.SetName(register.Name); acc.SetAvatar(); acc.Email = register.Email; if (info != null) { var existingBySteam = db.Accounts.FirstOrDefault(x => x.SteamID == info.steamid); if (existingBySteam != null) return new RegisterResponse(RegisterResponse.Code.SteamAlreadyRegistered); acc.SteamID = info.steamid; acc.SteamName = info.personaname; } else if (string.IsNullOrEmpty(register.PasswordHash)) { return new RegisterResponse(RegisterResponse.Code.InvalidPassword); } LogIP(db, acc, ip); LogUserID(db, acc, register.UserID, register.InstallID); db.Accounts.Add(acc); db.SaveChanges(); var smurfs = acc.GetSmurfs().Where(a => a.PunishmentsByAccountID.Any(x => x.BanExpires > DateTime.UtcNow)); if (smurfs.Any()) { await server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("Smurf Alert! {0} might be a smurf of {1}. Check https://zero-k.info/Users/AdminUserDetail/{2}", acc.Name, smurfs.OrderByDescending(x => x.Level).First().Name, acc.AccountID)); } } return new RegisterResponse(RegisterResponse.Code.Ok); }
public async Task <RegisterResponse> DoRegister(Register register, string ip) { if (!Account.IsValidLobbyName(register.Name)) { return(new RegisterResponse(RegisterResponse.Code.NameHasInvalidCharacters)); } if (server.ConnectedUsers.ContainsKey(register.Name)) { return(new RegisterResponse(RegisterResponse.Code.AlreadyConnected)); } if (string.IsNullOrEmpty(register.PasswordHash) && string.IsNullOrEmpty(register.SteamAuthToken)) { return(new RegisterResponse(RegisterResponse.Code.MissingBothPasswordAndToken)); } if (!VerifyIp(ip)) { return(new RegisterResponse(RegisterResponse.Code.BannedTooManyAttempts)); } var banPenalty = Punishment.GetActivePunishment(null, ip, register.UserID, x => x.BanLobby); if (banPenalty != null) { return new RegisterResponse(RegisterResponse.Code.Banned) { BanReason = banPenalty.Reason } } ; SteamWebApi.PlayerInfo info = null; if (!string.IsNullOrEmpty(register.SteamAuthToken)) { info = await server.SteamWebApi.VerifyAndGetAccountInformation(register.SteamAuthToken); if (info == null) { return(new RegisterResponse(RegisterResponse.Code.InvalidSteamToken)); } } using (var db = new ZkDataContext()) { var registerName = register.Name.ToUpper(); var existingByName = db.Accounts.FirstOrDefault(x => x.Name.ToUpper() == registerName); if (existingByName != null) { if (info != null && existingByName.SteamID == info.steamid) { return(new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisSteamToken)); } if (info == null && !string.IsNullOrEmpty(register.PasswordHash) && existingByName.VerifyPassword(register.PasswordHash)) { return(new RegisterResponse(RegisterResponse.Code.AlreadyRegisteredWithThisPassword)); } return(new RegisterResponse(RegisterResponse.Code.NameAlreadyTaken)); } var acc = new Account() { Name = register.Name }; acc.SetPasswordHashed(register.PasswordHash); acc.SetName(register.Name); acc.SetAvatar(); acc.Email = register.Email; if (info != null) { var existingBySteam = db.Accounts.FirstOrDefault(x => x.SteamID == info.steamid); if (existingBySteam != null) { return(new RegisterResponse(RegisterResponse.Code.SteamAlreadyRegistered)); } acc.SteamID = info.steamid; acc.SteamName = info.personaname; } else if (string.IsNullOrEmpty(register.PasswordHash)) { return(new RegisterResponse(RegisterResponse.Code.InvalidPassword)); } LogIP(db, acc, ip); LogUserID(db, acc, register.UserID); db.Accounts.Add(acc); db.SaveChanges(); } return(new RegisterResponse(RegisterResponse.Code.Ok)); }
public async Task <LoginCheckerResponse> DoLogin(Login login, string ip, List <ulong> dlc) { var limit = MiscVar.ZklsMaxUsers; if (limit > 0 && server.ConnectedUsers.Count >= limit) { return(new LoginCheckerResponse(LoginResponse.Code.ServerFull)); } await semaphore.WaitAsync(); try { var userID = login.UserID; var installID = login.InstallID; var lobbyVersion = login.LobbyVersion; using (var db = new ZkDataContext()) { if (!VerifyIp(ip)) { return(new LoginCheckerResponse(LoginResponse.Code.BannedTooManyConnectionAttempts)); } SteamWebApi.PlayerInfo info = null; if (!string.IsNullOrEmpty(login.SteamAuthToken)) { info = await server.SteamWebApi.VerifyAndGetAccountInformation(login.SteamAuthToken); if (info == null) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.InvalidSteamToken)); } } Account accBySteamID = null; Account accByLogin = null; if (info != null) { accBySteamID = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.SteamID == info.steamid); } if (!string.IsNullOrEmpty(login.Name)) { accByLogin = db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name == login.Name) ?? db.Accounts.Include(x => x.Clan).Include(x => x.Faction).FirstOrDefault(x => x.Name.Equals(login.Name, StringComparison.CurrentCultureIgnoreCase)); } if (accBySteamID == null) { if (accByLogin == null) { LogIpFailure(ip); if (!string.IsNullOrEmpty(login.Name)) { return(new LoginCheckerResponse(LoginResponse.Code.InvalidName)); } else { return(new LoginCheckerResponse(LoginResponse.Code.SteamNotLinkedAndLoginMissing)); } } if (string.IsNullOrEmpty(login.PasswordHash) || !accByLogin.VerifyPassword(login.PasswordHash)) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.InvalidPassword)); } } var acc = accBySteamID ?? accByLogin; var ret = new LoginCheckerResponse(LoginResponse.Code.Ok); ret.LoginResponse.Name = acc.Name; var user = ret.User; acc.Country = ResolveCountry(ip); if ((acc.Country == null) || string.IsNullOrEmpty(acc.Country)) { acc.Country = "??"; } acc.LobbyVersion = lobbyVersion; acc.LastLogin = DateTime.UtcNow; if (info != null) { if (db.Accounts.Any(x => x.SteamID == info.steamid && x.Name != acc.Name)) { LogIpFailure(ip); return(new LoginCheckerResponse(LoginResponse.Code.SteamLinkedToDifferentAccount)); } acc.SteamID = info.steamid; acc.SteamName = info.personaname; } user.LobbyVersion = login.LobbyVersion; user.IpAddress = ip; acc.VerifyAndAddDlc(dlc); UpdateUserFromAccount(user, acc); LogIP(db, acc, ip); LogUserID(db, acc, userID, installID); if (String.IsNullOrEmpty(installID) && !acc.HasVpnException) { await server.GhostChanSay(GlobalConst.ModeratorChannel, string.Format("{0} just logged in with an unsupported lobby https://zero-k.info/Users/AdminUserDetail/{1}", acc.Name, acc.AccountID)); } db.SaveChanges(); ret.LoginResponse.SessionToken = Guid.NewGuid().ToString(); // create session token var banPenalty = Punishment.GetActivePunishment(acc.AccountID, ip, userID, installID, x => x.BanLobby); if (banPenalty != null) { return (BlockLogin( $"Banned until {banPenalty.BanExpires} (match to {banPenalty.AccountByAccountID.Name}), reason: {banPenalty.Reason}", acc, ip, userID, installID)); } if (!acc.HasVpnException && GlobalConst.VpnCheckEnabled) { if (HasVpn(ip, acc, db)) { return(BlockLogin("Connection using proxy or VPN is not allowed! (You can ask for exception)", acc, ip, userID, installID)); } } return(ret); } } finally { semaphore.Release(); } }