more localization

fixed issue with IW4 parser not reading map changes properly
This commit is contained in:
RaidMax 2018-04-24 17:01:27 -05:00
parent 5dfaa4ebd6
commit 0e3d280595
32 changed files with 1186 additions and 772 deletions

View File

@ -46,7 +46,7 @@ namespace IW4MAdmin.Application.API
FlaggedMessageCount = 0; FlaggedMessageCount = 0;
E.Owner.Broadcast("If you suspect someone of ^5CHEATING ^7use the ^5!report ^7command").Wait(); E.Owner.Broadcast(Utilities.CurrentLocalization.LocalizationSet["GLOBAL_REPORT"]).Wait();
Events.Enqueue(new EventInfo( Events.Enqueue(new EventInfo(
EventInfo.EventType.ALERT, EventInfo.EventType.ALERT,
EventInfo.EventVersion.IW4MAdmin, EventInfo.EventVersion.IW4MAdmin,

View File

@ -58,6 +58,9 @@
<None Update="Localization\IW4MAdmin.en-US.json"> <None Update="Localization\IW4MAdmin.en-US.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>
<None Update="Localization\IW4MAdmin.es-ES.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None>
<None Update="Localization\IW4MAdmin.ru-RU.json"> <None Update="Localization\IW4MAdmin.ru-RU.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory> <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</None> </None>

View File

@ -3,6 +3,8 @@ set ProjectDir=%2
set TargetDir=%3 set TargetDir=%3
echo Deleting extra language files echo Deleting extra language files
if exist "%SolutionDir%Publish\Windows\en-US\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\en-US'
if exist "%SolutionDir%Publish\Windows\de\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\de' if exist "%SolutionDir%Publish\Windows\de\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\de'
if exist "%SolutionDir%Publish\Windows\es\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\es' if exist "%SolutionDir%Publish\Windows\es\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\es'
if exist "%SolutionDir%Publish\Windows\fr\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\fr' if exist "%SolutionDir%Publish\Windows\fr\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\fr'
@ -13,6 +15,17 @@ if exist "%SolutionDir%Publish\Windows\ru\" powershell Remove-Item -Force -Recur
if exist "%SolutionDir%Publish\Windows\zh-Hans\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\zh-Hans' if exist "%SolutionDir%Publish\Windows\zh-Hans\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\zh-Hans'
if exist "%SolutionDir%Publish\Windows\zh-Hant\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\zh-Hant' if exist "%SolutionDir%Publish\Windows\zh-Hant\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\zh-Hant'
if exist "%SolutionDir%Publish\WindowsPrerelease\en-US\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\en-US'
if exist "%SolutionDir%Publish\WindowsPrerelease\de\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\de'
if exist "%SolutionDir%Publish\WindowsPrerelease\es\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\es'
if exist "%SolutionDir%Publish\WindowsPrerelease\fr\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\fr'
if exist "%SolutionDir%Publish\WindowsPrerelease\it\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\it'
if exist "%SolutionDir%Publish\WindowsPrerelease\ja\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\ja'
if exist "%SolutionDir%Publish\WindowsPrerelease\ko\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\ko'
if exist "%SolutionDir%Publish\WindowsPrerelease\ru\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\ru'
if exist "%SolutionDir%Publish\WindowsPrerelease\zh-Hans\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\zh-Hans'
if exist "%SolutionDir%Publish\WindowsPrerelease\zh-Hant\" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\zh-Hant'
echo Deleting extra runtime files echo Deleting extra runtime files
if exist "%SolutionDir%Publish\Windows\runtimes\linux-arm" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\linux-arm' if exist "%SolutionDir%Publish\Windows\runtimes\linux-arm" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\linux-arm'
if exist "%SolutionDir%Publish\Windows\runtimes\linux-arm64" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\linux-arm64' if exist "%SolutionDir%Publish\Windows\runtimes\linux-arm64" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\linux-arm64'
@ -24,6 +37,19 @@ if exist "%SolutionDir%Publish\Windows\runtimes\osx-x64" powershell Remove-Item
if exist "%SolutionDir%Publish\Windows\runtimes\win-arm" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\win-arm' if exist "%SolutionDir%Publish\Windows\runtimes\win-arm" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\win-arm'
if exist "%SolutionDir%Publish\Windows\runtimes\win-arm64" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\win-arm64' if exist "%SolutionDir%Publish\Windows\runtimes\win-arm64" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\Windows\runtimes\win-arm64'
if exist "%SolutionDir%Publish\WindowsPrerelease\runtimes\linux-arm" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\runtimes\linux-arm'
if exist "%SolutionDir%Publish\WindowsPrerelease\runtimes\linux-arm64" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\runtimes\linux-arm64'
if exist "%SolutionDir%Publish\WindowsPrerelease\runtimes\linux-armel" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\runtimes\linux-armel'
if exist "%SolutionDir%Publish\WindowsPrerelease\runtimes\osx" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\runtimes\osx'
if exist "%SolutionDir%Publish\WindowsPrerelease\runtimes\osx-x64" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\runtimes\osx-x64'
if exist "%SolutionDir%Publish\WindowsPrerelease\runtimes\win-arm" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\runtimes\win-arm'
if exist "%SolutionDir%Publish\WindowsPrerelease\runtimes\win-arm64" powershell Remove-Item -Force -Recurse '%SolutionDir%Publish\WindowsPrerelease\runtimes\win-arm64'
echo Deleting misc files echo Deleting misc files
if exist "%SolutionDir%Publish\Windows\web.config" del "%SolutionDir%Publish\Windows\web.config" if exist "%SolutionDir%Publish\Windows\web.config" del "%SolutionDir%Publish\Windows\web.config"
del "%SolutionDir%Publish\Windows\*pdb" del "%SolutionDir%Publish\Windows\*pdb"
if exist "%SolutionDir%Publish\WindowsPrerelease\web.config" del "%SolutionDir%Publish\WindowsPrerelease\web.config"
del "%SolutionDir%Publish\WindowsPrerelease\*pdb"

View File

@ -75,11 +75,6 @@ namespace Application.EventParsers
if (cleanedEventLine.Contains("InitGame")) if (cleanedEventLine.Contains("InitGame"))
{ {
string dump = cleanedEventLine.Replace("InitGame: ", ""); string dump = cleanedEventLine.Replace("InitGame: ", "");
string[] values = dump.Split('\\', StringSplitOptions.RemoveEmptyEntries);
var dict = new Dictionary<string, string>();
for (int i = 0; i < values.Length; i += 2)
dict.Add(values[i], values[i + 1]);
return new GameEvent() return new GameEvent()
{ {
@ -93,8 +88,8 @@ namespace Application.EventParsers
{ {
ClientId = 1 ClientId = 1
}, },
Owner = server, Owner = server,
Extra = dict Extra = dump.DictionaryFromKeyValue()
}; };
} }

View File

@ -73,11 +73,6 @@ namespace Application.EventParsers
if (lineSplit[0].Contains("InitGame")) if (lineSplit[0].Contains("InitGame"))
{ {
string dump = cleanedEventLine.Replace("InitGame: ", ""); string dump = cleanedEventLine.Replace("InitGame: ", "");
string[] values = dump.Split('\\', StringSplitOptions.RemoveEmptyEntries);
var dict = new Dictionary<string, string>();
for (int i = 0; i < values.Length; i += 2)
dict.Add(values[i], values[i + 1]);
return new GameEvent() return new GameEvent()
{ {
@ -92,7 +87,7 @@ namespace Application.EventParsers
ClientId = 1 ClientId = 1
}, },
Owner = server, Owner = server,
Extra = dict Extra = dump.DictionaryFromKeyValue()
}; };
} }

View File

@ -11,16 +11,17 @@ namespace IW4MAdmin.Application.Localization
{ {
public static void Initialize() public static void Initialize()
{ {
string currentLocal = CultureInfo.CurrentCulture.Name; string currentLocale = Program.ServerManager.GetApplicationSettings().Configuration().CustomLocale ??
CultureInfo.CurrentCulture.Name.Substring(0, 2);
#if DEBUG #if DEBUG
// currentLocal = "ru-RU"; // currentLocal = "ru-RU";
#endif #endif
string localizationFile = $"Localization{Path.DirectorySeparatorChar}IW4MAdmin.{currentLocal}.json"; string localizationFile = $"Localization{Path.DirectorySeparatorChar}IW4MAdmin.{currentLocale}-{currentLocale.ToUpper()}.json";
string localizationContents; string localizationContents;
if (File.Exists(localizationFile)) if (File.Exists(localizationFile))
{ {
localizationContents = File.ReadAllText(localizationFile, Encoding.UTF8); localizationContents = File.ReadAllText(localizationFile, Encoding.UTF8);
} }
else else

View File

@ -7,6 +7,9 @@
"MANAGER_VERSION_SUCCESS": "IW4MAdmin is up to date", "MANAGER_VERSION_SUCCESS": "IW4MAdmin is up to date",
"MANAGER_INIT_FAIL": "Fatal error during initialization", "MANAGER_INIT_FAIL": "Fatal error during initialization",
"MANAGER_EXIT": "Press any key to exit...", "MANAGER_EXIT": "Press any key to exit...",
"MANAGER_SHUTDOWN_SUCCESS": "Shutdown complete",
"MANAGER_MONITORING_TEXT": "Now monitoring",
"MANAGER_CONNECTION_REST": "Connection has been reestablished with",
"SETUP_ENABLE_WEBFRONT": "Enable webfront", "SETUP_ENABLE_WEBFRONT": "Enable webfront",
"SETUP_ENABLE_MULTIOWN": "Enable multiple owners", "SETUP_ENABLE_MULTIOWN": "Enable multiple owners",
"SETUP_ENABLE_STEPPEDPRIV": "Enable stepped privilege hierarchy", "SETUP_ENABLE_STEPPEDPRIV": "Enable stepped privilege hierarchy",
@ -18,11 +21,25 @@
"SETUP_IPHUB_KEY": "Enter iphub.info api key", "SETUP_IPHUB_KEY": "Enter iphub.info api key",
"SETUP_DISPLAY_DISCORD": "Display discord link on webfront", "SETUP_DISPLAY_DISCORD": "Display discord link on webfront",
"SETUP_DISCORD_INVITE": "Enter discord invite link", "SETUP_DISCORD_INVITE": "Enter discord invite link",
"SETUP_SERVER_USET6M": "Use T6M parser", "SETUP_SERVER_USET6M": "Use Pluto T6 parser",
"SETUP_SERVER_USEIW5M": "Use Pluto IW5 Parser",
"SETUP_SERVER_MANUALLOG": "Enter manual log file path",
"SETUP_SERVER_IP": "Enter server IP Address", "SETUP_SERVER_IP": "Enter server IP Address",
"SETUP_SERVER_PORT": "Enter server port", "SETUP_SERVER_PORT": "Enter server port",
"SETUP_SERVER_RCON": "Enter server RCon password", "SETUP_SERVER_RCON": "Enter server RCon password",
"SETUP_SERVER_SAVE": "Configuration saved, add another", "SETUP_SERVER_SAVE": "Configuration saved, add another",
"SERVER_ERROR_DNE": "does not exist",
"SERVER_ERROR_LOG": "Invalid game log file",
"SERVER_ERROR_COMMAND_INGAME": "An internal error occured while processing your command",
"SERVER_ERROR_COMMAND_LOG": "command generated an error",
"SERVER_ERROR_UNFIXABLE": "Not monitoring server due to uncorrectable errors",
"SERVER_ERROR_DVAR": "Could not get the dvar value for",
"SERVER_ERROR_DVAR_HELP": "ensure the server has a map loaded",
"SERVER_ERROR_PLUGIN": "An error occured loading plugin",
"SERVER_ERROR_ADDPLAYER": "Unable to add player",
"SERVER_ERROR_POLLING": "reducing polling rate",
"SERVER_ERROR_COMMUNICATION": "Could not communicate with",
"SERVER_ERROR_EXCEPTION": "Unexpected exception on",
"SERVER_KICK_VPNS_NOTALLOWED": "VPNs are not allowed on this server", "SERVER_KICK_VPNS_NOTALLOWED": "VPNs are not allowed on this server",
"SERVER_KICK_TEXT": "You were kicked", "SERVER_KICK_TEXT": "You were kicked",
"SERVER_KICK_MINNAME": "Your name must contain at least 3 characters", "SERVER_KICK_MINNAME": "Your name must contain at least 3 characters",
@ -36,7 +53,7 @@
"SERVER_BAN_APPEAL": "appeal at", "SERVER_BAN_APPEAL": "appeal at",
"SERVER_REPORT_COUNT": "There are ^5{0} ^7recent reports", "SERVER_REPORT_COUNT": "There are ^5{0} ^7recent reports",
"SERVER_WARNLIMT_REACHED": "Too many warnings", "SERVER_WARNLIMT_REACHED": "Too many warnings",
"SERVER_WARNING": "Warning", "SERVER_WARNING": "WARNING",
"SERVER_WEBSITE_GENERIC": "this server's website", "SERVER_WEBSITE_GENERIC": "this server's website",
"BROADCAST_ONLINE": "^5IW4MADMIN ^7is now ^2ONLINE", "BROADCAST_ONLINE": "^5IW4MADMIN ^7is now ^2ONLINE",
"BROADCAST_OFFLINE": "IW4MAdmin is going offline", "BROADCAST_OFFLINE": "IW4MAdmin is going offline",
@ -104,6 +121,77 @@
"COMMANDS_PASSWORD_FAIL": "Your password must be at least 5 characters long", "COMMANDS_PASSWORD_FAIL": "Your password must be at least 5 characters long",
"COMMANDS_PASSWORD_SUCCESS": "Your password has been set successfully", "COMMANDS_PASSWORD_SUCCESS": "Your password has been set successfully",
"COMMANDS_PING_TARGET": "ping is", "COMMANDS_PING_TARGET": "ping is",
"COMMANDS_PING_SELF": "Your ping is" "COMMANDS_PING_SELF": "Your ping is",
"COMMANDS_QUIT_DESC": "quit IW4MAdmin",
"COMMANDS_OWNER_DESC": "claim ownership of the server",
"COMMANDS_WARN_DESC": "warn client for infringing rules",
"COMMANDS_WARNCLEAR_DESC": "remove all warnings for a client",
"COMMANDS_KICK_DESC": "kick a client by name",
"COMMANDS_SAY_DESC": "broadcast message to all clients",
"COMMANDS_TEMPBAN_DESC": "temporarily ban a client for specified time (defaults to 1 hour)",
"COMMANDS_BAN_DESC": "permanently ban a client from the server",
"COMMANDS_UNBAN_DESC": "unban client by client id",
"COMMANDS_WHO_DESC": "give information about yourself",
"COMMANDS_LIST_DESC": "list active clients",
"COMMANDS_HELP_DESC": "list all available commands",
"COMMANDS_FASTRESTART_DESC": "fast restart current map",
"COMMANDS_MAPROTATE_DESC": "cycle to the next map in rotation",
"COMMANDS_SETLEVEL_DESC": "set client to specified privilege level",
"COMMANDS_USAGE_DESC": "get application memory usage",
"COMMANDS_USAGE_TEXT": "is using",
"COMMANDS_UPTIME_DESC": "get current application running time",
"COMMANDS_UPTIME_TEXT": "has been online for",
"COMMANDS_ADMINS_DESC": "list currently connected privileged clients",
"COMMANDS_MAP_DESC": "change to specified map",
"COMMANDS_FIND_DESC": "find client in database",
"COMMANDS_RULES_DESC": "list server rules",
"COMMANDS_PM_DESC": "send message to other client",
"COMMANDS_FLAG_DESC": "flag a suspicious client and announce to admins on join",
"COMMANDS_REPORT_DESC": "report a client for suspicious behavior",
"COMMANDS_REPORTS_DESC": "get or clear recent reports",
"COMMANDS_MASK_DESC": "hide your presence as a privileged client",
"COMMANDS_BANINFO_DESC": "get information about a ban for a client",
"COMMANDS_ALIAS_DESC": "get past aliases and ips of a client",
"COMMANDS_RCON_DESC": "send rcon command to server",
"COMMANDS_PLUGINS_DESC": "view all loaded plugins",
"COMMANDS_IP_DESC": "view your external IP address",
"COMMANDS_PRUNE_DESC": "demote any privileged clients that have not connected recently (defaults to 30 days)",
"COMMANDS_SETPASSWORD_DESC": "set your authentication password",
"COMMANDS_PING_DESC": "get client's ping",
"COMMANDS_ARGS_PLAYER": "player",
"COMMANDS_ARGS_REASON": "reason",
"COMMANDS_ARGS_MESSAGE": "message",
"COMMANDS_ARGS_DURATION": "duration (m|h|d|w|y)",
"COMMANDS_ARGS_CLIENTID": "client id",
"COMMANDS_ARGS_COMMANDS": "commands",
"COMMANDS_ARGS_LEVEL": "level",
"COMMANDS_ARGS_MAP": "map",
"COMMANDS_ARGS_CLEAR": "clear",
"COMMANDS_ARGS_INACTIVE": "inactive days",
"COMMANDS_ARGS_PASSWORD": "password",
"PLUGINS_LOGIN_COMMANDS_LOGIN_DESC": "login using password",
"PLUGINS_LOGIN_COMMANDS_LOGIN_SUCCESS": "You are now logged in",
"PLUGINS_LOGIN_COMMANDS_LOGIN_FAIL": "Your password is incorrect",
"PLUGINS_STATS_COMMANDS_RESET_DESC": "reset your stats to factory-new",
"PLUGINS_STATS_COMMANDS_RESET_SUCCESS": "Your stats for this server have been reset",
"PLUGINS_STATS_COMMANDS_RESET_FAIL": "You must be connected to a server to reset your stats",
"PLUGINS_STATS_COMMANDS_VIEW_DESC": "view your stats",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME": "The specified player must be ingame",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME_SELF": "You must be ingame to view your stats",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL": "Cannot find the player you specified",
"PLUGINS_STATS_COMMANDS_VIEW_SUCCESS": "Stats for",
"PLUGINS_STATS_COMMANDS_TOP_DESC": "view the top 5 players in this server",
"PLUGINS_STATS_COMMANDS_TOP_TEXT": "Top Players",
"PLUGINS_STATS_TEXT_KILLS": "KILLS",
"PLUGINS_STATS_TEXT_DEATHS": "DEATHS",
"PLUGINS_STATS_TEXT_SKILL": "SKILL",
"GLOBAL_DAYS": "days",
"GLOBAL_HOURS": "hours",
"GLOBAL_MINUTES": "minutes",
"GLOBAL_REPORT": "If you suspect someone of ^5CHEATING ^7use the ^5!report ^7command",
"GLOBAL_ERROR": "Error",
"GLOBAL_WARNING": "Warning",
"GLOBAL_INFO": "Info",
"GLOBAL_VERBOSE": "Verbose"
} }
} }

View File

@ -0,0 +1,197 @@
{
"LocalizationName": "es-ES",
"LocalizationSet": {
"MANAGER_VERSION_FAIL": "No se ha podido conseguir la última versión de IW4MAdmin",
"MANAGER_VERSION_UPDATE": "tiene una actualización. La última versión es",
"MANAGER_VERSION_CURRENT": "Tu versión es",
"MANAGER_VERSION_SUCCESS": "IW4MAdmin está actualizado",
"MANAGER_INIT_FAIL": "Error fatal durante la inicialización",
"MANAGER_EXIT": "Presione cualquier tecla para salir...",
"MANAGER_SHUTDOWN_SUCCESS": "Apagado completo",
"MANAGER_MONITORING_TEXT": "Ahora monitoreando",
"MANAGER_CONNECTION_REST": "La conexión ha sido restablecida con",
"SETUP_ENABLE_WEBFRONT": "Habilitar frente de la web",
"SETUP_ENABLE_MULTIOWN": "Habilitar múltiples propietarios",
"SETUP_ENABLE_STEPPEDPRIV": "Habilitar jerarquía de privilegios por escalones",
"SETUP_ENABLE_CUSTOMSAY": "Habilitar nombre a decir personalizado",
"SETUP_SAY_NAME": "Ingresar nombre a decir personalizado",
"SETUP_USE_CUSTOMENCODING": "Usar analizador de codificación personalizado",
"SETUP_ENCODING_STRING": "Ingresar cadena de codificación",
"SETUP_ENABLE_VPNS": "Habilitar VPNs clientes",
"SETUP_IPHUB_KEY": "Ingresar clave api de iphub.info",
"SETUP_DISPLAY_DISCORD": "Mostrar link de Discord en frente de la web",
"SETUP_DISCORD_INVITE": "Ingresar link de invitación a discord",
"SETUP_SERVER_USET6M": "Usar analizador Pluto T6",
"SETUP_SERVER_USEIW5M": "Usar analizador Pluto IW5",
"SETUP_SERVER_MANUALLOG": "Ingresar manualmente la ruta del archivo de registro",
"SETUP_SERVER_IP": "Ingresar Dirección IP del servidor",
"SETUP_SERVER_PORT": "Ingresar puerto del servidor",
"SETUP_SERVER_RCON": "Ingresar contraseña RCon del servidor",
"SETUP_SERVER_SAVE": "Configuración guardada, añadir otra",
"SERVER_ERROR_DNE": "No existe",
"SERVER_ERROR_LOG": "Archivo de registro del juego invalido",
"SERVER_ERROR_COMMAND_INGAME": "Un error interno ocurrió mientras se procesaba tu comando",
"SERVER_ERROR_COMMAND_LOG": "Comando generó error",
"SERVER_ERROR_UNFIXABLE": "No se está supervisando el servidor debido a errores incorregibles",
"SERVER_ERROR_DVAR": "No se pudo obtener el valor dvar",
"SERVER_ERROR_DVAR_HELP": "asegúrate de que el servidor tenga un mapa cargado",
"SERVER_ERROR_PLUGIN": "Un error ocurrió mientras se cargaba el complemente",
"SERVER_ERROR_ADDPLAYER": "Incapaz de añadir al jugador",
"SERVER_ERROR_POLLING": "reduciendo la tasa de sondeo",
"SERVER_ERROR_COMMUNICATION": "No se ha podido comunicar con",
"SERVER_ERROR_EXCEPTION": "Excepción inesperada en",
"SERVER_KICK_VPNS_NOTALLOWED": "Las VPNs no están permitidas en este servidor",
"SERVER_KICK_TEXT": "Fuiste expulsado",
"SERVER_KICK_MINNAME": "Tu nombre debe contener al menos 3 caracteres",
"SERVER_KICK_NAME_INUSE": "Tu nombre está siendo usado por alguien más",
"SERVER_KICK_GENERICNAME": "Por favor cambia tu nombre usando /name",
"SERVER_KICK_CONTROLCHARS": "Tu nombre no puede contener caracteres de control",
"SERVER_TB_TEXT": "Estás temporalmente baneado",
"SERVER_TB_REMAIN": "Tú estás temporalmente baneado",
"SERVER_BAN_TEXT": "Estás baneado",
"SERVER_BAN_PREV": "Baneado anteriormente por",
"SERVER_BAN_APPEAL": "apela en",
"SERVER_REPORT_COUNT": "Hay ^5{0} ^7reportes recientes",
"SERVER_WARNLIMT_REACHED": "Muchas advertencias",
"SERVER_WARNING": "ADVERTENCIA",
"SERVER_WEBSITE_GENERIC": "el sitio web de este servidor",
"BROADCAST_ONLINE": "^5IW4MADMIN ^7está ahora ^2en línea",
"BROADCAST_OFFLINE": "IW4MAdmin está desconectado",
"COMMAND_HELP_SYNTAX": "sintaxis:",
"COMMAND_HELP_OPTIONAL": "opcional",
"COMMAND_UNKNOWN": "Has ingresado un comando desconocido",
"COMMAND_NOACCESS": "Tú no tienes acceso a ese comando",
"COMMAND_NOTAUTHORIZED": "Tú no estás autorizado para ejecutar ese comando",
"COMMAND_MISSINGARGS": "No se han proporcionado suficientes argumentos",
"COMMAND_TARGET_MULTI": "Múltiples jugadores coinciden con ese nombre",
"COMMAND_TARGET_NOTFOUND": "No se puede encontrar el jugador especificado",
"PLUGIN_IMPORTER_NOTFOUND": "No se encontraron complementos para cargar",
"PLUGIN_IMPORTER_REGISTERCMD": "Comando registrado",
"COMMANDS_OWNER_SUCCESS": "¡Felicidades, has reclamado la propiedad de este servidor!",
"COMMANDS_OWNER_FAIL": "Este servidor ya tiene un propietario",
"COMMANDS_WARN_FAIL": "No tiene los privilegios necesarios para advertir a",
"COMMANDS_WARNCLEAR_SUCCESS": "Todas las advertencias borradas para",
"COMMANDS_KICK_SUCCESS": "ha sido expulsado",
"COMMANDS_KICK_FAIL": "No tienes los privilegios necesarios para expulsar a",
"COMMANDS_TEMPBAN_SUCCESS": "ha sido baneado temporalmente por",
"COMMANDS_TEMPBAN_FAIL": "Tú no puedes banear temporalmente",
"COMMANDS_BAN_SUCCESS": "ha sido baneado permanentemente",
"COMMANDS_BAN_FAIL": "Tú no puedes banear",
"COMMANDS_UNBAN_SUCCESS": "Exitosamente desbaneado",
"COMMANDS_UNBAN_FAIL": "no está baneado",
"COMMANDS_HELP_NOTFOUND": "No se ha podido encontrar ese comando",
"COMMANDS_HELP_MOREINFO": "Escribe !help <nombre del comando> para obtener la sintaxis de uso del comando",
"COMMANDS_FASTRESTART_UNMASKED": "ha dado rápido reinicio al mapa",
"COMMANDS_FASTRESTART_MASKED": "Al mapa se le ha dado un reinicio rápido",
"COMMANDS_MAPROTATE": "Rotación de mapa en ^55 ^7segundos",
"COMMANDS_SETLEVEL_SELF": "No puedes cambiar tu propio nivel",
"COMMANDS_SETLEVEL_OWNER": "Solo puede haber un propietario. Modifica tu configuración si múltiples propietarios son requeridos",
"COMMANDS_SETLEVEL_STEPPEDDISABLED": "Este servidor no te permite promover",
"COMMANDS_SETLEVEL_LEVELTOOHIGH": "Tú solo puedes promover ^5{0} ^7a ^5{1} ^7o menor privilegio",
"COMMANDS_SETLEVEL_SUCCESS_TARGET": "¡Felicitaciones! has ha sido promovido a",
"COMMANDS_SETLEVEL_SUCCESS": "fue promovido con éxito",
"COMMANDS_SETLEVEL_FAIL": "Grupo inválido especificado",
"COMMANDS_ADMINS_NONE": "No hay administradores visibles en línea",
"COMMANDS_MAP_SUCCESS": "Cambiando al mapa",
"COMMANDS_MAP_UKN": "Intentando cambiar a un mapa desconocido",
"COMMANDS_FIND_MIN": "Por Favor introduzca al menos 3 caracteres",
"COMMANDS_FIND_EMPTY": "No se encontraron jugadores",
"COMMANDS_RULES_NONE": "El propietario del servidor no ha establecido ninguna regla",
"COMMANDS_FLAG_SUCCESS": "Has marcado a",
"COMMANDS_FLAG_UNFLAG": "Has desmarcado a",
"COMMANDS_FLAG_FAIL": "Tú no puedes marcar",
"COMMANDS_REPORT_FAIL_CAMP": "No puedes reportar a un jugador por campear",
"COMMANDS_REPORT_FAIL_DUPLICATE": "Ya has reportado a este jugador",
"COMMANDS_REPORT_FAIL_SELF": "No puedes reportarte a ti mismo",
"COMMANDS_REPORT_FAIL": "Tú no puedes reportar",
"COMMANDS_REPORT_SUCCESS": "Gracias por su reporte, un administrador ha sido notificado",
"COMMANDS_REPORTS_CLEAR_SUCCESS": "Reportes borrados con éxito",
"COMMANDS_REPORTS_NONE": "No hay jugadores reportados aun",
"COMMANDS_MASK_ON": "Ahora estás enmascarado",
"COMMANDS_MASK_OFF": "Ahora estás desenmascarado",
"COMMANDS_BANINFO_NONE": "No se encontró ban activo para ese jugador",
"COMMANDS_BANINO_SUCCESS": "fue baneado por ^5{0} ^7debido a:",
"COMMANDS_ALIAS_ALIASES": "Aliases",
"COMMANDS_ALIAS_IPS": "IPs",
"COMMANDS_RCON_SUCCESS": "Exitosamente enviado el comando RCon",
"COMMANDS_PLUGINS_LOADED": "Complementos cargados",
"COMMANDS_IP_SUCCESS": "Tu IP externa es",
"COMMANDS_PRUNE_FAIL": "Número inválido de días inactivos",
"COMMANDS_PRUNE_SUCCESS": "los usuarios privilegiados inactivos fueron podados",
"COMMANDS_PASSWORD_FAIL": "Tu contraseña debe tener al menos 5 caracteres de largo",
"COMMANDS_PASSWORD_SUCCESS": "Su contraseña ha sido establecida con éxito",
"COMMANDS_PING_TARGET": "ping es",
"COMMANDS_PING_SELF": "Tu ping es",
"COMMANDS_QUIT_DESC": "salir de IW4MAdmin",
"COMMANDS_OWNER_DESC": "reclamar la propiedad del servidor",
"COMMANDS_WARN_DESC": "advertir al cliente por infringir las reglas",
"COMMANDS_WARNCLEAR_DESC": "eliminar todas las advertencias de un cliente",
"COMMANDS_KICK_DESC": "expulsar a un cliente por su nombre",
"COMMANDS_SAY_DESC": "transmitir el mensaje a todos los clientes",
"COMMANDS_TEMPBAN_DESC": "banear temporalmente a un cliente por el tiempo especificado (predeterminado en 1 hora)",
"COMMANDS_BAN_DESC": "banear permanentemente un cliente del servidor",
"COMMANDS_UNBAN_DESC": "desbanear al cliente por ID",
"COMMANDS_WHO_DESC": "da información sobre ti",
"COMMANDS_LIST_DESC": "enlistar clientes activos",
"COMMANDS_HELP_DESC": "enlistar todos los comandos disponibles",
"COMMANDS_FASTRESTART_DESC": "dar reinicio rápido al mapa actial",
"COMMANDS_MAPROTATE_DESC": "pasar al siguiente mapa en rotación",
"COMMANDS_SETLEVEL_DESC": "establecer el cliente al nivel de privilegio especificado",
"COMMANDS_USAGE_DESC": "obtener uso de la memoria de la aplicación",
"COMMANDS_USAGE_TEXT": "está usando",
"COMMANDS_UPTIME_DESC": "obtener el tiempo de ejecución de la aplicación actual",
"COMMANDS_UPTIME_TEXT": "ha estado en línea por",
"COMMANDS_ADMINS_DESC": "enlistar clientes privilegiados actualmente conectados",
"COMMANDS_MAP_DESC": "cambiar al mapa especificado",
"COMMANDS_FIND_DESC": "encontrar cliente en la base de datos",
"COMMANDS_RULES_DESC": "enlistar reglas del servidor",
"COMMANDS_PM_DESC": "enviar mensaje a otro cliente",
"COMMANDS_FLAG_DESC": "marcar un cliente sospechoso y anunciar a los administradores al unirse",
"COMMANDS_REPORT_DESC": "reportar un cliente por comportamiento sospechoso",
"COMMANDS_REPORTS_DESC": "obtener o borrar informes recientes",
"COMMANDS_MASK_DESC": "esconde tu presencia como un cliente privilegiado",
"COMMANDS_BANINFO_DESC": "obtener información sobre el ban de un cliente",
"COMMANDS_ALIAS_DESC": "obtener alias e ips anteriores de un cliente",
"COMMANDS_RCON_DESC": "enviar el comando rcon al servidor",
"COMMANDS_PLUGINS_DESC": "ver todos los complementos cargados",
"COMMANDS_IP_DESC": "ver tu dirección IP externa",
"COMMANDS_PRUNE_DESC": "degradar a los clientes con privilegios que no se hayan conectado recientemente (el valor predeterminado es 30 días)",
"COMMANDS_SETPASSWORD_DESC": "configura tu contraseña de autenticación",
"COMMANDS_PING_DESC": "obtener ping del cliente",
"COMMANDS_ARGS_PLAYER": "jugador",
"COMMANDS_ARGS_REASON": "razón",
"COMMANDS_ARGS_MESSAGE": "mensaje",
"COMMANDS_ARGS_DURATION": "duración (m|h|d|w|y)",
"COMMANDS_ARGS_CLIENTID": "id del cliente",
"COMMANDS_ARGS_COMMANDS": "comandos",
"COMMANDS_ARGS_LEVEL": "nivel",
"COMMANDS_ARGS_MAP": "mapa",
"COMMANDS_ARGS_CLEAR": "borrar",
"COMMANDS_ARGS_INACTIVE": "días inactivo",
"COMMANDS_ARGS_PASSWORD": "contraseña",
"PLUGINS_LOGIN_COMMANDS_LOGIN_DESC": "iniciar sesión usando la contraseña",
"PLUGINS_LOGIN_COMMANDS_LOGIN_SUCCESS": "Ahora está conectado",
"PLUGINS_LOGIN_COMMANDS_LOGIN_FAIL": "tu contraseña es incorrecta",
"PLUGINS_STATS_COMMANDS_RESET_DESC": "restablece tus estadísticas a las nuevas de fábrica",
"PLUGINS_STATS_COMMANDS_RESET_SUCCESS": "Tus estadísticas para este servidor se han restablecido",
"PLUGINS_STATS_COMMANDS_RESET_FAIL": "Debes estar conectado a un servidor para restablecer tus estadísticas",
"PLUGINS_STATS_COMMANDS_VIEW_DESC": "ver tus estadísticas",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME": "El jugador especificado debe estar dentro del juego",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME_SELF": "Debes estar dentro del juego para ver tus estadísticas",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL": "No se puede encontrar el jugador que especificó",
"PLUGINS_STATS_COMMANDS_VIEW_SUCCESS": "Estadísticas para",
"PLUGINS_STATS_COMMANDS_TOP_DESC": "ver los 5 mejores jugadores en este servidor",
"PLUGINS_STATS_COMMANDS_TOP_TEXT": "Mejores Jugadores",
"PLUGINS_STATS_TEXT_KILLS": "Asesinatos",
"PLUGINS_STATS_TEXT_DEATHS": "Muertes",
"PLUGINS_STATS_TEXT_SKILL": "Habilidad",
"GLOBAL_DAYS": "días",
"GLOBAL_HOURS": "horas",
"GLOBAL_MINUTES": "minutos",
"GLOBAL_REPORT": "Si sospechas que alguien ^5usa cheats ^7usa el comando ^5!report",
"GLOBAL_ERROR": "Error",
"GLOBAL_WARNING": "Advertencia",
"GLOBAL_INFO": "Información",
"GLOBAL_VERBOSE": "Detallado"
}
}

View File

@ -2,29 +2,31 @@
"LocalizationName": "ru-RU", "LocalizationName": "ru-RU",
"LocalizationSet": { "LocalizationSet": {
"MANAGER_VERSION_FAIL": "Не удалось получить последнюю версию IW4MAdmin", "MANAGER_VERSION_FAIL": "Не удалось получить последнюю версию IW4MAdmin",
"MANAGER_VERSION_UPDATE": "имеет обновление. Последняя версия", "MANAGER_VERSION_UPDATE": "- есть обновление. Последняя версия:",
"MANAGER_VERSION_CURRENT": "Ваша версия", "MANAGER_VERSION_CURRENT": "Ваша версия:",
"MANAGER_VERSION_SUCCESS": "IW4MAdmin обновлен", "MANAGER_VERSION_SUCCESS": "IW4MAdmin обновлен",
"MANAGER_INIT_FAIL": "Неустранимая ошибка при инициализации", "MANAGER_INIT_FAIL": "Критическая ошибка во время инициализации",
"MANAGER_EXIT": "Нажмите любую клавишу чтобы выйти ...", "MANAGER_EXIT": "Нажмите любую клавишу, чтобы выйти...",
"SETUP_ENABLE_WEBFRONT": "Включить веб-интерфейс", "SETUP_ENABLE_WEBFRONT": "Включить веб-интерфейс",
"SETUP_ENABLE_MULTIOWN": "Включить поддержку нескольких владельцев", "SETUP_ENABLE_MULTIOWN": "Включить поддержку нескольких владельцев",
"SETUP_ENABLE_STEPPEDPRIV": "Включить последовательную иерархию прав", "SETUP_ENABLE_STEPPEDPRIV": "Включить последовательную иерархию прав",
"SETUP_ENABLE_CUSTOMSAY": "Включить серверное имя для чата", "SETUP_ENABLE_CUSTOMSAY": "Включить кастомное имя для чата",
"SETUP_SAY_NAME": "Введите серверное имя для чата", "SETUP_SAY_NAME": "Введите кастомное имя для чата",
"SETUP_USE_CUSTOMENCODING": "Использовать иную кодировку текста", "SETUP_USE_CUSTOMENCODING": "Использовать кастомную кодировку парсера",
"SETUP_ENCODING_STRING": "Введите желаемую кодировку", "SETUP_ENCODING_STRING": "Введите кодировку",
"SETUP_ENABLE_VPNS": "Разрешить игрокам подключаться с VPN", "SETUP_ENABLE_VPNS": "Включить поддержку VPN у игроков",
"SETUP_IPHUB_KEY": "Введите iphub.info api-ключ", "SETUP_IPHUB_KEY": "Введите iphub.info api-ключ",
"SETUP_DISPLAY_DISCORD": "Отображать ссылку на Discord в веб-интерфейсе", "SETUP_DISPLAY_DISCORD": "Отображать ссылку на Discord в веб-интерфейсе",
"SETUP_DISCORD_INVITE": "Введите ссылку-приглашение в Discord", "SETUP_DISCORD_INVITE": "Введите ссылку-приглашение в Discord",
"SETUP_SERVER_USET6M": "Использовать T6M парсер для Black Ops 2", "SETUP_SERVER_USET6M": "Использовать Pluto T6 парсер",
"SETUP_SERVER_USEIW5M": "Использовать парсер Pluto IW5",
"SETUP_SERVER_MANUALLOG": "Введите путь для лог-файла",
"SETUP_SERVER_IP": "Введите IP-адрес сервера", "SETUP_SERVER_IP": "Введите IP-адрес сервера",
"SETUP_SERVER_PORT": "введите порт сервера", "SETUP_SERVER_PORT": "Введите порт сервера",
"SETUP_SERVER_RCON": "Введите RCon пароль сервера", "SETUP_SERVER_RCON": "Введите RCon пароль сервера",
"SETUP_SERVER_SAVE": "Конфигурация сохранена, добавить еще?", "SETUP_SERVER_SAVE": "Настройки сохранены, добавить",
"SERVER_KICK_VPNS_NOTALLOWED": "Использование VPN не разрешено на этом сервере", "SERVER_KICK_VPNS_NOTALLOWED": "Использование VPN не разрешено на этом сервере",
"SERVER_KICK_TEXT": "Вы исключены", "SERVER_KICK_TEXT": "Вы были исключены",
"SERVER_KICK_MINNAME": "Ваше имя должно содержать хотя бы 3 символа", "SERVER_KICK_MINNAME": "Ваше имя должно содержать хотя бы 3 символа",
"SERVER_KICK_NAME_INUSE": "Ваше имя используется кем-то другим", "SERVER_KICK_NAME_INUSE": "Ваше имя используется кем-то другим",
"SERVER_KICK_GENERICNAME": "Пожалуйста, смените ваше имя, используя /name", "SERVER_KICK_GENERICNAME": "Пожалуйста, смените ваше имя, используя /name",
@ -36,42 +38,42 @@
"SERVER_BAN_APPEAL": "оспорить:", "SERVER_BAN_APPEAL": "оспорить:",
"SERVER_REPORT_COUNT": "Имеется ^5{0} ^7жалоб за последнее время", "SERVER_REPORT_COUNT": "Имеется ^5{0} ^7жалоб за последнее время",
"SERVER_WARNLIMT_REACHED": "Слишком много предупреждений", "SERVER_WARNLIMT_REACHED": "Слишком много предупреждений",
"SERVER_WARNING": "предупреждение", "SERVER_WARNING": "Предупреждение",
"SERVER_WEBSITE_GENERIC": "веб-сайт этого сервера", "SERVER_WEBSITE_GENERIC": "веб-сайт этого сервера",
"BROADCAST_ONLINE": "^5IW4MADMIN ^7сейчас ^2ОНЛАЙН", "BROADCAST_ONLINE": "^5IW4MADMIN ^7сейчас ^В СЕТИ",
"BROADCAST_OFFLINE": "IW4MAdmin отключается", "BROADCAST_OFFLINE": "IW4MAdmin отключается",
"COMMAND_HELP_SYNTAX": "синтаксис:", "COMMAND_HELP_SYNTAX": "синтаксис:",
"COMMAND_HELP_OPTIONAL": "опционально", "COMMAND_HELP_OPTIONAL": "опционально",
"COMMAND_UNKNOWN": "Вы ввели неизвестную команду", "COMMAND_UNKNOWN": "Вы ввели неизвестную команду",
"COMMAND_NOACCESS": "У вас нет доступа к этой команде", "COMMAND_NOACCESS": "У вас нет доступа к этой команде",
"COMMAND_NOTAUTHORIZED": "У вас нет разрешения выполнить эту команду", "COMMAND_NOTAUTHORIZED": "Вы не авторизованы для исполнения этой команды",
"COMMAND_MISSINGARGS": "Приведено недостаточно аргументов", "COMMAND_MISSINGARGS": "Недостаточно аргументов приведено",
"COMMAND_TARGET_MULTI": "Это имя использует не один игрок", "COMMAND_TARGET_MULTI": "Несколько игроков соответствуют этому имени",
"COMMAND_TARGET_NOTFOUND": "Невозможно найти указанного игрока", "COMMAND_TARGET_NOTFOUND": "Невозможно найти указанного игрока",
"PLUGIN_IMPORTER_NOTFOUND": "Нет загружаемых плагинов", "PLUGIN_IMPORTER_NOTFOUND": "Не найдено плагинов для загрузки",
"PLUGIN_IMPORTER_REGISTERCMD": "Зарегистрированная команда", "PLUGIN_IMPORTER_REGISTERCMD": "Зарегистрированная команда",
"COMMANDS_OWNER_SUCCESS": "Поздравляем, Вы стали владельцем этого сервера!", "COMMANDS_OWNER_SUCCESS": "Поздравления, вы утвердили владение этим сервером!",
"COMMANDS_OWNER_FAIL": "Этот сервер уже имеет владельца", "COMMANDS_OWNER_FAIL": "Этот сервер уже имеет владельца",
"COMMANDS_WARN_FAIL": "У вас недостаточно прав чтобы предупреждать!", "COMMANDS_WARN_FAIL": "У вас недостаточно прав, чтобы выносить предупреждения",
"COMMANDS_WARNCLEAR_SUCCESS": "Все предупреждения очищены за", "COMMANDS_WARNCLEAR_SUCCESS": "Все предупреждения очищены за",
"COMMANDS_KICK_SUCCESS": "был исключен", "COMMANDS_KICK_SUCCESS": "был исключен",
"COMMANDS_KICK_FAIL": "У вас недостаточно прав чтобы исключать!", "COMMANDS_KICK_FAIL": "У вас нет достаточных прав, чтобы исключать",
"COMMANDS_TEMPBAN_SUCCESS": "был временно забанен за", "COMMANDS_TEMPBAN_SUCCESS": "был временно забанен за",
"COMMANDS_TEMPBAN_FAIL": "Вы не можете временно банить!", "COMMANDS_TEMPBAN_FAIL": "Вы не можете выдавать временный бан",
"COMMANDS_BAN_SUCCESS": "был забанен навсегда", "COMMANDS_BAN_SUCCESS": "был забанен навсегда",
"COMMANDS_BAN_FAIL": "Вы не можете банить!", "COMMANDS_BAN_FAIL": "Вы не можете выдавать бан",
"COMMANDS_UNBAN_SUCCESS": "Успешно разбанен", "COMMANDS_UNBAN_SUCCESS": "Успешно разбанен",
"COMMANDS_UNBAN_FAIL": "не забанен", "COMMANDS_UNBAN_FAIL": "не забанен",
"COMMANDS_HELP_NOTFOUND": "Не удалось найти эту команду", "COMMANDS_HELP_NOTFOUND": "Не удалось найти эту команду",
"COMMANDS_HELP_MOREINFO": "Введите !help <имя команды>, чтобы узнать синтаксис команды", "COMMANDS_HELP_MOREINFO": "Введите !help <имя команды>, чтобы узнать синтаксис для использования команды",
"COMMANDS_FASTRESTART_UNMASKED": "перезапуск карты", "COMMANDS_FASTRESTART_UNMASKED": "перезапустил карту",
"COMMANDS_FASTRESTART_MASKED": "Карта перезапущена", "COMMANDS_FASTRESTART_MASKED": "Карта была перезапущена",
"COMMANDS_MAPROTATE": "Смена карты через ^55 ^7секунд", "COMMANDS_MAPROTATE": "Смена карты через ^55 ^7секунд",
"COMMANDS_SETLEVEL_SELF": "Вы не можете изменить свой уровень", "COMMANDS_SETLEVEL_SELF": "Вы не можете изменить свой уровень",
"COMMANDS_SETLEVEL_OWNER": "Возможен только 1 владелец. Включите возможность нескольких владельцев!", "COMMANDS_SETLEVEL_OWNER": "Может быть только 1 владелец. Измените настройки, если требуется несколько владельцов",
"COMMANDS_SETLEVEL_STEPPEDDISABLED": "Этот сервер не разрешает вам повыситься", "COMMANDS_SETLEVEL_STEPPEDDISABLED": "Этот сервер не разрешает вам повыситься",
"COMMANDS_SETLEVEL_LEVELTOOHIGH": "Вы только можете повысить ^5{0} ^7до ^5{1} ^7или понизиться в правах", "COMMANDS_SETLEVEL_LEVELTOOHIGH": "Вы только можете повысить ^5{0} ^7до ^5{1} ^7или понизиться в правах",
"COMMANDS_SETLEVEL_SUCCESS_TARGET": "Поздравляем! Вы были повышены до", "COMMANDS_SETLEVEL_SUCCESS_TARGET": "Поздравления! Вы были повышены до",
"COMMANDS_SETLEVEL_SUCCESS": "был успешно повышен", "COMMANDS_SETLEVEL_SUCCESS": "был успешно повышен",
"COMMANDS_SETLEVEL_FAIL": "Указана неверная группа", "COMMANDS_SETLEVEL_FAIL": "Указана неверная группа",
"COMMANDS_ADMINS_NONE": "Нет администраторов в сети", "COMMANDS_ADMINS_NONE": "Нет администраторов в сети",
@ -88,22 +90,108 @@
"COMMANDS_REPORT_FAIL_SELF": "Вы не можете пожаловаться на самого себя", "COMMANDS_REPORT_FAIL_SELF": "Вы не можете пожаловаться на самого себя",
"COMMANDS_REPORT_FAIL": "Вы не можете пожаловаться", "COMMANDS_REPORT_FAIL": "Вы не можете пожаловаться",
"COMMANDS_REPORT_SUCCESS": "Спасибо за вашу жалобу, администратор оповещен", "COMMANDS_REPORT_SUCCESS": "Спасибо за вашу жалобу, администратор оповещен",
"COMMANDS_REPORTS_CLEAR_SUCCESS": "Жалобы полностью очищены", "COMMANDS_REPORTS_CLEAR_SUCCESS": "Жалобы успешно очищены",
"COMMANDS_REPORTS_NONE": "Пока нет жалоб на игроков", "COMMANDS_REPORTS_NONE": "Пока нет жалоб на игроков",
"COMMANDS_MASK_ON": "Вы замаскированы", "COMMANDS_MASK_ON": "Вы теперь замаскированы",
"COMMANDS_MASK_OFF": "Маскировка снята", "COMMANDS_MASK_OFF": "Вы теперь демаскированы",
"COMMANDS_BANINFO_NONE": "Нет активного запрета для этого игрока", "COMMANDS_BANINFO_NONE": "Не найдено действующего бана для этого игрока",
"COMMANDS_BANINO_SUCCESS": "был забанен ^5{0} ^7на:", "COMMANDS_BANINO_SUCCESS": "был забанен игроком ^5{0} ^7на:",
"COMMANDS_ALIAS_ALIASES": "Псевдонимы", "COMMANDS_ALIAS_ALIASES": "Имена",
"COMMANDS_ALIAS_IPS": "IP", "COMMANDS_ALIAS_IPS": "IP",
"COMMANDS_RCON_SUCCESS": " RCon команда успешно отправлена", "COMMANDS_RCON_SUCCESS": "Успешно отправлена команда RCon",
"COMMANDS_PLUGINS_LOADED": "Загруженные плагины", "COMMANDS_PLUGINS_LOADED": "Загруженные плагины",
"COMMANDS_IP_SUCCESS": "Ваш внешний IP-адрес", "COMMANDS_IP_SUCCESS": "Ваш внешний IP:",
"COMMANDS_PRUNE_FAIL": "Недопустимое количество неактивных дней", "COMMANDS_PRUNE_FAIL": "Неверное количество дней бездействия",
"COMMANDS_PRUNE_SUCCESS": "неактивные привилегированные пользователи были разжалованы", "COMMANDS_PRUNE_SUCCESS": "бездействующих пользователей с правами было сокращено",
"COMMANDS_PASSWORD_FAIL": "Ваш пароль должен содержать не менее 5 символов", "COMMANDS_PASSWORD_FAIL": "Ваш пароль должен быть хотя бы 5 символов в длину",
"COMMANDS_PASSWORD_SUCCESS": "Ваш пароль успешно установлен", "COMMANDS_PASSWORD_SUCCESS": "Ваш пароль был успешно установлен",
"COMMANDS_PING_TARGET": "пинг", "COMMANDS_PING_TARGET": "пинг:",
"COMMANDS_PING_SELF": "Ваш пинг" "COMMANDS_PING_SELF": "Ваш пинг:",
"MANAGER_SHUTDOWN_SUCCESS": "Выключение завершено",
"MANAGER_MONITORING_TEXT": "Идет мониторинг",
"MANAGER_CONNECTION_REST": "Соединение было восстановлено с помощью",
"SERVER_ERROR_DNE": "не существует",
"SERVER_ERROR_LOG": "Неверный файл игрового лога",
"SERVER_ERROR_COMMAND_INGAME": "Произошла внутренняя ошибка при обработке вашей команды",
"SERVER_ERROR_COMMAND_LOG": "команда сгенерировала ошибку",
"SERVER_ERROR_UNFIXABLE": "Мониторинг сервера выключен из-за неисправимых ошибок",
"SERVER_ERROR_DVAR": "Не удалось получить значение dvar:",
"SERVER_ERROR_DVAR_HELP": "убедитесь, что на сервере загружена карта",
"SERVER_ERROR_PLUGIN": "Произошла ошибка загрузки плагина",
"SERVER_ERROR_ADDPLAYER": "Не удалось добавить игрока",
"SERVER_ERROR_POLLING": "снижение частоты обновления данных",
"SERVER_ERROR_COMMUNICATION": "Не удалось связаться с",
"SERVER_ERROR_EXCEPTION": "Неожиданное исключение на",
"COMMANDS_QUIT_DESC": "покинуть IW4MAdmin",
"COMMANDS_OWNER_DESC": "утверить владение сервером",
"COMMANDS_WARN_DESC": "предупредить игрока за нарушение правил",
"COMMANDS_WARNCLEAR_DESC": "удалить все предупреждения у игрока",
"COMMANDS_KICK_DESC": "исключить игрока по имени",
"COMMANDS_SAY_DESC": "транслировать сообщения всем игрокам",
"COMMANDS_TEMPBAN_DESC": "временно забанить игрока на определенное время (по умолчанию: 1 час)",
"COMMANDS_BAN_DESC": "навсегда забанить игрока на сервере",
"COMMANDS_UNBAN_DESC": "разбанить игрока по ID игрока",
"COMMANDS_WHO_DESC": "предоставить информацию о себе",
"COMMANDS_LIST_DESC": "перечислить действующих игроков",
"COMMANDS_HELP_DESC": "перечислить все доступные команды",
"COMMANDS_FASTRESTART_DESC": "перезапустить нынешнюю карту",
"COMMANDS_MAPROTATE_DESC": "переключиться на следующую карту в ротации",
"COMMANDS_SETLEVEL_DESC": "установить особый уровень прав игроку",
"COMMANDS_USAGE_DESC": "узнать о потреблении памяти приложением",
"COMMANDS_USAGE_TEXT": "используется",
"COMMANDS_UPTIME_DESC": "получить время с начала запуска текущего приложения",
"COMMANDS_UPTIME_TEXT": "был в сети",
"COMMANDS_ADMINS_DESC": "перечислить присоединенных на данный момент игроков с правами",
"COMMANDS_MAP_DESC": "сменить на определенную карту",
"COMMANDS_FIND_DESC": "найти игрока в базе данных",
"COMMANDS_RULES_DESC": "перечислить правила сервера",
"COMMANDS_PM_DESC": "отправить сообщение другому игроку",
"COMMANDS_FLAG_DESC": "отметить подозрительного игрока и сообщить администраторам, чтобы присоединились",
"COMMANDS_REPORT_DESC": "пожаловаться на игрока за подозрительное поведение",
"COMMANDS_REPORTS_DESC": "получить или очистить последние жалобы",
"COMMANDS_MASK_DESC": "скрыть свое присутствие как игрока с правами",
"COMMANDS_BANINFO_DESC": "получить информацию о бане игрока",
"COMMANDS_ALIAS_DESC": "получить прошлые имена и IP игрока",
"COMMANDS_RCON_DESC": "отправить RCon команду на сервер",
"COMMANDS_PLUGINS_DESC": "просмотреть все загруженные плагины",
"COMMANDS_IP_DESC": "просмотреть ваш внешний IP-адрес",
"COMMANDS_PRUNE_DESC": "понизить любых игроков с правами, которые не подключались за последнее время (по умолчанию: 30 дней)",
"COMMANDS_SETPASSWORD_DESC": "установить свой пароль аутентификации",
"COMMANDS_PING_DESC": "получить пинг игрока",
"COMMANDS_ARGS_PLAYER": "игрок",
"COMMANDS_ARGS_REASON": "причина",
"COMMANDS_ARGS_MESSAGE": "сообщение",
"COMMANDS_ARGS_DURATION": "длительность (m|h|d|w|y)",
"COMMANDS_ARGS_CLIENTID": "ID игрока",
"COMMANDS_ARGS_COMMANDS": "команды",
"COMMANDS_ARGS_LEVEL": "уровень",
"COMMANDS_ARGS_MAP": "карта",
"COMMANDS_ARGS_CLEAR": "очистить",
"COMMANDS_ARGS_INACTIVE": "дни бездействия",
"COMMANDS_ARGS_PASSWORD": "пароль",
"PLUGINS_LOGIN_COMMANDS_LOGIN_DESC": "войти, используя пароль",
"PLUGINS_LOGIN_COMMANDS_LOGIN_SUCCESS": "Вы теперь вошли",
"PLUGINS_LOGIN_COMMANDS_LOGIN_FAIL": "Ваш пароль неверный",
"PLUGINS_STATS_COMMANDS_RESET_DESC": "сбросить вашу статистику под ноль",
"PLUGINS_STATS_COMMANDS_RESET_SUCCESS": "Ваша статистика на этом сервере была сброшена",
"PLUGINS_STATS_COMMANDS_RESET_FAIL": "Вы должны быть подключены к серверу, чтобы сбросить свою статистику",
"PLUGINS_STATS_COMMANDS_VIEW_DESC": "просмотреть свою статистику",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME": "Указанный игрок должен быть в игре",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME_SELF": "Вы должны быть в игре, чтобы просмотреть свою статистику",
"PLUGINS_STATS_COMMANDS_VIEW_FAIL": "Не удается найти игрока, которого вы указали.",
"PLUGINS_STATS_COMMANDS_VIEW_SUCCESS": "Статистика",
"PLUGINS_STATS_COMMANDS_TOP_DESC": "показать топ-5 лучших игроков на этом сервере",
"PLUGINS_STATS_COMMANDS_TOP_TEXT": "Лучшие игроки",
"PLUGINS_STATS_TEXT_KILLS": "УБИЙСТВ",
"PLUGINS_STATS_TEXT_DEATHS": "СМЕРТЕЙ",
"PLUGINS_STATS_TEXT_SKILL": "МАСТЕРСТВО",
"GLOBAL_DAYS": "дней",
"GLOBAL_HOURS": "часов",
"GLOBAL_MINUTES": "минут",
"GLOBAL_REPORT": "Если вы подозреваете кого-то в ^5ЧИТЕРСТВЕ^7, используйте команду ^5!report",
"GLOBAL_ERROR": "Ошибка",
"GLOBAL_WARNING": "Предупреждение",
"GLOBAL_INFO": "Информация",
"GLOBAL_VERBOSE": "Подробно"
} }
} }

