refactor handling of duplicate login

This commit is contained in:
aljazerzen 2021-03-25 12:33:56 +01:00
parent 2bfbdf74e3
commit 0ea102dc9c
22 changed files with 50 additions and 69 deletions

View File

@ -125,7 +125,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "ServerWentMad: Prawdopodobnie wersje są niekompatybilne, sprawdź aktualizacje!",
"main.login.timeout": "Timeout: Serwer nie odpowiedział na czas. (Przeciążenie, bądź błędy sieci).",
"main.login.server_shut_down": "Serwer zamknięty",
"main.login.already_logged_in": "Jesteś już zalogowany na serwerze.",
"main.login.network_error": "Błąd sieci.",
"main.login.failed_sending_request": "Zapytanie do serwera weryfikacji nie powiodło się",
"main.login.client_crashed": "Crash clienta",

View File

@ -149,7 +149,6 @@ https://veloren.net/account/.
"main.login.outdated_client_or_server": "Inkompatible Version",
"main.login.timeout": "Zeitüberschreitung",
"main.login.server_shut_down": "Server heruntergefahren",
"main.login.already_logged_in": "Ihr seid bereits eingeloggt",
"main.login.network_error": "Netzwerkfehler",
"main.login.failed_sending_request": "Authentifizierung fehlgeschlagen",
"main.login.invalid_character": "Ungültiger Charakter",

View File

@ -48,7 +48,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "ServerWentMad: Probably versions are incompatible, check for updates.",
"main.login.timeout": "Timeout: Server did not respond in time. (Overloaded or network issues).",
"main.login.server_shut_down": "Server shut down",
"main.login.already_logged_in": "You are already logged into the server.",
"main.login.network_error": "Network error",
"main.login.network_wrong_version": "The server is running a different version than you are. Check your version and update your game.",
"main.login.failed_sending_request": "Request to Auth server failed",

View File

@ -49,7 +49,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "ServerEnloquecido: Probablemente las versiones son incompatibles, revisa si hay actualizaciones.",
"main.login.timeout": "Timeout: El servidor no respondió a tiempo. (Sobrecargado o con problemas de red).",
"main.login.server_shut_down": "Servidor apagado",
"main.login.already_logged_in": "Ya estás conectado al servidor.",
"main.login.network_error": "Error de red",
"main.login.network_wrong_version": "El servidor está ejecutando una versión diferente a la tuya. Comprueba tu versión y actualiza tu juego.",
"main.login.failed_sending_request": "Petición al servidor de autenticación fallida",

View File

@ -150,7 +150,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "ServidorEnloquecido: Probablemente las versiones son incompatibles, intenta actualizar tu cliente.",
"main.login.timeout": "Tiempo de espera agotado: El servidor no respondio a tiempo. (Puede estar sobrecargado o tener problemas de red).",
"main.login.server_shut_down": "El servidor se apagó",
"main.login.already_logged_in": "Ya estás conectado al servidor.",
"main.login.network_error": "Error de red",
"main.login.failed_sending_request": "El pedido al servidor de autenticacion fallo",
"main.login.invalid_character": "El personaje seleccionado no es válido",

View File

@ -46,7 +46,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "ServeurPasContent: Les versions sont probablement incompatibles, verifiez les mises à jour.",
"main.login.timeout": "DélaiEcoulé: Le serveur n'a pas répondu à temps. (Surchage ou problèmes réseau).",
"main.login.server_shut_down": "Extinction du Serveur",
"main.login.already_logged_in": "Vous êtes déjà connecté sur ce serveur.",
"main.login.network_error": "Problème Réseau",
"main.login.network_wrong_version": "Le serveur fonctionne avec une version différente de la vôtre. Vérifiez votre version et mettez votre jeu à jour.",
"main.login.failed_sending_request": "Demande d'authentification serveur échouée",

View File

@ -171,7 +171,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "Il server è impazzito: Probabilmente le versioni sono incompatibili, controlla per degli aggiornamenti",
"main.login.timeout": "Tempo scaduto: Il server non ha risposto in tempo. (In sovraccarico o problemi di rete)",
"main.login.server_shut_down": "Il server è stato chiuso",
"main.login.already_logged_in": "Hai già effettuato l'accesso al server",
"main.login.network_error": "Errore di rete",
"main.login.failed_sending_request": "Richiesta ai server di autenticazione fallita",
"main.login.invalid_character": "Il personaggio selezionato è invalido",

