mirror of
https://github.com/Shu-Ying/main_plugin_farm.git
synced 2026-10-28 21:19:58 +08:00
fixed # 修复头像框资源位置错误的BUG
This commit is contained in:
@@ -44,7 +44,8 @@ def build(root, output):
|
||||
files = {}
|
||||
integration = root / "integrations/zhenxun"
|
||||
for name in (
|
||||
"__init__.py", "runtime.py", "commands.py", "requirements.txt",
|
||||
"__init__.py", "runtime.py", "commands.py", "data_paths.py",
|
||||
"requirements.txt",
|
||||
):
|
||||
files[name] = (integration / name).read_bytes()
|
||||
files["_vendor/__init__.py"] = b'"""Private shared farm modules."""\n'
|
||||
|
||||
@@ -88,6 +88,7 @@ def export(root):
|
||||
webgl_source = root / "src/farm_render/source_assets"
|
||||
manifest = json.loads((webgl_source / "manifest.json").read_bytes())
|
||||
metadata["pest"] = manifest["pest"]
|
||||
metadata["panel"] = manifest["panel"]
|
||||
entries = {path.relative_to(source).as_posix(): path for path in paths}
|
||||
entries.update({name: webgl_source / name for name in manifest["images"]})
|
||||
with ZipFile(output, "w", compression=ZIP_STORED) as bundle:
|
||||
|
||||
@@ -8,10 +8,78 @@ import re
|
||||
import sys
|
||||
|
||||
|
||||
def panel_layout(environment):
|
||||
prefab = next(
|
||||
entry.asset for obj in environment.objects
|
||||
if obj.type.name == 'AssetBundle'
|
||||
for path, entry in obj.read().m_Container
|
||||
if path.endswith('/webglpersioninfo.prefab')
|
||||
)
|
||||
nodes = {}
|
||||
|
||||
def visit(pointer, parent=None):
|
||||
game_object = pointer.read()
|
||||
components = [c.component for c in game_object.m_Component]
|
||||
transform = next(c.read() for c in components
|
||||
if c.type.name == 'RectTransform')
|
||||
rect = [0, 0, 100, 100]
|
||||
if parent is not None:
|
||||
lo, hi = transform.m_AnchorMin, transform.m_AnchorMax
|
||||
pivot, pos = transform.m_Pivot, transform.m_AnchoredPosition
|
||||
w = parent[2] * (hi.x - lo.x) + transform.m_SizeDelta.x
|
||||
h = parent[3] * (hi.y - lo.y) + transform.m_SizeDelta.y
|
||||
rect = [
|
||||
parent[0] + parent[2] * (lo.x + (hi.x-lo.x)*pivot.x)
|
||||
+ pos.x - w*pivot.x,
|
||||
parent[1] + parent[3] * (1-lo.y-(hi.y-lo.y)*pivot.y)
|
||||
- pos.y - h*(1-pivot.y), w, h,
|
||||
]
|
||||
for component in components:
|
||||
if component.type.name != 'MonoBehaviour':
|
||||
continue
|
||||
data = component.read_typetree()
|
||||
if 'm_Sprite' in data or 'm_Text' in data:
|
||||
nodes[game_object.m_Name] = {
|
||||
'rect': rect, 'data': data,
|
||||
}
|
||||
for child in transform.m_Children:
|
||||
visit(child.read().m_GameObject, rect)
|
||||
|
||||
visit(prefab)
|
||||
sprites = []
|
||||
sprite_ids = {}
|
||||
for name in ('PersionInfoBG', 'HeadFrame', 'ExpBar', 'ExpProgress',
|
||||
'GoldIcon', 'CouponIcon'):
|
||||
node = nodes[name]
|
||||
sprite_id = node['data']['m_Sprite']['m_PathID']
|
||||
path = f'webgl/panel/{name}.png'
|
||||
sprite_ids[sprite_id] = path
|
||||
sprites.append({'name': name, 'sprite': path, 'rect': node['rect']})
|
||||
fields = []
|
||||
for node_name, field in (('NameT', 'name'), ('text', 'experience'),
|
||||
('LevelT', 'level'), ('GoldT', 'point'),
|
||||
('CouponT', 'vip_point')):
|
||||
node = nodes[node_name]
|
||||
color = node['data']['m_Color']
|
||||
fields.append({
|
||||
'field': field, 'rect': node['rect'],
|
||||
'alignment': node['data']['m_FontData']['m_Alignment'],
|
||||
'color': [round(color[c]*255) for c in ('r', 'g', 'b')],
|
||||
})
|
||||
return {
|
||||
'reference_canvas': [1920, 1080],
|
||||
'source_prefab': 'mainscene#WebGLPersionInfo',
|
||||
'anchor': 'top_left', 'sprites': sprites,
|
||||
'avatar': nodes['HeadIcon']['rect'], 'fields': fields,
|
||||
}, sprite_ids
|
||||
|
||||
|
||||
def extract(bundle, destination):
|
||||
import UnityPy
|
||||
from PIL import Image
|
||||
|
||||
environment = UnityPy.load(str(bundle))
|
||||
panel, panel_ids = panel_layout(environment)
|
||||
destination.mkdir(parents=True, exist_ok=True)
|
||||
images = {}
|
||||
for obj in environment.objects:
|
||||
@@ -19,7 +87,9 @@ def extract(bundle, destination):
|
||||
continue
|
||||
sprite = obj.read()
|
||||
name = sprite.m_Name
|
||||
if re.fullmatch(r"pest\d+", name):
|
||||
if obj.path_id in panel_ids:
|
||||
path = panel_ids[obj.path_id]
|
||||
elif re.fullmatch(r"pest\d+", name):
|
||||
path = f"pest/{name}.png"
|
||||
elif name in ("Icon_PlantSeed", "Icon_PlantWither"):
|
||||
path = "webgl/" + (
|
||||
@@ -28,9 +98,23 @@ def extract(bundle, destination):
|
||||
else:
|
||||
continue
|
||||
image = sprite.image
|
||||
full_size = (round(sprite.m_Rect.width), round(sprite.m_Rect.height))
|
||||
if obj.path_id in panel_ids and image.size != full_size:
|
||||
offset = sprite.m_RD.textureRectOffset
|
||||
position = (round(offset.x),
|
||||
full_size[1] - round(offset.y) - image.height)
|
||||
if (min(position) < 0 or position[0]+image.width > full_size[0]
|
||||
or position[1]+image.height > full_size[1]):
|
||||
raise ValueError('Panel sprite exceeds its original canvas')
|
||||
full = Image.new('RGBA', full_size)
|
||||
full.paste(image, position)
|
||||
image = full
|
||||
if image.size != (round(sprite.m_Rect.width),
|
||||
round(sprite.m_Rect.height)):
|
||||
raise ValueError("Sprite extraction lost its full canvas")
|
||||
raise ValueError(
|
||||
f'Sprite extraction lost its full canvas: {name} '
|
||||
f'{image.size} vs {sprite.m_Rect}'
|
||||
)
|
||||
target = destination / path
|
||||
target.parent.mkdir(parents=True, exist_ok=True)
|
||||
image.save(target)
|
||||
@@ -38,8 +122,8 @@ def extract(bundle, destination):
|
||||
"size": list(image.size),
|
||||
"sha256": hashlib.sha256(target.read_bytes()).hexdigest(),
|
||||
}
|
||||
if len(images) != 40:
|
||||
raise ValueError("Expected 38 pest frames and two common crop sprites")
|
||||
if len(images) != 46:
|
||||
raise ValueError("Expected 38 pests, two crop and six panel sprites")
|
||||
manifest = {
|
||||
"schema": 1,
|
||||
"source_url": (
|
||||
@@ -49,6 +133,7 @@ def extract(bundle, destination):
|
||||
"source_sha256": hashlib.sha256(bundle.read_bytes()).hexdigest(),
|
||||
"extractor": "UnityPy 1.25.4 Sprite.image; full sprite rect checked",
|
||||
"images": images,
|
||||
"panel": panel,
|
||||
"pest": {
|
||||
"frames": [f"pest/pest{i}.png" for i in range(1, 76, 2)],
|
||||
"sample_rate": 24,
|
||||
|
||||
Reference in New Issue
Block a user