From d8c667ff51e324762041ec33f9bdd846117a896e Mon Sep 17 00:00:00 2001 From: SantaSpeen Date: Wed, 26 Jul 2023 00:32:11 +0300 Subject: [PATCH] Added new translations; Added new event; --- src/core/Client.py | 54 +++++---- src/core/Client.pyi | 2 +- src/core/core.py | 28 ++--- src/modules/EventsSystem/events_system.py | 2 + src/modules/i18n/files/cn.json | 80 ++++++++----- src/modules/i18n/files/en.json | 52 ++++++--- src/modules/i18n/files/ru.json | 22 ++++ src/modules/i18n/i18n-builtins.pyi | 133 +++++++++------------- src/modules/i18n/i18n.py | 103 +++++++---------- 9 files changed, 254 insertions(+), 222 deletions(-) diff --git a/src/core/Client.py b/src/core/Client.py index db98a1c..681f523 100644 --- a/src/core/Client.py +++ b/src/core/Client.py @@ -111,8 +111,7 @@ class Client: if not self.__alive: self.log.debug(f"{self.nick}.kick('{reason}') skipped: Not alive;") return - # TODO: i18n - self.log.info(f"Kicked with reason: \"{reason}\"") + self.log.info(i18n.game_player_kicked.format(reason)) await self._send(f"K{reason}") self.__alive = False @@ -272,8 +271,7 @@ class Client: data = await self._recv(True) if data.startswith(b"f"): file = data[1:].decode(config.enc) - # TODO: i18n - self.log.info(f"Requested mode: {file!r}") + self.log.info(i18n.client_mod_request.format(repr(file))) size = -1 for mod in self.__Core.mods_list: if type(mod) == int: @@ -312,10 +310,9 @@ class Client: tr = time.monotonic() - t if self.__Core.lock_upload: self.__Core.lock_upload = False - # TODO: i18n - msg = f"Mod sent: Size {round(size / MB, 3)}mb Speed {math.ceil(size / tr / MB)}Mb/s ({int(tr)}s)" + msg = i18n.client_mod_sent.format(round(size / MB, 3), math.ceil(size / tr / MB), int(tr)) if speed: - msg += f" of limit {int(speed * 2)}Mb/s" + msg += i18n.client_mod_sent_limit.format(int(speed * 2)) self.log.info(msg) sent = sl0 + sl1 ok = sent == size @@ -323,8 +320,7 @@ class Client: self.log.debug(f"SplitLoad_0: {sl0}; SplitLoad_1: {sl1}; At all ({ok}): Sent: {sent}; Lost: {lost}") if not ok: self.__alive = False - # TODO: i18n - self.log.error(f"Error while sending: {file!r}") + self.log.error(i18n.client_mod_sent_error.format(repr(file))) return elif data.startswith(b"SR"): path_list = '' @@ -385,10 +381,11 @@ class Client: lua_data = ev.call_lua_event("onVehicleSpawn", self.cid, car_id, car_data[car_data.find("{"):]) if 1 in lua_data: allow = False - ev_data_list = ev.call_event("onCarSpawn", car=car_json, car_id=car_id, player=self) - d2 = await ev.call_async_event("onCarSpawn", car=car_json, car_id=car_id, player=self) + ev_data_list = ev.call_event("onCarSpawn", data=car_json, car_id=car_id, player=self) + d2 = await ev.call_async_event("onCarSpawn", data=car_json, car_id=car_id, player=self) ev_data_list.extend(d2) for ev_data in ev_data_list: + self.log.debug(ev_data) # TODO: handle event onCarSpawn pass pkt = f"Os:{self.roles}:{self.nick}:{self.cid}-{car_id}:{car_data}" @@ -435,10 +432,11 @@ class Client: ev.call_lua_event("onVehicleDeleted", self.cid, car_id) admin_allow = False # Delete from admin, for example... - ev_data_list = ev.call_event("onCarDelete", car=self._cars[car_id], car_id=car_id, player=self) - d2 = await ev.call_async_event("onCarDelete", car=self._cars[car_id], car_id=car_id, player=self) + ev_data_list = ev.call_event("onCarDelete", data=self._cars[car_id], car_id=car_id, player=self) + d2 = await ev.call_async_event("onCarDelete", data=self._cars[car_id], car_id=car_id, player=self) ev_data_list.extend(d2) for ev_data in ev_data_list: + self.log.debug(ev_data) # TODO: handle event onCarDelete pass @@ -474,10 +472,11 @@ class Client: lua_data = ev.call_lua_event("onVehicleEdited", self.cid, car_id, data[data.find("{"):]) if 1 in lua_data: allow = False - ev_data_list = ev.call_event("onCarEdited", car=new_car_json, car_id=car_id, player=self) - d2 = await ev.call_async_event("onCarEdited", car=new_car_json, car_id=car_id, player=self) + ev_data_list = ev.call_event("onCarEdited", data=new_car_json, car_id=car_id, player=self) + d2 = await ev.call_async_event("onCarEdited", data=new_car_json, car_id=car_id, player=self) ev_data_list.extend(d2) for ev_data in ev_data_list: + self.log.debug(ev_data) # TODO: handle event onCarEdited pass @@ -508,8 +507,8 @@ class Client: car_json = json.loads(raw_data[raw_data.find("{"):]) except Exception as e: self.log.debug(f"Invalid new_car_json: Error: {e}; Data: {raw_data}") - ev.call_event("onCarReset", car=car_json, car_id=car_id, player=self) - await ev.call_async_event("onCarReset", car=car_json, car_id=car_id, player=self) + ev.call_event("onCarReset", data=car_json, car_id=car_id, player=self) + await ev.call_async_event("onCarReset", data=car_json, car_id=car_id, player=self) self.log.debug(f"Car reset: car_id={car_id}") else: self.log.debug(f"Invalid car: car_id={car_id}") @@ -539,6 +538,11 @@ class Client: case "t": # Broken details self.log.debug(f"Something changed/broken: {raw_data}") + cid, car_id = self._get_cid_vid(raw_data[5:]) + if car_id != -1 and cid == self.cid and self._cars[car_id]: + data = raw_data[raw_data.find("{"):] + ev.call_event("onCar", car_id=car_id, data=data) + await ev.call_async_event("onCarFocusMove", car_id=car_id, data=data) await self._send(raw_data, to_all=True, to_self=False) case "m": # Move focus car @@ -546,16 +550,18 @@ class Client: cid, car_id = self._get_cid_vid(raw_data[5:]) if car_id != -1 and cid == self.cid and self._cars[car_id]: self._focus_car = car_id + data = raw_data[raw_data.find("{"):] + ev.call_event("onCarFocusMove", car_id=car_id, data=data) + await ev.call_async_event("onCarFocusMove", car_id=car_id, data=data) await self._send(raw_data, to_all=True, to_self=True) async def _connected_handler(self): - self.log.info(f"Syncing time: {round(time.monotonic() - self._connect_time, 2)}s") # Client connected ev.call_event("onPlayerJoin", player=self) await ev.call_async_event("onPlayerJoin", player=self) await self._send(f"Sn{self.nick}", to_all=True) # I don't know for what it - await self._send(f"JWelcome {self.nick}!", to_all=True) # Hello message + await self._send(i18n.game_welcome_message.format(self.nick), to_all=True) # Hello message for client in self.__Core.clients: if not client: @@ -565,6 +571,7 @@ class Client: continue await self._send(car['packet']) + self.log.info(i18n.client_sync_time.format(round(time.monotonic() - self._connect_time, 2))) self._ready = True async def _chat_handler(self, data): @@ -604,7 +611,7 @@ class Client: await self._send(f"C:{message}", to_all=to_all, to_self=to_self, writer=writer) need_send = False except KeyError | AttributeError: - self.log.error(f"Returns invalid data: {ev_data}") + self.log.error(i18n.client_event_invalid_data.format(ev_data)) if need_send: if config.Options['log_chat']: self.log.info(f"{self.nick}: {msg}") @@ -681,8 +688,11 @@ class Client: ev.call_event("onPlayerDisconnect", player=self) await ev.call_async_event("onPlayerDisconnect", player=self) - # TODO: i18n - self.log.info(f"Disconnected, online time: {round((time.monotonic() - self._connect_time) / 60, 2)}min.") + self.log.info( + i18n.client_player_disconnected.format( + round((time.monotonic() - self._connect_time) / 60, 2) + ) + ) self.__Core.clients[self.cid] = None del self.__Core.clients_by_id[self.cid] del self.__Core.clients_by_nick[self.nick] diff --git a/src/core/Client.pyi b/src/core/Client.pyi index 4ff83ce..ccf28b4 100644 --- a/src/core/Client.pyi +++ b/src/core/Client.pyi @@ -35,7 +35,7 @@ class Client: self._ready = False self._focus_car = -1 self._identifiers = [] - self._cars: List[Optional[Dict[str, int]]] = [] + self._cars: List[Union[Dict[str, Union[str, bool, Dict[str, Union[str, List[int], float]]]], None]] = [] self._snowman: Dict[str, Union[int, str]] = {"id": -1, "packet": ""} self._last_position = {} async def __gracefully_kick(self): ... diff --git a/src/core/core.py b/src/core/core.py index bf2c69e..cd6f69a 100644 --- a/src/core/core.py +++ b/src/core/core.py @@ -142,8 +142,7 @@ class Core: async def heartbeat(self, test=False): if config.Auth["private"] or self.direct: if test: - # TODO: i18n - self.log.info(f"Server runnig in Direct connect mode.") + self.log.info(i18n.core_direct_mode) self.direct = True return @@ -184,31 +183,30 @@ class Core: if not (body.get("status") is not None and body.get("code") is not None and body.get("msg") is not None): - self.log.error("Missing/invalid json members in backend response") - raise KeyboardInterrupt + self.log.error(i18n.core_auth_server_error) + return status = body.get("status") msg = body.get("msg") if status == "2000": if test: - # TODO: i18n - self.log.info(f"Authenticated! {msg}") + self.log.debug(f"Authenticated! {msg}") elif status == "200": if test: - self.log.info(f"Resumed authenticated session. {msg}") + self.log.debug(f"Resumed authenticated session. {msg}") else: self.log.debug(f"Auth: data {data}") self.log.debug(f"Auth: code {code}, body {body}") - self.log.error(f"Backend REFUSED the auth key. Reason: " - f"{msg or 'Backend did not provide a reason'}") - self.log.info(f"Server still runnig, but only in Direct connect mode.") + + self.log.error(i18n.core_auth_server_refused.format( + msg or i18n.core_auth_server_refused_no_reason)) + self.log.info(i18n.core_auth_server_refused_direct_node) self.direct = True else: self.direct = True if test: - # TODO: i18n - self.log.error("Cannot authenticate server.") - self.log.info(f"Server still runnig, but only in Direct connect mode.") + self.log.error(i18n.core_auth_server_no_response) + self.log.info(i18n.core_auth_server_refused_direct_node) # if not config.Auth['private']: # raise KeyboardInterrupt @@ -263,8 +261,7 @@ class Core: self.log.debug(f"mods_list: {self.mods_list}") len_mods = len(self.mods_list) - 1 if len_mods > 0: - # TODO: i18n - self.log.info(f"Loaded {len_mods} mods: {round(self.mods_list[0] / MB, 2)}mb") + self.log.info(i18n.core_mods_loaded.format(len_mods, round(self.mods_list[0] / MB, 2))) self.log.info(i18n.init_ok) await self.heartbeat(True) @@ -278,7 +275,6 @@ class Core: t = asyncio.wait(tasks, return_when=asyncio.FIRST_EXCEPTION) await ev.call_async_event("_plugins_start") - # await ev.call_async_event("_lua_plugins_start") self.run = True self.log.info(i18n.start) diff --git a/src/modules/EventsSystem/events_system.py b/src/modules/EventsSystem/events_system.py index e1eaae8..8ec3437 100644 --- a/src/modules/EventsSystem/events_system.py +++ b/src/modules/EventsSystem/events_system.py @@ -31,6 +31,8 @@ class EventsSystem: "onCarDelete": [], "onCarEdited": [], "onCarReset": [], + "" + "onCarFocusMove": [], "onSentPing": [], # Only sync "onChangePosition": [], # Only sync "onPlayerDisconnect": [], diff --git a/src/modules/i18n/files/cn.json b/src/modules/i18n/files/cn.json index f745560..983c7e4 100644 --- a/src/modules/i18n/files/cn.json +++ b/src/modules/i18n/files/cn.json @@ -1,48 +1,70 @@ { - "": "基础阶段", - "hello": "来自KuiToi服务器的问候!", - "config_path": "使用{}进行配置。", + "": "基本阶段", + "hello": "来自 KuiToi-Server 的问候!", + "config_path": "使用 {} 进行配置。", "init_ok": "初始化完成。", "start": "服务器已启动!", "stop": "服务器已停止!", "": "服务器认证", - "auth_need_key": "需要BeamMP密钥才能启动!", - "auth_empty_key": "BeamMP密钥为空!", - "auth_cannot_open_browser": "无法打开浏览器:{}", - "auth_use_link": "使用此链接:{}", + "auth_need_key": "启动需要 BeamMP 密钥!", + "auth_empty_key": "BeamMP 密钥为空!", + "auth_cannot_open_browser": "无法打开浏览器: {}", + "auth_use_link": "使用此链接: {}", - "": "GUI阶段", + "": "GUI 阶段", "GUI_yes": "是", "GUI_no": "否", - "GUI_ok": "确定", + "GUI_ok": "好的", "GUI_cancel": "取消", - "GUI_need_key_message": "需要BeamMP密钥才能启动!\n是否在浏览器中打开链接以获取密钥?", - "GUI_enter_key_message": "请输入密钥:", - "GUI_cannot_open_browser": "无法打开浏览器。\n请使用此链接:{}", + "GUI_need_key_message": "启动需要 BeamMP 密钥!\n是否要在浏览器中打开链接以获取密钥?", + "GUI_enter_key_message": "请输入密钥:", + "GUI_cannot_open_browser": "无法打开浏览器。\n使用此链接: {}", - "": "Web阶段", - "web_start": "WebAPI已启动{}(CTRL+C停止)", + "": "Web 阶段", + "web_start": "WebAPI 已启动 {} (按 CTRL+C 停止)", - "": "命令:man", - "man_message_man": "man - 显示COMMAND的帮助页面。\n用法:man COMMAND", - "help_message_man": "显示COMMAND的帮助页面。", + "": "核心短语", + "core_direct_mode": "服务器以直接连接模式启动。", + "core_auth_server_error": "从 BeamMP 认证服务器收到不正确的响应。", + "core_auth_server_refused": "BeamMP 认证服务器拒绝您的密钥。原因: {}", + "core_auth_server_refused_no_reason": "BeamMP 认证服务器未提供原因。", + "core_auth_server_refused_direct_node": "服务器仍在运行,但以直接连接模式运行。", + "core_auth_server_no_response": "认证服务器无响应。", + "core_mods_loaded": "{} 个模组已加载。{}Mb", + + "": "游戏短语", + "game_player_kicked": "因为 \"{}\" 被踢出游戏。", + "game_welcome_message": "欢迎 {}!", + + "": "客户端短语", + "client_mod_request": "请求模组: {}", + "client_mod_sent": "发送模组: 大小: {}mb, 速度: {}Mb/s ({}秒)", + "client_mod_sent_limit": " (限制 {}Mb/s)", + "client_mod_sent_error": "发送模组时出错: {}", + "client_sync_time": "同步时间 {}秒。", + "client_event_invalid_data": "从事件返回的数据无效: {}", + "client_player_disconnected": "已从服务器断开连接。游戏时间: {} 分钟。", + + "": "命令: man", + "man_message_man": "man - 显示 COMMAND 的帮助页面。\n用法:man COMMAND", + "help_message_man": "显示 COMMAND 的帮助页面。", "man_for": "帮助页面", - "man_message_not_found": "man:找不到帮助页面。", - "man_command_not_found": "man:找不到\"{}\"命令!", + "man_message_not_found": "man: 找不到帮助页面。", + "man_command_not_found": "man: 找不到命令\"{}\"!", - "": "命令:help", - "man_message_help": "help - 显示命令的名称和简短描述。\n用法:help [--raw]\n命令`help`列出所有可用的命令,并为每个命令提供简短描述。", - "help_message_help": "显示命令的名称和简短描述。", + "": "命令: help", + "man_message_help": "help - 显示命令的名称和简要描述。\n用法:help [--raw]\n`help` 命令显示所有可用命令的列表以及每个命令的简要描述。", + "help_message_help": "显示命令的名称和简要描述。", "help_command": "命令", "help_message": "文本", - "help_message_not_found": "无文本", + "help_message_not_found": "找不到文本。", - "": "命令:stop", - "man_message_stop": "stop - 关闭服务器。\n用法:stop", - "help_message_stop": "关闭服务器。", + "": "命令: stop", + "man_message_stop": "stop - 停止服务器。\n用法:stop", + "help_message_stop": "停止服务器。", - "": "命令:exit", - "man_message_exit": "exit - 关闭服务器。\n用法:exit", - "help_message_exit": "关闭服务器。" + "": "命令: exit", + "man_message_exit": "exit - 停止服务器。\n用法:exit", + "help_message_exit": "停止服务器。" } \ No newline at end of file diff --git a/src/modules/i18n/files/en.json b/src/modules/i18n/files/en.json index 8c1adda..1b4d3f4 100644 --- a/src/modules/i18n/files/en.json +++ b/src/modules/i18n/files/en.json @@ -1,42 +1,64 @@ { "": "Basic phases", - "hello": "Greetings from KuiToi Server!", - "config_path": "Use {} to configure.", - "init_ok": "Initialization complete.", + "hello": "Hello from KuiToi-Server!", + "config_path": "Use {} for configuration.", + "init_ok": "Initialization completed.", "start": "Server started!", "stop": "Server stopped!", "": "Server auth", - "auth_need_key": "A BeamMP key is required to start the server!", - "auth_empty_key": "The BeamMP key is empty!", + "auth_need_key": "A BeamMP key is required to start!", + "auth_empty_key": "BeamMP key is empty!", "auth_cannot_open_browser": "Failed to open browser: {}", "auth_use_link": "Use this link: {}", "": "GUI phases", "GUI_yes": "Yes", "GUI_no": "No", - "GUI_ok": "Ok", + "GUI_ok": "OK", "GUI_cancel": "Cancel", - "GUI_need_key_message": "A BeamMP key is required to start the server!\nDo you want to open the link in a browser to obtain the key?", + "GUI_need_key_message": "A BeamMP key is required to start!\nDo you want to open the link in your browser to obtain the key?", "GUI_enter_key_message": "Please enter the key:", "GUI_cannot_open_browser": "Failed to open browser.\nUse this link: {}", "": "Web phases", - "web_start": "WebAPI started at {} (Press CTRL+C to quit)", + "web_start": "WebAPI started on {} (CTRL+C to stop)", + + "": "Core phrases", + "core_direct_mode": "Server started in direct connection mode.", + "core_auth_server_error": "Incorrect response received from BeamMP authentication server.", + "core_auth_server_refused": "BeamMP authentication server rejected your key. Reason: {}", + "core_auth_server_refused_no_reason": "BeamMP authentication server did not provide a reason.", + "core_auth_server_refused_direct_node": "Server is still running, but in direct connection mode.", + "core_auth_server_no_response": "Failed to authenticate the server.", + "core_mods_loaded": "{} mods loaded. {}Mb", + + "": "In-game phrases", + "game_player_kicked": "Kicked for reason: \"{}\"", + "game_welcome_message": "Welcome {}!", + + "": "Client class phrases", + "client_mod_request": "Mod requested: {}", + "client_mod_sent": "Mod sent: Size: {}mb, Speed: {}Mb/s ({}sec)", + "client_mod_sent_limit": " (limit {}Mb/s)", + "client_mod_sent_error": "Error sending mod: {}", + "client_sync_time": "Sync time {}sec.", + "client_event_invalid_data": "Invalid data returned from event: {}", + "client_player_disconnected": "Disconnected from the server. Game time: {} min.", "": "Command: man", - "man_message_man": "man - Displays help page for COMMAND.\nUsage: man COMMAND", - "help_message_man": "Displays help page for COMMAND.", + "man_message_man": "man - Shows help page for COMMAND.\nUsage: man COMMAND", + "help_message_man": "Shows help page for COMMAND.", "man_for": "Help page for", - "man_message_not_found": "man: Help page not found.", + "man_message_not_found": "man: No help page found.", "man_command_not_found": "man: Command \"{}\" not found!", "": "Command: help", - "man_message_help": "help - Displays the names and short descriptions of commands.\nUsage: help [--raw]\nThe `help` command displays a list of all available commands and a brief description of each command.", - "help_message_help": "Displays the names and short descriptions of commands.", + "man_message_help": "help - Shows the names and brief descriptions of commands.\nUsage: help [--raw]\nThe `help` command displays a list of all available commands and a brief description for each command.", + "help_message_help": "Shows the names and brief descriptions of commands.", "help_command": "Command", - "help_message": "Description", - "help_message_not_found": "No description available.", + "help_message": "Text", + "help_message_not_found": "No text found.", "": "Command: stop", "man_message_stop": "stop - Stops the server.\nUsage: stop", diff --git a/src/modules/i18n/files/ru.json b/src/modules/i18n/files/ru.json index 294f44a..73f71d0 100644 --- a/src/modules/i18n/files/ru.json +++ b/src/modules/i18n/files/ru.json @@ -24,6 +24,28 @@ "": "Web phases", "web_start": "WebAPI запустился на {} (CTRL+C для выключения)", + "": "Core phrases", + "core_direct_mode": "Сервер запушен в режиме прямого подключения.", + "core_auth_server_error": "Поступил не корректный ответ от сервером авторизации BeamMP.", + "core_auth_server_refused": "Сервер авторизации BeamMP отклонил ваш ключ. Причина: {}", + "core_auth_server_refused_no_reason": "Сервер авторизации BeamMP не сообщил причины.", + "core_auth_server_refused_direct_node": "Сервер всё ещё работает, но в режиме прямого подключения.", + "core_auth_server_no_response": "Не получилось авторизовать сервер.", + "core_mods_loaded": "Загружено {} модов. {}Мб", + + "": "In-game phrases", + "game_player_kicked": "Кикнут по причине: \"{}\"", + "game_welcome_message": "Добро пожаловать {}!", + + "": "Client class phrases", + "client_mod_request": "Запрошен мод: {}", + "client_mod_sent": "Мод отправлен: Вес: {}мб, Скорость: {}Мб/с ({}сек)", + "client_mod_sent_limit": " (лимит {}Мб/с)", + "client_mod_sent_error": "Ошибка при отправке мода: {}", + "client_sync_time": "Время синхронизации {}сек.", + "client_event_invalid_data": "Из ивента вернулись не верные данные: {}", + "client_player_disconnected": "Вышел с сервера. Время игры: {} мин", + "": "Command: man", "man_message_man": "man - Показывает страничку помощи для COMMAND.\nИспользование: man COMMAND", "help_message_man": "Показывает страничку помощи для COMMAND.", diff --git a/src/modules/i18n/i18n-builtins.pyi b/src/modules/i18n/i18n-builtins.pyi index d9523f7..3d71a0a 100644 --- a/src/modules/i18n/i18n-builtins.pyi +++ b/src/modules/i18n/i18n-builtins.pyi @@ -1,93 +1,72 @@ class i18n: # Basic phases - hello: str = data["hello"] - config_path: str = data["config_path"] - init_ok: str = data["init_ok"] - start: str = data["start"] - stop: str = data["stop"] + hello: str + config_path: str + init_ok: str + start: str + stop: str # Server auth - auth_need_key: str = data["auth_need_key"] - auth_empty_key: str = data["auth_empty_key"] - auth_cannot_open_browser: str = data["auth_cannot_open_browser"] - auth_use_link: str = data["auth_use_link"] + auth_need_key: str + auth_empty_key: str + auth_cannot_open_browser: str + auth_use_link: str # GUI phases - GUI_yes: str = data["GUI_yes"] - GUI_no: str = data["GUI_no"] - GUI_ok: str = data["GUI_ok"] - GUI_cancel: str = data["GUI_cancel"] - GUI_need_key_message: str = data["GUI_need_key_message"] - GUI_enter_key_message: str = data["GUI_enter_key_message"] - GUI_cannot_open_browser: str = data["GUI_cannot_open_browser"] + GUI_yes: str + GUI_no: str + GUI_ok: str + GUI_cancel: str + GUI_need_key_message: str + GUI_enter_key_message: str + GUI_cannot_open_browser: str # Web phases - web_start: str = data["web_start"] + web_start: str + + # Core phrases + + core_direct_mode: str + core_auth_server_error: str + core_auth_server_refused: str + core_auth_server_refused_no_reason: str + core_auth_server_refused_direct_node: str + core_auth_server_no_response: str + core_mods_loaded: str + + # In-game phrases + + game_player_kicked: str + game_welcome_message: str + + # Client class phrases + + client_mod_request: str + client_mod_sent: str + client_mod_sent_limit: str + client_mod_sent_error: str + client_sync_time: str + client_event_invalid_data: str + client_player_disconnected: str # Command: man - man_message_man: str = data["man_message_man"] - help_message_man: str = data["help_message_man"] - man_for: str = data["man_for"] - man_message_not_found: str = data["man_message_not_found"] - man_command_not_found: str = data["man_command_not_found"] + man_message_man: str + help_message_man: str + man_for: str + man_message_not_found: str + man_command_not_found: str # Command: help - man_message_help: str = data["man_message_help"] - help_message_help: str = data["help_message_help"] - help_command: str = data["help_command"] - help_message: str = data["help_message"] - help_message_not_found: str = data["help_message_not_found"] + man_message_help: str + help_message_help: str + help_command: str + help_message: str + help_message_not_found: str # Command: stop - man_message_stop: str = data["man_message_stop"] - help_message_stop: str = data["help_message_stop"] + man_message_stop: str + help_message_stop: str # Command: exit - man_message_exit: str = data["man_message_exit"] - help_message_exit: str = data["help_message_exit"] - - data = { - "": "Basic phases", - "hello": "Hello from KuiToi-Server!", - "config_path": "Use {} for config.", - "init_ok": "Initializing ready.", - "start": "Server started!", - "stop": "Goodbye!", - - "": "Server auth", - "auth_need_key": "BEAM key needed for starting the server!", - "auth_empty_key": "Key is empty!", - "auth_cannot_open_browser": "Cannot open browser: {}", - "auth_use_link": "Use this link: {}", - - "": "GUI phases", - "GUI_yes": "Yes", - "GUI_no": "No", - "GUI_ok": "Ok", - "GUI_cancel": "Cancel", - "GUI_need_key_message": "BEAM key needed for starting the server!\nDo you need to open the web link to obtain the key?", - "GUI_enter_key_message": "Please type your key:", - "GUI_cannot_open_browser": "Cannot open browser.\nUse this link: {}", - - "": "Command: man", - "man_message_man": "man - display the manual page for COMMAND.\nUsage: man COMMAND", - "help_message_man": "Display the manual page for COMMAND.", - "man_for": "Manual for command", - "man_message_not_found": "man: Manual message not found.", - "man_command_not_found": "man: command \"{}\" not found!", - - "": "Command: help", - "man_message_help": "help - display names and brief descriptions of available commands.\nUsage: help [--raw]\nThe `help` command displays a list of all available commands along with a brief description of each command.", - "help_message_help": "Display names and brief descriptions of available commands", - "help_command": "Command", - "help_message": "Help message", - "help_message_not_found": "No help message found", - - "": "Command: stop", - "man_message_stop": "stop - Just shutting down the server.\nUsage: stop", - "help_message_stop": "Server shutdown.", - - "": "Command: exit", - "man_message_exit": "exit - Just shutting down the server.\nUsage: stop", - "help_message_exit": "Server shutdown." -} + man_message_exit: str + help_message_exit: str diff --git a/src/modules/i18n/i18n.py b/src/modules/i18n/i18n.py index 2afb957..1894fe8 100644 --- a/src/modules/i18n/i18n.py +++ b/src/modules/i18n/i18n.py @@ -14,56 +14,13 @@ from core.utils import get_logger class i18n: + data = {} def __init__(self, data): - # Basic phases - self.hello: str = data["hello"] - self.config_path: str = data["config_path"] - self.init_ok: str = data["init_ok"] - self.start: str = data["start"] - self.stop: str = data["stop"] + i18n.data = data - # Server auth - self.auth_need_key: str = data["auth_need_key"] - self.auth_empty_key: str = data["auth_empty_key"] - self.auth_cannot_open_browser: str = data["auth_cannot_open_browser"] - self.auth_use_link: str = data["auth_use_link"] - - # GUI phases - self.GUI_yes: str = data["GUI_yes"] - self.GUI_no: str = data["GUI_no"] - self.GUI_ok: str = data["GUI_ok"] - self.GUI_cancel: str = data["GUI_cancel"] - self.GUI_need_key_message: str = data["GUI_need_key_message"] - self.GUI_enter_key_message: str = data["GUI_enter_key_message"] - self.GUI_cannot_open_browser: str = data["GUI_cannot_open_browser"] - - # Web phases - self.web_start: str = data["web_start"] - - # Command: man - self.man_message_man: str = data["man_message_man"] - self.help_message_man: str = data["help_message_man"] - self.man_for: str = data["man_for"] - self.man_message_not_found: str = data["man_message_not_found"] - self.man_command_not_found: str = data["man_command_not_found"] - - # Command: help - self.man_message_help: str = data["man_message_help"] - self.help_message_help: str = data["help_message_help"] - self.help_command: str = data["help_command"] - self.help_message: str = data["help_message"] - self.help_message_not_found: str = data["help_message_not_found"] - - # Command: help - self.man_message_stop: str = data["man_message_stop"] - self.help_message_stop: str = data["help_message_stop"] - - # Command: exit - self.man_message_exit: str = data["man_message_exit"] - self.help_message_exit: str = data["help_message_exit"] - - self.data = data + def __getattribute__(self, key): + return i18n.data[key] class MultiLanguage: @@ -92,43 +49,65 @@ class MultiLanguage: # noinspection PyDictDuplicateKeys self.__data = { "": "Basic phases", - "hello": "Greetings from KuiToi Server!", - "config_path": "Use {} to configure.", - "init_ok": "Initialization complete.", + "hello": "Hello from KuiToi-Server!", + "config_path": "Use {} for configuration.", + "init_ok": "Initialization completed.", "start": "Server started!", "stop": "Server stopped!", "": "Server auth", - "auth_need_key": "A BeamMP key is required to start the server!", - "auth_empty_key": "The BeamMP key is empty!", + "auth_need_key": "A BeamMP key is required to start!", + "auth_empty_key": "BeamMP key is empty!", "auth_cannot_open_browser": "Failed to open browser: {}", "auth_use_link": "Use this link: {}", "": "GUI phases", "GUI_yes": "Yes", "GUI_no": "No", - "GUI_ok": "Ok", + "GUI_ok": "OK", "GUI_cancel": "Cancel", - "GUI_need_key_message": "A BeamMP key is required to start the server!\nDo you want to open the link in a browser to obtain the key?", + "GUI_need_key_message": "A BeamMP key is required to start!\nDo you want to open the link in your browser to obtain the key?", "GUI_enter_key_message": "Please enter the key:", "GUI_cannot_open_browser": "Failed to open browser.\nUse this link: {}", "": "Web phases", - "web_start": "WebAPI started at {} (Press CTRL+C to quit)", + "web_start": "WebAPI started on {} (CTRL+C to stop)", + + "": "Core phrases", + "core_direct_mode": "Server started in direct connection mode.", + "core_auth_server_error": "Incorrect response received from BeamMP authentication server.", + "core_auth_server_refused": "BeamMP authentication server rejected your key. Reason: {}", + "core_auth_server_refused_no_reason": "BeamMP authentication server did not provide a reason.", + "core_auth_server_refused_direct_node": "Server is still running, but in direct connection mode.", + "core_auth_server_no_response": "Failed to authenticate the server.", + "core_mods_loaded": "{} mods loaded. {}Mb", + + "": "In-game phrases", + "game_player_kicked": "Kicked for reason: \"{}\"", + "game_welcome_message": "Welcome {}!", + + "": "Client class phrases", + "client_mod_request": "Mod requested: {}", + "client_mod_sent": "Mod sent: Size: {}mb, Speed: {}Mb/s ({}sec)", + "client_mod_sent_limit": " (limit {}Mb/s)", + "client_mod_sent_error": "Error sending mod: {}", + "client_sync_time": "Sync time {}sec.", + "client_event_invalid_data": "Invalid data returned from event: {}", + "client_player_disconnected": "Disconnected from the server. Game time: {} min.", "": "Command: man", - "man_message_man": "man - Displays help page for COMMAND.\nUsage: man COMMAND", - "help_message_man": "Displays help page for COMMAND.", + "man_message_man": "man - Shows help page for COMMAND.\nUsage: man COMMAND", + "help_message_man": "Shows help page for COMMAND.", "man_for": "Help page for", - "man_message_not_found": "man: Help page not found.", + "man_message_not_found": "man: No help page found.", "man_command_not_found": "man: Command \"{}\" not found!", "": "Command: help", - "man_message_help": "help - Displays the names and short descriptions of commands.\nUsage: help [--raw]\nThe `help` command displays a list of all available commands and a brief description of each command.", - "help_message_help": "Displays the names and short descriptions of commands.", + "man_message_help": "help - Shows the names and brief descriptions of commands.\nUsage: help [--raw]\nThe `help` command displays a list of all available commands and a brief description for each command.", + "help_message_help": "Shows the names and brief descriptions of commands.", "help_command": "Command", - "help_message": "Description", - "help_message_not_found": "No description available.", + "help_message": "Text", + "help_message_not_found": "No text found.", "": "Command: stop", "man_message_stop": "stop - Stops the server.\nUsage: stop",