Compare commits

..

No commits in common. "e5c87bf42e70b7e4246db4c2eceec13fb1a74063" and "df4105ec61be602fbd9fee8f1b6b72df65c9fca7" have entirely different histories.

30 changed files with 1547 additions and 399 deletions

View File

@ -7,24 +7,15 @@
import os import os
import sys import sys
import rtoml import rtoml
import io
sys.path.append(os.path.abspath(os.curdir)) sys.path.append(os.path.abspath(os.curdir))
is_github = "-github" in sys.argv
if is_github:
stdout = sys.stdout
sys.stdout = io.StringIO()
try: try:
from Difficult_Rocket import DR_status from Difficult_Rocket import DR_status
except ImportError: except ImportError:
raise raise
if is_github: args = ["-env", "-github-dev"]
sys.stdout = stdout
if sys.argv == [__file__]: # 没有输入参数,直接输出默认信息并输出 if sys.argv == [__file__]: # 没有输入参数,直接输出默认信息并输出
@ -37,6 +28,10 @@ if sys.argv == [__file__]: # 没有输入参数,直接输出默认信息并
config_file["window"]["height"] = 768 config_file["window"]["height"] = 768
rtoml.dump(config_file, open("./config/main.toml", "w")) rtoml.dump(config_file, open("./config/main.toml", "w"))
elif os.path.abspath(os.curdir) in sys.path and "-env" in sys.argv:
with open("./.github/workflows/env.ps1", encoding="utf-8", mode="w") as env_file:
print(f'$env:DR_version = "{DR_status.DR_version}"', file=env_file)
print(f'$env:Build_version = "{DR_status.Build_version}"', file=env_file)
elif os.path.abspath(os.curdir) in sys.path and "-github" in sys.argv: elif os.path.abspath(os.curdir) in sys.path and "-github" in sys.argv:
print(f"DR_version={DR_status.DR_version}") print(f"DR_version={DR_status.DR_version}")
print(f"Build_version={DR_status.Build_version}") print(f"Build_version={DR_status.Build_version}")

View File