View File

@ -1,4 +1,6 @@
using System; using SharedLibraryCore;
using System;
using System.Collections.Generic;
using System.IO; using System.IO;
namespace IW4MAdmin.Application namespace IW4MAdmin.Application
@ -28,7 +30,19 @@ namespace IW4MAdmin.Application
void Write(string msg, LogType type) void Write(string msg, LogType type)
{ {
string LogLine = $"[{DateTime.Now.ToString("HH:mm:ss")}] - {type}: {msg}"; string stringType;
try
{
stringType = Utilities.CurrentLocalization.LocalizationSet[$"GLOBAL_{type.ToString().ToUpper()}"];
}
catch(KeyNotFoundException)
{
stringType = type.ToString();
}
string LogLine = $"[{DateTime.Now.ToString("HH:mm:ss")}] - {stringType}: {msg}";
lock (ThreadLock) lock (ThreadLock)
{ {
#if DEBUG #if DEBUG

View File

@ -130,7 +130,7 @@ namespace IW4MAdmin.Application
} }
ServerManager.Start(); ServerManager.Start();
ServerManager.Logger.WriteVerbose("Shutdown complete"); ServerManager.Logger.WriteVerbose(loc["MANAGER_SHUTDOWN_SUCCESS"]);
} }

View File

@ -184,7 +184,7 @@ namespace IW4MAdmin.Application
catch (Exception e) catch (Exception e)
{ {
Logger.WriteError($"An error occured loading plugin {Plugin.Name}"); Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationSet["SERVER_ERROR_PLUGIN"]} {Plugin.Name}");
Logger.WriteDebug($"Exception: {e.Message}"); Logger.WriteDebug($"Exception: {e.Message}");
Logger.WriteDebug($"Stack Trace: {e.StackTrace}"); Logger.WriteDebug($"Stack Trace: {e.StackTrace}");
} }
@ -226,7 +226,7 @@ namespace IW4MAdmin.Application
Commands.Add(new CIP()); Commands.Add(new CIP());
Commands.Add(new CMask()); Commands.Add(new CMask());
Commands.Add(new CPruneAdmins()); Commands.Add(new CPruneAdmins());
Commands.Add(new CKillServer()); //Commands.Add(new CKillServer());
Commands.Add(new CSetPassword()); Commands.Add(new CSetPassword());
Commands.Add(new CPing()); Commands.Add(new CPing());
@ -247,7 +247,7 @@ namespace IW4MAdmin.Application
_servers.Add(ServerInstance); _servers.Add(ServerInstance);
} }
Logger.WriteVerbose($"Now monitoring {ServerInstance.Hostname}"); Logger.WriteVerbose($"{Utilities.CurrentLocalization.LocalizationSet["MANAGER_MONITORING_TEXT"]} {ServerInstance.Hostname}");
// this way we can keep track of execution time and see if problems arise. // this way we can keep track of execution time and see if problems arise.
var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY); var Status = new AsyncStatus(ServerInstance, UPDATE_FREQUENCY);
@ -259,9 +259,9 @@ namespace IW4MAdmin.Application
catch (ServerException e) catch (ServerException e)
{ {
Logger.WriteError($"Not monitoring server {Conf.IPAddress}:{Conf.Port} due to uncorrectable errors"); Logger.WriteError($"{Utilities.CurrentLocalization.LocalizationSet["SERVER_ERROR_UNFIXABLE"]} [{Conf.IPAddress}:{Conf.Port}]");
if (e.GetType() == typeof(DvarException)) if (e.GetType() == typeof(DvarException))
Logger.WriteDebug($"Could not get the dvar value for {(e as DvarException).Data["dvar_name"]} (ensure the server has a map loaded)"); Logger.WriteDebug($"{Utilities.CurrentLocalization.LocalizationSet["SERVER_ERROR_DVAR"]} {(e as DvarException).Data["dvar_name"]} ({Utilities.CurrentLocalization.LocalizationSet["SERVER_ERROR_DVAR_HELP"]})");
else if (e.GetType() == typeof(NetworkException)) else if (e.GetType() == typeof(NetworkException))
{ {
Logger.WriteDebug(e.Message); Logger.WriteDebug(e.Message);

View File

@ -103,7 +103,7 @@ namespace Application.RconParsers
IPAddress = cIP, IPAddress = cIP,
Ping = Ping, Ping = Ping,
Score = score, Score = score,
IsBot = npID == -1 IsBot = npID == 0
}; };
StatusPlayers.Add(P); StatusPlayers.Add(P);
} }

