mirror of
https://wiilab.wiimart.org/wiimart/SWF-Checker
synced 2025-09-05 21:11:03 +02:00
Compare commits
No commits in common. "main" and "v2.3" have entirely different histories.
@ -9,7 +9,4 @@ It checks for:
|
|||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
On your terminal, run `python3 SWFChecker.py` to start.
|
If a SWF was made with ActionScript 2 (or 1) and Flash version 8 (or older), it will say it can work with the Wii. If the game's stage resolution (in pixels) is larger than 700x500 pixels, it will warn about possible overlapping/clipping on the Wii.
|
||||||
Make sure that your SWF file is in the same folder as the checker.
|
|
||||||
|
|
||||||
If a SWF was made with ActionScript 2 (or 1) and Flash version 8 (or older), it will say it can work with the Wii. If the game's stage resolution (in pixels) is larger than 700x500 pixels, it will warn about possible overlapping/clipping on the Wii.
|
|
||||||
|
137
SWFChecker.py
137
SWFChecker.py
@ -1,4 +1,3 @@
|
|||||||
from __future__ import print_function
|
|
||||||
import os
|
import os
|
||||||
import zlib
|
import zlib
|
||||||
from sys import version, exit
|
from sys import version, exit
|
||||||
@ -6,13 +5,12 @@ import platform
|
|||||||
|
|
||||||
platf = platform.system()
|
platf = platform.system()
|
||||||
if platf == "Windows":
|
if platf == "Windows":
|
||||||
os.system("title SWF Checker v3.0")
|
os.system("title SWF Checker v2.3")
|
||||||
os.system("cls")
|
os.system("clear")
|
||||||
else:
|
else:
|
||||||
os.system("clear")
|
os.system("clear")
|
||||||
|
|
||||||
print(f"SWF Version Checker v3.0\nPython {version}")
|
print(f"SWF Version Checker v2.3\nPython {version}")
|
||||||
print(f"made by idkwh")
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
swf = input("SWF Filename: ").strip()
|
swf = input("SWF Filename: ").strip()
|
||||||
@ -20,83 +18,61 @@ except KeyboardInterrupt:
|
|||||||
print("\nExiting...")
|
print("\nExiting...")
|
||||||
exit()
|
exit()
|
||||||
|
|
||||||
def parsetags(data):
|
def CheckSWF(swf):
|
||||||
pos = 8 # start after signature & header
|
try:
|
||||||
rect_bits = (data[pos] >> 3) & 0x1F
|
if not os.path.exists(swf):
|
||||||
pos += int((5 + rect_bits * 4 + 7) / 8) # skip RECT
|
print("Error: File not found. Please check the filename and try again.")
|
||||||
pos += 4 # skip frame rate/count
|
return None, None, None
|
||||||
|
|
||||||
tags = []
|
with open(swf, "rb") as f:
|
||||||
|
obj = f.read()
|
||||||
|
|
||||||
while pos + 2 <= len(data):
|
# decompress (CWS, zlib)
|
||||||
tag_header = int.from_bytes(data[pos:pos + 2], 'little')
|
if obj[:3] == b"CWS":
|
||||||
pos += 2
|
print("SWF is compressed (zlib, CWS head), uncompressing...")
|
||||||
|
obj = b"FWS" + obj[3:8] + zlib.decompress(obj[8:])
|
||||||
|
|
||||||
tag_code = tag_header >> 6
|
flashver = obj[3]
|
||||||
tag_length = tag_header & 0x3F
|
|
||||||
|
|
||||||
if tag_length == 0x3F:
|
result_isas3 = False
|
||||||
if pos + 4 > len(data):
|
fileAttrIdx = obj.find(b'\x45')
|
||||||
break
|
# looks for FileAttributes, (actionScript3: false/true)
|
||||||
tag_length = int.from_bytes(data[pos:pos + 4], 'little')
|
if fileAttrIdx != -1:
|
||||||
pos += 4
|
flags_byte = obj[fileAttrIdx + 2]
|
||||||
|
if flags_byte in [0x0, 0x1]:
|
||||||
|
result_isas3 = False
|
||||||
|
else:
|
||||||
|
result_isas3 = (flags_byte & 0x08) != 0
|
||||||
|
|
||||||
if pos + tag_length > len(data):
|
# fallback method (looks for doabc (as3 only))
|
||||||
break
|
|
||||||
|
|
||||||
tag_data = data[pos:pos + tag_length]
|
|
||||||
tags.append((tag_code, tag_data))
|
|
||||||
pos += tag_length
|
|
||||||
|
|
||||||
return tags
|
|
||||||
|
|
||||||
|
|
||||||
def CheckSWF(swf_path):
|
|
||||||
if not os.path.exists(swf_path):
|
|
||||||
print("File not found. Please check the filename and try again.")
|
|
||||||
if platf == "Windows":
|
|
||||||
os.system("pause")
|
|
||||||
exit()
|
|
||||||
else:
|
else:
|
||||||
os.system("/bin/bash -c 'read -s -n 1 -p \"Press any key to exit.\"'")
|
doabc_IDX = obj.find(b'\x52')
|
||||||
exit()
|
if doabc_IDX != -1:
|
||||||
|
doabc_len = int.from_bytes(obj[doabc_IDX+1:doabc_IDX+4], "little")
|
||||||
|
result_isas3 = (doabc_len > 10)
|
||||||
|
else:
|
||||||
|
result_isas3 = False
|
||||||
|
|
||||||
|
# looks for doaction (as2/1 only)
|
||||||
|
doact_idx = obj.find(b'\x0C')
|
||||||
|
if doact_idx != -1 and not result_isas3:
|
||||||
|
result_isas3 = False
|
||||||
|
|
||||||
|
if flashver >= 9:
|
||||||
|
isas3 = result_isas3 # AS3 support is based on external result
|
||||||
|
else:
|
||||||
|
isas3 = False # AS3 does not exist before Flash Player 9
|
||||||
|
|
||||||
|
asver = "ActionScript 3.0 (incompatible)" if isas3 else "ActionScript 1.0/2.0 (compatible)"
|
||||||
|
return flashver, asver, obj
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("\nExiting...")
|
||||||
|
exit()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"exception occurred!\n{e}")
|
||||||
return None, None, None
|
return None, None, None
|
||||||
|
|
||||||
with open(swf_path, "rb") as f:
|
|
||||||
data = f.read()
|
|
||||||
|
|
||||||
if data[:3] == b"CWS":
|
|
||||||
print("SWF is compressed. Decompressing...")
|
|
||||||
data = b"FWS" + data[3:8] + zlib.decompress(data[8:])
|
|
||||||
|
|
||||||
flashver = data[3]
|
|
||||||
tags = parsetags(data)
|
|
||||||
|
|
||||||
has_as3 = False
|
|
||||||
has_doabc = False
|
|
||||||
has_doaction = False
|
|
||||||
|
|
||||||
for tag_code, tag_data in tags:
|
|
||||||
if tag_code == 69: # fileattributes
|
|
||||||
if len(tag_data) >= 1:
|
|
||||||
flags = tag_data[0]
|
|
||||||
if flags & 0x08:
|
|
||||||
has_as3 = True
|
|
||||||
elif tag_code == 82: # doabc (AS3.0 Only)
|
|
||||||
has_doabc = True
|
|
||||||
elif tag_code == 12: # doaction (AS1/2.0)
|
|
||||||
has_doaction = True
|
|
||||||
|
|
||||||
if has_as3 or has_doabc:
|
|
||||||
is_as3 = True
|
|
||||||
elif has_doaction:
|
|
||||||
is_as3 = False
|
|
||||||
else:
|
|
||||||
is_as3 = False
|
|
||||||
|
|
||||||
asver = "ActionScript 3.0 (incompatible)" if is_as3 else "ActionScript 1.0/2.0 (compatible)"
|
|
||||||
return flashver, asver, data
|
|
||||||
|
|
||||||
def GetStageWH(obj):
|
def GetStageWH(obj):
|
||||||
rectS = 8
|
rectS = 8
|
||||||
nbits = (obj[rectS] >> 3) & 0x1F
|
nbits = (obj[rectS] >> 3) & 0x1F
|
||||||
@ -122,18 +98,15 @@ flashver, asver, SWFDAT = CheckSWF(swf)
|
|||||||
if flashver is not None:
|
if flashver is not None:
|
||||||
w, h = GetStageWH(SWFDAT)
|
w, h = GetStageWH(SWFDAT)
|
||||||
print(f"SWF Dimensions: {w}x{h} pixels")
|
print(f"SWF Dimensions: {w}x{h} pixels")
|
||||||
if flashver <= 8: # compatible
|
if flashver > 8:
|
||||||
print(f"Flash version: {flashver}, this SWF is compatible with the Wii.")
|
print(f"Flash version: {flashver}, this version MAY NOT be compatible with the Wii.")
|
||||||
elif flashver == 9: # kirby tv notice
|
else:
|
||||||
print(f"Flash version: {flashver}, this SWF may be compatible if injected inside the Kirby TV Channel")
|
print(f"Flash version: {flashver}, this version is compatible with the Wii.")
|
||||||
else: # too new
|
|
||||||
print(f"Flash version: {flashver}, this SWF is not compatible with the Wii.")
|
|
||||||
|
|
||||||
print(f"ActionScript version: {asver}")
|
print(f"ActionScript version: {asver}")
|
||||||
if w > 700 and h > 500:
|
if w > 700 and h > 500:
|
||||||
print("WARNING: The given SWF might overlap/clip on the Wii.")
|
print("WARNING: The given SWF might overlap/clip on the Wii.")
|
||||||
else:
|
else:
|
||||||
print("The SWF shouldn't overlap and/or clip on the Wii.")
|
print("The SWF should NOT overlap and/or clip on the Wii.")
|
||||||
|
|
||||||
if platf == "Windows":
|
if platf == "Windows":
|
||||||
os.system("pause")
|
os.system("pause")
|
||||||
|
139
requirements.txt
139
requirements.txt
@ -1,15 +1,136 @@
|
|||||||
|
aiohappyeyeballs==2.4.4
|
||||||
|
aiohttp==3.11.10
|
||||||
|
aiosignal==1.3.1
|
||||||
|
altgraph==0.17.4
|
||||||
|
art==6.4
|
||||||
|
attrs==24.2.0
|
||||||
|
babel==2.16.0
|
||||||
|
beautifulsoup4==4.12.3
|
||||||
blinker==1.9.0
|
blinker==1.9.0
|
||||||
certifi==2025.8.3
|
bs4==0.0.2
|
||||||
charset-normalizer==3.4.3
|
certifi==2024.8.30
|
||||||
click==8.2.1
|
cffi==1.17.1
|
||||||
|
charset-normalizer==3.4.0
|
||||||
|
click==8.1.7
|
||||||
colorama==0.4.6
|
colorama==0.4.6
|
||||||
dotenv==0.9.9
|
config==0.5.1
|
||||||
Flask==3.1.1
|
contourpy==1.3.1
|
||||||
|
croniter==5.0.1
|
||||||
|
cryptography==44.0.2
|
||||||
|
cx_Freeze==7.2.7
|
||||||
|
cx_Logging==3.2.1
|
||||||
|
cycler==0.12.1
|
||||||
|
decorator==5.1.1
|
||||||
|
discord==2.3.2
|
||||||
|
discord-py-interactions==5.13.2
|
||||||
|
discord-typings==0.9.0
|
||||||
|
discord.ext.context==0.1.8
|
||||||
|
discord.py==2.4.0
|
||||||
|
distlib==0.3.9
|
||||||
|
dnslib==0.9.25
|
||||||
|
emoji==2.14.0
|
||||||
|
ffpyplayer==4.5.2
|
||||||
|
filelock==3.16.1
|
||||||
|
Flask==3.1.0
|
||||||
|
flask-babel==4.0.0
|
||||||
|
Flask-Enterprise==1.0
|
||||||
|
flask-ipban==1.1.5
|
||||||
|
Flask-SSLify==0.1.5
|
||||||
|
Flask-WTF==1.2.2
|
||||||
|
fontstyle==1.0.1.2
|
||||||
|
fonttools==4.57.0
|
||||||
|
frozenlist==1.5.0
|
||||||
|
gevent==24.11.1
|
||||||
|
greenlet==3.1.1
|
||||||
|
h11==0.14.0
|
||||||
|
HyFetch==1.99.0
|
||||||
idna==3.10
|
idna==3.10
|
||||||
|
imageio==2.36.1
|
||||||
|
imageio-ffmpeg==0.5.1
|
||||||
|
isodate==0.7.2
|
||||||
itsdangerous==2.2.0
|
itsdangerous==2.2.0
|
||||||
Jinja2==3.1.6
|
Jinja2==3.1.4
|
||||||
|
keyboard==0.13.5
|
||||||
|
kiwisolver==1.4.8
|
||||||
|
lief==0.15.1
|
||||||
|
lxml==5.3.0
|
||||||
|
markdown-it-py==3.0.0
|
||||||
MarkupSafe==3.0.2
|
MarkupSafe==3.0.2
|
||||||
python-dotenv==1.1.1
|
matplotlib==3.10.1
|
||||||
requests==2.32.4
|
mdurl==0.1.2
|
||||||
urllib3==2.5.0
|
moviepy==2.1.1
|
||||||
|
multidict==6.1.0
|
||||||
|
mysql-connector-python==9.1.0
|
||||||
|
mysql-to-sqlite3==2.3.0
|
||||||
|
numpy==2.2.0
|
||||||
|
opencv-python==4.10.0.84
|
||||||
|
outcome==1.3.0.post0
|
||||||
|
packaging==24.2
|
||||||
|
parse-pip-search==0.0.1
|
||||||
|
pefile==2023.2.7
|
||||||
|
pillow==11.0.0
|
||||||
|
platformdirs==4.3.6
|
||||||
|
proglog==0.1.10
|
||||||
|
propcache==0.2.1
|
||||||
|
psutil==6.1.1
|
||||||
|
pyaes==1.6.1
|
||||||
|
pyasn1==0.6.1
|
||||||
|
pycparser==2.22
|
||||||
|
pycurl==7.45.6
|
||||||
|
pygame==2.6.1
|
||||||
|
Pygments==2.18.0
|
||||||
|
pyinstaller==6.11.1
|
||||||
|
pyinstaller-hooks-contrib==2024.11
|
||||||
|
pyparsing==3.2.3
|
||||||
|
PyQt5==5.15.11
|
||||||
|
PyQt5-Qt5==5.15.2
|
||||||
|
PyQt5_sip==12.16.1
|
||||||
|
PyQtWebEngine==5.15.7
|
||||||
|
PyQtWebEngine-Qt5==5.15.2
|
||||||
|
PySimpleSOAP==1.16.2
|
||||||
|
PySocks==1.7.1
|
||||||
|
python-dateutil==2.9.0.post0
|
||||||
|
python-dotenv==1.0.1
|
||||||
|
python-slugify==8.0.4
|
||||||
|
pytimeparse2==1.7.1
|
||||||
|
pytz==2024.2
|
||||||
|
pywin32==308
|
||||||
|
pywin32-ctypes==0.2.3
|
||||||
|
PyYAML==6.0.2
|
||||||
|
requests==2.32.3
|
||||||
|
requests-file==2.1.0
|
||||||
|
requests-pkcs12==1.25
|
||||||
|
requests-toolbelt==1.0.0
|
||||||
|
rich==13.9.4
|
||||||
|
rsa==4.9
|
||||||
|
selenium==4.30.0
|
||||||
|
simplejson==3.19.3
|
||||||
|
sip==6.9.1
|
||||||
|
six==1.17.0
|
||||||
|
sniffio==1.3.1
|
||||||
|
soaplib==1.0.0
|
||||||
|
sortedcontainers==2.4.0
|
||||||
|
soupsieve==2.6
|
||||||
|
spyne==2.14.0
|
||||||
|
suds==1.2.0
|
||||||
|
tabulate==0.9.0
|
||||||
|
text-unidecode==1.3
|
||||||
|
tomli==2.2.1
|
||||||
|
tqdm==4.67.1
|
||||||
|
trio==0.29.0
|
||||||
|
trio-websocket==0.12.2
|
||||||
|
types-python-dateutil==2.9.0.20241206
|
||||||
|
typing_extensions==4.12.2
|
||||||
|
urllib3==2.2.3
|
||||||
|
virtualenv==20.28.0
|
||||||
|
vscode-ext==1.5.4
|
||||||
|
waitress==3.0.2
|
||||||
|
websocket-client==1.8.0
|
||||||
Werkzeug==3.1.3
|
Werkzeug==3.1.3
|
||||||
|
wfastcgi==3.0.0
|
||||||
|
wsproto==1.2.0
|
||||||
|
WTForms==3.2.1
|
||||||
|
yarl==1.18.3
|
||||||
|
zeep==4.3.1
|
||||||
|
zope.event==5.0
|
||||||
|
zope.interface==7.2
|
||||||
|
Loading…
x
Reference in New Issue
Block a user