from ._base import * def rename_character_view(request): username = request.session.get('username') if not username: return redirect('login') # 馃敼 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 """, [username]) account_info = cursor.fetchone() if not account_info: return JsonResponse({'success': False, 'message': 'Error: Cuenta no encontrada.'}) account_id, email, acore_ip = account_info client_ip = request.META.get('REMOTE_ADDR', '') # 馃敼 Obtener personajes del usuario desde la base de datos `acore_characters` 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()] # 馃敼 Obtener el precio del renombrado price_obj = RenamePrice.objects.first() price = price_obj.price if price_obj else 2.00 # 馃敼 Ejecutar el comando SOAP para verificar el servidor command = f".server info" response = execute_soap_command(command) if request.method == 'POST': character_name = request.POST.get('character') if response is None: return JsonResponse({'success': False, 'message': 'Error de comunicaci贸n con el servidor. Intente nuevamente m谩s tarde.'}) if not character_name: return JsonResponse({'success': False, 'message': 'Por favor, seleccione un personaje.'}) if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para renombrar este personaje.'}) # 馃敼 Crear sesi贸n de pago con Stripe success_url = request.build_absolute_uri(reverse('rename-success')) cancel_url = request.build_absolute_uri(reverse('rename-cancel')) stripe_response = create_checkout_session( account_id=account_id, username=username, email=email, acore_ip=acore_ip, amount=price, character_name=character_name, success_url=success_url, cancel_url=cancel_url, product_name=f"Renombrar personaje: {character_name}" ) if stripe_response["success"]: request.session['rename_character'] = character_name return JsonResponse({ 'success': True, 'session_id': stripe_response["session_id"], 'stripe_public_key': settings.STRIPE_PUBLIC_KEY }) else: return JsonResponse({'success': False, 'message': f'Error al iniciar el pago: {stripe_response["error"]}'}) return render(request, 'account/rename_character.html', {'characters': characters, 'price': price}) @require_paid_stripe() def rename_success_view(request): # Procesar el comando SOAP tras el pago exitoso character_name = request.session.get('rename_character') if not character_name: return redirect('rename-character') command = f".char rename {character_name}" response = execute_soap_command(command) if response is None or response.strip() == "": message = f"El personaje {character_name} ha sido marcado para renombrar." request.session.pop('rename_character', None) # Limpiar la sesi贸n return render(request, 'account/rename_success.html', {'message': message}) else: return render(request, 'account/rename_success.html', {'message': f"Error: {response}"}) def rename_cancel_view(request): username = request.session.get('username') if not username: return redirect('login') return render(request, 'account/rename_cancel.html') 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') # 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: return JsonResponse({'success': False, 'message': 'No se seleccion贸 un personaje para restaurar.'}) # Restaurar v铆a SOAP y responder en JSON (isla React) try: command = f".char del restore {guid}" # Comando SOAP para restaurar el personaje response = execute_soap_command(command) # Ejecuta el comando SOAP if response == "success": return JsonResponse({ 'success': True, 'message': 'Personaje restaurado exitosamente.', 'redirect': reverse('my-account'), }) else: return JsonResponse({'success': False, 'message': 'Hubo un error al restaurar el personaje.'}) except Exception as e: return JsonResponse({'success': False, 'message': f'Hubo un error al intentar restaurar el personaje: {str(e)}'}) # 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, 'character_data': [ {'guid': c['guid'], 'name': c['name'], 'level': c['level']} for c in character_list ], }) def restore_items_view(request): username = request.session.get('username') if not username: return redirect('login') 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)}") # La isla React usa AJAX (X-Requested-With); en ese caso respondemos JSON. is_ajax = request.headers.get('X-Requested-With') == 'XMLHttpRequest' 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: if is_ajax: return JsonResponse({'error': f'Error al obtener los 铆tems eliminados: {str(e)}'}) messages.error(request, f"Error al obtener los 铆tems eliminados: {str(e)}") if is_ajax: return JsonResponse({'items': deleted_items}) 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: if is_ajax: return JsonResponse({'success': False, 'message': 'Selecciona un personaje y un 铆tem para restaurar.'}) 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) ok = "success" in response.lower() except Exception as e: if is_ajax: return JsonResponse({'success': False, 'message': f'Error al restaurar el 铆tem: {str(e)}'}) messages.error(request, f"Error al restaurar el 铆tem: {str(e)}") return redirect('restore-items') if is_ajax: msg = ('脥tem restaurado exitosamente.' if ok else 'No se pudo restaurar el 铆tem.') return JsonResponse({'success': ok, 'message': msg}) messages.success(request, "脥tem restaurado exitosamente.") if ok else messages.error(request, "No se pudo restaurar el 铆tem.") return redirect('restore-items') return render(request, 'account/restore_items.html', { 'characters': characters, 'deleted_items': deleted_items, 'selected_character': selected_character, 'character_names': characters, }) def quest_character_view(request): username = request.session.get('username') if not username: return redirect('login') return render(request, 'account/quest_character.html') def send_gift_view(request): username = request.session.get('username') if not username: return redirect('login') return render(request, 'account/send_gift.html') def customize_character_view(request): username = request.session.get('username') if not username: return redirect('login') # ?? 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 """, [username]) account_info = cursor.fetchone() if not account_info: return JsonResponse({'success': False, 'message': 'Error: Cuenta no encontrada.'}) account_id, email, acore_ip = account_info client_ip = request.META.get('REMOTE_ADDR', '') # ?? Obtener personajes del usuario desde la base de datos `acore_characters` 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()] # Obtener el precio de la personalizaci贸n (si se gestiona desde el admin) price_obj = CustomizePrice.objects.first() price = price_obj.price if price_obj else 1.00 if request.method == 'POST': character_name = request.POST.get('character') # Validar si el personaje fue seleccionado if not character_name: return JsonResponse({'success': False, 'message': 'Por favor, seleccione un personaje.'}) # Verificar si el personaje pertenece al usuario if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para personalizar este personaje.'}) # Crear sesi贸n de pago con Stripe success_url = request.build_absolute_uri(reverse('customize-success')) cancel_url = request.build_absolute_uri(reverse('customize-cancel')) stripe_response = create_checkout_session( account_id=account_id, username=username, email=email, acore_ip=acore_ip, amount=price, character_name=character_name, success_url=success_url, cancel_url=cancel_url, product_name=f"Personalizar personaje: {character_name}" ) if stripe_response["success"]: # Guardar temporalmente el nombre del personaje en la sesi贸n request.session['customize_character'] = character_name return JsonResponse({ 'success': True, 'session_id': stripe_response["session_id"], 'stripe_public_key': settings.STRIPE_PUBLIC_KEY }) else: return JsonResponse({'success': False, 'message': f'Error al iniciar el pago: {stripe_response["error"]}'}) return render(request, 'account/customize_character.html', {'characters': characters, 'price': price}) @require_paid_stripe() def customize_success_view(request): # Procesar el comando SOAP tras el pago exitoso character_name = request.session.get('customize_character') if not character_name: return redirect('customize-character') command = f".char customi {character_name}" response = execute_soap_command(command) if response is None or response.strip() == "": message = f"El personaje {character_name} ha sido marcado para personalizaci贸n." request.session.pop('customize_character', None) # Limpiar la sesi贸n return render(request, 'account/customize_success.html', {'message': message}) else: return render(request, 'account/customize_success.html', {'message': f"Error: {response}"}) def customize_cancel_view(request): return render(request, 'account/customize_cancel.html') def change_race_character_view(request): username = request.session.get('username') if not username: return redirect('login') # Obtener personajes del usuario desde la base de datos `acore_characters` with connections['acore_auth'].cursor() as cursor: cursor.execute(""" SELECT id, email, last_ip FROM account WHERE username = %s """, [username]) account_info = cursor.fetchone() if not account_info: return JsonResponse({'success': False, 'message': 'Error: Cuenta no encontrada.'}) account_id, email, acore_ip = account_info client_ip = request.META.get('REMOTE_ADDR', '') # ?? Obtener personajes del usuario desde la base de datos `acore_characters` 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()] # Obtener el precio del cambio de raza price_obj = ChangeRacePrice.objects.first() price = price_obj.price if price_obj else 10.00 # Precio predeterminado si no hay registro if request.method == 'POST': character_name = request.POST.get('character') # Validar si el personaje fue seleccionado if not character_name: return JsonResponse({'success': False, 'message': 'Por favor, seleccione un personaje.'}) # Verificar si el personaje pertenece al usuario if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para cambiar la raza de este personaje.'}) # Crear sesi贸n de pago con Stripe success_url = request.build_absolute_uri(reverse('change-race-success')) cancel_url = request.build_absolute_uri(reverse('change-race-cancel')) stripe_response = create_checkout_session( account_id=account_id, username=username, email=email, acore_ip=acore_ip, amount=price, character_name=character_name, success_url=success_url, cancel_url=cancel_url, product_name=f"Cambio de Raza del personaje: {character_name}" ) if stripe_response["success"]: # Guardar el personaje en la sesi贸n para el cambio request.session['change_race_character'] = character_name return JsonResponse({ 'success': True, 'session_id': stripe_response["session_id"], 'stripe_public_key': settings.STRIPE_PUBLIC_KEY }) else: return JsonResponse({'success': False, 'message': f'Error al iniciar el pago: {stripe_response["error"]}'}) return render(request, 'account/change_race.html', {'characters': characters, 'price': price}) @require_paid_stripe() def change_race_success_view(request): # Procesar el comando SOAP tras el pago exitoso character_name = request.session.get('change_race_character') if not character_name: return redirect('change-race') command = f".char changerace {character_name}" response = execute_soap_command(command) if response is None or response.strip() == "": message = f"El personaje {character_name} ha sido marcado para cambio de raza." request.session.pop('change_race_character', None) # Limpiar la sesi贸n return render(request, 'account/change_race_success.html', {'message': message}) else: return render(request, 'account/change_race_success.html', {'message': f"Error: {response}"}) def change_race_cancel_view(request): return render(request, 'account/change_race_cancel.html') def change_faction_character_view(request): username = request.session.get('username') if not username: return redirect('login') # Obtener personajes del usuario desde la base de datos `acore_characters` with connections['acore_auth'].cursor() as cursor: cursor.execute(""" SELECT id, email, last_ip FROM account WHERE username = %s """, [username]) account_info = cursor.fetchone() if not account_info: return JsonResponse({'success': False, 'message': 'Error: Cuenta no encontrada.'}) account_id, email, acore_ip = account_info client_ip = request.META.get('REMOTE_ADDR', '') # ?? Obtener personajes del usuario desde la base de datos `acore_characters` 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()] # Obtener el precio del cambio de facci贸n price_obj = ChangeFactionPrice.objects.first() price = price_obj.price if price_obj else 10.00 if request.method == 'POST': character_name = request.POST.get('character') # Validar si el personaje fue seleccionado if not character_name: return JsonResponse({'success': False, 'message': 'Por favor, seleccione un personaje.'}) # Verificar si el personaje pertenece al usuario if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para cambiar la facci贸n de este personaje.'}) # Crear sesi贸n de pago con Stripe success_url = request.build_absolute_uri(reverse('change-faction-success')) cancel_url = request.build_absolute_uri(reverse('change-faction-cancel')) stripe_response = create_checkout_session( account_id=account_id, username=username, email=email, acore_ip=acore_ip, amount=price, character_name=character_name, success_url=success_url, cancel_url=cancel_url, product_name=f"Cambiar Faccion del personaje: {character_name}" ) if stripe_response["success"]: # Guardar el personaje seleccionado en la sesi贸n request.session['change_faction_character'] = character_name return JsonResponse({ 'success': True, 'session_id': stripe_response["session_id"], 'stripe_public_key': settings.STRIPE_PUBLIC_KEY }) else: return JsonResponse({'success': False, 'message': f'Error al iniciar el pago: {stripe_response["error"]}'}) return render(request, 'account/change_faction.html', {'characters': characters, 'price': price}) @require_paid_stripe() def change_faction_success_view(request): # Procesar el comando SOAP tras el pago exitoso character_name = request.session.get('change_faction_character') if not character_name: return redirect('change-faction-character') command = f".char changef {character_name}" response = execute_soap_command(command) if response is None or response.strip() == "": message = f"El personaje {character_name} ha cambiado de facci贸n con 茅xito." request.session.pop('change_faction_character', None) # Limpiar la sesi贸n return render(request, 'account/change_faction_success.html', {'message': message}) else: return render(request, 'account/change_faction_success.html', {'message': f"Error: {response}"}) def change_faction_cancel_view(request): return render(request, 'account/change_faction_cancel.html') def level_up_character_view(request): username = request.session.get('username') if not username: return redirect('login') # Obtener personajes del usuario desde la base de datos `acore_characters` with connections['acore_auth'].cursor() as cursor: cursor.execute(""" SELECT id, email, last_ip FROM account WHERE username = %s """, [username]) account_info = cursor.fetchone() if not account_info: return JsonResponse({'success': False, 'message': 'Error: Cuenta no encontrada.'}) account_id, email, acore_ip = account_info client_ip = request.META.get('REMOTE_ADDR', '') # ?? Obtener personajes del usuario desde la base de datos `acore_characters` 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()] # Obtener el precio de subir a nivel 80 price_obj = LevelUpPrice.objects.first() price = price_obj.price if price_obj else 10.00 if request.method == 'POST': character_name = request.POST.get('character') # Validar si el personaje fue seleccionado if not character_name: return JsonResponse({'success': False, 'message': 'Por favor, seleccione un personaje.'}) # Verificar si el personaje pertenece al usuario if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para subir de nivel a este personaje.'}) # Crear sesi贸n de pago con Stripe success_url = request.build_absolute_uri(reverse('level-up-success')) cancel_url = request.build_absolute_uri(reverse('level-up-cancel')) stripe_response = create_checkout_session( account_id=account_id, username=username, email=email, acore_ip=acore_ip, amount=price, character_name=character_name, success_url=success_url, cancel_url=cancel_url, product_name=f"Subir el Nivel 80 del personaje: {character_name}" ) if stripe_response["success"]: # Guardar el personaje en la sesi贸n para usarlo despu茅s del pago request.session['levelup_character'] = character_name return JsonResponse({ 'success': True, 'session_id': stripe_response["session_id"], 'stripe_public_key': settings.STRIPE_PUBLIC_KEY }) else: return JsonResponse({'success': False, 'message': f'Error al iniciar el pago: {stripe_response["error"]}'}) return render(request, 'account/level_up.html', {'characters': characters, 'price': price}) @require_paid_stripe() def level_up_success_view(request): character_name = request.session.get('levelup_character') if not character_name: return redirect('level-up-character') # Ejecutar el comando SOAP command = f".char level {character_name} 80" response = execute_soap_command(command) if response is None or response.strip() == "": message = f"El personaje {character_name} ha sido subido al nivel 80." else: message = f"Error: {response}" # Limpiar la sesi贸n request.session.pop('levelup_character', None) return render(request, 'account/level_up_success.html', {'message': message}) def level_up_cancel_view(request): return render(request, 'account/level_up_cancel.html') def gold_character_view(request): username = request.session.get('username') if not username: return redirect('login') # Obtener personajes y estado de conexi贸n del usuario try: with connections['acore_auth'].cursor() as cursor: cursor.execute(""" SELECT id, email, last_ip FROM account WHERE username = %s """, [username]) account_info = cursor.fetchone() if not account_info: return JsonResponse({'success': False, 'message': 'Error: Cuenta no encontrada.'}) account_id, email, acore_ip = account_info client_ip = request.META.get('REMOTE_ADDR', '') # Obtener personajes del usuario desde la base de datos `acore_characters` with connections['acore_characters'].cursor() as cursor: cursor.execute(""" SELECT name, online, money FROM characters WHERE account = %s """, [account_id]) characters_data = cursor.fetchall() characters = {row[0]: {'online': row[1], 'money': row[2]} for row in characters_data} except Exception as e: return JsonResponse({'success': False, 'message': f'Error al obtener los personajes: {str(e)}'}) # Obtener precios del oro gold_prices = GoldPrice.objects.all().order_by('gold_amount') if request.method == 'POST': character_name = request.POST.get('character') gold_amount = request.POST.get('gold_amount') # Validaciones iniciales if not character_name or not gold_amount: return JsonResponse({'success': False, 'message': 'Seleccione un personaje y una cantidad de oro.'}) if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para enviar oro a este personaje.'}) if characters[character_name]['online'] == 1: return JsonResponse({'success': False, 'message': 'El personaje debe estar desconectado para recibir oro.'}) try: gold_amount = int(gold_amount) except ValueError: return JsonResponse({'success': False, 'message': 'Cantidad de oro no v谩lida.'}) gold_price = GoldPrice.objects.filter(gold_amount=gold_amount).first() if not gold_price: return JsonResponse({'success': False, 'message': 'Cantidad de oro no v谩lida.'}) # El precio va en euros (con decimales); el helper lo pasa a c茅ntimos (脳100) stripe_price = gold_price.price # Crear sesi贸n de pago con Stripe success_url = request.build_absolute_uri(reverse('gold-success')) cancel_url = request.build_absolute_uri(reverse('gold-cancel')) # Llamada corregida a create_checkout_session con todos los par谩metros requeridos stripe_response = create_checkout_session( account_id=account_id, username=username, email=email, acore_ip=acore_ip, amount=stripe_price, # El precio calculado character_name=character_name, success_url=success_url, cancel_url=cancel_url, product_name=f"Aumentar el Oro: {gold_amount} al Personaje: {character_name}" ) if stripe_response["success"]: # Guardar en sesi贸n los datos para el callback tras el pago request.session['gold_transaction'] = { 'character_name': character_name, 'gold_amount': gold_amount } return JsonResponse({ 'success': True, 'session_id': stripe_response["session_id"], 'stripe_public_key': settings.STRIPE_PUBLIC_KEY }) else: return JsonResponse({'success': False, 'message': f'Error al iniciar el pago: {stripe_response["error"]}'}) return render(request, 'account/gold_character.html', { 'characters': characters, 'gold_prices': gold_prices, 'character_names': list(characters.keys()), 'gold_options': [{'gold_amount': p.gold_amount, 'price': str(p.price)} for p in gold_prices], }) @require_paid_stripe() def gold_success_view(request): # Procesar el pago exitoso transaction = request.session.pop('gold_transaction', None) if not transaction: return redirect('gold-character') character_name = transaction['character_name'] gold_amount = int(transaction['gold_amount']) # Calcular el oro en formato del juego game_gold_amount = gold_amount * 10000 # Actualizar la cantidad de oro en la base de datos with connections['acore_characters'].cursor() as cursor: cursor.execute(""" UPDATE characters SET money = money + %s WHERE name = %s """, [game_gold_amount, character_name]) return render(request, 'account/gold_success.html', {'character_name': character_name, 'gold_amount': gold_amount}) def gold_cancel_view(request): return render(request, 'account/gold_cancel.html') def transfer_character_view(request): username = request.session.get('username') if not username: return redirect('login') # Obtener el precio de transferencia price_obj = TransferPrice.objects.first() price = price_obj.price if price_obj else 10.00 # Obtener el ID de usuario desde acore_auth.account with connections['acore_auth'].cursor() as cursor: cursor.execute("SELECT id, email, last_ip FROM account WHERE username = %s", [username]) user_data = cursor.fetchone() if not user_data: return JsonResponse({'success': False, 'message': 'Cuenta no encontrada. Por favor, inicie sesi贸n nuevamente.'}) user_id, email, acore_ip = user_data # ID de la cuenta, email y la 煤ltima IP # Obtener personajes de la cuenta de origen with connections['acore_characters'].cursor() as cursor: cursor.execute(""" SELECT name, class, online FROM characters WHERE account = %s """, [user_id]) characters = cursor.fetchall() if request.method == 'POST': character_name = request.POST.get('character') destination_account = request.POST.get('destination_account') token = request.POST.get('security_token') # Validaciones if not all([character_name, destination_account, token]): return JsonResponse({'success': False, 'message': 'Por favor, complete todos los campos.'}) character = next((char for char in characters if char[0] == character_name), None) if not character: return JsonResponse({'success': False, 'message': 'No tienes permiso para transferir este personaje.'}) # Verificar si el personaje est谩 desconectado if character[2] == 1: # Si est谩 conectado return JsonResponse({'success': False, 'message': 'El personaje debe estar desconectado para ser transferido.'}) # Verificar el token de seguridad security_token = SecurityToken.objects.filter(user_id=user_id, token=token).first() if not security_token: return JsonResponse({'success': False, 'message': 'Token de seguridad incorrecto.'}) # Verificar si el token ha expirado if security_token.expires_at < timezone.now(): return JsonResponse({'success': False, 'message': 'El token ha expirado. Solicite uno nuevo.'}) # Verificar si la cuenta de destino existe with connections['acore_auth'].cursor() as cursor: cursor.execute("SELECT id FROM account WHERE username = %s", [destination_account]) destination_account_data = cursor.fetchone() if not destination_account_data: return JsonResponse({'success': False, 'message': 'La cuenta de destino no existe.'}) # Verificar restricciones en la cuenta de destino destination_account_id = destination_account_data[0] with connections['acore_characters'].cursor() as cursor: cursor.execute(""" SELECT account, name, class, level, online FROM characters WHERE account = %s """, [destination_account_id]) destination_characters = cursor.fetchall() if not any(char[3] >= 55 and char[2] != 6 for char in destination_characters): return JsonResponse({'success': False, 'message': 'La cuenta destino debe tener al menos un personaje de nivel 55 o superior que no sea Caballero de la Muerte.'}) if any(char[2] == 6 for char in destination_characters): return JsonResponse({'success': False, 'message': 'La cuenta destino no puede tener un Caballero de la Muerte.'}) # Verificar que ninguna cuenta est茅 online for char in destination_characters: if char[4] == 1: return JsonResponse({'success': False, 'message': 'Todos los personajes de la cuenta destino deben estar desconectados.'}) for char in characters: if char[2] == 1: return JsonResponse({'success': False, 'message': 'Todos los personajes de la cuenta origen deben estar desconectados.'}) # Crear sesi贸n de pago con Stripe success_url = request.build_absolute_uri(reverse('transfer-success')) cancel_url = request.build_absolute_uri(reverse('transfer-cancel')) # Llamada corregida a create_checkout_session con todos los par谩metros requeridos stripe_response = create_checkout_session( username=username, email=email, acore_ip=acore_ip, account_id=user_id, # Pasar el account_id amount=price, # El precio de la transferencia character_name=character_name, success_url=success_url, cancel_url=cancel_url, product_name=f"Transferir el personaje: {character_name} a la cuenta de destino: {destination_account}" ) if stripe_response["success"]: # Guardar los datos de la transferencia en la sesi贸n para usarlos despu茅s del pago request.session['transfer_data'] = { 'character_name': character_name, 'destination_account': destination_account } return JsonResponse({ 'success': True, 'session_id': stripe_response["session_id"], 'stripe_public_key': settings.STRIPE_PUBLIC_KEY }) else: return JsonResponse({'success': False, 'message': f'Error al iniciar el pago: {stripe_response["error"]}'}) return render(request, 'account/transfer_character.html', { 'characters': characters, 'price': price, 'character_names': [c[0] for c in characters], }) @require_paid_stripe() def transfer_success_view(request): transfer_data = request.session.get('transfer_data') if not transfer_data: return redirect('transfer-character') character_name = transfer_data['character_name'] destination_account = transfer_data['destination_account'] # Ejecutar comando SOAP command = f".char changeaccount {destination_account} {character_name}" response = execute_soap_command(command) if response is None or response.strip() == "": message = f"El personaje {character_name} ha sido transferido a la cuenta {destination_account}." request.session.pop('transfer_data', None) # Limpiar sesi贸n return render(request, 'account/transfer_success.html', {'message': message}) else: return render(request, 'account/transfer_success.html', {'message': f"Error: {response}"}) def transfer_cancel_view(request): return render(request, 'account/transfer_cancel.html') def revive_character_view(request): username = request.session.get('username') if not username: return redirect('login') # Obtener personajes del usuario desde la base de datos `acore_characters` with connections['acore_characters'].cursor() as cursor: cursor.execute(""" SELECT name, online FROM characters WHERE account = ( SELECT id FROM acore_auth.account WHERE username = %s ) """, [username]) characters_data = cursor.fetchall() characters = {row[0]: row[1] for row in characters_data} # Diccionario con nombre y estado de conexi贸n if request.method == 'POST': character_name = request.POST.get('character') # Validar si el personaje fue seleccionado if not character_name: return JsonResponse({'success': False, 'message': 'Por favor, seleccione un personaje.'}) # Verificar si el personaje pertenece al usuario if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para revivir este personaje.'}) # Verificar si el personaje est谩 desconectado if characters[character_name] == 1: # Si est谩 conectado return JsonResponse({'success': False, 'message': 'El personaje debe estar desconectado para ser revivido.'}) # Verificar el historial de uso del comando `revive` last_revive = ReviveHistory.objects.filter(character_name=character_name).order_by('-used_at').first() if last_revive and last_revive.used_at > now() - timedelta(hours=12): return JsonResponse({'success': False, 'message': 'El personaje solo puede revivirse una vez cada 12 horas.'}) # Ejecutar el comando SOAP command = f".revive {character_name}" response = execute_soap_command(command) # None = fallo de comunicaci贸n con el servidor if response is None: return JsonResponse({'success': False, 'message': 'Error de comunicaci贸n con el servidor. Intente nuevamente m谩s tarde.'}) # Respuesta vac铆a = 茅xito (el comando .revive no devuelve texto si va bien) if response.strip() == "": ReviveHistory.objects.create(character_name=character_name, used_at=now()) return JsonResponse({'success': True, 'message': f'El personaje {character_name} ha sido revivido con 茅xito.'}) # Respuesta no vac铆a = el servidor devolvi贸 un mensaje/error return JsonResponse({'success': False, 'message': f'{response}'}) return render(request, 'account/revive_character.html', {'characters': characters.keys()}) def unstuck_character_view(request): username = request.session.get('username') if not username: return redirect('login') # Obtener personajes del usuario desde la base de datos `acore_characters` with connections['acore_characters'].cursor() as cursor: cursor.execute(""" SELECT name, online FROM characters WHERE account = ( SELECT id FROM acore_auth.account WHERE username = %s ) """, [username]) characters_data = cursor.fetchall() characters = {row[0]: row[1] for row in characters_data} # Diccionario con nombre y estado de conexi贸n if request.method == 'POST': character_name = request.POST.get('character') # Validar si el personaje fue seleccionado if not character_name: return JsonResponse({'success': False, 'message': 'Por favor, seleccione un personaje.'}) # Verificar si el personaje pertenece al usuario if character_name not in characters: return JsonResponse({'success': False, 'message': 'No tienes permiso para desbloquear este personaje.'}) # Verificar si el personaje est谩 desconectado if characters[character_name] == 1: # Si est谩 conectado return JsonResponse({'success': False, 'message': 'El personaje debe estar desconectado para ser desbloqueado.'}) # Verificar el historial de uso del comando last_unstuck = UnstuckHistory.objects.filter(character_name=character_name).order_by('-used_at').first() if last_unstuck and last_unstuck.used_at > now() - timedelta(hours=12): return JsonResponse({'success': False, 'message': 'El personaje solo puede desbloquearse una vez cada 12 horas.'}) # Ejecutar el comando SOAP command = f".unstuck {character_name} startzone" response = execute_soap_command(command) if response is None: return JsonResponse({'success': False, 'message': 'Error de comunicaci贸n con el servidor. Intente nuevamente m谩s tarde.'}) # Analizar la respuesta if f"You are summoning {character_name} (offline)" in response: # Registrar el uso del comando UnstuckHistory.objects.create(character_name=character_name, used_at=now()) return JsonResponse({'success': True, 'message': f'El personaje {character_name} ha sido desbloqueado con 茅xito.'}) else: return JsonResponse({'success': False, 'message': f'Error: {response}'}) return render(request, 'account/unstuck_character.html', {'characters': characters.keys()})