pyscreeps-arena 0.3a1__tar.gz → 0.3a2__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.3a1 → pyscreeps-arena-0.3a2}/PKG-INFO +1 -1
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/compiler.py +193 -138
- pyscreeps-arena-0.3a2/pyscreeps_arena/core/config.py +18 -0
- pyscreeps-arena-0.3a2/pyscreeps_arena/core/const.py +27 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/localization.py +12 -0
- pyscreeps-arena-0.3a2/pyscreeps_arena/project.7z +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena.egg-info/PKG-INFO +1 -1
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena.egg-info/requires.txt +1 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/setup.py +2 -1
- pyscreeps-arena-0.3a1/pyscreeps_arena/core/config.py +0 -13
- pyscreeps-arena-0.3a1/pyscreeps_arena/core/const.py +0 -16
- pyscreeps-arena-0.3a1/pyscreeps_arena/project.7z +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/__init__.py +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/build.py +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/core/__init__.py +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/core/basic.py +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/core/core.py +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/core/main.py +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena/core/utils.py +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena.egg-info/SOURCES.txt +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena.egg-info/dependency_links.txt +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena.egg-info/entry_points.txt +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena.egg-info/top_level.txt +0 -0
- {pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/setup.cfg +0 -0
|
@@ -12,9 +12,9 @@ from colorama import Fore
|
|
|
12
12
|
|
|
13
13
|
WAIT = Fore.YELLOW + ">>>" + Fore.RESET
|
|
14
14
|
GREEN = Fore.GREEN + "{}" + Fore.RESET
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
15
|
+
python_version_info = sys.version_info
|
|
16
|
+
python_version_info = f"{python_version_info.major}.{python_version_info.minor}.{python_version_info.micro}"
|
|
17
|
+
|
|
18
18
|
|
|
19
19
|
# def InsertPragmaBefore(content:str) -> str:
|
|
20
20
|
# """
|
|
@@ -32,7 +32,7 @@ class Compiler_Const:
|
|
|
32
32
|
"!=": "!==",
|
|
33
33
|
}
|
|
34
34
|
}
|
|
35
|
-
PYFILE_IGNORE_CHECK_FNAMES = ['
|
|
35
|
+
PYFILE_IGNORE_CHECK_FNAMES = ['builtin/const.py', 'builtin/proto.py', 'builtin/utils.py']
|
|
36
36
|
|
|
37
37
|
PYFILE_PRAGMA_INSERTS = """
|
|
38
38
|
# __pragma__('noalias', 'undefined')
|
|
@@ -42,12 +42,35 @@ class Compiler_Const:
|
|
|
42
42
|
"""
|
|
43
43
|
|
|
44
44
|
TOTAL_INSERT_AT_HEAD = """
|
|
45
|
-
|
|
45
|
+
import { createConstructionSite, findClosestByPath, findClosestByRange, findInRange, findPath, getCpuTime, getDirection, getHeapStatistics, getObjectById, getObjects, getObjectsByPrototype, getRange, getTerrainAt, getTicks,} from 'game/utils';
|
|
46
|
+
import { ConstructionSite, Creep, GameObject, OwnedStructure, Resource, Source, Structure, StructureContainer, StructureExtension, StructureRampart, StructureRoad, StructureSpawn, StructureTower, StructureWall,} from 'game/prototypes';
|
|
47
|
+
import { ATTACK, ATTACK_POWER, BODYPART_COST, BODYPART_HITS, BOTTOM, BOTTOM_LEFT, BOTTOM_RIGHT, BUILD_POWER, CARRY, CARRY_CAPACITY, CONSTRUCTION_COST, CONSTRUCTION_COST_ROAD_SWAMP_RATIO, CONSTRUCTION_COST_ROAD_WALL_RATIO, CONTAINER_CAPACITY, CONTAINER_HITS, CREEP_SPAWN_TIME, DISMANTLE_COST, DISMANTLE_POWER, ERR_BUSY, ERR_FULL, ERR_INVALID_ARGS, ERR_INVALID_TARGET, ERR_NAME_EXISTS, ERR_NOT_ENOUGH_ENERGY, ERR_NOT_ENOUGH_EXTENSIONS, ERR_NOT_ENOUGH_RESOURCES, ERR_NOT_FOUND, ERR_NOT_IN_RANGE, ERR_NOT_OWNER, ERR_NO_BODYPART, ERR_NO_PATH, ERR_TIRED, EXTENSION_ENERGY_CAPACITY, EXTENSION_HITS, HARVEST_POWER, HEAL, HEAL_POWER, LEFT, MAX_CONSTRUCTION_SITES, MAX_CREEP_SIZE, MOVE, OBSTACLE_OBJECT_TYPES, OK, RAMPART_HITS, RAMPART_HITS_MAX, RANGED_ATTACK, RANGED_ATTACK_DISTANCE_RATE, RANGED_ATTACK_POWER, RANGED_HEAL_POWER, REPAIR_COST, REPAIR_POWER, RESOURCES_ALL, RESOURCE_DECAY, RESOURCE_ENERGY, RIGHT, ROAD_HITS, ROAD_WEAROUT, SOURCE_ENERGY_REGEN, SPAWN_ENERGY_CAPACITY, SPAWN_HITS, STRUCTURE_PROTOTYPES, TERRAIN_PLAIN, TERRAIN_SWAMP, TERRAIN_WALL, TOP, TOP_LEFT, TOP_RIGHT, TOUGH, TOWER_CAPACITY, TOWER_COOLDOWN, TOWER_ENERGY_COST, TOWER_FALLOFF, TOWER_FALLOFF_RANGE, TOWER_HITS, TOWER_OPTIMAL_RANGE, TOWER_POWER_ATTACK, TOWER_POWER_HEAL, TOWER_POWER_REPAIR, TOWER_RANGE, WALL_HITS, WALL_HITS_MAX, WORK} from 'game/constants';
|
|
48
|
+
|
|
49
|
+
import {arenaInfo} from "game";
|
|
50
|
+
import {Visual} from "game/visual"
|
|
51
|
+
import {searchPath} from "game/path-finder"
|
|
46
52
|
"""
|
|
47
53
|
|
|
48
54
|
TOTAL_INSERT_BEFORE_MAIN = """
|
|
49
55
|
"""
|
|
50
56
|
|
|
57
|
+
TOTAL_APPEND_ATEND = """
|
|
58
|
+
export var sch = Scheduler();
|
|
59
|
+
|
|
60
|
+
know.now = 0;
|
|
61
|
+
export var loop = function () {
|
|
62
|
+
know.now = get.ticks ();
|
|
63
|
+
if (know.now === 1) {
|
|
64
|
+
init (know);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
know.update_(know);
|
|
68
|
+
step (know);
|
|
69
|
+
sch.handle();
|
|
70
|
+
std.show_usage ();
|
|
71
|
+
};
|
|
72
|
+
"""
|
|
73
|
+
|
|
51
74
|
TOTAL_SIMPLE_REPLACE_WITH = {
|
|
52
75
|
}
|
|
53
76
|
|
|
@@ -67,34 +90,12 @@ class Compiler_Const:
|
|
|
67
90
|
|
|
68
91
|
JS_VM = "org.transcrypt.__runtime__.js"
|
|
69
92
|
|
|
70
|
-
GAME_UTILS = './builtin.utils.js'
|
|
71
|
-
GAME_PROTO = './builtin.proto.js'
|
|
72
|
-
GAME_CONST = './builtin.const.js'
|
|
73
93
|
BUILTIN_TRANS = ["engine.js"]
|
|
74
94
|
OTHER_IGNORE_WITH = "./builtin"
|
|
75
95
|
|
|
76
|
-
SYSTEM_MODULES_IGNORE = {
|
|
77
|
-
GAME_UTILS: ['CircleVisualStyle', 'Color', 'CostMatrix', 'CreateConstructionSiteResult', 'Direction', 'DoesZapCodeSpaceFlag',
|
|
78
|
-
'FindPathOptions', 'Goal', 'HeapInfo',
|
|
79
|
-
'LineStyle', 'LineVisualStyle', 'PolyVisualStyle', 'RectVisualStyle', 'SearchPathOptions', 'SearchPathResult', 'Terrain',
|
|
80
|
-
'TextAlign', 'TextVisualStyle',
|
|
81
|
-
'Visual', 'getAt', 'searchPath'],
|
|
82
|
-
GAME_PROTO: ['BodyPartType', 'CreepAttackResult', 'CreepBuildResult', 'CreepDropResult', 'CreepHarvestResult', 'CreepHealResult',
|
|
83
|
-
'CreepMoveResult', 'CreepPickupResult',
|
|
84
|
-
'CreepPullResult', 'CreepRangedAttackResult', 'CreepRangedHealResult', 'CreepRangedMassAttackResult',
|
|
85
|
-
'CreepTransferResult', 'CreepWithdrawResult',
|
|
86
|
-
'ResourceType', 'SpawnCreepResult', 'Store', 'TowerAttackResult', 'TowerHealResult', 'Spawning', 'ScoreController',
|
|
87
|
-
'Flag', 'Position'],
|
|
88
|
-
GAME_CONST: ['RESOURCE_SCORE'],
|
|
89
|
-
}
|
|
90
|
-
SYSTEM_MODULES_TRANSNAME = { # 对应的在js中的名字 | Corresponding name in js
|
|
91
|
-
GAME_UTILS: "game/utils",
|
|
92
|
-
GAME_PROTO: "game/prototypes",
|
|
93
|
-
GAME_CONST: "game/constants",
|
|
94
|
-
}
|
|
95
|
-
GENERATE_IGNORE_PYFILES = ['config.py'] # Won't be compiled into the final js code, only for defines.
|
|
96
|
-
|
|
97
96
|
JS_IMPORT_PAT = re.compile(r'from\s+[\'\"]([^\']+)[\'\"]')
|
|
97
|
+
JS_EXPORT_PAT = re.compile(r'export\s+{([^}]+)}')
|
|
98
|
+
PY_IMPORT_PAT = re.compile(r'from\s+(.+)(?=\s+import)\s+import\s+\*')
|
|
98
99
|
INSERT_PAT = re.compile(r'#\s*insert\s+([^\n]*)') # 因为被判定的string为单line,所以不需要考虑多行的情况
|
|
99
100
|
|
|
100
101
|
TRANSCRYPT_ERROR_REPLACE = {
|
|
@@ -102,6 +103,25 @@ class Compiler_Const:
|
|
|
102
103
|
r"new\s+set\s*\(": r"set(",
|
|
103
104
|
}
|
|
104
105
|
|
|
106
|
+
ARENA_IMPORTS_GETTER = {
|
|
107
|
+
const.ARENA_GREEN: lambda: f"""
|
|
108
|
+
|
|
109
|
+
""",
|
|
110
|
+
const.ARENA_BLUE: lambda: f"""
|
|
111
|
+
import {{ Flag, StructureTower }} from 'arena/season_{config.season}/capture_the_flag/basic';
|
|
112
|
+
""",
|
|
113
|
+
const.ARENA_RED: lambda: f"""
|
|
114
|
+
import {{ RESOURCE_SCORE, RESOURCE_SCORE_X, RESOURCE_SCORE_Y, RESOURCE_SCORE_Z, ScoreCollector, AreaEffect, EFFECT_DAMAGE, EFFECT_FREEZE }} from 'arena/season_{config.season}/collect_and_control/basic';
|
|
115
|
+
""",
|
|
116
|
+
const.ARENA_GRAY: lambda: f"""
|
|
117
|
+
// import {{ Flag }} from 'game/prototypes'
|
|
118
|
+
import("game/prototypes")
|
|
119
|
+
.then((module) => {{ const Flag = module.Flag; }})
|
|
120
|
+
.catch((error) => {{ }});
|
|
121
|
+
""",
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
|
|
105
125
|
class Compiler_Utils(Compiler_Const):
|
|
106
126
|
last_output = False # 一个小标志位,我只想输出一次此类告警信息
|
|
107
127
|
|
|
@@ -134,7 +154,6 @@ class Compiler_Utils(Compiler_Const):
|
|
|
134
154
|
with open(fpath, 'r', encoding=encoding) as f: # 使用检测到的编码打开文件
|
|
135
155
|
return f.read()
|
|
136
156
|
|
|
137
|
-
|
|
138
157
|
def copy_to(self) -> list:
|
|
139
158
|
"""
|
|
140
159
|
复制src到build目录 | copy all files in src to build
|
|
@@ -149,6 +168,7 @@ class Compiler_Utils(Compiler_Const):
|
|
|
149
168
|
if os.path.exists(self.build_dir):
|
|
150
169
|
shutil.rmtree(self.build_dir)
|
|
151
170
|
shutil.copytree(self.src_dir, self.build_dir)
|
|
171
|
+
shutil.copytree(self.src_dir, os.path.join(self.build_dir, "src"))
|
|
152
172
|
srcs = [] # src下所有python文件的路径 | paths of all python files under src
|
|
153
173
|
for root, dirs, files in os.walk(self.build_dir):
|
|
154
174
|
for file in files:
|
|
@@ -165,7 +185,7 @@ class Compiler_Utils(Compiler_Const):
|
|
|
165
185
|
return srcs
|
|
166
186
|
|
|
167
187
|
@staticmethod
|
|
168
|
-
def potential_check(fpath:str, fname:str) -> bool:
|
|
188
|
+
def potential_check(fpath: str, fname: str) -> bool:
|
|
169
189
|
"""
|
|
170
190
|
检查某个py文件内是否有潜在问题 | check if there are potential problems in a py file
|
|
171
191
|
|
|
@@ -175,8 +195,8 @@ class Compiler_Utils(Compiler_Const):
|
|
|
175
195
|
bool: 是否有警告
|
|
176
196
|
"""
|
|
177
197
|
# 文件路径检查
|
|
178
|
-
if fpath.endswith('__init__.py') and fpath.find("builtin") == -1:
|
|
179
|
-
|
|
198
|
+
# if fpath.endswith('__init__.py') and fpath.find("builtin") == -1:
|
|
199
|
+
# core.error("potential_check", LOC_NOT_SUPPORT_PYFILE_INIT, ln=config.language, ecode=-1, head='\n')
|
|
180
200
|
if fname in Compiler.PYFILE_IGNORE_CHECK_FNAMES:
|
|
181
201
|
return False
|
|
182
202
|
|
|
@@ -212,10 +232,10 @@ class Compiler_Utils(Compiler_Const):
|
|
|
212
232
|
for i, line in enumerate(lines): # 遍历源代码的每一行 | iterate over each line of source code
|
|
213
233
|
striped = line.strip() # 去掉行首尾的空格和换行符 | strip leading and trailing whitespace
|
|
214
234
|
# 使用正则表达式匹配不同的条件语句 | use regex to match different conditional statements
|
|
215
|
-
if_match = re.match(r'#\s*>\s*if\s+([^:.]*)$', striped)
|
|
216
|
-
elif_match = re.match(r'#\s*>\s*elif\s+([^:.]*)$', striped)
|
|
217
|
-
else_match = re.match(r'#\s*>\s*else$', striped)
|
|
218
|
-
endif_match = re.match(r'#\s*>\s*endif$', striped)
|
|
235
|
+
if_match = re.match(r'#\s*>\s*if\s+([^:.]*)$', striped) # 匹配 '# > if' 语句 | match '# > if' statement
|
|
236
|
+
elif_match = re.match(r'#\s*>\s*elif\s+([^:.]*)$', striped) # 匹配 '# > elif' 语句 | match '# > elif' statement
|
|
237
|
+
else_match = re.match(r'#\s*>\s*else$', striped) # 匹配 '# > else' 语句 | match '# > else' statement
|
|
238
|
+
endif_match = re.match(r'#\s*>\s*endif$', striped) # 匹配 '# > endif' 语句 | match '# > endif' statement
|
|
219
239
|
|
|
220
240
|
if if_match: # 如果当前行是 '# > if' 语句 | if it's a '# > if' statement
|
|
221
241
|
condition = if_match.group(1) # 提取条件表达式 | extract the condition expression
|
|
@@ -233,6 +253,80 @@ class Compiler_Utils(Compiler_Const):
|
|
|
233
253
|
|
|
234
254
|
return '\n'.join(result) # 将处理后的所有代码行连接成一个字符串,并返回最终结果 | join all processed lines into a string and return
|
|
235
255
|
|
|
256
|
+
def find_chain_import(self, fpath: str, search_dirs: list[str], project_path: str = None, records: dict[str, None] = None) -> list[str]:
|
|
257
|
+
"""
|
|
258
|
+
查找文件中的所有import语句,并返回所有import的文件路径 | find all import statements in a file and return the paths of all imported files
|
|
259
|
+
PY_IMPORT_PAT: re.compile(r'\s+from\s+(.+)(?=\s+import)\s+import\s+\*')
|
|
260
|
+
:param fpath: str 目标文件路径 | target file path
|
|
261
|
+
:param search_dirs: list[str] 搜索目录 | search directories
|
|
262
|
+
:param project_path=None: str python项目中的概念,指根文件所在的目录。如果不指定,默认使用第一次调用时给定的fpath,并且稍后的递归会全部使用此路径 |
|
|
263
|
+
concept in python-project, refers to the directory where the root file is located. If not specified, the fpath given at the first call is used by default, and all subsequent recursions will use this path
|
|
264
|
+
:param records=None: dict[str, None] 记录已经查找过的文件路径,避免重复查找 | record the file paths that have been searched to avoid duplicate searches
|
|
265
|
+
"""
|
|
266
|
+
if records is None:
|
|
267
|
+
records = {}
|
|
268
|
+
if not os.path.exists(fpath):
|
|
269
|
+
core.error('Compiler.find_chain_import', core.lformat(LOC_FILE_NOT_EXISTS, [fpath]), head='\n', ln=config.language)
|
|
270
|
+
imps = []
|
|
271
|
+
content = self.auto_read(fpath)
|
|
272
|
+
project_path = project_path or os.path.dirname(fpath)
|
|
273
|
+
for no, line in enumerate(content.split('\n')):
|
|
274
|
+
m = self.PY_IMPORT_PAT.match(line)
|
|
275
|
+
if m:
|
|
276
|
+
target = m.group(1)
|
|
277
|
+
target_path = project_path
|
|
278
|
+
|
|
279
|
+
## 向前定位 | locate forward
|
|
280
|
+
if target.startswith('.'):
|
|
281
|
+
target_path = os.path.dirname(fpath) # 因为使用了相对路径,所以需要先定位到当前文件所在的目录 |
|
|
282
|
+
# because relative path is used, need to locate the directory where the current file is located first
|
|
283
|
+
count = 0
|
|
284
|
+
for c in target:
|
|
285
|
+
if c == '.':
|
|
286
|
+
count += 1
|
|
287
|
+
else:
|
|
288
|
+
break
|
|
289
|
+
if count > 1:
|
|
290
|
+
for _ in range(count - 1):
|
|
291
|
+
target_path = os.path.dirname(target_path)
|
|
292
|
+
|
|
293
|
+
## 向后定位 | locate backward
|
|
294
|
+
while (_idx := target.find('.')) != -1:
|
|
295
|
+
first_name = target[:_idx]
|
|
296
|
+
target_path = os.path.join(target_path, first_name)
|
|
297
|
+
target = target[_idx + 1:]
|
|
298
|
+
|
|
299
|
+
## 检查是否存在 | check if exists
|
|
300
|
+
this_path = os.path.join(target_path, target)
|
|
301
|
+
if os.path.isdir(this_path):
|
|
302
|
+
this_path = os.path.join(this_path, '__init__.py')
|
|
303
|
+
else:
|
|
304
|
+
this_path += '.py'
|
|
305
|
+
|
|
306
|
+
if not os.path.exists(this_path):
|
|
307
|
+
core.error('Compiler.find_chain_import', core.lformat(LOC_CHAIN_FILE_NOT_EXISTS, [fpath, no + 1, this_path]), head='\n', ln=config.language)
|
|
308
|
+
if this_path not in records:
|
|
309
|
+
records[this_path] = None
|
|
310
|
+
tmp = self.find_chain_import(this_path, search_dirs, project_path, records) + [this_path]
|
|
311
|
+
imps.extend(tmp)
|
|
312
|
+
|
|
313
|
+
return imps
|
|
314
|
+
|
|
315
|
+
@staticmethod
|
|
316
|
+
def relist_pyimports_to_jsimports(base_dir:str, pyimps:list[str]) -> list[str]:
|
|
317
|
+
"""
|
|
318
|
+
将python的imports路径列表转换为js的imports路径列表 | convert a list of python imports paths to a list of js imports paths
|
|
319
|
+
"""
|
|
320
|
+
jsimps = []
|
|
321
|
+
for pyimp in pyimps:
|
|
322
|
+
rel_path_nodes:list[str] = os.path.relpath(pyimp, base_dir).replace('\\', '/').split('/')
|
|
323
|
+
if rel_path_nodes[-1] == '__init__.py':
|
|
324
|
+
rel_path_nodes.pop()
|
|
325
|
+
else:
|
|
326
|
+
rel_path_nodes[-1] = rel_path_nodes[-1][:-3]
|
|
327
|
+
jsimps.append('./' + '.'.join(rel_path_nodes) + '.js')
|
|
328
|
+
return jsimps
|
|
329
|
+
|
|
236
330
|
|
|
237
331
|
class CompilerBase(Compiler_Utils):
|
|
238
332
|
|
|
@@ -259,7 +353,6 @@ class CompilerBase(Compiler_Utils):
|
|
|
259
353
|
self.target_dir = os.path.join(self.build_dir, '__target__')
|
|
260
354
|
self.build_name = os.path.basename(self.build_dir)
|
|
261
355
|
|
|
262
|
-
|
|
263
356
|
@property
|
|
264
357
|
def builtin_py(self) -> str:
|
|
265
358
|
"""
|
|
@@ -282,13 +375,13 @@ class CompilerBase(Compiler_Utils):
|
|
|
282
375
|
return os.path.join(self.target_dir, 'main.js')
|
|
283
376
|
|
|
284
377
|
|
|
285
|
-
|
|
286
378
|
class Compiler(CompilerBase):
|
|
287
379
|
def pre_compile(self):
|
|
288
380
|
"""
|
|
289
381
|
预编译 | Precompile
|
|
290
382
|
"""
|
|
291
|
-
src_paths = self.copy_to()
|
|
383
|
+
src_paths: list[str] = self.copy_to() # 复制src到build目录 | copy all files in src to build
|
|
384
|
+
# 获取src目录下的所有.py文件的路径 | get the paths of all .py files under src
|
|
292
385
|
|
|
293
386
|
core.lprint(WAIT, LOC_PREPROCESSING, end="", ln=config.language)
|
|
294
387
|
py_fpath, py_names, warn_flag = [], [], False
|
|
@@ -300,9 +393,7 @@ class Compiler(CompilerBase):
|
|
|
300
393
|
# 将PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "")插入到文件开头
|
|
301
394
|
content = self.auto_read(fpath)
|
|
302
395
|
content = self.PYFILE_PRAGMA_INSERTS.replace("\t", "").replace(" ", "") + content
|
|
303
|
-
|
|
304
|
-
if fpath == self.target_py:
|
|
305
|
-
content = self.auto_read(self.builtin_py) + content
|
|
396
|
+
|
|
306
397
|
with open(fpath, 'w', encoding='utf-8') as f: # 注意,这里修改的是build目录下的文件,不是源文件 | Note that the file under the build directory is modified here, not the source file
|
|
307
398
|
f.write(content)
|
|
308
399
|
|
|
@@ -316,42 +407,28 @@ class Compiler(CompilerBase):
|
|
|
316
407
|
|
|
317
408
|
_usubs_ = [] # update_subclass
|
|
318
409
|
_pre_import_, _pre_imp_detail_ = [], {} # > import
|
|
410
|
+
_imports = [] # chain import
|
|
319
411
|
_pre_sort_ = {} # > sort
|
|
320
412
|
_pre_define_ = {} # > define
|
|
321
413
|
_js_replace_, _insert_id_ = {}, 0 # > insert
|
|
322
414
|
|
|
323
|
-
|
|
324
|
-
#
|
|
325
|
-
# 获取在src目录内定义的所有继承了Updatable或CreepLogic的类 |
|
|
326
|
-
# get all classes that inherit from Updatable or CreepLogic defined in the src directory
|
|
327
|
-
for i, fpath in enumerate(py_fpath):
|
|
328
|
-
if fpath in src_paths:
|
|
329
|
-
content = self.auto_read(fpath)
|
|
330
|
-
for line in content.split('\n'):
|
|
331
|
-
m = re.search(r'class\s+([^\s(]+)\s*\((Updatable|CreepLogic)', line)
|
|
332
|
-
if m:
|
|
333
|
-
_usubs_.append(m.group(1))
|
|
334
|
-
|
|
335
|
-
# change REPALCE: '/// $UPDATABLE.UPDATES$ ///'
|
|
336
|
-
_rp_key = "/// $UPDATABLE.UPDATES$ ///"
|
|
337
|
-
_rp_txt = ""
|
|
338
|
-
for usub in _usubs_:
|
|
339
|
-
_rp_txt += "try{" + f"if ({usub} && !Updatable.UPDATES.includes({usub}))Updatable.UPDATES.append({usub});" + "}catch(e){ if (!(e instanceof ReferenceError)) throw e; }\n"
|
|
340
|
-
self.TOTAL_SIMPLE_REPLACE_WITH[_rp_key] = _rp_txt
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
# ----------------------------------- IMPORT ----------------------------------- #
|
|
344
|
-
# 获取所有.py文件中的所有import的内容,并记录下来fname:[imp1, imp2, ...]
|
|
345
|
-
# | get all import in .py files, and record them fname:[imp1, imp2, ...]
|
|
415
|
+
# -------------------------------- ONLY IMPORT * -------------------------------- #
|
|
416
|
+
# 只允许from xxx import *的情况 | only allow from xxx import *
|
|
346
417
|
for i, fpath in enumerate(py_fpath):
|
|
347
|
-
fname = py_names[i][:-3] + '.js'
|
|
348
418
|
content = self.auto_read(fpath)
|
|
349
|
-
for
|
|
350
|
-
|
|
419
|
+
for line in content.split('\n'):
|
|
420
|
+
# 1. 检查 import xxx的情况 | check import xxx
|
|
421
|
+
m = re.match(r'\s*import\s+([^\s]+)', line)
|
|
351
422
|
if m:
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
423
|
+
core.error('Compiler.pre_compile', core.lformat(LOC_IMPORT_STAR_ERROR, [m.group(1), m.group(1)]), head='\n', ln=config.language)
|
|
424
|
+
# 2. 检查 from xxx import yyys的情况(yyys不能是*) | check from xxx import yyys(yyys can't be *)
|
|
425
|
+
m = re.match(r'\n\s*from\s+([^\s]+)\s+import\s+([^\s]+)', line)
|
|
426
|
+
if m and (not m.group(2) or m.group(2)[0] != '*'):
|
|
427
|
+
core.error('Compiler.pre_compile', core.lformat(LOC_IMPORT_STAR2_ERROR, [m.group(1), m.group(2), m.group(1)]), head='\n', ln=config.language)
|
|
428
|
+
|
|
429
|
+
# -------------------------------- EXPAND IMPORT * -------------------------------- #
|
|
430
|
+
_imports = self.find_chain_import(self.target_py, [os.path.dirname(self.src_dir), self.src_dir])
|
|
431
|
+
_js_imports = self.relist_pyimports_to_jsimports(self.build_dir, _imports)
|
|
355
432
|
|
|
356
433
|
# ----------------------------------- REMOVE ----------------------------------- #
|
|
357
434
|
# 移除所有# > remove所在行的内容
|
|
@@ -370,7 +447,11 @@ class Compiler(CompilerBase):
|
|
|
370
447
|
# 获取所有.py文件中的所有# > sort的内容,并记录下来(不存在则默认为65535)
|
|
371
448
|
# | get all # > sort in .py files, and record them (default 65535 if not exists)
|
|
372
449
|
for i, fpath in enumerate(py_fpath):
|
|
373
|
-
fname = py_names[i]
|
|
450
|
+
fname = py_names[i]
|
|
451
|
+
if fname.endswith('__init__.py'):
|
|
452
|
+
fname = fname[:-12] + '.js'
|
|
453
|
+
else:
|
|
454
|
+
fname = fname[:-3] + '.js'
|
|
374
455
|
content = self.auto_read(fpath)
|
|
375
456
|
m = re.search(r'#\s*>\s*sort\s+(\d+)', content)
|
|
376
457
|
if m:
|
|
@@ -416,11 +497,6 @@ class Compiler(CompilerBase):
|
|
|
416
497
|
for fpath in py_fpath:
|
|
417
498
|
content = self.auto_read(fpath)
|
|
418
499
|
|
|
419
|
-
# std.py PYSCREEPS_ARENA_PYTHON_VERSION replace
|
|
420
|
-
if os.path.basename(fpath).lower() == 'std.py':
|
|
421
|
-
content = content.replace('PYSCREEPS_ARENA_PYTHON_VERSION_EN', f'\"{python_version_en}\"')
|
|
422
|
-
content = content.replace('PYSCREEPS_ARENA_PYTHON_VERSION_CN', f'\"{python_version_cn}\"')
|
|
423
|
-
|
|
424
500
|
for key in _def_keys:
|
|
425
501
|
content = re.sub(r'[^_A-Za-z0-9]' + key, self._kfc_wrapper(_pre_define_[key]), content)
|
|
426
502
|
|
|
@@ -462,18 +538,7 @@ class Compiler(CompilerBase):
|
|
|
462
538
|
f.write(new_content)
|
|
463
539
|
|
|
464
540
|
core.lprint(GREEN.format('[2/6]'), LOC_DONE, " ", LOC_PREPROCESSING_FINISH, sep="", head="\r", ln=config.language)
|
|
465
|
-
return
|
|
466
|
-
|
|
467
|
-
def clear_not_generate_pyfile(self):
|
|
468
|
-
"""
|
|
469
|
-
清空不需要编译的py文件 | clear not generate py file
|
|
470
|
-
:return:
|
|
471
|
-
"""
|
|
472
|
-
for root, dirs, files in os.walk(self.build_dir):
|
|
473
|
-
for file in files:
|
|
474
|
-
if file.endswith('.py') and file in self.GENERATE_IGNORE_PYFILES:
|
|
475
|
-
with open(os.path.join(root, file), 'w', encoding='utf-8') as f:
|
|
476
|
-
f.write('')
|
|
541
|
+
return _imports, _js_imports, _pre_sort_, _pre_define_, _js_replace_
|
|
477
542
|
|
|
478
543
|
def transcrypt_cmd(self):
|
|
479
544
|
# 执行cmd命令: transcrypt -b -m -n -s -e 6 target | execute cmd: transcrypt -b -m -n -s -e 6 target
|
|
@@ -497,7 +562,7 @@ class Compiler(CompilerBase):
|
|
|
497
562
|
return '{' if matched.group(0)[0] == '{' else ''
|
|
498
563
|
|
|
499
564
|
@staticmethod
|
|
500
|
-
def _keep_first_char(matched:re.Match) -> str:
|
|
565
|
+
def _keep_first_char(matched: re.Match) -> str:
|
|
501
566
|
"""
|
|
502
567
|
保留第一个字符 | keep the first char
|
|
503
568
|
:param matched: re.match object | re.match对象
|
|
@@ -506,7 +571,7 @@ class Compiler(CompilerBase):
|
|
|
506
571
|
return matched.group(0)[0]
|
|
507
572
|
|
|
508
573
|
@staticmethod
|
|
509
|
-
def _kfc_wrapper(replace:str) -> callable:
|
|
574
|
+
def _kfc_wrapper(replace: str) -> callable:
|
|
510
575
|
"""
|
|
511
576
|
获取一个保留第一个字符的函数 | get a function to keep the first char
|
|
512
577
|
:param replace: str
|
|
@@ -518,7 +583,7 @@ class Compiler(CompilerBase):
|
|
|
518
583
|
|
|
519
584
|
return _kfc
|
|
520
585
|
|
|
521
|
-
def analyze_rebuild_main_js(self, defs:dict[str, object]) -> tuple[str, list[str]]:
|
|
586
|
+
def analyze_rebuild_main_js(self, defs: dict[str, object], modules=None) -> tuple[str, list[str]]:
|
|
522
587
|
"""
|
|
523
588
|
分析main.js中导入的模块名称和先后顺序, 并重新生成main.js | analyze the module names and order imported in main.js, and rebuild main.js
|
|
524
589
|
* 主要移除非SYSTEM_MODULES_IGNORE中的模块导入语句 | mainly remove the module import statements that are not in SYSTEM_MODULES_IGNORE
|
|
@@ -532,16 +597,17 @@ class Compiler(CompilerBase):
|
|
|
532
597
|
# create undefined
|
|
533
598
|
imports = ""
|
|
534
599
|
|
|
535
|
-
if defs.get('USE_TUTORIAL_FLAG', '0') == '0' and defs.get('USE_ARENA_FLAG', '0') == '0':
|
|
536
|
-
|
|
537
|
-
if defs.get('USE_SCORE_COLLECTOR', '0') == '0':
|
|
538
|
-
|
|
539
|
-
imports += '\n'
|
|
600
|
+
# if defs.get('USE_TUTORIAL_FLAG', '0') == '0' and defs.get('USE_ARENA_FLAG', '0') == '0':
|
|
601
|
+
# imports += 'var Flag = undefined;\n'
|
|
602
|
+
# if defs.get('USE_SCORE_COLLECTOR', '0') == '0':
|
|
603
|
+
# imports += 'var ScoreController = undefined;\nvar RESOURCE_SCORE = undefined;\n'
|
|
604
|
+
# imports += '\n'
|
|
540
605
|
|
|
541
606
|
core.lprint(WAIT, LOC_ANALYZING_AND_REBUILDING_MAIN_JS, end="", ln=config.language)
|
|
542
607
|
|
|
543
608
|
content = self.auto_read(self.target_js)
|
|
544
|
-
modules
|
|
609
|
+
if modules is None: modules = []
|
|
610
|
+
new_modules, new_content = [],""
|
|
545
611
|
for line in content.split('\n'):
|
|
546
612
|
m = re.search(self.JS_IMPORT_PAT, line)
|
|
547
613
|
if not m:
|
|
@@ -549,22 +615,22 @@ class Compiler(CompilerBase):
|
|
|
549
615
|
continue
|
|
550
616
|
# remove ignore if in SYSTEM_MODULES_IGNORE
|
|
551
617
|
module = m.group(1)
|
|
552
|
-
for ignore in self.SYSTEM_MODULES_IGNORE.get(module, []):
|
|
553
|
-
line = re.sub(r'[\s{]' + ignore + ',?', self._keep_lbracket, line)
|
|
554
|
-
|
|
555
|
-
# do not add in modules if in system_modules_ignores
|
|
556
|
-
if module in self.SYSTEM_MODULES_IGNORE:
|
|
557
|
-
if module in self.SYSTEM_MODULES_TRANSNAME:
|
|
558
|
-
line = line.replace(module, self.SYSTEM_MODULES_TRANSNAME[module]) # 调整为js中的名称
|
|
559
|
-
imports += line + '\n'
|
|
560
|
-
continue
|
|
561
618
|
|
|
562
619
|
_ignore = False
|
|
563
620
|
if module in modules: _ignore = True
|
|
621
|
+
if module in new_modules: _ignore = True
|
|
622
|
+
if not _ignore: new_modules.append(module)
|
|
623
|
+
|
|
624
|
+
# conbine modules
|
|
625
|
+
modules = new_modules + modules
|
|
626
|
+
new_modules = []
|
|
627
|
+
for module in modules:
|
|
628
|
+
_ignore = False
|
|
564
629
|
if not _ignore and module.startswith(self.OTHER_IGNORE_WITH): _ignore = True
|
|
565
630
|
for keeps in self.BUILTIN_TRANS:
|
|
566
631
|
if module.endswith(keeps): _ignore = False
|
|
567
|
-
if not _ignore:
|
|
632
|
+
if not _ignore: new_modules.append(module)
|
|
633
|
+
modules = new_modules
|
|
568
634
|
|
|
569
635
|
# save raw main.js
|
|
570
636
|
with open(self.target_js[:-3] + ".raw.js", 'w', encoding='utf-8') as f:
|
|
@@ -587,7 +653,7 @@ class Compiler(CompilerBase):
|
|
|
587
653
|
"""
|
|
588
654
|
return re.sub(r'import[^\n]*\n', '', raw)
|
|
589
655
|
|
|
590
|
-
def generate_total_js(self, usr_modules, t_imps:
|
|
656
|
+
def generate_total_js(self, usr_modules, t_imps: list[str], f_sorts, f_replaces, g_replaces) -> str:
|
|
591
657
|
"""
|
|
592
658
|
生成总的main.js
|
|
593
659
|
按照如下顺序组合:
|
|
@@ -597,31 +663,23 @@ class Compiler(CompilerBase):
|
|
|
597
663
|
./game.utils.js # IGNORE
|
|
598
664
|
{usr_modules}
|
|
599
665
|
:param usr_modules: list[str] # js vm + 用户自定义模块
|
|
600
|
-
:param t_imps:
|
|
666
|
+
:param t_imps: list[str] # main前需要导入的模块
|
|
601
667
|
:param f_sorts: dict{module_name: sort_priority}
|
|
602
668
|
:param f_replaces: dict{module_name: dict{old: new}}
|
|
603
669
|
:param g_replaces: dict{old: new}
|
|
604
670
|
:return: str
|
|
605
671
|
"""
|
|
606
|
-
|
|
672
|
+
arena_name = const.ARENA_NAMES.get(config.arena, const.ARENA_NAMES['green']) # like green -> spawn_and_swamp
|
|
673
|
+
self.TOTAL_INSERT_AT_HEAD += self.ARENA_IMPORTS_GETTER[arena_name]() # add arena imports
|
|
674
|
+
total_js = f"const __VERSION__ = '{const.VERSION}';\nconst __PYTHON_VERSION__ = '{python_version_info}';" + self.TOTAL_INSERT_AT_HEAD + f"\nexport var LANGUAGE = '{config.language}';\n"
|
|
607
675
|
|
|
608
676
|
core.lprint(WAIT, LOC_GENERATING_TOTAL_MAIN_JS, end="", ln=config.language)
|
|
609
677
|
|
|
678
|
+
# TODO: IMPS donot work
|
|
679
|
+
|
|
610
680
|
# resort modules
|
|
611
681
|
f_sorts[self.JS_VM] = -1
|
|
612
682
|
|
|
613
|
-
err_flag = False
|
|
614
|
-
for module in usr_modules:
|
|
615
|
-
if module[2:] not in f_sorts:
|
|
616
|
-
print(Fore.RED + '\n[Error] ' + Fore.RESET + f'"{module[2:-3]}.py" is not a user module.')
|
|
617
|
-
imp_detail = t_imps.get(module, None)
|
|
618
|
-
if imp_detail:
|
|
619
|
-
print("\t\t-- May be imported by user in: %s" % imp_detail)
|
|
620
|
-
else:
|
|
621
|
-
print("\t\t-- Please move this file into the 'src' directory.")
|
|
622
|
-
err_flag = True
|
|
623
|
-
if err_flag:
|
|
624
|
-
sys.exit(1)
|
|
625
683
|
for i in range(len(usr_modules)):
|
|
626
684
|
for j in range(i + 1, len(usr_modules)):
|
|
627
685
|
if f_sorts[usr_modules[i][2:]] > f_sorts[usr_modules[j][2:]]:
|
|
@@ -639,7 +697,6 @@ class Compiler(CompilerBase):
|
|
|
639
697
|
total_js += "----------------------------------------\n\n"
|
|
640
698
|
total_js += content + '\n'
|
|
641
699
|
|
|
642
|
-
|
|
643
700
|
total_js += self.TOTAL_INSERT_BEFORE_MAIN
|
|
644
701
|
|
|
645
702
|
# write main.js
|
|
@@ -648,6 +705,12 @@ class Compiler(CompilerBase):
|
|
|
648
705
|
content = re.sub(old, new, content)
|
|
649
706
|
total_js += content
|
|
650
707
|
|
|
708
|
+
# TOTAL_APPEND_ATEND
|
|
709
|
+
total_js += self.TOTAL_APPEND_ATEND
|
|
710
|
+
|
|
711
|
+
# replace export-pat
|
|
712
|
+
total_js = re.sub(self.JS_EXPORT_PAT, "", total_js)
|
|
713
|
+
|
|
651
714
|
# global replace
|
|
652
715
|
for old, new in g_replaces.items():
|
|
653
716
|
total_js = re.sub(old, new, total_js)
|
|
@@ -672,7 +735,6 @@ class Compiler(CompilerBase):
|
|
|
672
735
|
return int(m.group(1))
|
|
673
736
|
return 65535
|
|
674
737
|
|
|
675
|
-
|
|
676
738
|
def find_add_pure_js_files(self, sorts, modules):
|
|
677
739
|
"""
|
|
678
740
|
找到所有的纯js文件,并添加到modules中
|
|
@@ -690,31 +752,24 @@ class Compiler(CompilerBase):
|
|
|
690
752
|
sorts[fname] = self.__parse_js_file_sort(fpath)
|
|
691
753
|
modules.append("./" + fname)
|
|
692
754
|
|
|
693
|
-
def compile(self,
|
|
755
|
+
def compile(self, paste=False):
|
|
694
756
|
"""
|
|
695
757
|
编译
|
|
696
|
-
:param export_to: 指定main.mjs的输出路径(/main.mjs)
|
|
697
758
|
:param paste: 是否复制到剪贴板
|
|
698
759
|
:return:
|
|
699
760
|
"""
|
|
700
|
-
imps,
|
|
701
|
-
self.clear_not_generate_pyfile() # 清空不需要编译的py文件(请确保在pre_compile之后)
|
|
761
|
+
imps, jimps, sorts, defs, reps = self.pre_compile()
|
|
702
762
|
self.transcrypt_cmd()
|
|
703
|
-
imports, modules = self.analyze_rebuild_main_js(defs)
|
|
763
|
+
imports, modules = self.analyze_rebuild_main_js(defs, jimps)
|
|
704
764
|
self.find_add_pure_js_files(sorts, modules)
|
|
705
|
-
total_js = imports + "\n" + self.generate_total_js(
|
|
765
|
+
total_js = imports + "\n" + self.generate_total_js(modules, imps, sorts, self.FILE_STRONG_REPLACE, reps)
|
|
706
766
|
|
|
707
767
|
core.lprint(WAIT, LOC_EXPORTING_TOTAL_MAIN_JS, end="", ln=config.language)
|
|
708
768
|
|
|
709
769
|
# ensure exported main.mjs path
|
|
710
770
|
build_main_mjs = os.path.join(self.build_dir, 'main.mjs')
|
|
711
771
|
|
|
712
|
-
if not
|
|
713
|
-
# 尝试读取defs
|
|
714
|
-
mjs_path = defs.get('MAIN_JS_PATH', build_main_mjs)
|
|
715
|
-
else:
|
|
716
|
-
mjs_path = export_to
|
|
717
|
-
|
|
772
|
+
mjs_path = config.target if config.target is not None else config.TARGET_GETTER()
|
|
718
773
|
if not mjs_path.endswith('js'):
|
|
719
774
|
mjs_path = os.path.join(mjs_path, 'main.mjs')
|
|
720
775
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# pyscreeps_arena - config.py
|
|
4
|
+
# Author: 我阅读理解一直可以的
|
|
5
|
+
# Template: V0.1
|
|
6
|
+
# Versions:
|
|
7
|
+
# .2025 01 01 - v0.1:
|
|
8
|
+
# Created.
|
|
9
|
+
#
|
|
10
|
+
import os
|
|
11
|
+
from pyscreeps_arena.core import const
|
|
12
|
+
arena = "green"
|
|
13
|
+
season = "beta"
|
|
14
|
+
language = 'cn'
|
|
15
|
+
# 默认路径: 用户 + ScreepsArena + beta-spawn_and_swamp + main.mjs
|
|
16
|
+
target = None
|
|
17
|
+
TARGET_GETTER = lambda: os.path.join(os.path.expanduser('~'), 'ScreepsArena', f'{season}-{const.ARENA_NAMES.get(arena, "spawn_and_swamp")}', 'main.mjs')
|
|
18
|
+
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
# -*- coding: utf-8 -*-
|
|
2
|
+
#
|
|
3
|
+
# pyscreeps_arena - const.py
|
|
4
|
+
# Author: 我阅读理解一直可以的
|
|
5
|
+
# Template: V0.1
|
|
6
|
+
# Versions:
|
|
7
|
+
# .2025 01 01 - v0.1:
|
|
8
|
+
# Created.
|
|
9
|
+
#
|
|
10
|
+
import re
|
|
11
|
+
|
|
12
|
+
VERSION = "0.3a2"
|
|
13
|
+
AUTHOR = "我阅读理解一直可以的"
|
|
14
|
+
STEAM_ID = "1029562896"
|
|
15
|
+
GITHUB_NAME = "EagleBaby"
|
|
16
|
+
|
|
17
|
+
ARENA_GREEN = "spawn_and_swamp"
|
|
18
|
+
ARENA_BLUE = "capture_the_flag"
|
|
19
|
+
ARENA_RED = "collect_and_control"
|
|
20
|
+
ARENA_GRAY = "tutorial"
|
|
21
|
+
|
|
22
|
+
ARENA_NAMES = {
|
|
23
|
+
"green": ARENA_GREEN,
|
|
24
|
+
"blue" : ARENA_BLUE,
|
|
25
|
+
"red" : ARENA_RED,
|
|
26
|
+
"gray" : ARENA_GRAY,
|
|
27
|
+
}
|
|
@@ -25,6 +25,18 @@ LOC_PREPROCESSING_FINISH = {
|
|
|
25
25
|
'en': "Preprocessing finished.",
|
|
26
26
|
'cn': "预处理完成。",
|
|
27
27
|
}
|
|
28
|
+
LOC_IMPORT_STAR_ERROR = {
|
|
29
|
+
'en': "Only 'from xxx import *' is allowed, but found 'import {}'." + Fore.LIGHTBLUE_EX + "Maybe you can use 'from {} import *' instead." + Fore.RESET,
|
|
30
|
+
'cn': "只允许'from xxx import *',但是发现了'import {}'。" + Fore.LIGHTBLUE_EX + "也许你可以使用'from {} import *'代替之。" + Fore.RESET,
|
|
31
|
+
}
|
|
32
|
+
LOC_IMPORT_STAR2_ERROR = {
|
|
33
|
+
'en': "Only 'from xxx import *' is allowed, but found 'from {} import {}'." + Fore.LIGHTBLUE_EX + "Maybe you can use 'from {} import *' instead." + Fore.RESET,
|
|
34
|
+
'cn': "只允许'from xxx import *',但是发现了'from {} import {}'。 " + Fore.LIGHTBLUE_EX + "也许你可以使用'from {} import *'代替之。" + Fore.RESET,
|
|
35
|
+
}
|
|
36
|
+
LOC_CHAIN_FILE_NOT_EXISTS = {
|
|
37
|
+
'en': "During search chain-import at {}, lineno {}:\n\tfile not exists: {}",
|
|
38
|
+
'cn': "在搜索链式导入时,位于 {},行号 {}:\n\t文件不存在: {}",
|
|
39
|
+
}
|
|
28
40
|
LOC_TRANSCRYPTING = {
|
|
29
41
|
'en': "Transcrypting ... # cmd:{}",
|
|
30
42
|
'cn': "转译中 ... # cmd命令:{}",
|
|
Binary file
|
|
@@ -7,7 +7,7 @@ with open(r"T:\New_PC\Import_Project\uploads\pyscreeps-arena_upload\pyscreeps-ar
|
|
|
7
7
|
long_description = f.read()
|
|
8
8
|
setup(
|
|
9
9
|
name='pyscreeps-arena',
|
|
10
|
-
version='0.
|
|
10
|
+
version='0.3a2',
|
|
11
11
|
description='Python api|interface to play game: Screeps: Arena.',
|
|
12
12
|
long_description=long_description,
|
|
13
13
|
long_description_content_type='text/markdown',
|
|
@@ -34,6 +34,7 @@ setup(
|
|
|
34
34
|
'pyperclip',
|
|
35
35
|
'colorama',
|
|
36
36
|
'py7zr',
|
|
37
|
+
'chardet',
|
|
37
38
|
'Transcrypt==3.9.3',
|
|
38
39
|
'mkdocs',
|
|
39
40
|
'mkdocstrings[python]',
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
# -*- coding: utf-8 -*-
|
|
2
|
-
#
|
|
3
|
-
# pyscreeps_arena - const.py
|
|
4
|
-
# Author: 我阅读理解一直可以的
|
|
5
|
-
# Template: V0.1
|
|
6
|
-
# Versions:
|
|
7
|
-
# .2025 01 01 - v0.1:
|
|
8
|
-
# Created.
|
|
9
|
-
#
|
|
10
|
-
import re
|
|
11
|
-
|
|
12
|
-
VERSION = "0.1"
|
|
13
|
-
AUTHOR = "我阅读理解一直可以的"
|
|
14
|
-
STEAM_ID = "1029562896"
|
|
15
|
-
GITHUB_NAME = "EagleBaby"
|
|
16
|
-
|
|
Binary file
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{pyscreeps-arena-0.3a1 → pyscreeps-arena-0.3a2}/pyscreeps_arena.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|