View File

@ -155,7 +155,7 @@ namespace Application.RconParsers
IPAddress = ipAddress, IPAddress = ipAddress,
Ping = Ping, Ping = Ping,
Score = score, Score = score,
IsBot = networkId < 1 IsBot = networkId == 0
}); });
} }
} }

View File

@ -186,7 +186,7 @@ namespace Application.RconParsers
IPAddress = ipAddress, IPAddress = ipAddress,
Ping = Ping, Ping = Ping,
Score = score, Score = score,
IsBot = networkId < 1 IsBot = networkId == 0
}); });
} }
} }

View File

@ -195,7 +195,7 @@ namespace IW4MAdmin
catch (Exception E) catch (Exception E)
{ {
Manager.GetLogger().WriteError($"Unable to add player {polledPlayer.Name}::{polledPlayer.NetworkId}"); Manager.GetLogger().WriteError($"{loc["SERVER_ERROR_ADDPLAYER"]} {polledPlayer.Name}::{polledPlayer.NetworkId}");
Manager.GetLogger().WriteDebug(E.StackTrace); Manager.GetLogger().WriteDebug(E.StackTrace);
return false; return false;
} }
@ -466,7 +466,7 @@ namespace IW4MAdmin
if (ConnectionErrors > 0) if (ConnectionErrors > 0)
{ {
Logger.WriteVerbose($"Connection has been reestablished with {IP}:{Port}"); Logger.WriteVerbose($"{loc["MANAGER_CONNECTION_REST"]} {IP}:{Port}");
Throttled = false; Throttled = false;
} }
ConnectionErrors = 0; ConnectionErrors = 0;
@ -479,7 +479,7 @@ namespace IW4MAdmin
ConnectionErrors++; ConnectionErrors++;
if (ConnectionErrors == 1) if (ConnectionErrors == 1)
{ {
Logger.WriteError($"{e.Message} {IP}:{Port}, reducing polling rate"); Logger.WriteError($"{e.Message} {IP}:{Port}, {loc["SERVER_ERROR_POLLING"]}");
Logger.WriteDebug($"Internal Exception: {e.Data["internal_exception"]}"); Logger.WriteDebug($"Internal Exception: {e.Data["internal_exception"]}");
Throttled = true; Throttled = true;
} }
@ -569,7 +569,7 @@ namespace IW4MAdmin
//#if !DEBUG //#if !DEBUG
catch (NetworkException) catch (NetworkException)
{ {
Logger.WriteError($"Could not communicate with {IP}:{Port}"); Logger.WriteError($"{loc["SERVER_ERROR_COMMUNICATION"]} {IP}:{Port}");
return false; return false;
} }
@ -582,7 +582,7 @@ namespace IW4MAdmin
catch (Exception E) catch (Exception E)
{ {
Logger.WriteError($"Encountered error on {IP}:{Port}"); Logger.WriteError($"{loc["SERVER_ERROR_EXCEPTION"]} {IP}:{Port}");
Logger.WriteDebug("Error Message: " + E.Message); Logger.WriteDebug("Error Message: " + E.Message);
Logger.WriteDebug("Error Trace: " + E.StackTrace); Logger.WriteDebug("Error Trace: " + E.StackTrace);
return false; return false;
@ -680,9 +680,9 @@ namespace IW4MAdmin
if (!File.Exists(logPath)) if (!File.Exists(logPath))
{ {
Logger.WriteError($"Gamelog {logPath} does not exist!"); Logger.WriteError($"{logPath} {loc["SERVER_ERROR_DNE"]}");
#if !DEBUG #if !DEBUG
throw new ServerException($"Invalid gamelog file {logPath}"); throw new ServerException($"{loc["SERVER_ERROR_LOG"]} {logPath}");
#endif #endif
} }
else else
@ -796,10 +796,10 @@ namespace IW4MAdmin
catch (Exception Except) catch (Exception Except)
{ {
Logger.WriteError(String.Format("A command request \"{0}\" generated an error.", C.Name)); Logger.WriteError(String.Format($"\"{0}\" {loc["SERVER_ERROR_COMMAND_LOG"]}", C.Name));
Logger.WriteDebug(String.Format("Error Message: {0}", Except.Message)); Logger.WriteDebug(String.Format("Error Message: {0}", Except.Message));
Logger.WriteDebug(String.Format("Error Trace: {0}", Except.StackTrace)); Logger.WriteDebug(String.Format("Error Trace: {0}", Except.StackTrace));
await E.Origin.Tell("^1An internal error occured while processing your command^7"); await E.Origin.Tell($"^1{loc["SERVER_ERROR_COMMAND_INGAME"]}");
#if DEBUG #if DEBUG
await E.Origin.Tell(Except.Message); await E.Origin.Tell(Except.Message);
#endif #endif
@ -824,12 +824,29 @@ namespace IW4MAdmin
{ {
Logger.WriteInfo($"New map loaded - {ClientNum} active players"); Logger.WriteInfo($"New map loaded - {ClientNum} active players");
var dict = (Dictionary<string, string>)E.Extra; // iw4 doesn't log the game info
Gametype = dict["g_gametype"].StripColors(); if (E.Extra == null)
Hostname = dict["sv_hostname"].StripColors(); {
var dict = await this.GetInfoAsync();
Gametype = dict["gametype"].StripColors();
Hostname = dict["hostname"].StripColors();
string mapname = dict["mapname"].StripColors();
CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname };
}
else
{
var dict = (Dictionary<string, string>)E.Extra;
Gametype = dict["g_gametype"].StripColors();
Hostname = dict["sv_hostname"].StripColors();
string mapname = dict["mapname"].StripColors();
CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname };
}
string mapname = dict["mapname"].StripColors();
CurrentMap = Maps.Find(m => m.Name == mapname) ?? new Map() { Alias = mapname, Name = mapname };
} }
if (E.Type == GameEvent.EventType.MapEnd) if (E.Type == GameEvent.EventType.MapEnd)

View File

@ -1,4 +1,4 @@
{ {
"current-version-stable": 2.0, "current-version-stable": 2.0,
"current-version-prerelease": 2.0 "current-version-prerelease": 2.1
} }

View File

@ -11,18 +11,18 @@ class HistoryGraph(Resource):
custom_style = Style( custom_style = Style(
background='transparent', background='transparent',
plot_background='transparent', plot_background='transparent',
foreground='rgba(109, 118, 126, 0.3)', foreground='#6c757d',
foreground_strong='rgba(109, 118, 126, 0.3)', foreground_strong='#6c757d',
foreground_subtle='rgba(109, 118, 126, 0.3)', foreground_subtle='#6c757d',
opacity='0.1', opacity='0.1',
opacity_hover='0.2', opacity_hover='0.2',
transition='100ms ease-in', transition='0ms',
colors=('#007acc', '#749363') colors=('#749363','#007acc'),
) )
graph = pygal.StackedLine( graph = pygal.Line(
stroke_style={'width': 0.4}, stroke_style={'width': 0.4},
show_dots=False, #show_dots=False,
show_legend=False, show_legend=False,
fill=True, fill=True,
style=custom_style, style=custom_style,
@ -36,9 +36,9 @@ class HistoryGraph(Resource):
instance_counts = [history['count'] for history in ctx.history.instance_history][-history_count:] instance_counts = [history['count'] for history in ctx.history.instance_history][-history_count:]
client_counts = [history['count'] for history in ctx.history.client_history][-history_count:] client_counts = [history['count'] for history in ctx.history.client_history][-history_count:]
graph.add('Instance Count', instance_counts)
graph.add('Client Count', client_counts) graph.add('Client Count', client_counts)
return { 'message' : graph.render(), graph.add('Instance Count', instance_counts)
return { 'message' : graph.render().replace("<title>Pygal</title>", ""),
'data_points' : len(instance_count), 'data_points' : len(instance_count),
'instance_count' : 0 if len(instance_counts) is 0 else instance_counts[-1], 'instance_count' : 0 if len(instance_counts) is 0 else instance_counts[-1],
'client_count' : 0 if len(client_counts) is 0 else client_counts[-1] 'client_count' : 0 if len(client_counts) is 0 else client_counts[-1]

View File

@ -14,42 +14,50 @@
<span class="h4 text-muted">&mdash; {{client_count}} clients</span> <span class="h4 text-muted">&mdash; {{client_count}} clients</span>
</figcaption> </figcaption>
</figure> </figure>
</div> </div>
<div class="col-12"> <div class="col-12">
</div> </div>
</div> </div>
{% endblock %} {% endblock %}
{% block scripts %} {% block scripts %}
<script type="text/javascript" src="http://kozea.github.com/pygal.js/latest/pygal-tooltips.min.js"></script> <script type="text/javascript" src="http://kozea.github.com/pygal.js/latest/pygal-tooltips.min.js"></script>
<script> <script>
let dataPoints = {{data_points}}; let dataPoints = {{data_points}};
let zoomLevel = Math.ceil(dataPoints / 2); let maxPoints = {{ max_data_points }};
let maxPoints = {{max_data_points}} maxPoints = Math.min(maxPoints, dataPoints);
//console.log(dataPoints); let zoomLevel = Math.floor(maxPoints);
let performingZoom = false;
function updateHistoryGraph() { function updateHistoryGraph() {
$.get('/history/' + zoomLevel) perfomingZoom = true;
.done(function (content) { $.get('/history/' + zoomLevel)
$('#history_graph').html(content.message); .done(function (content) {
dataPoints = content.data_points $('#history_graph').html(content.message);
}); maxPoints = Math.min(maxPoints, dataPoints);
perfomingZoom = false;
});
}
//setInterval(updateHistoryGraph, 30000);
$('#history_graph_zoom_out').click(function () {
if (performingZoom === true) {
return false;
} }
setInterval(updateHistoryGraph, 30000); zoomLevel = Math.floor(zoomLevel * 2) <= maxPoints ? Math.floor(zoomLevel * 2) : maxPoints;
updateHistoryGraph();
});
$('#history_graph_zoom_out').click(function () { $('#history_graph_zoom_in').click(function () {
// console.log(zoomLevel); if (performingZoom === true) {
zoomLevel = zoomLevel * 2 <= maxPoints ? Math.ceil(zoomLevel * 2) : dataPoints; return false;
updateHistoryGraph(); }
}); zoomLevel = zoomLevel / 2 > 2 ? Math.ceil(zoomLevel / 2) : 2;
updateHistoryGraph();
});
$('#history_graph_zoom_in').click(function () { </script>
// console.log(zoomLevel);
zoomLevel = zoomLevel / 2 > 2 ? Math.ceil(zoomLevel / 2) : 2;
updateHistoryGraph();
});
</script>
{% endblock %} {% endblock %}

View File

@ -14,6 +14,18 @@
.oi:hover { .oi:hover {
color: #fff !important; color: #fff !important;
} }
.dot {
opacity: 0;
padding: 5px;
}
.dot:hover {
opacity: 1;
}
.tooltip-box {
fill: #343a40 !important;
}
</style> </style>
</head> </head>

View File

@ -8,7 +8,7 @@ namespace IW4MAdmin.Plugins.Login.Commands
{ {
public class CLogin : Command public class CLogin : Command
{ {
public CLogin() : base("login", "login using password", "l", Player.Permission.Trusted, false, new CommandArgument[] public CLogin() : base("login", Utilities.CurrentLocalization.LocalizationSet["PLUGINS_LOGIN_COMMANDS_LOGIN_DESC"], "l", Player.Permission.Trusted, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
@ -25,12 +25,12 @@ namespace IW4MAdmin.Plugins.Login.Commands
if (hashedPassword[0] == client.Password) if (hashedPassword[0] == client.Password)
{ {
Plugin.AuthorizedClients[E.Origin.ClientId] = true; Plugin.AuthorizedClients[E.Origin.ClientId] = true;
await E.Origin.Tell("You are now logged in"); await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["PLUGINS_LOGIN_COMMANDS_LOGIN_SUCCESS"]);
} }
else else
{ {
await E.Origin.Tell("Your password is incorrect"); await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["PLUGINS_LOGIN_COMMANDS_LOGIN_FAIL"]);
} }
} }
} }

View File

@ -11,7 +11,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
{ {
public class ResetStats : Command public class ResetStats : Command
{ {
public ResetStats() : base("resetstats", "reset your stats to factory-new", "rs", Player.Permission.User, false) { } public ResetStats() : base("resetstats", Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_COMMANDS_RESET_DESC"], "rs", Player.Permission.User, false) { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
@ -31,12 +31,12 @@ namespace IW4MAdmin.Plugins.Stats.Commands
// fixme: this doesn't work properly when another context exists // fixme: this doesn't work properly when another context exists
await svc.SaveChangesAsync(); await svc.SaveChangesAsync();
await E.Origin.Tell("Your stats for this server have been reset"); await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_COMMANDS_RESET_SUCCESS"]);
} }
else else
{ {
await E.Origin.Tell("You must be connected to a server to reset your stats"); await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_COMMANDS_RESET_FAIL"]);
} }
} }
} }

View File

@ -12,7 +12,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
{ {
class TopStats : Command class TopStats : Command
{ {
public TopStats() : base("topstats", "view the top 5 players on this server", "ts", Player.Permission.User, false) { } public TopStats() : base("topstats", Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_COMMANDS_TOP_DESC"], "ts", Player.Permission.User, false) { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
@ -43,17 +43,17 @@ namespace IW4MAdmin.Plugins.Stats.Commands
if (!E.Message.IsBroadcastCommand()) if (!E.Message.IsBroadcastCommand())
{ {
await E.Origin.Tell("^5--Top Players--"); await E.Origin.Tell($"^5--{Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_COMMANDS_TOP_TEXT"]}--");
foreach (var stat in topStats) foreach (var stat in topStats)
await E.Origin.Tell($"^3{stat.Name}^7 - ^5{stat.KDR} ^7KDR | ^5{stat.Skill} ^7SKILL"); await E.Origin.Tell($"^3{stat.Name}^7 - ^5{stat.KDR} ^7KDR | ^5{stat.Skill} ^7{Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_TEXT_SKILL"]}");
} }
else else
{ {
await E.Owner.Broadcast("^5--Top Players--"); await E.Owner.Broadcast($"^5--{Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_COMMANDS_TOP_TEXT"]}--");
foreach (var stat in topStats) foreach (var stat in topStats)
await E.Owner.Broadcast($"^3{stat.Name}^7 - ^5{stat.KDR} ^7KDR | ^5{stat.Skill} ^7SKILL"); await E.Owner.Broadcast($"^3{stat.Name}^7 - ^5{stat.KDR} ^7KDR | ^5{stat.Skill} ^7{Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_TEXT_SKILL"]}");
} }
} }
} }

View File

@ -12,7 +12,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
{ {
public class CViewStats : Command public class CViewStats : Command
{ {
public CViewStats() : base("stats", "view your stats", "xlrstats", Player.Permission.User, false, new CommandArgument[] public CViewStats() : base("stats", Utilities.CurrentLocalization.LocalizationSet["PLUGINS_STATS_COMMANDS_VIEW_DESC"], "xlrstats", Player.Permission.User, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
@ -24,15 +24,17 @@ namespace IW4MAdmin.Plugins.Stats.Commands
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
var loc = Utilities.CurrentLocalization.LocalizationSet;
if (E.Target?.ClientNumber < 0) if (E.Target?.ClientNumber < 0)
{ {
await E.Origin.Tell("The specified player must be ingame"); await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME"]);
return; return;
} }
if (E.Origin.ClientNumber < 0 && E.Target == null) if (E.Origin.ClientNumber < 0 && E.Target == null)
{ {
await E.Origin.Tell("You must be ingame to view your stats"); await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL_INGAME_SELF"]);
return; return;
} }
@ -41,7 +43,7 @@ namespace IW4MAdmin.Plugins.Stats.Commands
if (E.Data.Length > 0 && E.Target == null) if (E.Data.Length > 0 && E.Target == null)
{ {
await E.Origin.Tell("Cannot find the player you specified"); await E.Origin.Tell(loc["PLUGINS_STATS_COMMANDS_VIEW_FAIL"]);
return; return;
} }
@ -51,26 +53,26 @@ namespace IW4MAdmin.Plugins.Stats.Commands
if (E.Target != null) if (E.Target != null)
{ {
pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Target.ClientId).First(); pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Target.ClientId).First();
statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill); statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Skill} ^7{loc["PLUGINS_STATS_TEXT_SKILL"]}";
} }
else else
{ {
pStats = pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Origin.ClientId).First(); pStats = pStats = clientStats.Find(c => c.ServerId == serverId && c.ClientId == E.Origin.ClientId).First();
statLine = String.Format("^5{0} ^7KILLS | ^5{1} ^7DEATHS | ^5{2} ^7KDR | ^5{3} ^7SKILL", pStats.Kills, pStats.Deaths, pStats.KDR, pStats.Skill); statLine = $"^5{pStats.Kills} ^7{loc["PLUGINS_STATS_TEXT_KILLS"]} | ^5{pStats.Deaths} ^7{loc["PLUGINS_STATS_TEXT_DEATHS"]} | ^5{pStats.KDR} ^7KDR | ^5{pStats.Skill} ^7{loc["PLUGINS_STATS_TEXT_SKILL"]}";
} }
if (E.Message.IsBroadcastCommand()) if (E.Message.IsBroadcastCommand())
{ {
string name = E.Target == null ? E.Origin.Name : E.Target.Name; string name = E.Target == null ? E.Origin.Name : E.Target.Name;
await E.Owner.Broadcast($"Stats for ^5{name}^7"); await E.Owner.Broadcast($"{loc["PLUGINS_STATS_COMMANDS_VIEW_SUCCESS"]} ^5{name}^7");
await E.Owner.Broadcast(statLine); await E.Owner.Broadcast(statLine);
} }
else else
{ {
if (E.Target != null) if (E.Target != null)
await E.Origin.Tell($"Stats for ^5{E.Target.Name}^7"); await E.Origin.Tell($"{loc["PLUGINS_STATS_COMMANDS_VIEW_SUCCESS"]} ^5{E.Target.Name}^7");
await E.Origin.Tell(statLine); await E.Origin.Tell(statLine);
} }
} }