View File

@ -148,7 +148,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "Versieprobleem: De versie tussen de client en de server komen niet overeen. Check of er updates zijn/",
"main.login.timeout": "Timeout: De server deed er te lang over om te antwoorden. (Overblast of netwerk problemen).",
"main.login.server_shut_down": "Server is afgesloten",
"main.login.already_logged_in": "Je account is al reeds ingelogd op de server.",
"main.login.network_error": "Network problemen",
"main.login.failed_sending_request": "Kon verzoek niet naar authenticatie server sturen",
"main.login.invalid_character": "Het geselecteerde karakter is ongeldig",

View File

@ -150,7 +150,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "Sannsynligvis er versjoner inkompatible, se etter oppdateringer.",
"main.login.timeout": "Serveren svarte ikke i tide. (Overbelastet eller nettverksproblemer).",
"main.login.server_shut_down": "Serveren stoppet",
"main.login.already_logged_in": "Du er allerede logget på serveren.",
"main.login.network_error": "Nettverksfeil",
"main.login.failed_sending_request": "Forespørsel til godkjenningsserver mislyktes",
"main.login.invalid_character": "Den valgte karakteren er ugyldig",

View File

@ -45,7 +45,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "Servidor enlouqueceu: Provavelmente as versões são incompatíveis. Verifique se há atualizações.",
"main.login.timeout": "Tempo esgotado: Servidor não respondeu a tempo. (Sobrecarregado ou com problemas de rede).",
"main.login.server_shut_down": "Servidor encerrou ou desligou",
"main.login.already_logged_in": "Você já está logado neste servidor.",
"main.login.network_error": "Erro de Rede",
"main.login.failed_sending_request": "Requisição ao servidor de autenticação falhou",
"main.login.invalid_character": "O personagem selecionado é inválido",

View File

@ -123,7 +123,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "Servidor endoideceu: Provavelmente as versões são incompativéis, verifique se há versões mais recentes.",
"main.login.timeout": "Tempo esgotado: O servidor não respondeu a tempo. (Sobrecarregado ou problemas de rede).",
"main.login.server_shut_down": "O servidor encerrou",
"main.login.already_logged_in": "Vocé ja está logado neste servidor.",
"main.login.network_error": "Error de rede",
"main.login.failed_sending_request": "Pedido ao servidor de autenticação falhou",
"main.login.client_crashed": "O cliente crashou",

View File

@ -149,7 +149,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "ServerWentMad: Возможно, версии несовместимы. Проверьте наличие обновлений.",
"main.login.timeout": "Timeout: Сервер не ответил вовремя. (Перегрузка или проблемы с сетью).",
"main.login.server_shut_down": "Сервер выключен",
"main.login.already_logged_in": "Вы уже вошли на сервер.",
"main.login.network_error": "Ошибка сети",
"main.login.failed_sending_request": "Запрос аутентификации провален",
"main.login.invalid_character": "Выбранный персонаж недоступен",

View File

@ -48,7 +48,6 @@ bir hesap oluşturabilirsin."#,
"main.login.outdated_client_or_server": "SunucuÇılgınaDöndü: Muhtemelen versiyonlar uyuşmuyor, güncellemeleri kontrol et.",
"main.login.timeout": "Zamanaşımı: Sunucu zamanında cevap vermedi. (Aşırı yüklenme veya ağ sorunları).",
"main.login.server_shut_down": "Sunucu kapandı",
"main.login.already_logged_in": "Zaten sunucuya giriş yapmışsın.",
"main.login.network_error": "Ağ hatası",
"main.login.failed_sending_request": "Kimlik doğrulama sunucusuna istek gönderilemedi",
"main.login.invalid_character": "Seçilen karakter geçersiz",

View File

@ -45,7 +45,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "Помилка: ймовірно версії не сумісні, перевірте оновлення.",
"main.login.timeout": "Тайм-аут: сервер не відповів вчасно (перенавантажений, або проблеми з Вашою мережею).",
"main.login.server_shut_down": "Сервер вимкнено",
"main.login.already_logged_in": "Ви вже підключені до сервера.",
"main.login.network_error": "Помилка мережі",
"main.login.failed_sending_request": "Запит до сервера авторизації невдалий",
"main.login.invalid_character": "Обраний персонаж недоступний",

