Implementado Ban History, Restore Character, Restore Items

This commit is contained in:
adevopg
2025-02-19 22:12:22 +01:00
parent 137dc853f8
commit 3f962f8368
5 changed files with 437 additions and 131 deletions
+247 -17
View File
@@ -199,19 +199,19 @@ def login_view(request):
password = form.cleaned_data['password']
ip_address = request.META.get('REMOTE_ADDR') # Obtener la IP del cliente
# Llamar a la funci¨®n de autenticaci¨®n
# Llamar a la función de autenticación
if authenticate(username, password):
# Guardar el intento exitoso
log_login_attempt(username, "Exito", ip_address)
# Guardar el nombre de usuario en may¨²sculas en la sesi¨®n
# Guardar el nombre de usuario en mayúsculas en la sesión
request.session['username'] = username.upper()
return JsonResponse({'success': True})
else:
# Guardar el intento fallido
log_login_attempt(username, "Fracaso", ip_address)
return JsonResponse({'success': False, 'error': "Usuario o contrase?a incorrectos"})
return JsonResponse({'success': False, 'error': "Usuario o contraseña incorrectos"})
else:
return JsonResponse({'success': False, 'error': "Formulario no valido"})
@@ -675,7 +675,6 @@ def my_account(request):
})
def get_account_status(account_id):
with connections['acore_auth'].cursor() as cursor:
# Obtener información de la tabla 'account'
@@ -737,7 +736,7 @@ def get_account_status(account_id):
unban_timestamp, current_timestamp = ban_data
remaining_time = unban_timestamp - current_timestamp
user_info['is_banned'] = True
user_info['unban_date'] = datetime.datetime.fromtimestamp(unban_timestamp).strftime("%A %d de %B del %Y a las %H:%M:%S Horas")
user_info['unban_date'] = datetime.fromtimestamp(unban_timestamp).strftime("%A %d de %B del %Y a las %H:%M:%S Horas")
user_info['remaining_time'] = remaining_time
else:
user_info['is_banned'] = False
@@ -1259,17 +1258,173 @@ def rename_cancel_view(request):
return redirect('login')
return render(request, 'account/rename_cancel.html')
@csrf_exempt
def restore_character_view(request):
# Verifica si el usuario está autenticado y obtiene su nombre de usuario
username = request.session.get('username')
if not username:
return redirect('login')
return render(request, 'account/restore_character.html')
return redirect('login') # Redirige si no hay sesión
# Obtener la ID de cuenta del usuario conectado a partir del sistema de autenticación personalizada
try:
with connections['acore_auth'].cursor() as cursor:
cursor.execute("SELECT id FROM account WHERE username = %s", [username])
result = cursor.fetchone()
if not result:
# Si no se encuentra la cuenta, mostrar un error
messages.error(request, "No se encontró la cuenta asociada a ese usuario.")
return redirect('login') # Redirige al login si no se encuentra la cuenta
account_id = result[0] # Obtén el ID de la cuenta
except Exception as e:
messages.error(request, f"Ocurrió un error al recuperar la cuenta: {str(e)}")
return redirect('login')
# Verificar si se ha seleccionado un personaje para restaurar
if request.method == 'POST':
# Obtener el GUID del personaje seleccionado para restaurar
guid = request.POST.get('guid')
if not guid:
messages.error(request, "No se seleccionó un personaje para restaurar.")
return redirect('restore-character')
# Aquí es donde usamos SOAP en lugar de la actualización directa
try:
command = f".char del restore {guid}" # Comando SOAP para restaurar el personaje
response = execute_soap_command(command) # Ejecuta el comando SOAP
# Si la respuesta es exitosa, informamos al usuario
if response == "success":
messages.success(request, "Personaje restaurado exitosamente.")
return redirect('my-account') # Redirigir a la cuenta del usuario
else:
messages.error(request, "Hubo un error al restaurar el personaje.")
return redirect('restore-character')
except Exception as e:
messages.error(request, f"Hubo un error al intentar restaurar el personaje: {str(e)}")
return redirect('restore-character')
# Realizar la consulta para obtener los personajes eliminados de la cuenta
with connections['acore_characters'].cursor() as cursor:
cursor.execute("""
SELECT guid, level, deleteInfos_Name, deleteInfos_Account, deleteDate
FROM characters
WHERE deleteInfos_Account = %s AND deleteDate IS NOT NULL
""", [account_id]) # Filtra por account_id
# Obtener los resultados de la consulta
deleted_characters = cursor.fetchall()
# Si no hay personajes eliminados
if not deleted_characters:
return render(request, 'account/restore_character.html', {
'message': 'No hay personajes eliminados que puedas recuperar.'
})
# Crear un listado de personajes eliminados con su nombre y nivel (si lo tienes)
character_list = []
for character in deleted_characters:
guid, level, name, account_id, delete_date = character
# Agregar la información del personaje al listado
character_list.append({
'name': name,
'guid': guid,
'level': level,
'delete_date': delete_date
})
# Renderiza la plantilla con los personajes eliminados
return render(request, 'account/restore_character.html', {
'character_list': character_list
})
@csrf_exempt
def restore_items_view(request):
username = request.session.get('username')
if not username:
return redirect('login')
return render(request, 'account/restore_items.html')
characters = []
deleted_items = []
selected_character = None
try:
# Obtener la ID de cuenta del usuario
with connections['acore_auth'].cursor() as cursor:
cursor.execute("SELECT id FROM account WHERE username = %s", [username])
result = cursor.fetchone()
if result:
account_id = result[0]
else:
messages.error(request, "No se encontró la cuenta asociada.")
return redirect('login')
# Obtener los personajes del usuario
with connections['acore_characters'].cursor() as cursor:
cursor.execute("SELECT name FROM characters WHERE account = %s", [account_id])
characters = [row[0] for row in cursor.fetchall()]
except Exception as e:
messages.error(request, f"Error al obtener los personajes: {str(e)}")
if request.method == "GET" and "character_name" in request.GET:
selected_character = request.GET.get("character_name")
if selected_character:
try:
# Ejecutar comando SOAP para obtener ítems eliminados del personaje seleccionado
command = f".item restore list {selected_character}"
response = execute_soap_command(command)
# Procesar la respuesta del servidor
for line in response.split("\n"):
match = re.search(r"Recover id: (\d+) \| Item: (.+) \((\d+)\) \| Count: (\d+)", line)
if match:
recover_id = match.group(1)
item_name = match.group(2)
item_id = match.group(3)
count = match.group(4)
deleted_items.append({
"recover_id": recover_id,
"item_name": item_name,
"item_id": item_id,
"count": count
})
except Exception as e:
messages.error(request, f"Error al obtener los ítems eliminados: {str(e)}")
if request.method == "POST":
recover_id = request.POST.get("recover_id")
selected_character = request.POST.get("character_name")
if not recover_id or not selected_character:
messages.error(request, "Selecciona un personaje y un ítem para restaurar.")
return redirect('restore-items')
try:
# Ejecutar comando SOAP para restaurar el ítem
command = f".item restore {recover_id} {selected_character}"
response = execute_soap_command(command)
if "success" in response.lower():
messages.success(request, "Ítem restaurado exitosamente.")
else:
messages.error(request, "No se pudo restaurar el ítem.")
except Exception as e:
messages.error(request, f"Error al restaurar el ítem: {str(e)}")
return redirect('restore-items')
return render(request, 'account/restore_items.html', {
'characters': characters,
'deleted_items': deleted_items,
'selected_character': selected_character
})
def quest_character_view(request):
username = request.session.get('username')
@@ -1288,7 +1443,7 @@ def customize_character_view(request):
if not username:
return redirect('login')
# ?? Obtener informaci��n de la cuenta desde acore_auth
# ?? Obtener información de la cuenta desde acore_auth
with connections['acore_auth'].cursor() as cursor:
cursor.execute("""
SELECT id, email, last_ip FROM account WHERE username = %s
@@ -2318,13 +2473,20 @@ def d_points_view(request):
def points_history_view(request):
return render(request, 'account/points_history.html')
def format_datetime(timestamp):
if timestamp:
return datetime.utcfromtimestamp(timestamp).strftime('%d-%m-%Y %H:%M:%S')
return "No disponible"
def trans_history_view(request):
"""
Vista para mostrar el historial de transacciones de la cuenta y sus personajes.
"""
username = request.session.get('username') # Obtener el nombre de usuario de la sesi¨®n
username = request.session.get('username') # Obtener el nombre de usuario de la sesión
if username:
# Filtramos las transacciones que corresponden al usuario y a los personajes asociados
@@ -2335,22 +2497,90 @@ def trans_history_view(request):
# Renderizamos la vista con el historial de transacciones
return render(request, 'account/trans_history.html', {'transactions': transactions})
def ban_history_view(request):
return render(request, 'account/ban_history.html')
def get_account_id(username):
# Consulta para obtener el account_id a partir del username
with connections['acore_auth'].cursor() as cursor:
cursor.execute("""
SELECT id
FROM account
WHERE username = %s
""", [username])
result = cursor.fetchone()
return result[0] if result else None
def get_ban_history(account_id):
# Consulta de baneos de la cuenta
with connections['acore_auth'].cursor() as cursor:
cursor.execute("""
SELECT bandate, unbandate, banreason, active, account.username
FROM account_banned
JOIN account ON account_banned.id = account.id
WHERE account_banned.id = %s
""", [account_id])
account_bans = cursor.fetchall()
# Formatear las fechas
account_bans = [(format_datetime(ban[0]), format_datetime(ban[1]), ban[2], ban[3], ban[4]) for ban in account_bans]
# Consulta de baneos de los personajes asociados a la cuenta
with connections['acore_characters'].cursor() as cursor:
cursor.execute("""
SELECT bandate, unbandate, banreason, active, characters.name
FROM character_banned
JOIN characters ON character_banned.guid = characters.guid
WHERE characters.account = %s
""", [account_id])
character_bans = cursor.fetchall()
# Formatear las fechas
character_bans = [(format_datetime(ban[0]), format_datetime(ban[1]), ban[2], ban[3], ban[4]) for ban in character_bans]
return account_bans, character_bans
def calculate_unmute_date(mute_date, mute_duration):
if isinstance(mute_date, int):
mute_date = datetime.fromtimestamp(mute_date)
return mute_date + timedelta(seconds=mute_duration)
def ban_history_view(request):
# Verificar si el usuario tiene un `username` en la sesión
username = request.session.get('username')
if not username:
return redirect('login')
# Obtener el account_id a partir del username
account_id = get_account_id(username)
if not account_id:
return redirect('login') # O redirigir a otra página si no se encuentra el account_id
print(f"Account ID: {account_id}") # Depurar el account_id
account_bans, character_bans = get_ban_history(account_id)
return render(request, 'account/ban_history.html', {
'account_bans': account_bans,
'character_bans': character_bans,
'now': datetime.now(),
})
def security_history_view(request):
username = request.session.get('username')
if not username:
return redirect('login') # Si no est¨¢ autenticado, redirigir al login
return redirect('login') # Si no está autenticado, redirigir al login
# Obtener los ¨²ltimos 20 intentos de inicio de sesi¨®n
# Obtener los últimos 20 intentos de inicio de sesión
login_attempts = LoginAttempt.objects.filter(username=username).order_by('-timestamp')[:20]
return render(request, 'account/security_history.html', {'login_attempts': login_attempts})
def log_login_attempt(username, status, ip_address):
# Registrar intento de inicio de sesi¨®n en el historial
# Registrar intento de inicio de sesión en el historial
LoginAttempt.objects.create(
username=username,
status=status,