305 lines
9.9 KiB
GDScript
305 lines
9.9 KiB
GDScript
extends Node
|
|
|
|
signal residents_received(residents)
|
|
signal games_received(games)
|
|
signal login_successful()
|
|
signal login_failed(error_msg)
|
|
|
|
var all_residents = []
|
|
var all_games = []
|
|
|
|
var is_logged_in: bool = false
|
|
var auth_token: String = ""
|
|
var token_expiration: int = 0
|
|
var residencia_id: int = -1
|
|
var user_id = -1
|
|
|
|
var partidas_activas: Array = []
|
|
var partidas_completadas: Array = []
|
|
|
|
# -------------------------- LOGIN --------------------------
|
|
|
|
func login(email: String, password: String):
|
|
var http_request = HTTPRequest.new()
|
|
get_tree().root.add_child(http_request)
|
|
http_request.connect("request_completed", Callable(self, "_on_login_response").bind(http_request))
|
|
|
|
var data = {
|
|
"email": email,
|
|
"password": password
|
|
}
|
|
var json_body = JSON.stringify(data)
|
|
var headers = ["Content-Type: application/json"]
|
|
var error = http_request.request(AppConstants.ENDPOINT_LOG_IN, headers, HTTPClient.METHOD_POST, json_body)
|
|
|
|
if error != OK:
|
|
print("[LOGIN] ❌ Error al iniciar la solicitud de login:", error)
|
|
|
|
func _on_login_response(result, response_code, headers, body, request_node):
|
|
print("[LOGIN] 📡 Código de respuesta:", response_code)
|
|
if response_code == 200:
|
|
var parsed = JSON.parse_string(body.get_string_from_utf8())
|
|
if parsed and parsed.has("token"):
|
|
auth_token = parsed["token"]
|
|
token_expiration = parsed.get("expiresIn", 0)
|
|
user_id = parsed.get("idUser", -1)
|
|
residencia_id = parsed.get("idResidencia", -1)
|
|
is_logged_in = true
|
|
print("[LOGIN] ✅ Login exitoso. Usuario ID: %d, Residencia ID: %d" % [user_id, residencia_id])
|
|
emit_signal("login_successful")
|
|
else:
|
|
print("[LOGIN] ⚠️ Respuesta sin token recibido.")
|
|
emit_signal("login_failed", "Respuesta sin token.")
|
|
else:
|
|
print("[LOGIN] ❌ Fallo en login. Código de respuesta:", response_code)
|
|
emit_signal("login_failed", "Login fallido. Código: %d" % response_code)
|
|
|
|
request_node.queue_free()
|
|
|
|
# -------------------------- INICIO Y FIN DE PARTIDA --------------------------
|
|
|
|
func start_game(resident, level, level_name):
|
|
var partida = {
|
|
"idUser": user_id,
|
|
"idResident": resident,
|
|
"start_time": Time.get_unix_time_from_system(),
|
|
"level_name": level_name,
|
|
"level": level,
|
|
"fails": 0
|
|
}
|
|
partidas_activas.append(partida)
|
|
print("[JUEGO] ▶️ Partida iniciada para residente ID %d en nivel %d" % [resident, level])
|
|
|
|
func end_game(level_name : String, game_name : String):
|
|
var now = Time.get_unix_time_from_system()
|
|
|
|
var games = await get_games_loaded()
|
|
var game_id = 0
|
|
for game in games:
|
|
if game.nombre == game_name.to_lower():
|
|
game_id = game.id
|
|
break
|
|
|
|
if game_id == 0:
|
|
print("[PARTIDA] ⚠️ No se encontró el juego en la base de datos.")
|
|
return
|
|
|
|
var partidas_a_borrar := []
|
|
|
|
# Lógica específica para Gimnasio
|
|
if game_name == AppConstants.NAME_JUEGO_GIMNASIO:
|
|
for partida in partidas_activas:
|
|
if partida.level_name == level_name:
|
|
var tiempo_total = now - partida["start_time"]
|
|
var tiempo_previo := 0
|
|
|
|
# SOLO sumar duración de partidas completadas del mismo residente
|
|
for p in partidas_completadas:
|
|
if p["idResident"] == partida["idResident"]:
|
|
tiempo_previo += p["duracion"]
|
|
|
|
var duracion_real = max(tiempo_total - tiempo_previo, 0)
|
|
|
|
var data = {
|
|
"idResidente": partida["idResident"],
|
|
"idUsuario": partida["idUser"],
|
|
"num": 0,
|
|
"duracion": duracion_real,
|
|
"dificultad": partida["level"]
|
|
}
|
|
|
|
print("[JUEGO] 🛑 Partida", partida["level_name"], "Residente", data["idResidente"], "Duración:", duracion_real ,"segundos.")
|
|
send_game_data(data, game_id)
|
|
|
|
partida["duracion"] = duracion_real
|
|
partidas_completadas.append(partida)
|
|
|
|
# Borrar SOLO las partidas activas del ejercicio actual
|
|
partidas_activas = partidas_activas.filter(func(p): return p.level_name != level_name)
|
|
|
|
if partidas_activas.is_empty():
|
|
clear_completed_games()
|
|
|
|
# Lógica específica para Bingo auditivo y Flecha y reacciona
|
|
elif game_name == AppConstants.NAME_JUEGO_BINGO_AUDITIVO or game_name == AppConstants.NAME_JUEGO_FLECHA_Y_REACCIONA:
|
|
for partida in partidas_activas:
|
|
var duracion = now - partida["start_time"]
|
|
|
|
var data = {
|
|
"idResidente": partida["idResident"],
|
|
"idUsuario": partida["idUser"],
|
|
"num": partida["fails"],
|
|
"duracion": duracion,
|
|
"dificultad": partida["level"]
|
|
}
|
|
|
|
print("[PARTIDA] 📤 Enviando datos - Residente ID: %d, Duración: %d, Nivel: %d" % [data["idResidente"], duracion, data["dificultad"]])
|
|
send_game_data(data, game_id)
|
|
|
|
clear_active_games()
|
|
if partidas_activas.is_empty() and !partidas_completadas.is_empty():
|
|
clear_completed_games()
|
|
|
|
# Lógica especifica para Seguir la linea y Emparejar las sombras
|
|
else:
|
|
for partida in partidas_activas:
|
|
if partida.level_name == level_name:
|
|
var tiempo_total = now - partida["start_time"]
|
|
var tiempo_previo := 0
|
|
|
|
for p in partidas_completadas:
|
|
tiempo_previo += p["duracion"]
|
|
|
|
var duracion_real = max(tiempo_total - tiempo_previo, 0)
|
|
|
|
var data = {
|
|
"idResidente": partida["idResident"],
|
|
"idUsuario": partida["idUser"],
|
|
"num": partida["fails"],
|
|
"duracion": duracion_real,
|
|
"dificultad": partida["level"]
|
|
}
|
|
|
|
print("[JUEGO] 🛑 Partida", partida["level_name"], "finalizada. Duración:", duracion_real ,"segundos. Fallos:", partida["fails"])
|
|
send_game_data(data, game_id)
|
|
|
|
partida["duracion"] = duracion_real
|
|
partidas_completadas.append(partida)
|
|
partidas_activas.erase(partida)
|
|
|
|
|
|
func add_fail(level_name: String):
|
|
for partida in partidas_activas:
|
|
if partida.level_name == level_name:
|
|
partida["fails"] += 1
|
|
print("[JUEGO] ❌ Fallo añadido a ", level_name ,". Total fallos: ", partida["fails"])
|
|
break
|
|
|
|
func add_victory_by_resident(resident):
|
|
for partida in partidas_activas:
|
|
if partida.idResident == resident:
|
|
partida["fails"] = 1
|
|
print("[JUEGO] Victoria añadido a ", resident)
|
|
break
|
|
|
|
func remove_victory_by_resident(resident):
|
|
for partida in partidas_activas:
|
|
if partida.idResident == resident:
|
|
partida["fails"] = 0
|
|
print("[JUEGO] Victoria quitado a ", resident)
|
|
break
|
|
|
|
# Borra todas las partidas activas
|
|
func clear_active_games():
|
|
partidas_activas.clear()
|
|
print("[PARTIDA] 🗑️ Partidas activas limpiadas.")
|
|
|
|
func clear_completed_games():
|
|
partidas_completadas.clear()
|
|
print("[PARTIDA] 🗑️ Partidas completadas limpiadas.")
|
|
|
|
# Borra una partida activa específica por nombre
|
|
func remove_active_game(name: String):
|
|
for partida in partidas_activas:
|
|
if name == partida["level_name"]:
|
|
partidas_activas.erase(partida)
|
|
print("Partida ", name, " eliminada de partidas activas")
|
|
|
|
# -------------------------- GET RESIDENTS --------------------------
|
|
|
|
func get_residents():
|
|
var http_request = HTTPRequest.new()
|
|
get_tree().root.add_child(http_request)
|
|
http_request.connect("request_completed", Callable(self, "_on_request_get_residents").bind(http_request))
|
|
|
|
var headers = [
|
|
"User-Agent: Godot",
|
|
"Authorization: Bearer %s" % auth_token
|
|
]
|
|
var error = http_request.request(AppConstants.ENDPOINT_GET_ALL_RESIDENTS, headers)
|
|
|
|
if error != OK:
|
|
print("[RESIDENTES] ❌ Error al hacer GET de residentes:", error)
|
|
|
|
func _on_request_get_residents(result, response_code, headers, body, request_node):
|
|
print("[RESIDENTES] 📡 Código de respuesta:", response_code)
|
|
if response_code == 200:
|
|
var parsed = JSON.parse_string(body.get_string_from_utf8())
|
|
if parsed != null:
|
|
all_residents = parsed
|
|
print("[RESIDENTES] ✅ Residentes cargados:", all_residents.size())
|
|
emit_signal("residents_received", all_residents)
|
|
else:
|
|
print("[RESIDENTES] ❌ Error al parsear JSON de residentes.")
|
|
else:
|
|
print("[RESIDENTES] ❌ Error al obtener residentes. Código:", response_code)
|
|
|
|
request_node.queue_free()
|
|
|
|
func get_residents_loaded() -> Array:
|
|
get_residents()
|
|
var result = await self.residents_received
|
|
return result
|
|
|
|
# -------------------------- GET GAMES --------------------------
|
|
|
|
func get_games():
|
|
var http_request = HTTPRequest.new()
|
|
get_tree().root.add_child(http_request)
|
|
http_request.connect("request_completed", Callable(self, "_on_request_get_games").bind(http_request))
|
|
|
|
var headers = [
|
|
"User-Agent: Godot",
|
|
"Authorization: Bearer %s" % auth_token
|
|
]
|
|
var error = http_request.request(AppConstants.ENDPOINT_GET_ALL_GAMES, headers)
|
|
|
|
if error != OK:
|
|
print("[JUEGOS] ❌ Error al hacer GET de juegos:", error)
|
|
|
|
func _on_request_get_games(result, response_code, headers, body, request_node):
|
|
print("[JUEGOS] 📡 Código de respuesta:", response_code)
|
|
if response_code == 200:
|
|
var parsed = JSON.parse_string(body.get_string_from_utf8())
|
|
if parsed != null:
|
|
all_games = parsed
|
|
print("[JUEGOS] ✅ Juegos cargados:", all_games.size())
|
|
emit_signal("games_received", all_games)
|
|
else:
|
|
print("[JUEGOS] ❌ Error al parsear JSON de juegos.")
|
|
else:
|
|
print("[JUEGOS] ❌ Error al obtener juegos. Código:", response_code)
|
|
|
|
request_node.queue_free()
|
|
|
|
func get_games_loaded() -> Array:
|
|
get_games()
|
|
var result = await self.games_received
|
|
return result
|
|
|
|
# -------------------------- POST PARTIDA --------------------------
|
|
|
|
func send_game_data(data: Dictionary, game_id):
|
|
print("[PARTIDA] ▶️ Body: ", data, " . Residencia: ", residencia_id, " . Juego: ", game_id)
|
|
var http_request = HTTPRequest.new()
|
|
get_tree().root.add_child(http_request)
|
|
|
|
var json_body = JSON.stringify(data)
|
|
var headers = [
|
|
"Content-Type: application/json",
|
|
"Authorization: Bearer %s" % auth_token
|
|
]
|
|
var url = AppConstants.ENDPOINT_POST_GAME_STATS % [game_id]
|
|
|
|
http_request.connect("request_completed", Callable(self, "_on_game_data_sent").bind(http_request))
|
|
var error = http_request.request(url, headers, HTTPClient.METHOD_POST, json_body)
|
|
|
|
if error != OK:
|
|
print("[PARTIDA] ❌ Error al enviar los datos de la partida:", error)
|
|
|
|
func _on_game_data_sent(result, response_code, headers, body, http_request):
|
|
if response_code == 200 or response_code == 201:
|
|
print("[PARTIDA] ✅ Datos de partida registrados correctamente.")
|
|
else:
|
|
print("[PARTIDA] ❌ Error al registrar la partida. Código:", response_code)
|