From 86ea421f38aed6a78049cdc62c2a5fd6d463b495 Mon Sep 17 00:00:00 2001 From: idkwh Date: Thu, 28 Aug 2025 13:06:07 +0200 Subject: [PATCH] update --- SWFChecker.py | 137 +++++++++++++++++++++++++++------------------- requirements.txt | 139 +++-------------------------------------------- 2 files changed, 91 insertions(+), 185 deletions(-) diff --git a/SWFChecker.py b/SWFChecker.py index 14dd84f..4933019 100644 --- a/SWFChecker.py +++ b/SWFChecker.py @@ -1,3 +1,4 @@ +from __future__ import print_function import os import zlib from sys import version, exit @@ -5,12 +6,13 @@ import platform platf = platform.system() if platf == "Windows": - os.system("title SWF Checker v2.3") - os.system("clear") + os.system("title SWF Checker v3.0") + os.system("cls") else: os.system("clear") -print(f"SWF Version Checker v2.3\nPython {version}") +print(f"SWF Version Checker v3.0\nPython {version}") +print(f"made by idkwh") try: swf = input("SWF Filename: ").strip() @@ -18,61 +20,83 @@ except KeyboardInterrupt: print("\nExiting...") exit() -def CheckSWF(swf): - try: - if not os.path.exists(swf): - print("Error: File not found. Please check the filename and try again.") - return None, None, None +def parsetags(data): + pos = 8 # start after signature & header + rect_bits = (data[pos] >> 3) & 0x1F + pos += int((5 + rect_bits * 4 + 7) / 8) # skip RECT + pos += 4 # skip frame rate/count - with open(swf, "rb") as f: - obj = f.read() + tags = [] - # decompress (CWS, zlib) - if obj[:3] == b"CWS": - print("SWF is compressed (zlib, CWS head), uncompressing...") - obj = b"FWS" + obj[3:8] + zlib.decompress(obj[8:]) + while pos + 2 <= len(data): + tag_header = int.from_bytes(data[pos:pos + 2], 'little') + pos += 2 - flashver = obj[3] + tag_code = tag_header >> 6 + tag_length = tag_header & 0x3F - result_isas3 = False - fileAttrIdx = obj.find(b'\x45') - # looks for FileAttributes, (actionScript3: false/true) - if fileAttrIdx != -1: - flags_byte = obj[fileAttrIdx + 2] - if flags_byte in [0x0, 0x1]: - result_isas3 = False - else: - result_isas3 = (flags_byte & 0x08) != 0 + if tag_length == 0x3F: + if pos + 4 > len(data): + break + tag_length = int.from_bytes(data[pos:pos + 4], 'little') + pos += 4 - # fallback method (looks for doabc (as3 only)) + if pos + tag_length > len(data): + 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: - doabc_IDX = obj.find(b'\x52') - 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}") + os.system("/bin/bash -c 'read -s -n 1 -p \"Press any key to exit.\"'") + exit() 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): rectS = 8 nbits = (obj[rectS] >> 3) & 0x1F @@ -98,15 +122,18 @@ flashver, asver, SWFDAT = CheckSWF(swf) if flashver is not None: w, h = GetStageWH(SWFDAT) print(f"SWF Dimensions: {w}x{h} pixels") - if flashver > 8: - print(f"Flash version: {flashver}, this version MAY NOT be compatible with the Wii.") - else: - print(f"Flash version: {flashver}, this version is compatible with the Wii.") + if flashver <= 8: # compatible + print(f"Flash version: {flashver}, this SWF is compatible with the Wii.") + elif flashver == 9: # kirby tv notice + print(f"Flash version: {flashver}, this SWF may be compatible if injected inside the Kirby TV Channel") + else: # too new + print(f"Flash version: {flashver}, this SWF is not compatible with the Wii.") + print(f"ActionScript version: {asver}") if w > 700 and h > 500: print("WARNING: The given SWF might overlap/clip on the Wii.") else: - print("The SWF should NOT overlap and/or clip on the Wii.") + print("The SWF shouldn't overlap and/or clip on the Wii.") if platf == "Windows": os.system("pause") diff --git a/requirements.txt b/requirements.txt index 44dad18..368d6bf 100644 --- a/requirements.txt +++ b/requirements.txt @@ -1,136 +1,15 @@ -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 -bs4==0.0.2 -certifi==2024.8.30 -cffi==1.17.1 -charset-normalizer==3.4.0 -click==8.1.7 +certifi==2025.8.3 +charset-normalizer==3.4.3 +click==8.2.1 colorama==0.4.6 -config==0.5.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 +dotenv==0.9.9 +Flask==3.1.1 idna==3.10 -imageio==2.36.1 -imageio-ffmpeg==0.5.1 -isodate==0.7.2 itsdangerous==2.2.0 -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 +Jinja2==3.1.6 MarkupSafe==3.0.2 -matplotlib==3.10.1 -mdurl==0.1.2 -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 +python-dotenv==1.1.1 +requests==2.32.4 +urllib3==2.5.0 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