View File

@ -5,7 +5,7 @@
### Version 2.1 ### Version 2.1
_______ _______
### About ### About
**IW4MAdmin** is an administration tool for [IW4x](https://iw4xcachep26muba.onion.link/), [Pluto T6](https://forum.plutonium.pw/category/33/plutonium-t6) [Pluto IW5](https://forum.plutonium.pw/category/5/plutonium-iw5), and most Call of Duty® dedicated servers. It allows complete control of your server; from changing maps, to banning players, **IW4MAdmin** monitors and records activity on your server(s). With plugin support, extending its functionality is a breeze. **IW4MAdmin** is an administration tool for [IW4x](https://iw4xcachep26muba.onion.link/), [Pluto T6](https://forum.plutonium.pw/category/33/plutonium-t6), [Pluto IW5](https://forum.plutonium.pw/category/5/plutonium-iw5), and most Call of Duty® dedicated servers. It allows complete control of your server; from changing maps, to banning players, **IW4MAdmin** monitors and records activity on your server(s). With plugin support, extending its functionality is a breeze.
### Setup ### Setup
**IW4MAdmin** requires minimal configuration to run. There is only one prerequisite. **IW4MAdmin** requires minimal configuration to run. There is only one prerequisite.

View File

@ -15,7 +15,7 @@ namespace SharedLibraryCore.Commands
public class CQuit : Command public class CQuit : Command
{ {
public CQuit() : public CQuit() :
base("quit", "quit IW4MAdmin", "q", Player.Permission.Owner, false) base("quit", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_QUIT_DESC"], "q", Player.Permission.Owner, false)
{ } { }
public override Task ExecuteAsync(GameEvent E) public override Task ExecuteAsync(GameEvent E)
@ -27,7 +27,7 @@ namespace SharedLibraryCore.Commands
public class COwner : Command public class COwner : Command
{ {
public COwner() : public COwner() :
base("owner", "claim ownership of the server", "o", Player.Permission.User, false) base("owner", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_OWNER_DESC"], "o", Player.Permission.User, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -46,16 +46,16 @@ namespace SharedLibraryCore.Commands
public class CWarn : Command public class CWarn : Command
{ {
public CWarn() : public CWarn() :
base("warn", "warn player for infringing rules", "w", Player.Permission.Trusted, true, new CommandArgument[] base("warn", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_WARN_DESC"], "w", Player.Permission.Trusted, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "reason", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_REASON"],
Required = true Required = true
} }
}) })
@ -73,11 +73,11 @@ namespace SharedLibraryCore.Commands
public class CWarnClear : Command public class CWarnClear : Command
{ {
public CWarnClear() : public CWarnClear() :
base("warnclear", "remove all warning for a player", "wc", Player.Permission.Trusted, true, new CommandArgument[] base("warnclear", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_WARNCLEAR_DESC"], "wc", Player.Permission.Trusted, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
} }
}) })
@ -94,17 +94,17 @@ namespace SharedLibraryCore.Commands
public class CKick : Command public class CKick : Command
{ {
public CKick() : public CKick() :
base("kick", "kick a player by name", "k", Player.Permission.Trusted, true, new CommandArgument[] base("kick", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_KICK_DESC"], "k", Player.Permission.Trusted, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "reason", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_REASON"],
Required = true Required = true
} }
}) })
{ } { }
@ -125,11 +125,11 @@ namespace SharedLibraryCore.Commands
public class CSay : Command public class CSay : Command
{ {
public CSay() : public CSay() :
base("say", "broadcast message to all players", "s", Player.Permission.Moderator, false, new CommandArgument[] base("say", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_SAY_DESC"], "s", Player.Permission.Moderator, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "message", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_MESSAGE"],
Required = true Required = true
} }
}) })
@ -144,21 +144,21 @@ namespace SharedLibraryCore.Commands
public class CTempBan : Command public class CTempBan : Command
{ {
public CTempBan() : public CTempBan() :
base("tempban", "temporarily ban a player for specified time (defaults to 1 hour)", "tb", Player.Permission.Moderator, true, new CommandArgument[] base("tempban", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_TEMPBAN_DESC"], "tb", Player.Permission.Moderator, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "duration (m|h|d|w|y)", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_DURATION"],
Required = true, Required = true,
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "reason", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_REASON"],
Required = true Required = true
} }
}) })
@ -184,16 +184,16 @@ namespace SharedLibraryCore.Commands
public class CBan : Command public class CBan : Command
{ {
public CBan() : public CBan() :
base("ban", "permanently ban a player from the server", "b", Player.Permission.SeniorAdmin, true, new CommandArgument[] base("ban", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_BAN_DESC"], "b", Player.Permission.SeniorAdmin, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "reason", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_REASON"],
Required = true Required = true
} }
}) })
@ -214,16 +214,16 @@ namespace SharedLibraryCore.Commands
public class CUnban : Command public class CUnban : Command
{ {
public CUnban() : public CUnban() :
base("unban", "unban player by client id", "ub", Player.Permission.SeniorAdmin, true, new CommandArgument[] base("unban", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_UNBAN_DESC"], "ub", Player.Permission.SeniorAdmin, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "client id", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_CLIENTID"],
Required = true, Required = true,
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "reason", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_REASON"],
Required = true Required = true
} }
}) })
@ -247,7 +247,7 @@ namespace SharedLibraryCore.Commands
public class CWhoAmI : Command public class CWhoAmI : Command
{ {
public CWhoAmI() : public CWhoAmI() :
base("whoami", "give information about yourself.", "who", Player.Permission.User, false) base("whoami", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_WHO_DESC"], "who", Player.Permission.User, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -260,7 +260,7 @@ namespace SharedLibraryCore.Commands
public class CList : Command public class CList : Command
{ {
public CList() : public CList() :
base("list", "list active clients", "l", Player.Permission.Moderator, false) base("list", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_LIST_DESC"], "l", Player.Permission.Moderator, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -295,11 +295,11 @@ namespace SharedLibraryCore.Commands
public class CHelp : Command public class CHelp : Command
{ {
public CHelp() : public CHelp() :
base("help", "list all available commands", "h", Player.Permission.User, false, new CommandArgument[] base("help", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_HELP_DESC"], "h", Player.Permission.User, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "command", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_COMMANDS"],
Required = false Required = false
} }
}) })
@ -359,7 +359,7 @@ namespace SharedLibraryCore.Commands
public class CFastRestart : Command public class CFastRestart : Command
{ {
public CFastRestart() : public CFastRestart() :
base("fastrestart", "fast restart current map", "fr", Player.Permission.Moderator, false) base("fastrestart", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_FASTRESTART_DESC"], "fr", Player.Permission.Moderator, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -376,7 +376,7 @@ namespace SharedLibraryCore.Commands
public class CMapRotate : Command public class CMapRotate : Command
{ {
public CMapRotate() : public CMapRotate() :
base("maprotate", "cycle to the next map in rotation", "mr", Player.Permission.Administrator, false) base("maprotate", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_MAPROTATE_DESC"], "mr", Player.Permission.Administrator, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -393,16 +393,16 @@ namespace SharedLibraryCore.Commands
public class CSetLevel : Command public class CSetLevel : Command
{ {
public CSetLevel() : public CSetLevel() :
base("setlevel", "set player to specified administration level", "sl", Player.Permission.Moderator, true, new CommandArgument[] base("setlevel", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_SETLEVEL_DESC"], "sl", Player.Permission.Moderator, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "level", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_LEVEL"],
Required = true Required = true
} }
}) })
@ -437,7 +437,6 @@ namespace SharedLibraryCore.Commands
if (E.Origin.Level < Player.Permission.Owner) if (E.Origin.Level < Player.Permission.Owner)
{ {
await E.Origin.Tell(string.Format(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_SETLEVEL_LEVELTOOHIGH"], E.Target.Name, (E.Origin.Level - 1).ToString())); await E.Origin.Tell(string.Format(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_SETLEVEL_LEVELTOOHIGH"], E.Target.Name, (E.Origin.Level - 1).ToString()));
await E.Origin.Tell($"You can only promote ^5{E.Target.Name} ^7to ^5{(E.Origin.Level - 1)} ^7or lower privilege");
return; return;
} }
} }
@ -480,32 +479,33 @@ namespace SharedLibraryCore.Commands
public class CUsage : Command public class CUsage : Command
{ {
public CUsage() : public CUsage() :
base("usage", "get current application memory usage", "us", Player.Permission.Moderator, false) base("usage", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_USAGE_DESC"], "us", Player.Permission.Moderator, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
await E.Origin.Tell("IW4M Admin is using " + Math.Round(((System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / 2048f) / 1200f), 1) + "MB"); await E.Origin.Tell($"IW4MAdmin {Utilities.CurrentLocalization.LocalizationSet["COMMANDS_USAGE_TEXT"]}" + Math.Round(((System.Diagnostics.Process.GetCurrentProcess().PrivateMemorySize64 / 2048f) / 1200f), 1) + "MB");
} }
} }
public class CUptime : Command public class CUptime : Command
{ {
public CUptime() : public CUptime() :
base("uptime", "get current application running time", "up", Player.Permission.Moderator, false) base("uptime", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_UPTIME_DESC"], "up", Player.Permission.Moderator, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
TimeSpan uptime = DateTime.Now - System.Diagnostics.Process.GetCurrentProcess().StartTime; TimeSpan uptime = DateTime.Now - System.Diagnostics.Process.GetCurrentProcess().StartTime;
await E.Origin.Tell(String.Format("IW4M Admin has been up for {0} days, {1} hours, and {2} minutes", uptime.Days, uptime.Hours, uptime.Minutes)); var loc = Utilities.CurrentLocalization.LocalizationSet;
await E.Origin.Tell($"IW4M Admin {loc["COMMANDS_UPTIME_TEXT"]} {uptime.Days} {loc["GLOBAL_DAYS"]}, {uptime.Hours} {loc["GLOBAL_HOURS"]}, {uptime.Minutes} {loc["GLOBAL_MINUTES"]}");
} }
} }
public class CListAdmins : Command public class CListAdmins : Command
{ {
public CListAdmins() : public CListAdmins() :
base("admins", "list currently connected admins", "a", Player.Permission.User, false) base("admins", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ADMINS_DESC"], "a", Player.Permission.User, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -532,11 +532,11 @@ namespace SharedLibraryCore.Commands
public class CLoadMap : Command public class CLoadMap : Command
{ {
public CLoadMap() : public CLoadMap() :
base("map", "change to specified map", "m", Player.Permission.Administrator, false, new CommandArgument[] base("map", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_MAP_DESC"], "m", Player.Permission.Administrator, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "map", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_MAP"],
Required = true Required = true
} }
}) })
@ -565,11 +565,11 @@ namespace SharedLibraryCore.Commands
public class CFindPlayer : Command public class CFindPlayer : Command
{ {
public CFindPlayer() : public CFindPlayer() :
base("find", "find player in database", "f", Player.Permission.Administrator, false, new CommandArgument[] base("find", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_FIND_DESC"], "f", Player.Permission.Administrator, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
} }
}) })
@ -608,7 +608,7 @@ namespace SharedLibraryCore.Commands
public class CListRules : Command public class CListRules : Command
{ {
public CListRules() : public CListRules() :
base("rules", "list server rules", "r", Player.Permission.User, false) base("rules", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_RULES_DESC"], "r", Player.Permission.User, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -643,16 +643,16 @@ namespace SharedLibraryCore.Commands
public class CPrivateMessage : Command public class CPrivateMessage : Command
{ {
public CPrivateMessage() : public CPrivateMessage() :
base("privatemessage", "send message to other player", "pm", Player.Permission.User, true, new CommandArgument[] base("privatemessage", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_PM_DESC"], "pm", Player.Permission.User, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "message", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_MESSAGE"],
Required = true Required = true
} }
}) })
@ -668,16 +668,16 @@ namespace SharedLibraryCore.Commands
public class CFlag : Command public class CFlag : Command
{ {
public CFlag() : public CFlag() :
base("flag", "flag a suspicious player and announce to admins on join", "fp", Player.Permission.Moderator, true, new CommandArgument[] base("flag", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_FLAG_DESC"], "fp", Player.Permission.Moderator, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "reason", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_REASON"],
Required = true Required = true
} }
}) })
@ -726,16 +726,16 @@ namespace SharedLibraryCore.Commands
public class CReport : Command public class CReport : Command
{ {
public CReport() : public CReport() :
base("report", "report a player for suspicious behavior", "rep", Player.Permission.User, true, new CommandArgument[] base("report", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_REPORT_DESC"], "rep", Player.Permission.User, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
}, },
new CommandArgument() new CommandArgument()
{ {
Name = "reason", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_REASON"],
Required = true Required = true
} }
}) })
@ -778,11 +778,11 @@ namespace SharedLibraryCore.Commands
public class CListReports : Command public class CListReports : Command
{ {
public CListReports() : public CListReports() :
base("reports", "get or clear recent reports", "reps", Player.Permission.Moderator, false, new CommandArgument[] base("reports", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_REPORTS_DESC"], "reps", Player.Permission.Moderator, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "clear", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_CLEAR"],
Required = false Required = false
} }
}) })
@ -790,7 +790,7 @@ namespace SharedLibraryCore.Commands
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
if (E.Data != null && E.Data.ToLower().Contains("clear")) if (E.Data != null && E.Data.ToLower().Contains(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_CLEAR"]))
{ {
E.Owner.Reports = new List<Report>(); E.Owner.Reports = new List<Report>();
await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_REPORTS_CLEAR_SUCCESS"]); await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_REPORTS_CLEAR_SUCCESS"]);
@ -811,7 +811,7 @@ namespace SharedLibraryCore.Commands
public class CMask : Command public class CMask : Command
{ {
public CMask() : public CMask() :
base("mask", "hide your presence as an administrator", "hide", Player.Permission.Moderator, false) base("mask", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_MASK_DESC"], "hide", Player.Permission.Moderator, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -834,11 +834,11 @@ namespace SharedLibraryCore.Commands
public class CListBanInfo : Command public class CListBanInfo : Command
{ {
public CListBanInfo() : public CListBanInfo() :
base("baninfo", "get information about a ban for a player", "bi", Player.Permission.Moderator, true, new CommandArgument[] base("baninfo", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_BANINFO_DESC"], "bi", Player.Permission.Moderator, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true Required = true
} }
}) })
@ -861,17 +861,17 @@ namespace SharedLibraryCore.Commands
await E.Origin.Tell($"^1{E.Target.Name} ^7{string.Format(success, penalty.Punisher.Name)} {penalty.Punisher.Name} {timeRemaining}"); await E.Origin.Tell($"^1{E.Target.Name} ^7{string.Format(success, penalty.Punisher.Name)} {penalty.Punisher.Name} {timeRemaining}");
} }
} }
public class CListAlias : Command public class CListAlias : Command
{ {
public CListAlias() : public CListAlias() :
base("alias", "get past aliases and ips of a player", "known", Player.Permission.Moderator, true, new CommandArgument[] base("alias", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ALIAS_DESC"], "known", Player.Permission.Moderator, true, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "player", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = true, Required = true,
} }
}) })
@ -899,11 +899,11 @@ namespace SharedLibraryCore.Commands
public class CExecuteRCON : Command public class CExecuteRCON : Command
{ {
public CExecuteRCON() : public CExecuteRCON() :
base("rcon", "send rcon command to server", "rcon", Player.Permission.Owner, false, new CommandArgument[] base("rcon", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_RCON_DESC"], "rcon", Player.Permission.Owner, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "command", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_COMMANDS"],
Required = true Required = true
} }
}) })
@ -922,12 +922,12 @@ namespace SharedLibraryCore.Commands
public class CPlugins : Command public class CPlugins : Command
{ {
public CPlugins() : public CPlugins() :
base("plugins", "view all loaded plugins", "p", Player.Permission.Administrator, false) base("plugins", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_PLUGINS_DESC"], "p", Player.Permission.Administrator, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {
await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_PLUGINS_LOADE"]); await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_PLUGINS_LOADED"]);
foreach (var P in Plugins.PluginImporter.ActivePlugins) foreach (var P in Plugins.PluginImporter.ActivePlugins)
{ {
await E.Origin.Tell(String.Format("^3{0} ^7[v^3{1}^7] by ^5{2}^7", P.Name, P.Version, P.Author)); await E.Origin.Tell(String.Format("^3{0} ^7[v^3{1}^7] by ^5{2}^7", P.Name, P.Version, P.Author));
@ -938,7 +938,7 @@ namespace SharedLibraryCore.Commands
public class CIP : Command public class CIP : Command
{ {
public CIP() : public CIP() :
base("getexternalip", "view your external IP address", "ip", Player.Permission.User, false) base("getexternalip", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_IP_DESC"], "ip", Player.Permission.User, false)
{ } { }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
@ -949,11 +949,11 @@ namespace SharedLibraryCore.Commands
public class CPruneAdmins : Command public class CPruneAdmins : Command
{ {
public CPruneAdmins() : base("prune", "demote any admins that have not connected recently (defaults to 30 days)", "pa", Player.Permission.Owner, false, new CommandArgument[] public CPruneAdmins() : base("prune", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_PRUNE_DESC"], "pa", Player.Permission.Owner, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "inactive days", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_INACTIVE"],
Required = false Required = false
} }
}) })
@ -975,7 +975,7 @@ namespace SharedLibraryCore.Commands
catch (FormatException) catch (FormatException)
{ {
await E.Origin.Tell("Invalid number of inactive days"); await E.Origin.Tell(Utilities.CurrentLocalization.LocalizationSet["COMMANDS_PRUNE_FAIL"]);
return; return;
} }
@ -999,11 +999,11 @@ namespace SharedLibraryCore.Commands
public class CSetPassword : Command public class CSetPassword : Command
{ {
public CSetPassword() : base("setpassword", "set your authentication password", "sp", Player.Permission.Moderator, false, new CommandArgument[] public CSetPassword() : base("setpassword", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_SETPASSWORD_DESC"], "sp", Player.Permission.Moderator, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "password", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PASSWORD"],
Required = true Required = true
} }
}) })
@ -1030,6 +1030,7 @@ namespace SharedLibraryCore.Commands
} }
} }
/*
public class CKillServer : Command public class CKillServer : Command
{ {
public CKillServer() : base("killserver", "kill the game server", "kill", Player.Permission.Administrator, false) public CKillServer() : base("killserver", "kill the game server", "kill", Player.Permission.Administrator, false)
@ -1081,19 +1082,20 @@ namespace SharedLibraryCore.Commands
} }
} }
} }
} }*/
public class CPing : Command public class CPing : Command
{ {
public CPing() : base("ping", "get client's ping", "pi", Player.Permission.User, false, new CommandArgument[] public CPing() : base("ping", Utilities.CurrentLocalization.LocalizationSet["COMMANDS_PING_DESC"], "pi", Player.Permission.User, false, new CommandArgument[]
{ {
new CommandArgument() new CommandArgument()
{ {
Name = "client", Name = Utilities.CurrentLocalization.LocalizationSet["COMMANDS_ARGS_PLAYER"],
Required = false Required = false
} }
}){} })
{ }
public override async Task ExecuteAsync(GameEvent E) public override async Task ExecuteAsync(GameEvent E)
{ {

View File

@ -18,6 +18,7 @@ namespace SharedLibraryCore.Configuration
public string IPHubAPIKey { get; set; } public string IPHubAPIKey { get; set; }
public string WebfrontBindUrl { get; set; } public string WebfrontBindUrl { get; set; }
public string CustomParserEncoding { get; set; } public string CustomParserEncoding { get; set; }
public string CustomLocale { get; set; }
public string Id { get; set; } public string Id { get; set; }
public List<ServerConfiguration> Servers { get; set; } public List<ServerConfiguration> Servers { get; set; }
public int AutoMessagePeriod { get; set; } public int AutoMessagePeriod { get; set; }

View File

@ -171,7 +171,6 @@ namespace SharedLibraryCore.RCon
OnSent.Reset(); OnSent.Reset();
OnReceived.Reset(); OnReceived.Reset();
string queryString = "";
byte[] payload = null; byte[] payload = null;
switch (type) switch (type)
@ -186,10 +185,11 @@ namespace SharedLibraryCore.RCon
case StaticHelpers.QueryType.GET_STATUS: case StaticHelpers.QueryType.GET_STATUS:
payload = "ÿÿÿÿgetstatus".Select(Convert.ToByte).ToArray(); payload = "ÿÿÿÿgetstatus".Select(Convert.ToByte).ToArray();
break; break;
case StaticHelpers.QueryType.GET_INFO:
payload = "ÿÿÿÿgetinfo".Select(Convert.ToByte).ToArray();
break;
} }
// byte[] payload = Utilities.EncodingType.GetBytes(queryString); // queryString.Select(Convert.ToByte).ToArray();
retrySend: retrySend:
try try
{ {

View File

@ -182,8 +182,9 @@ namespace SharedLibraryCore
public static long ConvertLong(this string str) public static long ConvertLong(this string str)
{ {
Int64.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out long id); if (Int64.TryParse(str, NumberStyles.HexNumber, CultureInfo.InvariantCulture, out long id))
return id; return id;
return 0;
} }
public static int ConvertToIP(this string str) public static int ConvertToIP(this string str)
@ -357,6 +358,22 @@ namespace SharedLibraryCore
return pID; return pID;
} }
public static Dictionary<string, string> DictionaryFromKeyValue(this string eventLine)
{
string[] values = eventLine.Substring(1).Split('\\');
Dictionary<string, string> dict = null;
if (values.Length % 2 == 0 && values.Length > 1)
{
dict = new Dictionary<string, string>();
for (int i = 0; i < values.Length; i += 2)
dict.Add(values[i], values[i + 1]);
}
return dict;
}
public static Task<Dvar<T>> GetDvarAsync<T>(this Server server, string dvarName) => server.RconParser.GetDvarAsync<T>(server.RemoteConnection, dvarName); public static Task<Dvar<T>> GetDvarAsync<T>(this Server server, string dvarName) => server.RconParser.GetDvarAsync<T>(server.RemoteConnection, dvarName);
public static Task SetDvarAsync(this Server server, string dvarName, object dvarValue) => server.RconParser.SetDvarAsync(server.RemoteConnection, dvarName, dvarValue); public static Task SetDvarAsync(this Server server, string dvarName, object dvarValue) => server.RconParser.SetDvarAsync(server.RemoteConnection, dvarName, dvarValue);
@ -365,5 +382,11 @@ namespace SharedLibraryCore
public static Task<List<Player>> GetStatusAsync(this Server server) => server.RconParser.GetStatusAsync(server.RemoteConnection); public static Task<List<Player>> GetStatusAsync(this Server server) => server.RconParser.GetStatusAsync(server.RemoteConnection);
public static async Task<Dictionary<string, string>> GetInfoAsync(this Server server)
{
var response = await server.RemoteConnection.SendQueryAsync(RCon.StaticHelpers.QueryType.GET_INFO);
return response.FirstOrDefault(r => r[0] == '\\')?.DictionaryFromKeyValue();
}
} }
} }