View File

@ -136,7 +136,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "服务器与客户端可能版本不兼容,请检查更新.",
"main.login.timeout": "超时: 服务器无法及时响应.",
"main.login.server_shut_down": "服务器已关闭",
"main.login.already_logged_in": "您已登入服务器.",
"main.login.network_error": "网络错误",
"main.login.failed_sending_request": "认证服务器请求失败",
"main.login.invalid_character": "选择的角色无效",

View File

@ -118,7 +118,6 @@ https://veloren.net/account/."#,
"main.login.outdated_client_or_server": "伺服器錯誤:版本可能不相容,請檢查更新。",
"main.login.timeout": "逾時:伺服器無法即時回應(也許試過載或者網路問題)。",
"main.login.server_shut_down": "伺服器已關閉",
"main.login.already_logged_in": "您已登入伺服器。",
"main.login.network_error": "網路錯誤",
"main.login.failed_sending_request": "認證伺服器請求失敗",
"main.login.client_crashed": "客戶端崩潰",

View File

@ -13,7 +13,6 @@ pub enum Error {
ServerShutdown,
TooManyPlayers,
NotOnWhitelist,
AlreadyLoggedIn,
AuthErr(String),
AuthClientError(AuthClientError),
AuthServerUrlInvalid(String),

View File

@ -538,7 +538,6 @@ impl Client {
self.send_msg_err(ClientRegister { token_or_username })?;
match self.register_stream.recv::<ServerRegisterAnswer>().await? {
Err(RegisterError::AlreadyLoggedIn(_, _)) => Err(Error::AlreadyLoggedIn),
Err(RegisterError::AuthError(err)) => Err(Error::AuthErr(err)),
Err(RegisterError::InvalidCharacter) => Err(Error::InvalidCharacter),
Err(RegisterError::NotOnWhitelist) => Err(Error::NotOnWhitelist),

View File

@ -10,7 +10,6 @@ use common::{
terrain::{Block, TerrainChunk},
trade::{PendingTrade, TradeId, TradeResult},
uid::Uid,
uuid::Uuid,
};
use hashbrown::HashMap;
use serde::{Deserialize, Serialize};
@ -192,7 +191,6 @@ pub enum DisconnectReason {
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq)]
pub enum RegisterError {
AlreadyLoggedIn(Uuid, String),
AuthError(String),
Banned(String),
Kicked(String),

View File

@ -44,6 +44,18 @@ impl Component for PendingLogin {
type Storage = IdvStorage<Self>;
}
#[derive(Debug)]
pub enum LoginError {
AlreadyLoggedIn(Uuid, String),
RegisterError(RegisterError),
}
impl From<RegisterError> for LoginError {
fn from(inner: RegisterError) -> LoginError {
LoginError::RegisterError(inner)
}
}
pub struct LoginProvider {
runtime: Arc<Runtime>,
accounts: HashMap<Uuid, String>,
@ -74,10 +86,10 @@ impl LoginProvider {
}
}
fn login(&mut self, uuid: Uuid, username: String) -> Result<(), RegisterError> {
fn login(&mut self, uuid: Uuid, username: String) -> Result<(), LoginError> {
// make sure that the user is not logged in already
if self.accounts.contains_key(&uuid) {
return Err(RegisterError::AlreadyLoggedIn(uuid, username));
return Err(LoginError::AlreadyLoggedIn(uuid, username));
}
info!(?username, "New User");
self.accounts.insert(uuid, username);
@ -121,19 +133,19 @@ impl LoginProvider {
admins: &HashSet<Uuid>,
whitelist: &HashSet<Uuid>,
banlist: &HashMap<Uuid, BanRecord>,
) -> Option<Result<(String, Uuid), RegisterError>> {
) -> Option<Result<(String, Uuid), LoginError>> {
match pending.pending_r.try_recv() {
Ok(Err(e)) => Some(Err(e)),
Ok(Err(e)) => Some(Err(e.into())),
Ok(Ok((username, uuid))) => {
if let Some(ban_record) = banlist.get(&uuid) {
// Pull reason string out of ban record and send a copy of it
return Some(Err(RegisterError::Banned(ban_record.reason.clone())));
return Some(Err(RegisterError::Banned(ban_record.reason.clone()).into()));
}
// user can only join if he is admin, the whitelist is empty (everyone can join)
// or his name is in the whitelist
if !whitelist.is_empty() && !whitelist.contains(&uuid) && !admins.contains(&uuid) {
return Some(Err(RegisterError::NotOnWhitelist));
return Some(Err(RegisterError::NotOnWhitelist.into()));
}
#[cfg(feature = "plugins")]
{
@ -144,7 +156,7 @@ impl LoginProvider {
Ok(e) => {
for i in e.into_iter() {
if let PlayerJoinResult::Kick(a) = i {
return Some(Err(RegisterError::Kicked(a)));
return Some(Err(RegisterError::Kicked(a).into()));
}
}
},
@ -164,7 +176,7 @@ impl LoginProvider {
error!("channel got closed to early, this shouldn't happen");
Some(Err(RegisterError::AuthError(
"Internal Error verifying".to_string(),
)))
).into()))
},
Err(tokio::sync::oneshot::error::TryRecvError::Empty) => None,
}

View File

@ -1,9 +1,4 @@
use crate::{
client::Client,
login_provider::{LoginProvider, PendingLogin},
metrics::PlayerMetrics,
EditableSettings,
};
use crate::{EditableSettings, client::Client, login_provider::{LoginError, LoginProvider, PendingLogin}, metrics::PlayerMetrics};
use common::{
comp::{Admin, Player, Stats},
event::{EventBus, ServerEvent},
@ -130,38 +125,35 @@ impl<'a> System<'a> for Sys {
finished_pending.push(entity);
trace!(?r, "pending login returned");
match r {
Err(e) => {
let mut retry = false;
if let RegisterError::AlreadyLoggedIn(uuid, ref username) = e {
if let Some((old_entity, old_client, _)) =
(&entities, &clients, &players)
.join()
.find(|(_, _, old_player)| old_player.uuid() == uuid)
{
// Remove old client
server_event_bus
.emit_now(ServerEvent::ClientDisconnect(old_entity));
let _ = old_client.send(ServerGeneral::Disconnect(
DisconnectReason::Kicked(String::from(
"You have logged in from another location.",
)),
));
// We can't login the new client right now as the
// removal of the old client and player occurs later in
// the tick, so we instead setup the new login to be
// processed in the next tick
// Create "fake" successful pending auth and mark it to
// be inserted into pending_logins at the end of this
// run
retries.push((
entity,
PendingLogin::new_success(username.to_string(), uuid),
));
retry = true;
}
}
if !retry {
client.send(ServerRegisterAnswer::Err(e))?;
Err(LoginError::RegisterError(e)) => {
client.send(ServerRegisterAnswer::Err(e))?;
return Ok(());
}
Err(LoginError::AlreadyLoggedIn(uuid, ref username)) => {
if let Some((old_entity, old_client, _)) =
(&entities, &clients, &players)
.join()
.find(|(_, _, old_player)| old_player.uuid() == uuid)
{
// Remove old client
server_event_bus
.emit_now(ServerEvent::ClientDisconnect(old_entity));
let _ = old_client.send(ServerGeneral::Disconnect(
DisconnectReason::Kicked(String::from(
"You have logged in from another location.",
)),
));
// We can't login the new client right now as the
// removal of the old client and player occurs later in
// the tick, so we instead setup the new login to be
// processed in the next tick
// Create "fake" successful pending auth and mark it to
// be inserted into pending_logins at the end of this
// run
retries.push((
entity,
PendingLogin::new_success(username.to_string(), uuid),
));
}
return Ok(());
},

View File

@ -148,9 +148,6 @@ impl PlayState for MainMenuState {
client::Error::ServerShutdown => {
localized_strings.get("main.login.server_shut_down").into()
},
client::Error::AlreadyLoggedIn => {
localized_strings.get("main.login.already_logged_in").into()
},
client::Error::NotOnWhitelist => {
localized_strings.get("main.login.not_on_whitelist").into()
},