@ -4,26 +4,28 @@
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------
import time
import logging.config
from pathlib import Path from pathlib import Path
from Difficult_Rocket.api.types import Options, Version from Difficult_Rocket.api.types import Options, Version
sdk_version = Version("0.9.0.0-alpha.0") # SDK 版本 sdk_version = Version("0.8.7.3") # SDK 版本
build_version = Version("2.2.0.0") # 编译文件版本(与游戏本体无关) build_version = Version("2.2.0.0") # 编译文件版本(与游戏本体无关)
api_version = Version("0.1.1.0") # API 版本 api_version = Version("0.1.1.0") # API 版本
__version__ = sdk_version __version__ = sdk_version
__all__ = [ __all__ = [
# __init__ # __init__
"DR_status", "DR_status",
# folder # folder
"api", "api",
"data",
"client", "client",
"server",
"command", "command",
"crash", "crash",
"exception", "exception",
"server",
"mod", "mod",
"utils", "utils",
# file # file
@ -35,12 +37,12 @@ __all__ = [
] ]
class _DRStatus(Options): class _DR_status(Options):
""" """
DR 的特性开关 / 基本状态 DR 的特性开关 / 基本状态
""" """
name = "DR Status" name = "DR Option"
# run status # run status
client_running: bool = False client_running: bool = False
server_running: bool = False server_running: bool = False
@ -51,6 +53,7 @@ class _DRStatus(Options):
report_translate_not_found: bool = True report_translate_not_found: bool = True
use_multiprocess: bool = False use_multiprocess: bool = False
use_cProfile: bool = False use_cProfile: bool = False
use_local_logging: bool = False
# tests # tests
playing: bool = False playing: bool = False
@ -73,52 +76,31 @@ class _DRStatus(Options):
return round(12 * self.gui_scale) return round(12 * self.gui_scale)
DR_status = _DRStatus() DR_status = _DR_status()
def load_logger(): def load_logging():
log_config_path = Path("./config/lndl-logger.toml") with open("./config/logger.toml") as f:
import rtoml
import rtoml logger_config = rtoml.load(f)
log_path = logger_config["handlers"]["file"]["filename"]
warn_config = False log_path = f"logs/{log_path.format(time.strftime('%Y-%m-%d %H-%M-%S', time.gmtime(time.time_ns() / 1000_000_000)))}"
if not log_config_path.is_file(): if not Path("logs/").is_dir():
# 生成默认配置文件 Path("logs/").mkdir()
from Difficult_Rocket.data import log_config logger_config["handlers"]["file"]["filename"] = log_path
logging.config.dictConfig(logger_config)
try:
log_config_path.write_text(log_config.default_config)
except (FileNotFoundError, OSError, PermissionError):
print("\033[31mFailed to write default log config file\033[0m")
warn_config = True
logger_config = rtoml.loads(log_config.default_config)
else:
# 读取配置文件
with open(log_config_path, encoding="utf-8") as f:
logger_config = rtoml.load(f)
# 输入 lndl 进行配置
from lib_not_dr.loggers.config import read_config, get_logger
read_config(logger_config)
logger = get_logger("main")
logger.info("Logger config loaded", tag="DR-init")
logger.info(f"DR status:\n{DR_status.as_markdown()}", tag="DR-init")
if warn_config:
logger.warn("Failed to load log config file, use default config", tag="DR-init")
# 读取日志配置 load_logging()
# 也保证可以直接运行,不带日志 ( 因为有默认配置 )
load_logger()
if DR_status.playing: if DR_status.playing:
from Difficult_Rocket.utils.thread import new_thread from Difficult_Rocket.utils.thread import new_thread
def think_it(something): def think_it(something):
return something return something
@new_thread("think") @new_thread("think")
def think(some_thing_to_think): def think(some_thing_to_think):
gotcha = think_it(some_thing_to_think) gotcha = think_it(some_thing_to_think)

View File

@ -11,6 +11,7 @@ github: @shenjackyuanjie
gitee: @shenjackyuanjie gitee: @shenjackyuanjie
""" """
__all__ = [ __all__ = [
"exception", "exception",
# 错误类定义 # 错误类定义

View File

@ -33,6 +33,7 @@ class BaseScreen(EventDispatcher, Options):
self.window_pointer = main_window self.window_pointer = main_window
if TYPE_CHECKING: if TYPE_CHECKING:
def on_command(self, command: CommandText, window: ClientWindow): def on_command(self, command: CommandText, window: ClientWindow):
""" """
命令输入事件 命令输入事件
@ -153,7 +154,7 @@ class BaseScreen(EventDispatcher, Options):
""" """
def on_file_drop( def on_file_drop(
self, x: int, y: int, paths: List[PathLike], window: ClientWindow self, x: int, y: int, paths: List[PathLike], window: ClientWindow
): ):
"""File(s) were dropped into the window, will return the position of the cursor and """File(s) were dropped into the window, will return the position of the cursor and
a list of paths to the files that were dropped. a list of paths to the files that were dropped.
@ -216,14 +217,14 @@ class BaseScreen(EventDispatcher, Options):
""" """
def on_mouse_drag( def on_mouse_drag(
self, self,
x: int, x: int,
y: int, y: int,
dx: int, dx: int,
dy: int, dy: int,
buttons: int, buttons: int,
modifiers: int, modifiers: int,
window: ClientWindow, window: ClientWindow,
): ):
"""The mouse was moved with one or more mouse buttons pressed. """The mouse was moved with one or more mouse buttons pressed.
@ -249,7 +250,7 @@ class BaseScreen(EventDispatcher, Options):
""" """
def on_mouse_press( def on_mouse_press(
self, x: int, y: int, button: int, modifiers: int, window: ClientWindow self, x: int, y: int, button: int, modifiers: int, window: ClientWindow
): ):
"""A mouse button was pressed (and held down). """A mouse button was pressed (and held down).
@ -268,7 +269,7 @@ class BaseScreen(EventDispatcher, Options):
""" """
def on_mouse_release( def on_mouse_release(
self, x: int, y: int, button: int, modifiers: int, window: ClientWindow self, x: int, y: int, button: int, modifiers: int, window: ClientWindow
): ):
"""A mouse button was released. """A mouse button was released.
@ -287,7 +288,7 @@ class BaseScreen(EventDispatcher, Options):
""" """
def on_mouse_scroll( def on_mouse_scroll(
self, x: int, y: int, scroll_x: float, scroll_y: float, window: ClientWindow self, x: int, y: int, scroll_x: float, scroll_y: float, window: ClientWindow
): ):
"""The mouse wheel was scrolled. """The mouse wheel was scrolled.

View File

@ -7,6 +7,7 @@
import os import os
import sys import sys
import time import time
import logging
import inspect import inspect
import functools import functools
import traceback import traceback
@ -42,9 +43,8 @@ from Difficult_Rocket.client.screen import DRDEBUGScreen
from Difficult_Rocket.client.fps.fps_log import FpsLogger from Difficult_Rocket.client.fps.fps_log import FpsLogger
from Difficult_Rocket.exception.language import LanguageNotFound from Difficult_Rocket.exception.language import LanguageNotFound
from lib_not_dr import loggers
logger = loggers.config.get_logger("client") logger = logging.getLogger("client")
class ClientOption(Options): class ClientOption(Options):
@ -78,7 +78,7 @@ class Client:
def __init__(self, game: "Game", net_mode="local"): def __init__(self, game: "Game", net_mode="local"):
start_time = time.time_ns() start_time = time.time_ns()
# logging # logging
self.logger = loggers.get_logger("client") self.logger = logging.getLogger("client")
self.logger.info(tr().client.setup.start()) self.logger.info(tr().client.setup.start())
# config # config
self.config = ClientOption() self.config = ClientOption()
@ -128,7 +128,7 @@ def pyglet_load_fonts_folder(folder) -> None:
if not font_path.exists(): if not font_path.exists():
font_path.mkdir(parents=True) font_path.mkdir(parents=True)
return None return None
logger.info(tr().client.load.font.start().format(font_path), tag="font") logger.info(tr().client.load.font.start().format(font_path))
start_time = time.time_ns() start_time = time.time_ns()
for dir_path, dir_names, file_names in os.walk(font_path): for dir_path, dir_names, file_names in os.walk(font_path):
dir_path = Path(dir_path) dir_path = Path(dir_path)
@ -136,8 +136,7 @@ def pyglet_load_fonts_folder(folder) -> None:
file_name = Path(file_name) file_name = Path(file_name)
if file_name.suffix in (".ttf", ".otf"): if file_name.suffix in (".ttf", ".otf"):
logger.debug( logger.debug(
tr().client.load.font.file().format(str(dir_path / file_name)), tr().client.load.font.file().format(str(dir_path / file_name))
tag="font",
) )
try: try:
pyglet.font.add_file(str(dir_path / file_name)) pyglet.font.add_file(str(dir_path / file_name))
@ -149,9 +148,7 @@ def pyglet_load_fonts_folder(folder) -> None:
) )
end_time = time.time_ns() end_time = time.time_ns()
use_time = end_time - start_time use_time = end_time - start_time
logger.info( logger.info(tr().client.load.font.use_time().format(use_time / 1000000000))
tr().client.load.font.use_time().format(use_time / 1000000000), tag="font"
)
def _call_back(call_back: Callable) -> Callable: def _call_back(call_back: Callable) -> Callable:
@ -243,7 +240,7 @@ class ClientWindow(Window):
start_time = time.time_ns() start_time = time.time_ns()
super().__init__(*args, **kwargs) super().__init__(*args, **kwargs)
# logging # logging
self.logger = loggers.get_logger("client") self.logger = logging.getLogger("client")
self.logger.info(tr().window.setup.start()) self.logger.info(tr().window.setup.start())
# value # value
self.game = game self.game = game
@ -310,13 +307,10 @@ class ClientWindow(Window):
# TODO: wait for pyglet 2.1 # TODO: wait for pyglet 2.1
pyglet.app.run(float(self.SPF)) pyglet.app.run(float(self.SPF))
except KeyboardInterrupt: except KeyboardInterrupt:
self.logger.warn( self.logger.warning("==========client stop. KeyboardInterrupt info==========")
"==========client stop. KeyboardInterrupt info==========", tag="starter"
)
traceback.print_exc() traceback.print_exc()
self.logger.warn( self.logger.warning(
"==========client stop. KeyboardInterrupt info end==========", "==========client stop. KeyboardInterrupt info end=========="
tag="starter",
) )
self.dispatch_event("on_close", "input") self.dispatch_event("on_close", "input")
sys.exit(0) sys.exit(0)
@ -503,7 +497,7 @@ class ClientWindow(Window):
@_call_screen_after @_call_screen_after
def on_key_press(self, symbol, modifiers) -> None: def on_key_press(self, symbol, modifiers) -> None:
if symbol == key.ESCAPE and not ( if symbol == key.ESCAPE and not (
modifiers & ~(key.MOD_NUMLOCK | key.MOD_CAPSLOCK | key.MOD_SCROLLLOCK) modifiers & ~(key.MOD_NUMLOCK | key.MOD_CAPSLOCK | key.MOD_SCROLLLOCK)
): ):
self.dispatch_event("on_close", "window") self.dispatch_event("on_close", "window")
if symbol == key.SLASH: if symbol == key.SLASH:

View File

@ -36,9 +36,9 @@ class FpsLogger:
else: else:
self.fps_list.append(float(1 / tick)) self.fps_list.append(float(1 / tick))
if len(self.fps_list) > self.count: if len(self.fps_list) > self.count:
self.fps_list = self.fps_list[-self.count + 1:] # 整个列表往前挪一位 self.fps_list = self.fps_list[-self.count + 1 :] # 整个列表往前挪一位
if len(self.get_fps_list) > self.count: if len(self.get_fps_list) > self.count:
self.get_fps_list = self.get_fps_list[-self.count + 1:] # 整个列表往前挪一位 self.get_fps_list = self.get_fps_list[-self.count + 1 :] # 整个列表往前挪一位
try: try:
self._fps = statistics.geometric_mean( self._fps = statistics.geometric_mean(
self.fps_list[-100:] self.fps_list[-100:]

View File

@ -20,8 +20,8 @@ from pyglet.text.formats import structured
default_style = { default_style = {
"font_name": "Times New Roman", "font_name": "Times New Roman",
"font_size": 12, "font_size": 12,
"bold": False, "bold": False,
"italic": False, "italic": False,
} }
@ -35,17 +35,17 @@ class SingleTextStyle:
""" """
def __init__( def __init__(
self, self,
font_name: str = "", font_name: str = "",
font_size: int = 12, font_size: int = 12,
bold: bool = False, bold: bool = False,
italic: bool = False, italic: bool = False,
color: str = "white", color: str = "white",
text_tag: list = None, text_tag: list = None,
show: bool = True, show: bool = True,
prefix: str = "", prefix: str = "",
suffix: str = "", suffix: str = "",
text: str = "", text: str = "",
): ):
self.font_name = font_name self.font_name = font_name
self.font_size = font_size self.font_size = font_size
@ -142,10 +142,10 @@ class SingleTextStyle:
""" """
assert isinstance(other, SingleTextStyle) assert isinstance(other, SingleTextStyle)
return ( return (
self.font_name == other.font_name self.font_name == other.font_name
and self.font_size == other.font_size and self.font_size == other.font_size
and self.color == other.color and self.color == other.color
and self.show == other.show and self.show == other.show
) )
def same_bold(self, other: "SingleTextStyle") -> bool: def same_bold(self, other: "SingleTextStyle") -> bool:
@ -215,9 +215,9 @@ class SingleTextStyle:
""" """
return ( return (
( (
font_HTML_end font_HTML_end
+ (bold_HTML_end if self.bold else "") + (bold_HTML_end if self.bold else "")
+ (italic_HTML_end if self.italic else "") + (italic_HTML_end if self.italic else "")
) )
if suffix if suffix
else self.HTML_bold() + self.HTML_italic() + self.HTML_font() else self.HTML_bold() + self.HTML_italic() + self.HTML_font()
@ -248,7 +248,7 @@ default_fonts_config = [
# Markdown 粗体语法规则匹配 # Markdown 粗体语法规则匹配
"match": re.compile(r"\*\*(.*?(?<!\s))\*\*"), "match": re.compile(r"\*\*(.*?(?<!\s))\*\*"),
"shown": re.compile(r"(?<=\*\*)(.*?(?<!\s))(?=\*\*)"), "shown": re.compile(r"(?<=\*\*)(.*?(?<!\s))(?=\*\*)"),
"tag": { "tag": {
# 为 match 匹配到的字符添加标签 # 为 match 匹配到的字符添加标签
"match": re.compile(r"\*\*"), "match": re.compile(r"\*\*"),
"style": SingleTextStyle(text_tag=["bold"]), "style": SingleTextStyle(text_tag=["bold"]),
@ -257,14 +257,14 @@ default_fonts_config = [
}, },
{ {
# Markdown 斜体语法规则匹配 # Markdown 斜体语法规则匹配
"match": re.compile(r"\*(.*?(?<!\s))\*"), "match": re.compile(r"\*(.*?(?<!\s))\*"),
"shown": re.compile(r"(?<=\*)(.*?(?<!\s))(?=\*)"), "shown": re.compile(r"(?<=\*)(.*?(?<!\s))(?=\*)"),
"ignore": { "ignore": {
# 如果匹配到的字符含有 tag 就忽略本次解析 # 如果匹配到的字符含有 tag 就忽略本次解析
"match": re.compile(r"\*"), "match": re.compile(r"\*"),
"tag": SingleTextStyle(text_tag=["italic"]), "tag": SingleTextStyle(text_tag=["italic"]),
}, },
"style": SingleTextStyle(italic=True), "style": SingleTextStyle(italic=True),
}, },
{ {
# Markdown 链接规则匹配 # Markdown 链接规则匹配
@ -308,11 +308,11 @@ def decode_text2HTML(text: str, configs=None, show_style: bool = False) -> str:
if ignore: # 为了方便退出 if ignore: # 为了方便退出
break break
for ignore_index in range( for ignore_index in range(
match_start + ignore_text.span()[0], match_start + ignore_text.span()[0],
match_start + ignore_text.span()[1], match_start + ignore_text.span()[1],
): # 对每一个可能的字符进行检测 ): # 对每一个可能的字符进行检测
if style_list[ignore_index].have_tag( if style_list[ignore_index].have_tag(
config["ignore"]["tag"] config["ignore"]["tag"]
): # 如果确实包含要忽略的 ): # 如果确实包含要忽略的
ignore = True # 忽略为True ignore = True # 忽略为True
break break
@ -324,7 +324,7 @@ def decode_text2HTML(text: str, configs=None, show_style: bool = False) -> str:
) # 根据配置的正则表达式匹配要添加tag的字符 ) # 根据配置的正则表达式匹配要添加tag的字符
for tag_text in tag_texts: # 对每一个匹配到的~~~~~~ for tag_text in tag_texts: # 对每一个匹配到的~~~~~~
for tag_index in range( for tag_index in range(
match_start + tag_text.span()[0], match_start + tag_text.span()[1] match_start + tag_text.span()[0], match_start + tag_text.span()[1]
): # 用于遍历匹配到的字符 ): # 用于遍历匹配到的字符
style_list[tag_index] += config["tag"]["style"] style_list[tag_index] += config["tag"]["style"]
# 为匹配到的字符添加样式 # 为匹配到的字符添加样式
@ -337,7 +337,7 @@ def decode_text2HTML(text: str, configs=None, show_style: bool = False) -> str:
# 为每一个显示的字符设置显示属性 # 为每一个显示的字符设置显示属性
for shown_text in shown_texts: # 每一个显示的匹配项 for shown_text in shown_texts: # 每一个显示的匹配项
for shown_index in range( for shown_index in range(
match_start + shown_text.span()[0], match_start + shown_text.span()[1] match_start + shown_text.span()[0], match_start + shown_text.span()[1]
): ):
style_list[shown_index].show = True style_list[shown_index].show = True
# 字体样式列表的 [shown_index] 设置显示属性变为 True # 字体样式列表的 [shown_index] 设置显示属性变为 True
@ -349,17 +349,17 @@ def decode_text2HTML(text: str, configs=None, show_style: bool = False) -> str:
if not style_list[style_index - 1].same_font(style_list[style_index]): if not style_list[style_index - 1].same_font(style_list[style_index]):
style_list[style_index - 1].suffix += style_list[ style_list[style_index - 1].suffix += style_list[
style_index - 1 style_index - 1
].HTML_font(suffix=True) ].HTML_font(suffix=True)
style_list[style_index].prefix += style_list[style_index].HTML_font() style_list[style_index].prefix += style_list[style_index].HTML_font()
if not style_list[style_index - 1].same_bold(style_list[style_index]): if not style_list[style_index - 1].same_bold(style_list[style_index]):
style_list[style_index - 1].suffix += style_list[ style_list[style_index - 1].suffix += style_list[
style_index - 1 style_index - 1
].HTML_bold(suffix=True) ].HTML_bold(suffix=True)
style_list[style_index].prefix += style_list[style_index].HTML_bold() style_list[style_index].prefix += style_list[style_index].HTML_bold()
if not style_list[style_index - 1].same_italic(style_list[style_index]): if not style_list[style_index - 1].same_italic(style_list[style_index]):
style_list[style_index - 1].suffix += style_list[ style_list[style_index - 1].suffix += style_list[
style_index - 1 style_index - 1
].HTML_italic(suffix=True) ].HTML_italic(suffix=True)
style_list[style_index].prefix += style_list[ style_list[style_index].prefix += style_list[
style_index style_index
].HTML_italic() ].HTML_italic()

View File

@ -50,9 +50,9 @@ class CommandText:
if find != -1: if find != -1:
if not len(text) == len(self.text): if not len(text) == len(self.text):
self.text = ( self.text = (
self.text[find + len(text):] self.text[find + len(text) :]
if not self.text[find + len(text)] == " " if not self.text[find + len(text)] == " "
else self.text[find + len(text) + 1:] else self.text[find + len(text) + 1 :]
) )
return True return True
return False return False
@ -68,7 +68,7 @@ class CommandText:
# 20230122 我现在也不知道为啥这么写了 # 20230122 我现在也不知道为啥这么写了
# 果然使用正则表达式就是让一个问题变成两个问题 # 果然使用正则表达式就是让一个问题变成两个问题
except IndexError: except IndexError:
self.text = self.text[finding.span()[1] + 1:] self.text = self.text[finding.span()[1] + 1 :]
return True return True
if next_find == " ": if next_find == " ":
return True return True

View File

@ -36,15 +36,15 @@ class CommandLineTextEntry(widgets.TextEntry):
""" """
def __init__( def __init__(
self, self,
x: int, x: int,
y: int, y: int,
width: int, width: int,
color: Optional[Tuple[int, int, int, int]] = (255, 255, 255, 255), color: Optional[Tuple[int, int, int, int]] = (255, 255, 255, 255),
text_color: Optional[Tuple[int, int, int, int]] = (0, 0, 0, 255), text_color: Optional[Tuple[int, int, int, int]] = (0, 0, 0, 255),
caret_color: Optional[Tuple[int, int, int, int]] = (0, 0, 0), caret_color: Optional[Tuple[int, int, int, int]] = (0, 0, 0),
batch: Optional[Batch] = None, batch: Optional[Batch] = None,
group: Optional[Group] = None, group: Optional[Group] = None,
): ):
super().__init__( super().__init__(
x=x, x=x,
@ -66,16 +66,16 @@ class CommandLine(widgets.WidgetBase):
""" """
def __init__( def __init__(
self, self,
x: int, x: int,
y: int, y: int,
width: int, width: int,
height: int, height: int,
length: int, length: int,
batch: Batch, batch: Batch,
group: Group = None, group: Group = None,
command_text: str = "/", command_text: str = "/",
font_size: int = 20, font_size: int = 20,
): ):
super().__init__(x, y, width, height) super().__init__(x, y, width, height)
@ -182,14 +182,14 @@ class CommandLine(widgets.WidgetBase):
""" """
assert isinstance(value, int), "Command View must be integer" assert isinstance(value, int), "Command View must be integer"
assert ( assert (
-self.length < value < self.length -self.length < value < self.length
), f"Command View must be bigger than {-self.length} and smaller than {self.length}" ), f"Command View must be bigger than {-self.length} and smaller than {self.length}"
if value == -1: # flush command list if value == -1: # flush command list
self._label.insert(0, self._label[-1]) self._label.insert(0, self._label[-1])
self._label.pop(-1) self._label.pop(-1)
for line in range(self.length): for line in range(self.length):
self._label[line].y = ( self._label[line].y = (
self.y + self.command_distance + (line * self.command_split) self.y + self.command_distance + (line * self.command_split)
) )
self._label[0].text = self.text self._label[0].text = self.text
self.text = "" self.text = ""
@ -223,10 +223,10 @@ class CommandLine(widgets.WidgetBase):
time.sleep(wait) time.sleep(wait)
if self._label[0].visible and not self.editing: if self._label[0].visible and not self.editing:
while ( while (
(self._label[0].opacity >= 30) (self._label[0].opacity >= 30)
and self._label[0].visible and self._label[0].visible
and (self._label[0] is this) and (self._label[0] is this)
and not self.editing and not self.editing
): ):
# (label 的透明度不是 0) and (label 还在显示) and (label 还是载入线程时候的那个label) and (现在不在输入新行) # (label 的透明度不是 0) and (label 还在显示) and (label 还是载入线程时候的那个label) and (现在不在输入新行)
self._label[0].opacity -= 2 self._label[0].opacity -= 2
@ -279,7 +279,7 @@ class CommandLine(widgets.WidgetBase):
if motion == key.MOTION_DELETE: # 确保不越界 if motion == key.MOTION_DELETE: # 确保不越界
self.text = f"{self.text[:self._text_position]}{self.text[self._text_position + 1:]}" # 简单粗暴的删除 self.text = f"{self.text[:self._text_position]}{self.text[self._text_position + 1:]}" # 简单粗暴的删除
elif ( elif (
motion == key.MOTION_BACKSPACE and self._text_position >= 1 motion == key.MOTION_BACKSPACE and self._text_position >= 1
): # 确保不越界 ): # 确保不越界
self.text = f"{self.text[:self._text_position - 1]}{self.text[self._text_position:]}" # 简单粗暴的删除 self.text = f"{self.text[:self._text_position - 1]}{self.text[self._text_position:]}" # 简单粗暴的删除
self._text_position -= 1 # 记得切换光标位置 self._text_position -= 1 # 记得切换光标位置
@ -288,19 +288,19 @@ class CommandLine(widgets.WidgetBase):
elif motion == key.MOTION_LEFT and self._text_position >= 0: # 确保不越界 elif motion == key.MOTION_LEFT and self._text_position >= 0: # 确保不越界
self._text_position -= 1 self._text_position -= 1
elif motion == key.MOTION_RIGHT and self._text_position <= len( elif motion == key.MOTION_RIGHT and self._text_position <= len(
self.text self.text
): # 确保不越界 ): # 确保不越界
self._text_position += 1 self._text_position += 1
elif motion in ( elif motion in (
key.MOTION_BEGINNING_OF_LINE, key.MOTION_BEGINNING_OF_LINE,
key.MOTION_BEGINNING_OF_FILE, key.MOTION_BEGINNING_OF_FILE,
key.MOTION_PREVIOUS_PAGE, key.MOTION_PREVIOUS_PAGE,
): ):
self._text_position = 0 self._text_position = 0
elif motion in ( elif motion in (
key.MOTION_END_OF_LINE, key.MOTION_END_OF_LINE,
key.MOTION_END_OF_FILE, key.MOTION_END_OF_FILE,
key.MOTION_NEXT_PAGE, key.MOTION_NEXT_PAGE,
): ):
self._text_position = len(self.text) self._text_position = len(self.text)

View File

@ -61,10 +61,10 @@ def crash_info_handler(info: Optional[str] = None) -> str:
def markdown_line_handler( def markdown_line_handler(
string: Optional[Union[str, bool, int, float]], string: Optional[Union[str, bool, int, float]],
code: bool = False, code: bool = False,
level: int = 1, level: int = 1,
end: str = "\n", end: str = "\n",
) -> str: ) -> str:
lvl = "- " * level lvl = "- " * level
f_string = string f_string = string

View File

@ -1,86 +0,0 @@
# -------------------------------
# Difficult Rocket
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
# All rights reserved
# -------------------------------
default_config = """config_version = 1
[Logger]
[Logger.client]
# 日志名称
logger_name = "client"
level_name = "debug"
# or 'DEBUG'
# or level = 10
outputs = ["std_out", "file_out"]
[Logger.server]
# 日志名称
logger_name = "server"
level_name = "debug"
# or 'DEBUG'
# or level = 10
outputs = ["std_out", "file_out"]
[Logger.main]
# 日志名称
logger_name = "main"
level_name = "debug"
# or 'DEBUG'
# or level = 10
outputs = ["std_out", "file_out"]
[Formatter]
[Formatter.main_formatter]
# 格式化器名称
class = "MainFormatter"
# 格式化器参数
time_format = "%Y-%m-%d %H:%M:%S"
msec_time_format = "{}-{:03d}"
use_absolute_path = false
[Formatter.std_formatter]
class = "StdFormatter"
sub_formatter = ["main_formatter"]
default_template = "[${log_time}][${level}]|${logger_name}:${logger_tag}|${messages}"
[Outstream]
[Outstream.std_out]
# 输出流名称
class = "StdioOutputStream"
# 输出流参数
formatter = "std_formatter"
use_stderr = false
# or true
level_name = "debug"
# or 'DEBUG'
# or level = 10
[Outstream.file_out]
class = "FileCacheOutputStream"
level = 10
# or level_name = 'DEBUG'
# or level_name = 'debug'
formatter = "std_formatter"
flush_count_limit = 10
# 5 条日志刷新一次
flush_time_limit = 5
# 5 秒刷新一次
# or flush_time_limit = 0.5
file_path = "./logs"
file_name = "dr-{time}.log"
"""
# 整的跟 export 一样
# fmt: off
__all__ = [
"default_config"
]
# fmt: on

View File

@ -94,15 +94,15 @@ class PressTextButton(widgets.WidgetBase):
""" """
def __init__( def __init__(
self, self,
x: int, x: int,
y: int, y: int,
width: int, width: int,
height: int, height: int,
text: str, text: str,
batch: Optional[Batch] = None, batch: Optional[Batch] = None,
group: Optional[Group] = None, group: Optional[Group] = None,
theme: Optional[ButtonThemeOptions] = None, theme: Optional[ButtonThemeOptions] = None,
): ):
super().__init__(x, y, width, height) super().__init__(x, y, width, height)
self.main_batch = batch or Batch() self.main_batch = batch or Batch()
@ -160,7 +160,7 @@ class PressTextButton(widgets.WidgetBase):
text_width = self.text_label.content_width text_width = self.text_label.content_width
self.text_label.x = self._x + (self.width - text_width) // 2 self.text_label.x = self._x + (self.width - text_width) // 2
self.text_label.y = ( self.text_label.y = (
self._y + (self.height - self.font_height) // 2 + (self.font_height * 0.2) self._y + (self.height - self.font_height) // 2 + (self.font_height * 0.2)
) # 修正一下位置 ) # 修正一下位置
def __contains__(self, item): def __contains__(self, item):

View File

@ -23,6 +23,7 @@ class BaseTheme(dict):
setattr(self, k, v) setattr(self, k, v)
if TYPE_CHECKING: if TYPE_CHECKING:
def init(self, batch: Batch, group: Group, **kwargs) -> None: def init(self, batch: Batch, group: Group, **kwargs) -> None:
""" """
Init theme Init theme

View File

@ -11,17 +11,27 @@ github: @shenjackyuanjie
gitee: @shenjackyuanjie gitee: @shenjackyuanjie
""" """
# import time
import logging
# import traceback
import logging.config
import multiprocessing import multiprocessing
# from io import StringIO
# from pathlib import Path
from typing import List, Optional, Dict from typing import List, Optional, Dict
# from Difficult_Rocket.utils import tools
from Difficult_Rocket.api.types import Options from Difficult_Rocket.api.types import Options
# from Difficult_Rocket.utils.translate import tr
# from Difficult_Rocket.runtime import DR_runtime
from Difficult_Rocket.mod.loader import ModManager from Difficult_Rocket.mod.loader import ModManager
from Difficult_Rocket.utils.thread import new_thread from Difficult_Rocket.utils.thread import new_thread
from Difficult_Rocket import client, server, DR_status
from lib_not_dr.loggers import config # from Difficult_Rocket.crash import write_info_to_cache
from lib_not_dr.loggers.logger import Logger from Difficult_Rocket import client, server, DR_status
class Console(Options): class Console(Options):
@ -65,7 +75,7 @@ class Game(Options):
console_class: Console = Console console_class: Console = Console
main_config: Dict main_config: Dict
logger: Logger logger: logging.Logger
mod_manager: ModManager mod_manager: ModManager
@ -74,6 +84,9 @@ class Game(Options):
def init_mods(self) -> None: def init_mods(self) -> None:
"""验证/加载 mod""" """验证/加载 mod"""
from Difficult_Rocket.mod import loader as mod_loader
mod_loader.logger = logging.getLogger("mod_manager")
self.mod_manager = ModManager() self.mod_manager = ModManager()
mod_class = self.mod_manager.load_mods() mod_class = self.mod_manager.load_mods()
self.mod_manager.init_mods(mod_class) self.mod_manager.init_mods(mod_class)
@ -107,7 +120,7 @@ class Game(Options):
self.server = server.Server(net_mode="local") self.server = server.Server(net_mode="local")
def init(self, **kwargs) -> bool: def init(self, **kwargs) -> bool:
self.logger = config.get_logger("main") self.logger = logging.getLogger("main")
self.load_file() self.load_file()
self.setup() self.setup()
self.log_env() self.log_env()

View File

@ -3,3 +3,4 @@
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com # Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------

View File

@ -6,6 +6,7 @@
import sys import sys
import time import time
import logging
import traceback import traceback
import importlib import importlib
from pathlib import Path from pathlib import Path
@ -15,11 +16,9 @@ from Difficult_Rocket.mod.api import ModInfo
from Difficult_Rocket.utils.translate import tr from Difficult_Rocket.utils.translate import tr
from Difficult_Rocket.api.types import Options from Difficult_Rocket.api.types import Options
from lib_not_dr.loggers import config
Game = TypeVar("Game") Game = TypeVar("Game")
logger = config.get_logger_from_old("mod_manager", "client") logger = logging.getLogger("mod_manager")
ONE_FILE_SUFFIX = (".py", ".pyc", ".pyd") ONE_FILE_SUFFIX = (".py", ".pyc", ".pyd")
PACKAGE_SUFFIX = (".pyz", ".zip", ".dr_mod") PACKAGE_SUFFIX = (".pyz", ".zip", ".dr_mod")
@ -74,41 +73,38 @@ class ModManager(Options):
:return: :return:
""" """
if not mod_path.exists(): if not mod_path.exists():
logger.error(tr().mod.load.faild.not_exist().format(mod_path), tag="load") logger.error(tr().mod.load.faild.not_exist().format(mod_path))
return None return None
_add_path_to_sys([mod_path.parent]) _add_path_to_sys([mod_path.parent])
try: try:
if mod_path.name == "__pycache__": if mod_path.name == "__pycache__":
# 忽略 __pycache__ 文件夹 (Python 编译文件) # 忽略 __pycache__ 文件夹 (Python 编译文件)
return None return None
logger.info(tr().mod.load.loading().format(mod_path), tag="load") logger.info(tr().mod.load.loading().format(mod_path))
if ( if (
mod_path.is_dir() mod_path.is_dir()
or mod_path.suffix in PACKAGE_SUFFIX or mod_path.suffix in PACKAGE_SUFFIX
or mod_path.suffix in ONE_FILE_SUFFIX or mod_path.suffix in ONE_FILE_SUFFIX
): ):
# 文件夹 mod # 文件夹 mod
loading_mod = importlib.import_module(mod_path.name) loading_mod = importlib.import_module(mod_path.name)
if not hasattr(loading_mod, "mod_class") or not issubclass( if not hasattr(loading_mod, "mod_class") or not issubclass(
loading_mod.mod_class, ModInfo loading_mod.mod_class, ModInfo
): ):
logger.warn( logger.warning(tr().mod.load.faild.no_mod_class().format(mod_path))
tr().mod.load.faild.no_mod_class().format(mod_path), tag="load"
)
return None return None
mod_class: type(ModInfo) = loading_mod.mod_class # 获取 mod 类 mod_class: type(ModInfo) = loading_mod.mod_class # 获取 mod 类
if mod_class.mod_id not in self.find_mod_paths: if mod_class.mod_id not in self.find_mod_paths:
self.find_mod_paths[mod_class.mod_id] = mod_path self.find_mod_paths[mod_class.mod_id] = mod_path
return mod_class return mod_class
except ImportError: except ImportError:
logger.warn( logger.warning(
tr().mod.load.faild.error().format(mod_path, traceback.format_exc()), tr().mod.load.faild.error().format(mod_path, traceback.format_exc())
tag="load",
) )
return None return None
def find_mods_in_path( def find_mods_in_path(
self, extra_mods_path: Optional[List[Path]] = None self, extra_mods_path: Optional[List[Path]] = None
) -> List[Path]: ) -> List[Path]:
""" """
查找所有 mod 路径 查找所有 mod 路径
@ -128,21 +124,19 @@ class ModManager(Options):
# 忽略 __pycache__ 文件夹 (Python 编译文件) # 忽略 __pycache__ 文件夹 (Python 编译文件)
continue continue
if ( if (
mod.is_dir() mod.is_dir()
or mod.suffix in PACKAGE_SUFFIX or mod.suffix in PACKAGE_SUFFIX
or mod.suffix in ONE_FILE_SUFFIX or mod.suffix in ONE_FILE_SUFFIX
): ):
# 文件夹 mod # 文件夹 mod
mods_path.append(mod) mods_path.append(mod)
logger.info( logger.info(tr().mod.finded().format(len(mods_path), time.time() - start_time))
tr().mod.finded().format(len(mods_path), time.time() - start_time), tag="find"
)
return mods_path return mods_path
def load_mods( def load_mods(
self, self,
extra_path: Optional[List[Path]] = None, extra_path: Optional[List[Path]] = None,
extra_mod_path: Optional[List[Path]] = None, extra_mod_path: Optional[List[Path]] = None,
) -> List[type(ModInfo)]: ) -> List[type(ModInfo)]:
""" """
加载所有 mod (可提供额外的 mod 路径) 加载所有 mod (可提供额外的 mod 路径)
@ -154,7 +148,7 @@ class ModManager(Options):
_add_path_to_sys(find_path) _add_path_to_sys(find_path)
mods = [] mods = []
start_time = time.time() start_time = time.time()
logger.info(tr().mod.load.start().format(find_path), tag="load") logger.info(tr().mod.load.start().format(find_path))
for path in find_path: for path in find_path:
if not path.exists(): if not path.exists():
path.mkdir(parents=True) path.mkdir(parents=True)
@ -166,7 +160,7 @@ class ModManager(Options):
for path in extra_mod_path: for path in extra_mod_path:
if (cache := self.load_mod(path)) is not None: if (cache := self.load_mod(path)) is not None:
mods.append(cache) mods.append(cache)
logger.info(tr().mod.load.use_time().format(time.time() - start_time), tag="load") logger.info(tr().mod.load.use_time().format(time.time() - start_time))
return mods return mods
def init_mods(self, mods: List[type(ModInfo)]): def init_mods(self, mods: List[type(ModInfo)]):
@ -180,16 +174,13 @@ class ModManager(Options):
try: try:
init_mod = mod_class() init_mod = mod_class()
self.loaded_mod_modules[init_mod.mod_id] = init_mod self.loaded_mod_modules[init_mod.mod_id] = init_mod
logger.info( logger.info(tr().mod.init.success().format(init_mod, init_mod.version))
tr().mod.init.success().format(init_mod, init_mod.version), tag="init"
)
except Exception as e: except Exception as e:
logger.error( logger.error(
tr().mod.init.faild().format(mod_class, e, traceback.format_exc()), tr().mod.init.faild().format(mod_class, e, traceback.format_exc())
tag="init",
) )
continue continue
logger.info(tr().mod.init.use_time().format(time.time() - start_time), tag="init") logger.info(tr().mod.init.use_time().format(time.time() - start_time))
def unload_mod(self, mod_id: str, game: Game) -> Optional[ModInfo]: def unload_mod(self, mod_id: str, game: Game) -> Optional[ModInfo]:
""" """
@ -199,20 +190,19 @@ class ModManager(Options):
:return: 卸载的 mod ModInfo :return: 卸载的 mod ModInfo
""" """
if ( if (
not (mod_class := self.loaded_mod_modules.get(mod_id)) not (mod_class := self.loaded_mod_modules.get(mod_id))
and (mod_class := self.get_mod_module(mod_id)) is None and (mod_class := self.get_mod_module(mod_id)) is None
): ):
logger.warn(tr().mod.unload.faild.not_find().format(mod_id), tag="unload") logger.warning(tr().mod.unload.faild.not_find().format(mod_id))
return None return None
try: try:
mod_class.on_unload(game=game) mod_class.on_unload(game=game)
self.loaded_mod_modules.pop(mod_class.mod_id) self.loaded_mod_modules.pop(mod_class.mod_id)
logger.info(tr().mod.unload.success().format(mod_id), tag="unload") logger.info(tr().mod.unload.success().format(mod_id))
return mod_class return mod_class
except Exception as e: except Exception as e:
logger.error( logger.error(
tr().mod.unload.faild.error().format(mod_id, e, traceback.format_exc()), tr().mod.unload.faild.error().format(mod_id, e, traceback.format_exc())
tag="unload",
) )
return None return None
@ -228,9 +218,7 @@ class ModManager(Options):
return return
mod_class: Optional[ModInfo] = None mod_class: Optional[ModInfo] = None
if unload.mod_id not in self.find_mod_paths: if unload.mod_id not in self.find_mod_paths:
logger.warn( logger.warning(tr().mod.reload.faild.not_find().format(unload.mod_id))
tr().mod.reload.faild.not_find().format(unload.mod_id), tag="reload"
)
paths = self.find_mods_in_path() paths = self.find_mods_in_path()
for path in paths: for path in paths:
mod_class = self.load_mod(path) mod_class = self.load_mod(path)
@ -243,4 +231,4 @@ class ModManager(Options):
self.init_mods([mod_class]) self.init_mods([mod_class])
if mod_id in self.loaded_mod_modules and mod_class is not None: if mod_id in self.loaded_mod_modules and mod_class is not None:
self.loaded_mod_modules[mod_id].on_load(game=game, old_self=mod_class) self.loaded_mod_modules[mod_id].on_load(game=game, old_self=mod_class)
logger.info(tr().mod.reload.success().format(mod_id), tag="reload") logger.info(tr().mod.reload.success().format(mod_id))

View File

@ -14,6 +14,7 @@ from typing import Optional, List, Tuple
from Difficult_Rocket.api.types import Options, Version from Difficult_Rocket.api.types import Options, Version
__all__ = ["DR_runtime"] __all__ = ["DR_runtime"]

View File

@ -13,12 +13,13 @@ gitee: @shenjackyuanjie
import os import os
import time import time
import logging
# import multiprocessing # import multiprocessing
from Difficult_Rocket.utils import tools from Difficult_Rocket.utils import tools
from Difficult_Rocket.utils.translate import tr from Difficult_Rocket.utils.translate import tr
# from Difficult_Rocket.api.delivery import Delivery
from lib_not_dr import loggers # from Difficult_Rocket.utils.new_thread import new_thread
# TODO 改变服务端启动逻辑 0.6.0(划掉 0.8.0)会写完的( # TODO 改变服务端启动逻辑 0.6.0(划掉 0.8.0)会写完的(
@ -28,7 +29,7 @@ class Server:
def __init__(self, net_mode="local"): def __init__(self, net_mode="local"):
start_time = time.time() start_time = time.time()
# logging # logging
self.logger = loggers.config.get_logger("server") self.logger = logging.getLogger("server")
self.logger.info(tr().server.setup.start()) self.logger.info(tr().server.setup.start())
# value # value
self.process_id = os.getpid() self.process_id = os.getpid()

View File

@ -29,13 +29,13 @@ class Camera:
""" """
def __init__( def __init__(
self, self,
window, window,
zoom: Optional[float] = 1.0, zoom: Optional[float] = 1.0,
dx: Optional[float] = 1.0, dx: Optional[float] = 1.0,
dy: Optional[float] = 1.0, dy: Optional[float] = 1.0,
min_zoom: Optional[float] = 1.0, min_zoom: Optional[float] = 1.0,
max_zoom: Optional[float] = 1.0, max_zoom: Optional[float] = 1.0,
) -> None: ) -> None:
self.window = window self.window = window
self.dx = dx self.dx = dx
@ -126,15 +126,15 @@ class GroupCamera(Group):
""" """
def __init__( def __init__(
self, self,
window, window,
order: int = 0, order: int = 0,
parent: Optional[Group] = None, parent: Optional[Group] = None,
view_x: Optional[int] = 0, view_x: Optional[int] = 0,
view_y: Optional[int] = 0, view_y: Optional[int] = 0,
zoom: Optional[float] = 1.0, zoom: Optional[float] = 1.0,
min_zoom: Optional[float] = 1.0, min_zoom: Optional[float] = 1.0,
max_zoom: Optional[float] = 1.0, max_zoom: Optional[float] = 1.0,
): ):
super().__init__(order=order, parent=parent) super().__init__(order=order, parent=parent)
self._window = window self._window = window
@ -219,17 +219,17 @@ class CenterGroupFrame(Group):
""" """
def __init__( def __init__(
self, self,
window, window,
order: int = 0, order: int = 0,
parent: Optional[Group] = None, parent: Optional[Group] = None,
dx: Optional[int] = 0, dx: Optional[int] = 0,
dy: Optional[int] = 0, dy: Optional[int] = 0,
width: Optional[int] = 0, width: Optional[int] = 0,
height: Optional[int] = 0, height: Optional[int] = 0,
zoom: Optional[float] = 1.0, zoom: Optional[float] = 1.0,
min_zoom: Optional[float] = 1.0, min_zoom: Optional[float] = 1.0,
max_zoom: Optional[float] = 1.0, max_zoom: Optional[float] = 1.0,
): ):
super().__init__(order=order, parent=parent) super().__init__(order=order, parent=parent)
self.window = window self.window = window

View File

@ -120,9 +120,9 @@ class FunctionThread(threading.Thread):
def new_thread( def new_thread(
arg: Optional[Union[str, Callable]] = None, arg: Optional[Union[str, Callable]] = None,
daemon: bool = False, daemon: bool = False,
log_thread: bool = True, log_thread: bool = True,
): ):
""" """
This is a one line solution to make your function executes in parallels. This is a one line solution to make your function executes in parallels.

View File

@ -17,6 +17,7 @@ import time
import math import math
import json import json
import rtoml import rtoml
import logging
import configparser import configparser
from pathlib import Path from pathlib import Path
@ -26,30 +27,28 @@ from defusedxml.ElementTree import parse
from Difficult_Rocket.exception.unsupport import NoMoreJson5 from Difficult_Rocket.exception.unsupport import NoMoreJson5
from lib_not_dr import loggers
# logger # logger
tools_logger = loggers.config.get_logger("tools") tools_logger = logging.getLogger("tools")
""" """
file config file config
""" """
file_error = { file_error = {
FileNotFoundError: "no {filetype} file was founded!:\n file name: {filename}\n file_type: {filetype}\n stack: {stack}", FileNotFoundError: "no {filetype} file was founded!:\n file name: {filename}\n file_type: {filetype}\n stack: {stack}",
KeyError: "no stack in {filetype} file {filename} was found! \n file type: {} \n file name: {} \n stack: {stack}", KeyError: "no stack in {filetype} file {filename} was found! \n file type: {} \n file name: {} \n stack: {stack}",
Exception: "get some {error_type} when read {filetype} file {filename}! \n file type: {} \n file name: {} \n stack: {stack}", Exception: "get some {error_type} when read {filetype} file {filename}! \n file type: {} \n file name: {} \n stack: {stack}",
} }
def load_file( def load_file(
file_name: Union[str, Path], file_name: Union[str, Path],
stack: Optional[Union[str, list, dict]] = None, stack: Optional[Union[str, list, dict]] = None,
raise_error: Optional[bool] = True, raise_error: Optional[bool] = True,
encoding: Optional[str] = "utf-8", encoding: Optional[str] = "utf-8",
) -> Union[dict, ElementTree.ElementTree]: ) -> Union[dict, ElementTree.ElementTree]:
if isinstance(file_name, Path): if isinstance(file_name, Path):
file_name = str(file_name) file_name = str(file_name)
f_type = file_name[file_name.rfind(".") + 1:] # 从最后一个.到末尾 (截取文件格式) f_type = file_name[file_name.rfind(".") + 1 :] # 从最后一个.到末尾 (截取文件格式)
get_file = NotImplementedError("解析失败,请检查文件类型/文件内容/文件是否存在!") get_file = NotImplementedError("解析失败,请检查文件类型/文件内容/文件是否存在!")
try: try:
if f_type == "xml": if f_type == "xml":
@ -96,7 +95,7 @@ def load_file(
def save_dict_file(file_name: str, data: dict, encoding: str = "utf-8") -> bool: def save_dict_file(file_name: str, data: dict, encoding: str = "utf-8") -> bool:
f_type = file_name[file_name.rfind(".") + 1:] # 从最后一个.到末尾 (截取文件格式) f_type = file_name[file_name.rfind(".") + 1 :] # 从最后一个.到末尾 (截取文件格式)
try: try:
if (f_type == "config") or (f_type == "conf") or (f_type == "ini"): if (f_type == "config") or (f_type == "conf") or (f_type == "ini"):
return False return False
@ -202,6 +201,36 @@ def format_bool(thing) -> bool:
raise TypeError("Need a 'like bool' not a {}".format(thing)) raise TypeError("Need a 'like bool' not a {}".format(thing))
level_ = [
"DEBUG",
"INFO",
"WARNING",
"ERROR",
"CRITICAL",
logging.DEBUG,
logging.INFO,
logging.WARNING,
logging.ERROR,
logging.CRITICAL,
]
def log_level(level):
if level in level_:
if (level == "DEBUG") or (level == logging.DEBUG):
return logging.DEBUG
if (level == "INFO") or (level == logging.INFO):
return logging.INFO
if (level == "WARNING") or (level == logging.WARNING):
return logging.WARNING
if (level == "ERROR") or (level == logging.ERROR):
return logging.ERROR
if (level == "CRITICAL") or (level == logging.CRITICAL):
return logging.CRITICAL
else:
raise ValueError("Need a like logging.level thing not anything else")
# linear_algebra # linear_algebra

View File

@ -36,7 +36,7 @@ class TranslateConfig:
def set(self, item: str, value: Union[bool, "Tr", "Translates"]) -> "TranslateConfig": def set(self, item: str, value: Union[bool, "Tr", "Translates"]) -> "TranslateConfig":
assert ( assert (
getattr(self, item, None) is not None getattr(self, item, None) is not None
), f"Config {item} is not in TranslateConfig" ), f"Config {item} is not in TranslateConfig"
assert isinstance(value, bool) assert isinstance(value, bool)
setattr(self, item, value) setattr(self, item, value)
@ -62,10 +62,10 @@ key_type = Union[str, int, Hashable]
class Translates: class Translates:
def __init__( def __init__(
self, self,
value: Union[Dict[str, Any], list, tuple, str], value: Union[Dict[str, Any], list, tuple, str],
config: Optional[TranslateConfig] = None, config: Optional[TranslateConfig] = None,
get_list: Optional[List[Tuple[bool, str]]] = None, get_list: Optional[List[Tuple[bool, str]]] = None,
): ):
"""一个用于翻译的东西 """一个用于翻译的东西
:param value: 翻译键节点 :param value: 翻译键节点
@ -77,9 +77,9 @@ class Translates:
self._get_list = get_list or [] self._get_list = get_list or []
def set_conf_( def set_conf_(
self, self,
option: Union[str, TranslateConfig], option: Union[str, TranslateConfig],
value: Optional[Union[bool, List[str]]] = None, value: Optional[Union[bool, List[str]]] = None,
) -> "Translates": ) -> "Translates":
assert isinstance(option, (TranslateConfig, str)) assert isinstance(option, (TranslateConfig, str))
if isinstance(option, TranslateConfig): if isinstance(option, TranslateConfig):
@ -117,7 +117,7 @@ class Translates:
print(raise_info) print(raise_info)
def __getitem__( def __getitem__(
self, item: Union[key_type, List[key_type], Tuple[key_type]] self, item: Union[key_type, List[key_type], Tuple[key_type]]
) -> "Translates": ) -> "Translates":
try: try:
if isinstance(item, (str, int, Hashable)): if isinstance(item, (str, int, Hashable)):
@ -127,11 +127,11 @@ class Translates:
for a_item in item: for a_item in item:
cache_value = cache_value[a_item] cache_value = cache_value[a_item]
if isinstance( if isinstance(
cache_value, cache_value,
( (
int, int,
str, str,
), ),
): ):
self._config.is_final = True self._config.is_final = True
self._get_list.append((True, item)) self._get_list.append((True, item))
@ -158,7 +158,7 @@ class Translates:
def __getattr__(self, item: key_type) -> "Translates": def __getattr__(self, item: key_type) -> "Translates":
if (self._config.is_final or any(x[0] for x in self._get_list)) and hasattr( if (self._config.is_final or any(x[0] for x in self._get_list)) and hasattr(
self._value, item self._value, item
): ):
return getattr(self._value, item) return getattr(self._value, item)
# 实际上我这里完全不需要处理正常需求,因为 __getattribute__ 已经帮我处理过了 # 实际上我这里完全不需要处理正常需求,因为 __getattribute__ 已经帮我处理过了
@ -181,10 +181,10 @@ class Tr:
""" """
def __init__( def __init__(
self, self,
language: str = None, language: str = None,
config: Optional[TranslateConfig] = None, config: Optional[TranslateConfig] = None,
lang_path: Optional[Path] = None, lang_path: Optional[Path] = None,
): ):
""" """
诶嘿我抄的MCDR 诶嘿我抄的MCDR

View File

@ -34,25 +34,18 @@ config_version = 1
# 格式化器参数 # 格式化器参数
time_format = "%Y-%m-%d %H:%M:%S" time_format = "%Y-%m-%d %H:%M:%S"
msec_time_format = "{}-{:03d}" msec_time_format = "{}-{:03d}"
use_absolute_path = false use_absolut_path = false
[Formatter.std_formatter] [Formatter.std_formatter]
class = "StdFormatter" formatter_class = "StdFormatter"
enable_color = true
sub_formatter = ["main_formatter"] sub_formatter = ["main_formatter"]
default_template = "[${log_time}][${level}]|${logger_name}:${logger_tag}|${messages}" default_template = "[{log_time}][{level}]|{logger_name}:{logger_tag}|{messages}"
[Formatter.file_std_formatter]
class = "StdFormatter"
enable_color = false
sub_formatter = ["main_formatter"]
default_template = "[${log_time}][${level}]|${logger_name}:${logger_tag}|${messages}"
[Outstream] [Outstream]
[Outstream.std_out] [Outstream.std_out]
# 输出流名称 # 输出流名称
class = "StdioOutputStream" class = "StdOutputStream"
# 输出流参数 # 输出流参数
formatter = "std_formatter" formatter = "std_formatter"
use_stderr = false use_stderr = false
@ -67,11 +60,11 @@ config_version = 1
level = 10 level = 10
# or level_name = 'DEBUG' # or level_name = 'DEBUG'
# or level_name = 'debug' # or level_name = 'debug'
formatter = "file_std_formatter" formatter = "std_formatter"
flush_count_limit = 10 flush_count_limit = 10
# 5 条日志刷新一次 # 5 条日志刷新一次
flush_time_limit = 5 flush_time_limit = 5
# 5 秒刷新一次 # 5 秒刷新一次
# or flush_time_limit = 0.5 # or flush_time_limit = 0.5
file_path = "./logs" file_path = "./logs"
file_name = "dr-{time}.log" file_name = "%s-dr.log"

123
config/local_logger.toml Normal file
View File

@ -0,0 +1,123 @@
logger_version = '1.0.0'
[Loggers]
[Loggers.root]
level = 'DEBUG'
color = 'main_color'
file = 'main_log_file'
handlers = ['main_std_handler']
[Loggers.client]
level = 'TRACE'
color = 'main_color'
file = 'main_log_file'
handlers = ['main_std_handler']
[Loggers.server]
level = 'TRACE'
color = 'DiGua_color'
file = 'main_log_file'
handlers = ['main_std_handler']
[Files]
[Files.main_log_file]
name = './logs/{long_time}_logs.md'
level = 'TRACE'
cache_len = 20
cache_time = 1
mode = 'a'
encoding = 'utf-8'
[Handler]
[Handler.main_std_handler]
class = 'str handler'
format = 'format.main_format'
[Handler.main_file_hander]
class = 'cached file handler'
format = 'format.main_format'
[Formatter]
main_format = '[{long_time}] [{logger_name}] {level} | {file_name}:{code_line} | {marker} | {message}'
file_name = 'no frame'
code_line = 'no frame'
short_time = '%Y-%m-%d %H-%M-%S'
long_time = '%Y-%m-%d %H-%M-%S:%%S'
[Colors]
[Colors.main_color]
# 翻了三个月的颜色啊
long_time = '\u001b[38;2;201;222;56m'
short_time = '\u001b[38;2;201;222;56m'
code_line = '\u001b[38;2;0;255;180m'
file_name = '\u001b[38;2;0;255;180m'
info = '\u001b[0m'
message = '\u001b[0m'
logger = '\u001b[0m'
marker = '\u001b[0m'
# level colors
TRACE.info = '\u001b[38;2;138;173;244m'
FINE.info = '\u001b[35;48;2;44;44;54m'
DEBUG.info = '\u001b[38;2;133;138;149m'
INFO.info = '\u001b[0m'
WARNING.info = '\u001b[33m'
ERROR.info = '\u001b[31m'
FATAL.info = '\u001b[38;2;255;255;0;48;2;120;10;10m'
FATAL.logger = '\u001b[38;2;245;189;230m'
[Colors.fancy_main_color]
long_time = '\u001b[38;2;201;222;56m'
short_time = '\u001b[38;2;201;222;56m'
file_name = '\u001b[38;2;0;255;180m'
code_line = '\u001b[38;2;0;255;180m'
info = '\u001b[0m'
message = '\u001b[0m'
logger = '\u001b[0m'
marker = '\u001b[0m'
# level colors
TRACE.info = '\u001b[38;2;138;173;244m'
TRACE.message = '\u001b[38;2;138;173;244m'
FINE.info = '\u001b[35;48;2;44;44;54m'
FINE.message = '\u001b[35m'
DEBUG.info = '\u001b[38;2;133;138;149m'
DEBUG.message = '\u001b[38;2;133;138;149m'
INFO.info = '\u001b[0m'
INFO.message = '\u001b[0m'
WARNING.info = '\u001b[33m'
WARNING.message = '\u001b[33m'
ERROR.info = '\u001b[31m'
ERROR.message = '\u001b[31m'
FATAL.info = '\u001b[38;2;255;255;0;48;2;120;10;10m'
FATAL.message = '\u001b[38;2;255;255;0;48;2;120;10;10m'
FATAL.logger = '\u001b[38;2;245;189;230m'
[Colors.DiGua_color]
# catppuccin Macchiato
long_time = '\u001b[38;2;202;211;245m'
short_time = '\u001b[38;2;202;211;245m'
file_name = '\u001b[38;2;139;213;202m'
code_line = '\u001b[38;2;166;218;149m'
info = '\u001b[0m'
logger = '\u001b[0m'
message = '\u001b[0m'
marker = '\u001b[0m'
# level colors
TRACE.info = '\u001b[38;2;138;173;244m'
TRACE.message = '\u001b[38;2;138;173;244m'
FINE.info = '\u001b[38;2;198;160;246m'
FINE.message = '\u001b[38;2;198;160;246m'
DEBUG.info = '\u001b[38;2;133;138;149m'
DEBUG.message = '\u001b[38;2;133;138;149m'
ERROR.info = '\u001b[38;2;237;135;150m'
ERROR.message = '\u001b[38;2;237;135;150m'
WARNING.info = '\u001b[38;2;245;169;127m'
WARNING.message = '\u001b[38;2;245;169;127m'
FATAL.info = '\u001b[38;2;255;255;0;48;2;120;10;10m'
FATAL.message = '\u001b[38;2;255;255;0;48;2;120;10;10m'
FATAL.loggger = '\u001b[38;2;245;189;230m'

View File

@ -9,16 +9,6 @@
### Rename ### Rename
- `Api_version` -> `api_version` - `Api_version` -> `api_version`
- `_DR_Status` -> `_DRStatus`
- `name` = `DR Option` -> `DR Status`
- 这毛病属实是没想到, 之前一直没发现
### Rework
- 将 `logging` 的依赖改为 `lib_not_dr.loggers`
- 以后都用 `lib_not_dr` 的 logger 了
- Change the dependency of `logging` to `lib_not_dr.loggers`
- Use `lib_not_dr` logger in the future
### Add ### Add

@ -1 +1 @@
Subproject commit f0eb5480b5a973a458cdfd3e7e91ef695de064d4 Subproject commit 544c180e728d1b1f7942cb7874f6e579c1acc02b

@ -1 +1 @@
Subproject commit 7df9ee869242f482579f1aa0ed5c61e39c4a444f Subproject commit e5b5e24807687b1a12dca73ce3055a2745d38cf9

1116
libs/utils/logger-old.py Normal file

File diff suppressed because it is too large Load Diff

View File

@ -4,6 +4,7 @@
# All rights reserved # All rights reserved
# ------------------------------- # -------------------------------
import logging
import warnings import warnings
import traceback import traceback
@ -15,11 +16,9 @@ from Difficult_Rocket.api.mod import ModInfo
from Difficult_Rocket.client import ClientWindow from Difficult_Rocket.client import ClientWindow
from Difficult_Rocket.api.types import Options, Version from Difficult_Rocket.api.types import Options, Version
from lib_not_dr import loggers
DR_rust_version = Version("0.2.23.0") # DR_mod 的 Rust 编写部分的兼容版本 DR_rust_version = Version("0.2.23.0") # DR_mod 的 Rust 编写部分的兼容版本
logger = loggers.config.get_logger_from_old("client.dr_game", "client") logger = logging.getLogger("client.dr_game")
class _DR_mod_runtime(Options): # NOQA class _DR_mod_runtime(Options): # NOQA

View File

@ -13,8 +13,12 @@ from lib_not_dr.nuitka import nuitka_config_type, raw_config_type
def gen_pyglet_no_follow_import() -> list: def gen_pyglet_no_follow_import() -> list:
no_follow_import = [] no_follow_import = []
no_follow_import += [f"pyglet.app.{x}" for x in ["win32", "xlib", "cocoa"]] no_follow_import += [
no_follow_import += [f"pyglet.input.{x}" for x in ["win32", "linux", "macos"]] f"pyglet.app.{x}" for x in ["win32", "xlib", "cocoa"]
]
no_follow_import += [
f"pyglet.input.{x}" for x in ["win32", "linux", "macos"]
]
no_follow_import += [ no_follow_import += [
f"pyglet.libs.{x}" f"pyglet.libs.{x}"
for x in ["win32", "x11", "wayland", "darwin", "egl", "headless"] for x in ["win32", "x11", "wayland", "darwin", "egl", "headless"]
@ -32,7 +36,9 @@ def gen_pyglet_no_follow_import() -> list:
"headless", "headless",
) )
] ]
no_follow_import += [f"pyglet.gl.{x}" for x in ["win32", "xlib", "cocoa", "headless"]] no_follow_import += [
f"pyglet.gl.{x}" for x in ["win32", "xlib", "cocoa", "headless"]
]
mult_plat_libs = ["app", "input", "libs", "window", "canvas", "gl"] mult_plat_libs = ["app", "input", "libs", "window", "canvas", "gl"]
if platform.system() == "Windows": if platform.system() == "Windows":
@ -53,15 +59,15 @@ def gen_pyglet_no_follow_import() -> list:
def main(config: raw_config_type) -> nuitka_config_type: def main(config: raw_config_type) -> nuitka_config_type:
print("debug", config) print('debug', config)
config = config["cli"] config = config['cli']
config["file-version"] = str(build_version) config['file-version'] = str(build_version)
config["product-version"] = str(sdk_version) config['product-version'] = str(sdk_version)
config["macos-app-version"] = str(sdk_version) config['macos-app-version'] = str(sdk_version)
config["nofollow-import-to"] += gen_pyglet_no_follow_import() config['nofollow-import-to'] += gen_pyglet_no_follow_import()
config["output-dir"] = "./build/nuitka-" + platform.system().lower() config['output-dir'] = './build/nuitka-' + platform.system().lower()
print("done", config) print('done', config)
return config return config