i18n: localize the client-facing Closing-link ERROR wrapper via trf (fr, es); QUIT-broadcast reasons stay canonical for S2S

This commit is contained in:
Jean Chevronnet 2026-08-25 14:35:13 +00:00
parent 9b51db07f5
commit 04671733d2
No known key found for this signature in database
GPG key ID: 439666D63A9477E4
12 changed files with 54 additions and 31 deletions

View file

@ -88,6 +88,16 @@
"XLINE: {0} removed a {1}" = "XLINE: {0} eliminó un {1}"
"XLINE: {0}-line on {1} expired" = "XLINE: la {0}-line sobre {1} ha expirado"
# --- cierre de enlace (ERROR del lado del cliente al desconectar) ---
"Closing link: ({0})" = "Cerrando enlace: ({0})"
"Closing link: (R-lined: {0})" = "Cerrando enlace: (R-lined: {0})"
"Closing link: (SAQUIT: {0})" = "Cerrando enlace: (SAQUIT: {0})"
"Closing link (registration refused)" = "Cerrando enlace (registro rechazado)"
"Closing link: (Too many connections from your IP)" = "Cerrando enlace: (Demasiadas conexiones desde tu IP)"
"Closing link: (Excess flood)" = "Cerrando enlace: (Exceso de flood)"
"Closing link (dropped)" = "Cerrando enlace (descartado)"
"Closing link (incorrect ping reply)" = "Cerrando enlace (respuesta de ping incorrecta)"
# --- avisos / desafíos ---
"*** Cloudflare Challenge: verification successful — you may continue." = "*** Desafío de Cloudflare: verificación exitosa — puedes continuar."
"*** Correct — you may now message freely; please resend your message." = "*** Correcto — ya puedes enviar mensajes libremente; por favor reenvía tu mensaje."

View file

@ -88,6 +88,16 @@
"XLINE: {0} removed a {1}" = "XLINE : {0} a supprimé un {1}"
"XLINE: {0}-line on {1} expired" = "XLINE : la {0}-line sur {1} a expiré"
# --- fermeture de lien (ERROR côté client au moment de la déconnexion) ---
"Closing link: ({0})" = "Fermeture du lien : ({0})"
"Closing link: (R-lined: {0})" = "Fermeture du lien : (R-lined : {0})"
"Closing link: (SAQUIT: {0})" = "Fermeture du lien : (SAQUIT : {0})"
"Closing link (registration refused)" = "Fermeture du lien (enregistrement refusé)"
"Closing link: (Too many connections from your IP)" = "Fermeture du lien : (Trop de connexions depuis votre IP)"
"Closing link: (Excess flood)" = "Fermeture du lien : (Excès de flood)"
"Closing link (dropped)" = "Fermeture du lien (abandonné)"
"Closing link (incorrect ping reply)" = "Fermeture du lien (réponse au ping incorrecte)"
# --- notices / défis ---
"*** Cloudflare Challenge: verification successful — you may continue." = "*** Défi Cloudflare : vérification réussie — vous pouvez continuer."
"*** Correct — you may now message freely; please resend your message." = "*** Correct — vous pouvez maintenant envoyer des messages librement ; veuillez renvoyer votre message."

View file

@ -1349,7 +1349,8 @@ impl Command for SaQuit {
.cloned()
.unwrap_or_else(|| "Services forced quit".to_string());
if s.uid_servprotected(tuid) { s.numeric(uid, ERR_NOPRIVILEGES, ":Cannot use an SA command on a network service"); return CmdResult::Fail; }
s.send(tuid, format!("ERROR :Closing link: (SAQUIT: {reason})"));
let m = s.trf("Closing link: (SAQUIT: {0})", &[reason.as_str()]);
s.send(tuid, format!("ERROR :{m}"));
s.remove_user(tuid, &format!("Quit: {reason}"));
let by = oper_nick(s, uid);
let m = s.trf("{0} used SAQUIT on {1}: {2}", &[by.as_str(), params[0].as_str(), reason.as_str()]);

View file

@ -572,7 +572,8 @@ impl Command for Nick {
});
if let Some((nk, id, ho, ip, rn)) = info {
if let Some(reason) = s.matched_rline(&nk, &id, &ho, &ip, &rn) {
s.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = s.trf("Closing link: ({0})", &[reason.as_str()]);
s.send(uid, format!("ERROR :{m}"));
s.remove_user(uid, &reason);
}
}

View file