View File

@ -2,14 +2,14 @@
"name": "asp.net", "name": "asp.net",
"private": true, "private": true,
"dependencies": { "dependencies": {
"bootstrap": "v4.0.0", "bootstrap": "v4.1.0",
"jquery": "3.3.1", "jquery": "3.3.1",
"popper.js": "v1.12.9", "popper.js": "v1.12.9",
"open-iconic": "1.1.1", "open-iconic": "1.1.1",
"moment-timezone": "0.5.14" "moment-timezone": "0.5.14"
}, },
"resolutions": { "resolutions": {
"bootstrap": "v4.0.0", "bootstrap": "v4.1.0",
"jquery": "3.3.1" "jquery": "3.3.1"
} }
} }

View File

@ -14,9 +14,9 @@
"outputFileName": "wwwroot/js/global.min.js", "outputFileName": "wwwroot/js/global.min.js",
"inputFiles": [ "inputFiles": [
"wwwroot/lib/jQuery/dist/jquery.min.js", "wwwroot/lib/jQuery/dist/jquery.min.js",
"wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
"wwwroot/lib/moment/min/moment.min.js", "wwwroot/lib/moment/min/moment.min.js",
"wwwroot/lib/moment-timezone/builds/moment-timezone.min.js", "wwwroot/lib/moment-timezone/builds/moment-timezone.min.js",
"wwwroot/lib/bootstrap/dist/js/bootstrap.min.js",
"wwwroot/js/action.js", "wwwroot/js/action.js",
"wwwroot/js/console.js", "wwwroot/js/console.js",
"wwwroot/js/penalty.js", "wwwroot/js/penalty.js",

File diff suppressed because it is too large Load Diff