215 lines
6.4 KiB
Python
215 lines
6.4 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
Debug & Validation per il gioco Windjammers
|
|
Verifica: sintassi JS, struttura HTML, funzioni critiche, errori comuni
|
|
"""
|
|
|
|
import re
|
|
import sys
|
|
import json
|
|
|
|
def extract_js(html_path):
|
|
"""Estrae il JavaScript dall'HTML"""
|
|
with open(html_path, 'r') as f:
|
|
html = f.read()
|
|
match = re.search(r'<script>(.*?)</script>', html, re.DOTALL)
|
|
if not match:
|
|
return None, "Nessun tag <script> trovato"
|
|
return match.group(1), None
|
|
|
|
def check_syntax(js):
|
|
"""Verifica la sintassi JavaScript con node"""
|
|
import subprocess
|
|
import tempfile
|
|
|
|
with tempfile.NamedTemporaryFile(mode='w', suffix='.js', delete=False) as f:
|
|
f.write(js)
|
|
tmp_path = f.name
|
|
|
|
try:
|
|
result = subprocess.run(
|
|
['node', '--check', tmp_path],
|
|
capture_output=True, text=True, timeout=10
|
|
)
|
|
if result.returncode != 0:
|
|
return False, result.stderr.strip()
|
|
return True, None
|
|
except Exception as e:
|
|
return False, str(e)
|
|
|
|
def check_functions(js):
|
|
"""Verifica che le funzioni critiche siano definite"""
|
|
required = [
|
|
'function Player',
|
|
'function Disc',
|
|
'function Particle',
|
|
'function AI',
|
|
'function initGame',
|
|
'function serve',
|
|
'function drawBg',
|
|
'function drawGoal',
|
|
'function drawMenu',
|
|
'function drawHUD',
|
|
'function handleMenuInput',
|
|
'function loop',
|
|
'function scorePoint',
|
|
'function checkGoal',
|
|
'function checkCatch',
|
|
'function handleP1',
|
|
'function handleP2'
|
|
]
|
|
|
|
missing = []
|
|
for func in required:
|
|
if func not in js:
|
|
missing.append(func)
|
|
|
|
return missing
|
|
|
|
def check_common_errors(js):
|
|
"""Cerca errori comuni nel codice"""
|
|
errors = []
|
|
|
|
# Verifica stringhe con + non escaped
|
|
# Cerca pattern tipo: "testo +variabile+ altro" (errore comune nel template)
|
|
bad_strings = re.findall(r'"[^"]*\+[a-zA-Z_]+\+[^"]*"', js)
|
|
for s in bad_strings:
|
|
# Salta gli URL che hanno + nel percorso (non è un errore)
|
|
if not any(x in s for x in ['http', '://', 'Math.random']):
|
|
errors.append(f"Stringa sospetta (possibile + non escaped): {s}")
|
|
|
|
# Verifica bilanciatura parentesi
|
|
stack = []
|
|
for i, char in enumerate(js):
|
|
if char == '{':
|
|
stack.append(('}', i))
|
|
elif char == '(':
|
|
stack.append((')', i))
|
|
elif char == '[':
|
|
stack.append((']', i))
|
|
elif char in ')}]':
|
|
if not stack:
|
|
errors.append(f"Parentesi '{char}' in posizione {i} senza apertura")
|
|
elif stack[-1][0] != char:
|
|
errors.append(f"Parentesi '{char}' in posizione {i} non corrisponde a '{stack[-1][0]}'")
|
|
else:
|
|
stack.pop()
|
|
|
|
if stack:
|
|
for char, pos in stack:
|
|
errors.append(f"Parentesi aperta in posizione {pos} non chiusa")
|
|
|
|
# Verifica che loop() venga chiamato
|
|
if 'loop()' not in js and 'loop();' not in js:
|
|
errors.append("La funzione loop() non viene chiamata!")
|
|
|
|
# Verifica che initCtrl venga chiamato
|
|
if 'initCtrl()' not in js:
|
|
errors.append("initCtrl() non viene chiamato!")
|
|
|
|
return errors
|
|
|
|
def check_canvas_draw(js):
|
|
"""Verifica che le funzioni di disegno usino correttamente il canvas"""
|
|
issues = []
|
|
|
|
# Verifica che drawMenu usi fillText per mostrare testo
|
|
if 'fillText' not in js:
|
|
issues.append("Nessun fillText trovato - il testo non verrà mostrato!")
|
|
|
|
# Cerca errori comuni nei colori
|
|
color_pattern = r'style\s*=\s*"#[0-9A-Fa-f]{8}"' # 8 digit hex (invalido)
|
|
bad_colors = re.findall(color_pattern, js)
|
|
if bad_colors:
|
|
issues.append(f"Colori hex invalidi trovati: {bad_colors}")
|
|
|
|
return issues
|
|
|
|
def check_game_state_transitions(js):
|
|
"""Verifica le transizioni di stato del gioco"""
|
|
states = ['menu', 'ready', 'countdown', 'playing', 'end']
|
|
found_states = []
|
|
|
|
for state in states:
|
|
if f'"{state}"' in js or f"'{state}'" in js:
|
|
found_states.append(state)
|
|
|
|
missing = set(states) - set(found_states)
|
|
return missing
|
|
|
|
def run_validation(html_path):
|
|
"""Esegue tutte le validazioni e stampa il report"""
|
|
print("=" * 60)
|
|
print("🔍 VALIDAZIONE GIOCO WINDJAMMERS")
|
|
print("=" * 60)
|
|
|
|
# 1. Estrazione JS
|
|
print("\n📋 1. Estrazione JavaScript...")
|
|
js, err = extract_js(html_path)
|
|
if err:
|
|
print(f" ❌ ERRORE: {err}")
|
|
return False
|
|
print(f" ✅ JS estratto ({len(js)} caratteri)")
|
|
|
|
# 2. Sintassi
|
|
print("\n📋 2. Verifica sintassi...")
|
|
ok, err = check_syntax(js)
|
|
if not ok:
|
|
print(f" ❌ ERRORE DI SINTASSI:")
|
|
print(f" {err}")
|
|
return False
|
|
print(" ✅ Sintassi corretta")
|
|
|
|
# 3. Funzioni critiche
|
|
print("\n📋 3. Verifica funzioni critiche...")
|
|
missing = check_functions(js)
|
|
if missing:
|
|
print(f" ❌ FUNZIONI MANCANTI:")
|
|
for f in missing:
|
|
print(f" - {f}")
|
|
return False
|
|
print(f" ✅ Tutte le 17 funzioni critiche presenti")
|
|
|
|
# 4. Errori comuni
|
|
print("\n📋 4. Ricerca errori comuni...")
|
|
errors = check_common_errors(js)
|
|
if errors:
|
|
print(f" ⚠️ PROBLEMI TROVATI:")
|
|
for e in errors:
|
|
print(f" - {e}")
|
|
return False
|
|
print(" ✅ Nessun errore comune trovato")
|
|
|
|
# 5. Canvas
|
|
print("\n📋 5. Verifica disegno canvas...")
|
|
issues = check_canvas_draw(js)
|
|
if issues:
|
|
print(f" ⚠️ PROBLEMI CANVAS:")
|
|
for i in issues:
|
|
print(f" - {i}")
|
|
else:
|
|
print(" ✅ Funzioni di disegno presenti")
|
|
|
|
# 6. Stati del gioco
|
|
print("\n📋 6. Verifica stati del gioco...")
|
|
missing_states = check_game_state_transitions(js)
|
|
if missing_states:
|
|
print(f" ⚠️ STATI MANCANTI: {missing_states}")
|
|
else:
|
|
print(" ✅ Tutti gli stati del gioco presenti")
|
|
|
|
# 7. Riepilogo
|
|
print("\n" + "=" * 60)
|
|
print("✅ VALIDAZIONE COMPLETATA - Il gioco dovrebbe funzionare!")
|
|
print("=" * 60)
|
|
return True
|
|
|
|
if __name__ == '__main__':
|
|
if len(sys.argv) > 1:
|
|
path = sys.argv[1]
|
|
else:
|
|
path = '/home/codex/giochino/index.html'
|
|
|
|
success = run_validation(path)
|
|
sys.exit(0 if success else 1)
|