@ -569,10 +569,8 @@ impl Ircd {
for m in &mut self.modules {
match m.on_user_register(&mut self.server, uid) {
ModResult::Deny => {
self.server.send(
uid,
"ERROR :Closing link (registration refused)".to_string(),
);
let m = self.server.trf("Closing link (registration refused)", &[]);
self.server.send(uid, format!("ERROR :{m}"));
self.server.remove_user(uid, "Registration refused");
return;
}
@ -588,15 +586,15 @@ impl Ircd {
(u.ident.clone(), u.host.clone(), u.addr.ip().to_string())
};
if let Some(reason) = self.server.matched_xline(&ident, &host, &ip) {
self.server
.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = self.server.trf("Closing link: ({0})", &[reason.as_str()]);
self.server.send(uid, format!("ERROR :{m}"));
self.server.remove_user(uid, &reason);
return;
}
// ident: apply a confirmed username (dropping `~`) and enforce requireident
if let Some(reason) = crate::modules::ident::finalize(&mut self.server, uid) {
self.server
.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = self.server.trf("Closing link: ({0})", &[reason.as_str()]);
self.server.send(uid, format!("ERROR :{m}"));
self.server.remove_user(uid, &reason);
return;
}
@ -613,8 +611,8 @@ impl Ircd {
)
};
if let Some(reason) = rl {
self.server
.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = self.server.trf("Closing link: ({0})", &[reason.as_str()]);
self.server.send(uid, format!("ERROR :{m}"));
self.server.remove_user(uid, &reason);
return;
}
@ -636,8 +634,8 @@ impl Ircd {
fn reject_link(&mut self, uid: Uid, reason: &str) {
self.server
.numeric(uid, ERR_PASSWDMISMATCH, &format!(":{reason}"));
self.server
.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = self.server.trf("Closing link: ({0})", &[reason]);
self.server.send(uid, format!("ERROR :{m}"));
self.server.remove_user(uid, reason);
}
@ -705,8 +703,8 @@ impl Ircd {
} else {
"Registration timeout"
};
self.server
.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = self.server.trf("Closing link: ({0})", &[reason]);
self.server.send(uid, format!("ERROR :{m}"));
self.quit_user(uid, reason);
}
// republish gauges (the core owns this state; the scrape thread only reads)

View file

@ -55,7 +55,8 @@ impl Module for AutoDrop {
.get::<DropCache>()
.is_some_and(|c| c.cmds.contains(&cmd.to_ascii_uppercase()));
if hit {
s.send(uid, "ERROR :Closing link (dropped)".to_string());
let m = s.trf("Closing link (dropped)", &[]);
s.send(uid, format!("ERROR :{m}"));
s.remove_user(uid, "Autodropped");
return ModResult::Deny;
}

View file

@ -68,10 +68,8 @@ pub fn on_pong(s: &mut Server, uid: Uid, params: &[String]) {
u.waitpong = None;
}
} else if s.conf_bool("conn_waitpong_killonbadreply", false) {
s.send(
uid,
"ERROR :Closing link (incorrect ping reply)".to_string(),
);
let m = s.trf("Closing link (incorrect ping reply)", &[]);
s.send(uid, format!("ERROR :{m}"));
s.remove_user(uid, "Incorrect ping reply");
}
}

View file

@ -210,7 +210,8 @@ fn act(s: &mut Server, uid: Uid, domain: &str) {
if closes {
// pre-registration users aren't caught by add_xline's enforce sweep, so close
// this connection explicitly (the ERROR flushes before the socket).
s.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = s.trf("Closing link: ({0})", &[reason.as_str()]);
s.send(uid, format!("ERROR :{m}"));
s.remove_user(uid, &reason);
}
}

View file

@ -71,7 +71,8 @@ impl Module for Filter {
"block" => s.notice_star(uid, &format!("Your message was blocked: {reason}")),
"silent" => {}
"kill" => {
s.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = s.trf("Closing link: ({0})", &[reason.as_str()]);
s.send(uid, format!("ERROR :{m}"));
s.remove_user(uid, &reason);
}
"kline" => {

View file

@ -58,7 +58,8 @@ impl Module for Flood {
if over {
if !fakelag {
// fakelag disabled: disconnect the flooder instead of throttling
srv.send(uid, "ERROR :Closing link: (Excess flood)".to_string());
let m = srv.trf("Closing link: (Excess flood)", &[]);
srv.send(uid, format!("ERROR :{m}"));
srv.mark_quit(uid, "Excess flood".to_string());
return ModResult::Deny;
}

View file

@ -481,10 +481,8 @@ impl Server {
// connflood — refuse an IP that's opening connections too fast (see modules::connflood)
if crate::modules::connflood::over_limit(self, ip) {
self.send(
uid,
"ERROR :Closing link: (Too many connections from your IP)".to_string(),
);
let m = self.trf("Closing link: (Too many connections from your IP)", &[]);
self.send(uid, format!("ERROR :{m}"));
self.remove_user(uid, "Connection throttled");
return;
}
@ -494,7 +492,8 @@ impl Server {
// connectclass — assign a connection class; a deny class or per-IP cap rejects
if let Some(reason) = crate::modules::connclass::assign(self, uid) {
self.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = self.trf("Closing link: ({0})", &[reason.as_str()]);
self.send(uid, format!("ERROR :{m}"));
self.remove_user(uid, &reason);
return;
}

View file

@ -270,7 +270,8 @@ impl Server {
.map(|(&uid, _)| uid)
.collect();
for uid in victims {
self.send(uid, format!("ERROR :Closing link: (R-lined: {reason})"));
let m = self.trf("Closing link: (R-lined: {0})", &[reason]);
self.send(uid, format!("ERROR :{m}"));
self.remove_user(uid, &format!("R-lined: {reason}"));
}
}
@ -365,7 +366,8 @@ impl Server {
})
.collect();
for (uid, reason) in victims {
self.send(uid, format!("ERROR :Closing link: ({reason})"));
let m = self.trf("Closing link: ({0})", &[reason.as_str()]);
self.send(uid, format!("ERROR :{m}"));
self.remove_user(uid, &reason);
}
}