pyscreeps-arena 0.5.8.1__tar.gz → 0.5.9.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/PKG-INFO +1 -1
- pyscreeps_arena-0.5.9.0/pyscreeps_arena/afters/__init__.py +6 -0
- pyscreeps_arena-0.5.9.0/pyscreeps_arena/afters/after_config.py +84 -0
- pyscreeps_arena-0.5.9.0/pyscreeps_arena/afters/after_custom.py +87 -0
- pyscreeps_arena-0.5.9.0/pyscreeps_arena/afters/after_empty.py +34 -0
- pyscreeps_arena-0.5.9.0/pyscreeps_arena/afters/after_prefab.py +67 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/compiler.py +110 -17
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/core/const.py +1 -1
- pyscreeps_arena-0.5.9.0/pyscreeps_arena/project.7z +0 -0
- pyscreeps_arena-0.5.9.0/pyscreeps_arena/ui/project_ui.py +948 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena.egg-info/PKG-INFO +1 -1
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena.egg-info/SOURCES.txt +5 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/setup.py +1 -1
- pyscreeps_arena-0.5.8.1/pyscreeps_arena/project.7z +0 -0
- pyscreeps_arena-0.5.8.1/pyscreeps_arena/ui/project_ui.py +0 -215
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/__init__.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/build.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/core/__init__.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/core/basic.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/core/config.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/core/core.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/core/main.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/core/utils.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/localization.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/P2PY.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/__init__.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/creeplogic_edit.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/map_render.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/mapviewer.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qcreeplogic/__init__.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qcreeplogic/model.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qcreeplogic/qcreeplogic.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapker/__init__.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapker/qmapmarker.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapker/qvariable.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapker/test_compact_variable.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapker/test_qmapmarker.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapker/test_qvariable.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapker/to_code.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/__init__.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/qcinfo.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/qco.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/qmapv.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/test_array_drag.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/test_drag.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/test_qcinfo.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/test_qco_drag.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/test_qmapv.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qmapv/test_simple_array.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qrecipe/__init__.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qrecipe/model.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/qrecipe/qrecipe.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena/ui/rs_icon.py +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena.egg-info/dependency_links.txt +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena.egg-info/entry_points.txt +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena.egg-info/requires.txt +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/pyscreeps_arena.egg-info/top_level.txt +0 -0
- {pyscreeps_arena-0.5.8.1 → pyscreeps_arena-0.5.9.0}/setup.cfg +0 -0
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
import sys
|
|
4
|
+
|
|
5
|
+
def ToConfigAfter(path='.', language='cn', arena='gray', level='basic'):
|
|
6
|
+
# 验证参数是否在范围内
|
|
7
|
+
valid_languages = ['cn', 'en']
|
|
8
|
+
valid_arenas = ['green', 'blue', 'red', 'gray']
|
|
9
|
+
valid_levels = ['basic', 'advanced']
|
|
10
|
+
|
|
11
|
+
if language not in valid_languages:
|
|
12
|
+
print(f"错误: language 参数必须是 {valid_languages} 中的一个")
|
|
13
|
+
return False
|
|
14
|
+
|
|
15
|
+
if arena not in valid_arenas:
|
|
16
|
+
print(f"错误: arena 参数必须是 {valid_arenas} 中的一个")
|
|
17
|
+
return False
|
|
18
|
+
|
|
19
|
+
if level not in valid_levels:
|
|
20
|
+
print(f"错误: level 参数必须是 {valid_levels} 中的一个")
|
|
21
|
+
return False
|
|
22
|
+
|
|
23
|
+
# 检查 build.py 文件是否存在
|
|
24
|
+
build_py_path = os.path.join(path, 'build.py')
|
|
25
|
+
if not os.path.exists(build_py_path):
|
|
26
|
+
print("build.py 文件不存在,跳过修改操作")
|
|
27
|
+
return False
|
|
28
|
+
|
|
29
|
+
# 读取文件内容
|
|
30
|
+
with open(build_py_path, 'r', encoding='utf-8') as f:
|
|
31
|
+
content = f.read()
|
|
32
|
+
|
|
33
|
+
# 使用正则表达式替换配置语句
|
|
34
|
+
# 替换 language 配置
|
|
35
|
+
content = re.sub(
|
|
36
|
+
r'config\.language\s*=\s*[\'"]([^\'"]*)[\'"]\s*#\s*\'en\'\s+or\s+\'cn\'',
|
|
37
|
+
f"config.language = '{language}' # 'en' or 'cn'",
|
|
38
|
+
content
|
|
39
|
+
)
|
|
40
|
+
|
|
41
|
+
# 替换 arena 配置
|
|
42
|
+
content = re.sub(
|
|
43
|
+
r'config\.arena\s*=\s*[\'"]([^\'"]*)[\'"]\s*#\s*\'green\',\s*\'blue\',\s*\'red\',\s*\'gray\'',
|
|
44
|
+
f"config.arena = '{arena}' # 'green', 'blue', 'red', 'gray'",
|
|
45
|
+
content
|
|
46
|
+
)
|
|
47
|
+
|
|
48
|
+
# 替换 level 配置
|
|
49
|
+
content = re.sub(
|
|
50
|
+
r'config\.level\s*=\s*[\'"]([^\'"]*)[\'"]\s*#\s*\'basic\',\s*\'advanced\'',
|
|
51
|
+
f"config.level = '{level}' # 'basic', 'advanced'",
|
|
52
|
+
content
|
|
53
|
+
)
|
|
54
|
+
|
|
55
|
+
# 写回文件
|
|
56
|
+
with open(build_py_path, 'w', encoding='utf-8') as f:
|
|
57
|
+
f.write(content)
|
|
58
|
+
|
|
59
|
+
print(f"已更新 build.py 配置:")
|
|
60
|
+
print(f" language = {language}")
|
|
61
|
+
print(f" arena = {arena}")
|
|
62
|
+
print(f" level = {level}")
|
|
63
|
+
return True
|
|
64
|
+
|
|
65
|
+
if __name__ == "__main__":
|
|
66
|
+
# 解析命令行参数
|
|
67
|
+
# 默认值
|
|
68
|
+
path = '.'
|
|
69
|
+
language = 'cn'
|
|
70
|
+
arena = 'gray'
|
|
71
|
+
level = 'basic'
|
|
72
|
+
|
|
73
|
+
# 处理命令行参数
|
|
74
|
+
if len(sys.argv) > 1:
|
|
75
|
+
path = sys.argv[1]
|
|
76
|
+
if len(sys.argv) > 2:
|
|
77
|
+
language = sys.argv[2]
|
|
78
|
+
if len(sys.argv) > 3:
|
|
79
|
+
arena = sys.argv[3]
|
|
80
|
+
if len(sys.argv) > 4:
|
|
81
|
+
level = sys.argv[4]
|
|
82
|
+
|
|
83
|
+
# 执行更新
|
|
84
|
+
ToConfigAfter(path, language, arena, level)
|
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
def ToCustomAfter(path='.'):
|
|
6
|
+
# 检查 prefab 目录是否存在
|
|
7
|
+
prefab_dir = os.path.join(path, 'src', 'prefab')
|
|
8
|
+
if not os.path.exists(prefab_dir):
|
|
9
|
+
print("src/prefab 目录不存在,跳过处理")
|
|
10
|
+
return
|
|
11
|
+
|
|
12
|
+
# 创建 src/custom 目录
|
|
13
|
+
custom_dir = os.path.join(path, 'src', 'custom')
|
|
14
|
+
if not os.path.exists(custom_dir):
|
|
15
|
+
os.makedirs(custom_dir)
|
|
16
|
+
print("已创建 src/custom 目录")
|
|
17
|
+
else:
|
|
18
|
+
print("src/custom 目录已存在,跳过创建操作")
|
|
19
|
+
|
|
20
|
+
# 遍历 prefab 目录中的非 _ 开头的 .py 文件
|
|
21
|
+
for file_name in os.listdir(prefab_dir):
|
|
22
|
+
if file_name.startswith('_') or not file_name.endswith('.py'):
|
|
23
|
+
continue
|
|
24
|
+
|
|
25
|
+
file_path = os.path.join(prefab_dir, file_name)
|
|
26
|
+
print(f"处理文件: {file_path}")
|
|
27
|
+
|
|
28
|
+
# 读取文件内容
|
|
29
|
+
with open(file_path, 'r', encoding='utf-8') as f:
|
|
30
|
+
content = f.read()
|
|
31
|
+
|
|
32
|
+
# 检查是否存在 """$TEMPLATE...""" 的内容
|
|
33
|
+
template_match = re.search(r'"""(\$TEMPLATE.*?)"""', content, re.DOTALL)
|
|
34
|
+
if template_match:
|
|
35
|
+
template_content = template_match.group(1)
|
|
36
|
+
# 移除开头的 $TEMPLATE 标记
|
|
37
|
+
template_content = re.sub(r'^\s*\$TEMPLATE\s*', '', template_content)
|
|
38
|
+
|
|
39
|
+
# 在 custom 目录下创建同名文件
|
|
40
|
+
custom_file_path = os.path.join(custom_dir, file_name)
|
|
41
|
+
with open(custom_file_path, 'w', encoding='utf-8') as f:
|
|
42
|
+
f.write(template_content)
|
|
43
|
+
print(f"已在 custom 目录下创建 {file_name} 文件")
|
|
44
|
+
else:
|
|
45
|
+
print(f"{file_name} 中未找到模板内容,跳过")
|
|
46
|
+
|
|
47
|
+
# 检查并修改 src/main.py 文件,在导入语句末尾添加 from custom import *
|
|
48
|
+
main_py_path = os.path.join(path, 'src', 'main.py')
|
|
49
|
+
if not os.path.exists(main_py_path):
|
|
50
|
+
print("src/main.py 文件不存在,跳过导入语句添加操作")
|
|
51
|
+
return
|
|
52
|
+
|
|
53
|
+
# 读取文件内容
|
|
54
|
+
with open(main_py_path, 'r') as f:
|
|
55
|
+
lines = f.readlines()
|
|
56
|
+
|
|
57
|
+
# 检查是否存在 from custom import * 语句
|
|
58
|
+
has_custom_import = False
|
|
59
|
+
import_end_line = 0
|
|
60
|
+
|
|
61
|
+
for i, line in enumerate(lines):
|
|
62
|
+
if re.search(r'from\s+custom\s+import\s+\*', line):
|
|
63
|
+
has_custom_import = True
|
|
64
|
+
break
|
|
65
|
+
# 检查是否为导入语句
|
|
66
|
+
if re.match(r'^(from|import)\s+', line.strip()):
|
|
67
|
+
import_end_line = i + 1 # 记录导入语句的结束位置(下一行)
|
|
68
|
+
|
|
69
|
+
if not has_custom_import:
|
|
70
|
+
# 在导入语句的末尾插入 from custom import * 语句
|
|
71
|
+
if import_end_line > 0:
|
|
72
|
+
# 在导入语句末尾插入
|
|
73
|
+
lines.insert(import_end_line, '\nfrom custom import *\n')
|
|
74
|
+
else:
|
|
75
|
+
# 如果没有导入语句,在文件开头插入
|
|
76
|
+
lines.insert(0, 'from custom import *\n')
|
|
77
|
+
|
|
78
|
+
# 写回文件
|
|
79
|
+
with open(main_py_path, 'w') as f:
|
|
80
|
+
f.writelines(lines)
|
|
81
|
+
print("已在 src/main.py 中导入语句末尾追加 from custom import * 语句")
|
|
82
|
+
else:
|
|
83
|
+
print("src/main.py 中已存在 from custom import * 语句,跳过添加操作")
|
|
84
|
+
|
|
85
|
+
|
|
86
|
+
if __name__ == "__main__":
|
|
87
|
+
ToCustomAfter('.')
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import re
|
|
3
|
+
|
|
4
|
+
def ToEmptyAfter(path='.'):
|
|
5
|
+
# 删除 src/basic.py 文件
|
|
6
|
+
basic_path = os.path.join(path, 'src', 'basic.py')
|
|
7
|
+
if os.path.exists(basic_path):
|
|
8
|
+
os.remove(basic_path)
|
|
9
|
+
print("已删除 src/basic.py")
|
|
10
|
+
else:
|
|
11
|
+
print("src/basic.py 不存在,跳过删除操作")
|
|
12
|
+
|
|
13
|
+
# 修改 src/main.py 文件,将 from basic import * 改为 from builtin import *
|
|
14
|
+
main_path = os.path.join(path, 'src', 'main.py')
|
|
15
|
+
if os.path.exists(main_path):
|
|
16
|
+
with open(main_path, 'r') as f:
|
|
17
|
+
content = f.read()
|
|
18
|
+
|
|
19
|
+
# 使用正则表达式替换,处理各种可能的空白字符
|
|
20
|
+
modified_content = re.sub(r'from\s+basic\s+import\s+\*', 'from builtin import *', content)
|
|
21
|
+
|
|
22
|
+
# 检查是否发生了替换
|
|
23
|
+
if modified_content != content:
|
|
24
|
+
with open(main_path, 'w') as f:
|
|
25
|
+
f.write(modified_content)
|
|
26
|
+
print("已修改 src/main.py,将 from basic import * 改为 from builtin import *")
|
|
27
|
+
else:
|
|
28
|
+
print("src/main.py 中未找到 from basic import * 语句,跳过修改操作")
|
|
29
|
+
else:
|
|
30
|
+
print("src/main.py 不存在,跳过修改操作")
|
|
31
|
+
|
|
32
|
+
if __name__ == "__main__":
|
|
33
|
+
ToEmptyAfter('.')
|
|
34
|
+
|
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
import os
|
|
2
|
+
import shutil
|
|
3
|
+
import re
|
|
4
|
+
|
|
5
|
+
def ToPrefabAfter(path='.'):
|
|
6
|
+
# 检查 docs/prefab 目录是否存在
|
|
7
|
+
source_dir = os.path.join(path, 'docs', 'prefab')
|
|
8
|
+
if not os.path.exists(source_dir):
|
|
9
|
+
print("docs/prefab 目录不存在,跳过移动操作")
|
|
10
|
+
return
|
|
11
|
+
|
|
12
|
+
# 检查 src 目录是否存在
|
|
13
|
+
src_dir = os.path.join(path, 'src')
|
|
14
|
+
if not os.path.exists(src_dir):
|
|
15
|
+
os.makedirs(src_dir)
|
|
16
|
+
print("已创建 src 目录")
|
|
17
|
+
|
|
18
|
+
# 移动 docs/prefab 到 src/prefab
|
|
19
|
+
dest_dir = os.path.join(src_dir, 'prefab')
|
|
20
|
+
if os.path.exists(dest_dir):
|
|
21
|
+
# 如果目标目录已存在,先删除
|
|
22
|
+
shutil.rmtree(dest_dir)
|
|
23
|
+
print("已删除现有 src/prefab 目录")
|
|
24
|
+
|
|
25
|
+
shutil.move(source_dir, dest_dir)
|
|
26
|
+
print("已将 docs/prefab 移动到 src/prefab")
|
|
27
|
+
|
|
28
|
+
# 检查并修改 src/main.py 文件
|
|
29
|
+
main_py_path = os.path.join(src_dir, 'main.py')
|
|
30
|
+
if not os.path.exists(main_py_path):
|
|
31
|
+
print("src/main.py 文件不存在,跳过导入语句添加操作")
|
|
32
|
+
return
|
|
33
|
+
|
|
34
|
+
# 读取文件内容
|
|
35
|
+
with open(main_py_path, 'r') as f:
|
|
36
|
+
lines = f.readlines()
|
|
37
|
+
|
|
38
|
+
# 检查是否存在 from prefab import * 语句
|
|
39
|
+
has_prefab_import = False
|
|
40
|
+
import_end_line = 0
|
|
41
|
+
|
|
42
|
+
for i, line in enumerate(lines):
|
|
43
|
+
if re.search(r'from\s+prefab\s+import\s+\*', line):
|
|
44
|
+
has_prefab_import = True
|
|
45
|
+
break
|
|
46
|
+
# 检查是否为导入语句
|
|
47
|
+
if re.match(r'^(from|import)\s+', line.strip()):
|
|
48
|
+
import_end_line = i + 1 # 记录导入语句的结束位置(下一行)
|
|
49
|
+
|
|
50
|
+
if not has_prefab_import:
|
|
51
|
+
# 在导入语句的末尾插入 from prefab import * 语句
|
|
52
|
+
if import_end_line > 0:
|
|
53
|
+
# 在导入语句末尾插入
|
|
54
|
+
lines.insert(import_end_line, 'from prefab import *\n')
|
|
55
|
+
else:
|
|
56
|
+
# 如果没有导入语句,在文件开头插入
|
|
57
|
+
lines.insert(0, 'from prefab import *\n')
|
|
58
|
+
|
|
59
|
+
# 写回文件
|
|
60
|
+
with open(main_py_path, 'w') as f:
|
|
61
|
+
f.writelines(lines)
|
|
62
|
+
print("已在 src/main.py 中导入语句末尾追加 from prefab import * 语句")
|
|
63
|
+
else:
|
|
64
|
+
print("src/main.py 中已存在 from prefab import * 语句,跳过添加操作")
|
|
65
|
+
|
|
66
|
+
if __name__ == "__main__":
|
|
67
|
+
ToPrefabAfter('.')
|
|
@@ -8,6 +8,7 @@ import shutil
|
|
|
8
8
|
import chardet
|
|
9
9
|
import subprocess
|
|
10
10
|
import pyperclip
|
|
11
|
+
import datetime
|
|
11
12
|
from colorama import Fore
|
|
12
13
|
from typing import List, Optional, Tuple, Union
|
|
13
14
|
|
|
@@ -52,6 +53,7 @@ def replace_src_prefix(file_list):
|
|
|
52
53
|
# """
|
|
53
54
|
# return PYFILE_PRAGMA_INSERTS + "\n" + content
|
|
54
55
|
class Compiler_Const:
|
|
56
|
+
CALLED_FUNCTIONS = ['behavior', 'sequence', 'selector', 'parallel', 'listen']
|
|
55
57
|
PROTO_DEFINES_DIRS = ["builtin", "library"]
|
|
56
58
|
FILE_STRONG_REPLACE = {
|
|
57
59
|
"std": {
|
|
@@ -108,14 +110,14 @@ export var loop = function () {
|
|
|
108
110
|
if (know.now === 1) {
|
|
109
111
|
std.show_welcome();
|
|
110
112
|
init (know);
|
|
111
|
-
|
|
113
|
+
|
|
112
114
|
}
|
|
113
115
|
step (know);
|
|
114
116
|
timeLine = get.cpu_us();
|
|
115
117
|
if (get._SCH_FLAG) sch.handle();
|
|
116
118
|
stepCost = get.cpu_us() - timeLine;
|
|
117
119
|
std.show_usage ();
|
|
118
|
-
|
|
120
|
+
print("knowCost:", knowCost, "monitorCost:", monitorCost, "stepCost:", stepCost);
|
|
119
121
|
if (know.draw) know.draw();
|
|
120
122
|
};
|
|
121
123
|
"""
|
|
@@ -648,6 +650,82 @@ class Compiler_Utils(Compiler_Const):
|
|
|
648
650
|
|
|
649
651
|
return result
|
|
650
652
|
|
|
653
|
+
@staticmethod
|
|
654
|
+
def stage_called_replace(caller_name: str, content: str) -> str:
|
|
655
|
+
"""
|
|
656
|
+
移除 '@<caller_name>(...)' 装饰器行,并在文末添加对应的 _<caller_name>Login 调用。
|
|
657
|
+
|
|
658
|
+
对于类方法: _<caller_name>Login("ClassName", "method_name", a, b, ...)
|
|
659
|
+
对于普通函数: _<caller_name>Login("", "function_name", a, b, ...)
|
|
660
|
+
"""
|
|
661
|
+
calls_to_add = []
|
|
662
|
+
deletions = []
|
|
663
|
+
|
|
664
|
+
# 1. 收集所有类定义的位置和缩进
|
|
665
|
+
class_pattern = re.compile(r'^(\s*)class\s+(\w+)', re.MULTILINE)
|
|
666
|
+
classes = [(m.start(), len(m.group(1)), m.group(2))
|
|
667
|
+
for m in class_pattern.finditer(content)]
|
|
668
|
+
|
|
669
|
+
# 2. 查找所有 @<caller_name>(...) 装饰器(支持多行参数)
|
|
670
|
+
decorator_pattern = re.compile(
|
|
671
|
+
r'^\s*@\s*' + re.escape(caller_name) + r'\s*\((.*?)\)\s*$\n?',
|
|
672
|
+
re.MULTILINE | re.DOTALL
|
|
673
|
+
)
|
|
674
|
+
|
|
675
|
+
for dec_match in decorator_pattern.finditer(content):
|
|
676
|
+
dec_start = dec_match.start()
|
|
677
|
+
dec_end = dec_match.end()
|
|
678
|
+
# 提取装饰器的参数
|
|
679
|
+
params_str = dec_match.group(1).strip()
|
|
680
|
+
|
|
681
|
+
# 查找接下来的函数定义(跳过可能的空行)
|
|
682
|
+
after_decorator = content[dec_end:]
|
|
683
|
+
func_match = re.search(r'^(\s*)def\s+([^\s\(]+)', after_decorator, re.MULTILINE)
|
|
684
|
+
|
|
685
|
+
if not func_match:
|
|
686
|
+
continue
|
|
687
|
+
|
|
688
|
+
func_indent_len = len(func_match.group(1))
|
|
689
|
+
func_name = func_match.group(2)
|
|
690
|
+
|
|
691
|
+
# 3. 确定类名:查找装饰器前最近的、缩进小于函数缩进的类
|
|
692
|
+
class_name = ""
|
|
693
|
+
for cls_pos, cls_indent_len, cls_name in reversed(classes):
|
|
694
|
+
if cls_pos < dec_match.start() and func_indent_len > cls_indent_len:
|
|
695
|
+
class_name = cls_name
|
|
696
|
+
break
|
|
697
|
+
|
|
698
|
+
# 4. 处理参数,保持参数的格式
|
|
699
|
+
# 移除参数中的换行和多余空格,保持参数列表的格式
|
|
700
|
+
params = []
|
|
701
|
+
if params_str:
|
|
702
|
+
# 简单处理参数,保持引号内的内容不变
|
|
703
|
+
# 这里可以根据需要进行更复杂的参数解析
|
|
704
|
+
params = [p.strip() for p in params_str.split(',') if p.strip()]
|
|
705
|
+
|
|
706
|
+
# 构建参数部分的字符串
|
|
707
|
+
params_part = ""
|
|
708
|
+
if params:
|
|
709
|
+
params_part = ", " + ", ".join(params)
|
|
710
|
+
|
|
711
|
+
# 5. 记录删除位置和调用信息
|
|
712
|
+
deletions.append((dec_start, dec_end))
|
|
713
|
+
calls_to_add.append(f'_{caller_name}Login("{class_name}", "{func_name}"{params_part})')
|
|
714
|
+
|
|
715
|
+
# 6. 应用删除(倒序避免位置偏移)
|
|
716
|
+
if not deletions:
|
|
717
|
+
return content
|
|
718
|
+
|
|
719
|
+
result = content
|
|
720
|
+
for start, end in sorted(deletions, key=lambda x: x[0], reverse=True):
|
|
721
|
+
result = result[:start] + result[end:]
|
|
722
|
+
|
|
723
|
+
# 7. 在文末添加调用
|
|
724
|
+
if calls_to_add:
|
|
725
|
+
result = '\n'.join(calls_to_add) + '\n' + result
|
|
726
|
+
|
|
727
|
+
return result
|
|
728
|
+
|
|
651
729
|
@staticmethod
|
|
652
730
|
def process_mate_code(code):
|
|
653
731
|
# 用于存储匹配到的信息
|
|
@@ -921,6 +999,8 @@ class Compiler(CompilerBase):
|
|
|
921
999
|
|
|
922
1000
|
# 将PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "")插入到文件开头
|
|
923
1001
|
content = self.auto_read(fpath)
|
|
1002
|
+
# 移除"""$..."""代码块
|
|
1003
|
+
content = re.sub(r'"""\$[\s\S]*?"""', '', content)
|
|
924
1004
|
content = self.PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "") + content
|
|
925
1005
|
# content = self.remove_long_docstring(content) # 移除长注释 | remove long docstring
|
|
926
1006
|
|
|
@@ -1077,10 +1157,13 @@ class Compiler(CompilerBase):
|
|
|
1077
1157
|
with open(fpath, 'w', encoding='utf-8') as f:
|
|
1078
1158
|
f.write(new_content)
|
|
1079
1159
|
|
|
1080
|
-
# ------------------------------------ 自定义:调用stage_recursive_replace ------------------------------------ #
|
|
1160
|
+
# ------------------------------------ 自定义:调用stage_recursive_replace和stage_called_replace ------------------------------------ #
|
|
1081
1161
|
for fpath in py_fpath:
|
|
1082
1162
|
content = self.auto_read(fpath)
|
|
1083
1163
|
content = self.stage_recursive_replace(content) # 调用stage_recursive_replace
|
|
1164
|
+
# 调用stage_called_replace处理四个装饰器
|
|
1165
|
+
for caller in self.CALLED_FUNCTIONS:
|
|
1166
|
+
content = self.stage_called_replace(caller, content)
|
|
1084
1167
|
with open(fpath, 'w', encoding='utf-8') as f:
|
|
1085
1168
|
f.write(content)
|
|
1086
1169
|
|
|
@@ -1217,12 +1300,22 @@ class Compiler(CompilerBase):
|
|
|
1217
1300
|
:param min_js_files: list[str] # .min.js文件路径列表
|
|
1218
1301
|
:return: str
|
|
1219
1302
|
"""
|
|
1220
|
-
arena_name = const.ARENA_NAMES.get(config.arena, const.ARENA_NAMES[
|
|
1303
|
+
arena_name = const.ARENA_NAMES.get(config.arena, const.ARENA_NAMES["green"]) # like green -> spawn_and_swamp
|
|
1221
1304
|
self.TOTAL_INSERT_AT_HEAD += self.ARENA_IMPORTS_GETTER[arena_name]() # add arena imports
|
|
1222
|
-
|
|
1223
|
-
|
|
1305
|
+
current_time = datetime.datetime.now()
|
|
1306
|
+
timestamp_ms = int(current_time.timestamp() * 1000)
|
|
1307
|
+
timestring = current_time.strftime("%Y-%m-%d %H:%M")
|
|
1308
|
+
|
|
1309
|
+
total_js = f"""const __VERSION__ = '{const.VERSION}';
|
|
1310
|
+
const __PYTHON_VERSION__ = '{python_version_info}';""" + self.TOTAL_INSERT_AT_HEAD + f"""
|
|
1311
|
+
export var LANGUAGE = '{config.language}';
|
|
1312
|
+
"""
|
|
1313
|
+
|
|
1314
|
+
total_js += f"export var TIMESTAMP = {timestamp_ms};\n"
|
|
1315
|
+
total_js += f"export var TIMESTRING = '{timestring}';\n"
|
|
1316
|
+
total_js += f"""const __AUTHOR__ = '{const.AUTHOR}';
|
|
1317
|
+
const __AUTHOR_CN__ = '{const.BILIBILI_NAME}';"""
|
|
1224
1318
|
|
|
1225
|
-
# 添加.min.js文件的import语句
|
|
1226
1319
|
if min_js_files:
|
|
1227
1320
|
for min_js_path in min_js_files:
|
|
1228
1321
|
min_js_filename = os.path.basename(min_js_path)
|
|
@@ -1342,14 +1435,6 @@ class Compiler(CompilerBase):
|
|
|
1342
1435
|
dir_path = os.path.dirname(mjs_path)
|
|
1343
1436
|
build_dir_path = os.path.dirname(build_main_mjs)
|
|
1344
1437
|
|
|
1345
|
-
# 复制.min.js文件到目标目录
|
|
1346
|
-
for min_js_path in min_js_files:
|
|
1347
|
-
min_js_filename = os.path.basename(min_js_path)
|
|
1348
|
-
# 复制到build目录
|
|
1349
|
-
shutil.copy(min_js_path, os.path.join(build_dir_path, min_js_filename))
|
|
1350
|
-
# 复制到最终导出目录
|
|
1351
|
-
shutil.copy(min_js_path, os.path.join(dir_path, min_js_filename))
|
|
1352
|
-
|
|
1353
1438
|
# 生成total_js,传入.min.js文件列表
|
|
1354
1439
|
total_js = imports + "\n" + self.generate_total_js(
|
|
1355
1440
|
replace_src_prefix(modules), imps, sorts, self.FILE_STRONG_REPLACE, reps, min_js_files
|
|
@@ -1365,6 +1450,14 @@ class Compiler(CompilerBase):
|
|
|
1365
1450
|
with open(mjs_path, 'w', encoding='utf-8') as f:
|
|
1366
1451
|
f.write(total_js)
|
|
1367
1452
|
|
|
1453
|
+
# 复制.min.js文件到目标目录
|
|
1454
|
+
for min_js_path in min_js_files:
|
|
1455
|
+
min_js_filename = os.path.basename(min_js_path)
|
|
1456
|
+
# 复制到build目录
|
|
1457
|
+
shutil.copy(min_js_path, os.path.join(build_dir_path, min_js_filename))
|
|
1458
|
+
# 复制到最终导出目录
|
|
1459
|
+
shutil.copy(min_js_path, os.path.join(dir_path, min_js_filename))
|
|
1460
|
+
|
|
1368
1461
|
core.lprint(GREEN.format('[6/6]'), LOC_DONE, " ", LOC_EXPORTING_TOTAL_MAIN_JS_FINISH, sep="", head="\r", ln=config.language)
|
|
1369
1462
|
|
|
1370
1463
|
if mjs_path != build_main_mjs:
|
|
@@ -1422,7 +1515,7 @@ if __name__ == '__main__':
|
|
|
1422
1515
|
# compiler.compile()
|
|
1423
1516
|
# compiler.clean()
|
|
1424
1517
|
test = """
|
|
1425
|
-
|
|
1518
|
+
|
|
1426
1519
|
def patrolling(self, c: Creep):
|
|
1427
1520
|
e = self.center.nearest(k.civilian.enemies, 5)
|
|
1428
1521
|
if e:
|
|
@@ -1432,6 +1525,6 @@ def patrolling(self, c: Creep):
|
|
|
1432
1525
|
):
|
|
1433
1526
|
case True: c.move(e, SWAMP_MOTION)
|
|
1434
1527
|
case False: c.move(self.bpos, SWAMP_MOTION)
|
|
1435
|
-
|
|
1528
|
+
|
|
1436
1529
|
"""
|
|
1437
1530
|
print(f"res=\n{Compiler.convert_match_to_if(test)}")
|
|
Binary file
|