2021-09-08 23:38:34 +08:00
|
|
|
|
# -------------------------------
|
|
|
|
|
# Difficult Rocket
|
2023-01-20 14:08:12 +08:00
|
|
|
|
# Copyright © 2020-2023 by shenjackyuanjie 3695888@qq.com
|
2021-09-08 23:38:34 +08:00
|
|
|
|
# All rights reserved
|
|
|
|
|
# -------------------------------
|
|
|
|
|
|
2021-04-02 23:31:54 +08:00
|
|
|
|
"""
|
2020-12-16 06:33:33 +08:00
|
|
|
|
writen by shenjackyuanjie
|
2021-09-08 23:38:34 +08:00
|
|
|
|
mail: 3695888@qq.com
|
2021-07-08 20:42:22 +08:00
|
|
|
|
github: @shenjackyuanjie
|
2021-09-08 23:38:34 +08:00
|
|
|
|
gitee: @shenjackyuanjie
|
2021-04-02 23:31:54 +08:00
|
|
|
|
"""
|
2020-12-16 06:33:33 +08:00
|
|
|
|
|
2021-08-13 12:25:29 +08:00
|
|
|
|
import os
|
2021-08-24 22:31:52 +08:00
|
|
|
|
import sys
|
|
|
|
|
import time
|
2021-09-22 06:21:48 +08:00
|
|
|
|
import math
|
2023-01-01 10:58:10 +08:00
|
|
|
|
import json
|
2023-12-31 02:32:40 +08:00
|
|
|
|
import tomli
|
2024-01-07 20:14:07 +08:00
|
|
|
|
import tomli_w
|
2021-09-22 06:21:48 +08:00
|
|
|
|
import configparser
|
2021-09-05 00:50:05 +08:00
|
|
|
|
|
2023-06-22 01:41:11 +08:00
|
|
|
|
from pathlib import Path
|
|
|
|
|
from typing import Union, Optional
|
2022-12-26 11:46:05 +08:00
|
|
|
|
from xml.etree import ElementTree
|
|
|
|
|
from defusedxml.ElementTree import parse
|
|
|
|
|
|
2022-06-29 13:45:25 +08:00
|
|
|
|
from Difficult_Rocket.exception.unsupport import NoMoreJson5
|
2022-06-21 20:15:36 +08:00
|
|
|
|
|
2023-12-13 12:04:30 +08:00
|
|
|
|
from lib_not_dr import loggers
|
|
|
|
|
|
2021-02-06 16:41:54 +08:00
|
|
|
|
# logger
|
2023-12-13 12:04:30 +08:00
|
|
|
|
tools_logger = loggers.config.get_logger("tools")
|
2021-07-08 20:42:22 +08:00
|
|
|
|
"""
|
2023-07-16 00:06:17 +08:00
|
|
|
|
file config
|
2021-07-08 20:42:22 +08:00
|
|
|
|
"""
|
|
|
|
|
|
2023-12-03 16:54:07 +08:00
|
|
|
|
file_error = {
|
|
|
|
|
FileNotFoundError: "no {filetype} file was founded!:\n file name: {filename}\n file_type: {filetype}\n stack: {stack}",
|
2024-05-26 14:01:48 +08:00
|
|
|
|
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}",
|
2023-12-03 16:54:07 +08:00
|
|
|
|
}
|
2021-07-08 20:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
2023-12-03 16:54:07 +08:00
|
|
|
|
def load_file(
|
2024-05-26 14:01:48 +08:00
|
|
|
|
file_name: Union[str, Path],
|
|
|
|
|
stack: Optional[Union[str, list, dict]] = None,
|
|
|
|
|
raise_error: Optional[bool] = True,
|
|
|
|
|
encoding: Optional[str] = "utf-8",
|
2023-12-03 16:54:07 +08:00
|
|
|
|
) -> Union[dict, ElementTree.ElementTree]:
|
2023-06-22 01:41:11 +08:00
|
|
|
|
if isinstance(file_name, Path):
|
|
|
|
|
file_name = str(file_name)
|
2024-05-26 14:01:48 +08:00
|
|
|
|
f_type = file_name[file_name.rfind(".") + 1 :] # 从最后一个.到末尾 (截取文件格式)
|
2023-12-03 16:54:07 +08:00
|
|
|
|
get_file = NotImplementedError("解析失败,请检查文件类型/文件内容/文件是否存在!")
|
2021-07-08 20:42:22 +08:00
|
|
|
|
try:
|
2023-12-03 16:54:07 +08:00
|
|
|
|
if f_type == "xml":
|
2022-12-26 11:46:05 +08:00
|
|
|
|
xml_load: ElementTree.ElementTree = parse(file_name)
|
2021-07-08 20:42:22 +08:00
|
|
|
|
if stack is not None:
|
2023-01-01 10:58:10 +08:00
|
|
|
|
get_file = xml_load.findall(stack)
|
2023-12-03 16:54:07 +08:00
|
|
|
|
elif (f_type == "config") or (f_type == "conf") or (f_type == "ini"):
|
2022-03-22 21:18:04 +08:00
|
|
|
|
get_file = configparser.ConfigParser()
|
|
|
|
|
get_file.read(file_name)
|
2021-07-08 20:42:22 +08:00
|
|
|
|
if stack:
|
2022-03-22 21:18:04 +08:00
|
|
|
|
get_file = get_file[stack]
|
2023-12-03 16:54:07 +08:00
|
|
|
|
elif f_type == "toml":
|
2023-12-31 02:32:40 +08:00
|
|
|
|
with open(file_name, mode="rb") as file:
|
|
|
|
|
get_file = tomli.load(file)
|
2022-12-22 10:54:28 +08:00
|
|
|
|
if stack is not None:
|
|
|
|
|
get_file = get_file[stack]
|
2023-12-03 16:54:07 +08:00
|
|
|
|
elif f_type == "json":
|
|
|
|
|
with open(file_name, mode="r", encoding=encoding) as file:
|
2023-01-01 10:58:10 +08:00
|
|
|
|
get_file = json.load(file)
|
|
|
|
|
if stack is not None:
|
|
|
|
|
get_file = get_file[stack]
|
2023-12-03 16:54:07 +08:00
|
|
|
|
elif f_type == "json5":
|
2022-06-18 17:53:35 +08:00
|
|
|
|
raise NoMoreJson5("我说什么也不用json5了!喵的")
|
2021-07-08 20:42:22 +08:00
|
|
|
|
except Exception as exp:
|
2022-07-25 18:28:42 +08:00
|
|
|
|
error_type = type(exp)
|
2021-11-06 19:07:32 +08:00
|
|
|
|
if error_type in file_error:
|
2023-12-03 16:54:07 +08:00
|
|
|
|
tools_logger.error(
|
|
|
|
|
file_error[error_type].format(
|
|
|
|
|
filetype=f_type, filename=file_name, stack=stack
|
|
|
|
|
)
|
|
|
|
|
)
|
2021-11-06 19:07:32 +08:00
|
|
|
|
else:
|
2023-12-03 16:54:07 +08:00
|
|
|
|
tools_logger.error(
|
|
|
|
|
file_error[Exception].format(
|
|
|
|
|
error_type=error_type,
|
|
|
|
|
filetype=f_type,
|
|
|
|
|
filename=file_name,
|
|
|
|
|
stack=stack,
|
|
|
|
|
)
|
|
|
|
|
)
|
2022-07-25 18:28:42 +08:00
|
|
|
|
if raise_error:
|
2022-12-08 09:53:22 +08:00
|
|
|
|
raise exp from None
|
2022-03-22 21:18:04 +08:00
|
|
|
|
return get_file
|
2021-07-08 20:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
2023-12-03 16:54:07 +08:00
|
|
|
|
def save_dict_file(file_name: str, data: dict, encoding: str = "utf-8") -> bool:
|
2024-05-26 14:01:48 +08:00
|
|
|
|
f_type = file_name[file_name.rfind(".") + 1 :] # 从最后一个.到末尾 (截取文件格式)
|
2023-01-01 10:58:10 +08:00
|
|
|
|
try:
|
2023-12-03 16:54:07 +08:00
|
|
|
|
if (f_type == "config") or (f_type == "conf") or (f_type == "ini"):
|
2023-01-01 10:58:10 +08:00
|
|
|
|
return False
|
2023-12-03 16:54:07 +08:00
|
|
|
|
elif f_type == "toml":
|
2024-01-07 20:14:07 +08:00
|
|
|
|
with open(file_name, mode="wb") as file:
|
|
|
|
|
tomli_w.dump(data, file)
|
2023-12-03 16:54:07 +08:00
|
|
|
|
elif f_type == "json":
|
|
|
|
|
with open(file_name, mode="w", encoding=encoding) as file:
|
2023-01-01 10:58:10 +08:00
|
|
|
|
json.dump(data, file)
|
2023-12-03 16:54:07 +08:00
|
|
|
|
elif f_type == "json5":
|
2023-01-01 10:58:10 +08:00
|
|
|
|
raise NoMoreJson5("我说什么也不用json5了!喵的")
|
|
|
|
|
except Exception as exp:
|
|
|
|
|
raise exp
|
|
|
|
|
|
|
|
|
|
|
2021-07-08 20:42:22 +08:00
|
|
|
|
# main config
|
2023-12-03 16:54:07 +08:00
|
|
|
|
main_config_file = load_file("./config/main.toml")
|
2021-07-08 20:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def get_At(name, in_xml, need_type=str):
|
|
|
|
|
"""
|
|
|
|
|
get Attribute from a XML tree
|
|
|
|
|
will raise TypeError if input is not str or list
|
2022-06-18 17:53:35 +08:00
|
|
|
|
XML json5 no! toml yes!
|
2021-07-08 20:42:22 +08:00
|
|
|
|
"""
|
|
|
|
|
name_type = type(name)
|
|
|
|
|
if name_type == list:
|
|
|
|
|
At_list = []
|
|
|
|
|
for need_name in name:
|
|
|
|
|
if in_xml.hasAttribute(need_name):
|
|
|
|
|
get = in_xml.getAttribute(need_name)
|
|
|
|
|
At_list.append(need_type(get))
|
|
|
|
|
else:
|
|
|
|
|
continue
|
|
|
|
|
return At_list
|
|
|
|
|
elif name_type == str:
|
|
|
|
|
if in_xml.hasAttribute(name):
|
2022-12-08 09:53:22 +08:00
|
|
|
|
attr = in_xml.getAttribute(name)
|
2021-07-08 20:42:22 +08:00
|
|
|
|
else:
|
|
|
|
|
return None
|
|
|
|
|
else:
|
2023-12-03 16:54:07 +08:00
|
|
|
|
raise TypeError(
|
|
|
|
|
"only str and list type is ok but you give me a" + name_type + "type"
|
|
|
|
|
)
|
2022-12-08 09:53:22 +08:00
|
|
|
|
return need_type(attr)
|
2021-07-08 20:42:22 +08:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
def default_name_handler(name_: str) -> str:
|
|
|
|
|
"""
|
|
|
|
|
won't change the string
|
|
|
|
|
just return one
|
|
|
|
|
"""
|
|
|
|
|
name = name_
|
2023-12-03 16:54:07 +08:00
|
|
|
|
name = name.replace("{time.time}", str(time.time()))
|
|
|
|
|
name = name.replace("{dir}", str(os.getcwd()))
|
|
|
|
|
name = name.replace("{py_v}", str(sys.version.split(" ")[0]))
|
|
|
|
|
name = name.replace("{version}", str(main_config_file["runtime"]["version"]))
|
|
|
|
|
name = name.replace("{write_v}", str(main_config_file["runtime"]["write_py_v"]))
|
2021-07-08 20:42:22 +08:00
|
|
|
|
return name
|
|
|
|
|
|
|
|
|
|
|
2021-08-13 12:25:29 +08:00
|
|
|
|
def name_handler(name: str, formats: dict = None) -> str:
|
2021-07-08 20:42:22 +08:00
|
|
|
|
if formats is None:
|
|
|
|
|
return default_name_handler(name)
|
|
|
|
|
name = default_name_handler(name)
|
|
|
|
|
for need_replace in formats:
|
|
|
|
|
replace = formats[need_replace]
|
2023-12-03 16:54:07 +08:00
|
|
|
|
if need_replace == "{date}":
|
|
|
|
|
if "{date}" in formats:
|
|
|
|
|
replace = time.strftime(formats["{date}"], time.gmtime(time.time()))
|
2021-08-13 12:25:29 +08:00
|
|
|
|
else:
|
2023-12-03 16:54:07 +08:00
|
|
|
|
replace = time.strftime(
|
|
|
|
|
main_config_file["runtime"]["date_fmt"], time.gmtime(time.time())
|
|
|
|
|
)
|
2021-07-08 20:42:22 +08:00
|
|
|
|
name = name.replace(need_replace, replace)
|
|
|
|
|
return name
|
|
|
|
|
|
|
|
|
|
|
2021-04-02 23:31:54 +08:00
|
|
|
|
"""
|
2021-01-23 19:55:35 +08:00
|
|
|
|
some tools
|
2021-04-02 23:31:54 +08:00
|
|
|
|
"""
|
2020-12-23 23:19:16 +08:00
|
|
|
|
|
2023-12-03 16:54:07 +08:00
|
|
|
|
yes = ["true", "1", 1, 1.0, True]
|
|
|
|
|
no = ["false", "0", 0, 0.0, False, None]
|
2020-12-16 06:33:33 +08:00
|
|
|
|
|
2021-09-02 22:47:10 +08:00
|
|
|
|
|
|
|
|
|
def format_bool(thing) -> bool:
|
|
|
|
|
"""
|
|
|
|
|
:param thing 啥都行,只要是能传进来的都可以
|
|
|
|
|
|
|
|
|
|
如果看起来像"True" 比如 'true','1',1
|
|
|
|
|
就返回 True
|
|
|
|
|
如果看起来像"False" 比如 'false','0',0
|
|
|
|
|
就返回 False
|
|
|
|
|
都不像就 raise TypeError
|
|
|
|
|
感谢来自MCDReforged的各位同志《你能在MCDR群里聊除了MCDR的任何东西》
|
|
|
|
|
"""
|
|
|
|
|
if (thing in yes) or (isinstance(thing, str) and thing.lower() in yes):
|
2020-12-16 06:33:33 +08:00
|
|
|
|
return True
|
2021-09-02 22:47:10 +08:00
|
|
|
|
elif (thing in no) or (isinstance(thing, str) and thing.lower() in no):
|
2020-12-16 06:33:33 +08:00
|
|
|
|
return False
|
|
|
|
|
else:
|
2021-09-02 22:47:10 +08:00
|
|
|
|
raise TypeError("Need a 'like bool' not a {}".format(thing))
|
2020-12-22 18:13:59 +08:00
|
|
|
|
|
2020-12-23 23:19:16 +08:00
|
|
|
|
|
2021-03-20 10:52:40 +08:00
|
|
|
|
# linear_algebra
|
2021-02-14 23:15:54 +08:00
|
|
|
|
|
2023-12-03 16:54:07 +08:00
|
|
|
|
|
2021-04-03 12:15:24 +08:00
|
|
|
|
def C_R_P(position, degrees): # stand for calculation
|
2021-03-20 10:52:40 +08:00
|
|
|
|
"""
|
2021-07-08 20:42:22 +08:00
|
|
|
|
very thanks for lenny from pyglet developer
|
2021-03-20 10:56:08 +08:00
|
|
|
|
https://github.com/LennyPhoenix
|
2021-03-20 10:52:40 +08:00
|
|
|
|
this part of code is write by him
|
|
|
|
|
"""
|
|
|
|
|
radians = degrees * (math.pi / 180)
|
|
|
|
|
cos = math.cos(radians)
|
|
|
|
|
sin = math.sin(radians)
|
2023-12-03 16:54:07 +08:00
|
|
|
|
rotated_pos = (
|
|
|
|
|
position[0] * cos - position[1] * sin,
|
|
|
|
|
position[0] * sin + position[1] * cos,
|
|
|
|
|
)
|
2021-03-20 10:52:40 +08:00
|
|
|
|
return rotated_pos
|