from ._base import * from .account import get_account_status, get_account_characters def recruit_a_friend_view(request): username = request.session.get('username') account_status = None characters = [] claimed_rewards_count = 0 # Si el usuario está logueado, obtener su información if username: # Obtener información del usuario with connections['acore_auth'].cursor() as cursor: cursor.execute("SELECT id, last_ip FROM account WHERE username = %s", [username]) account_data = cursor.fetchone() if account_data: account_id = account_data[0] user_ip = account_data[1] account_status = get_account_status(account_id) characters = get_account_characters(account_id) claimed_rewards_count = ClaimedReward.objects.filter(account_id=account_id).count() else: account_id = None user_ip = None else: account_id = None user_ip = None # Obtener todas las recompensas all_rewards = RecruitReward.objects.all() available_rewards = [] # Si el usuario está logueado, filtrar recompensas disponibles if account_id: available_rewards = [reward for reward in all_rewards if not ClaimedReward.objects.filter(account_id=account_id, recruit_reward=reward).exists()] # Manejar solicitudes POST (solo si el usuario está logueado) if request.method == 'POST': if not username: return JsonResponse({'success': False, 'message': 'Debes estar logueado para reclamar una recompensa.'}) if not account_id or account_status is None: return JsonResponse({'success': False, 'message': 'No se ha encontrado tu cuenta.'}) reward_id = request.POST.get('reward_id') character_name = request.POST.get('character') if not reward_id or not character_name: return JsonResponse({'success': False, 'message': 'Selecciona una recompensa y un personaje.'}) try: reward = RecruitReward.objects.get(id=reward_id) # Verificar si ya se ha reclamado la recompensa if ClaimedReward.objects.filter(account_id=account_id, recruit_reward=reward).exists(): return JsonResponse({'success': False, 'message': 'Ya has reclamado esta recompensa.'}) # Verificar si cumple los requisitos if account_status['recruited_level_80_count'] < reward.required_friends: return JsonResponse({'success': False, 'message': 'No cumples con los requisitos.'}) # Obtener amigos reclutados que han alcanzado el nivel 80 recruited_friends = get_recruited_friends_at_level_80(account_id, reward.required_friends) # Comprobar si alguno de los reclutados es válido if len(recruited_friends) < reward.required_friends: return JsonResponse({'success': False, 'message': 'No cumples con los requisitos o los amigos tienen la misma IP.'}) # Comprobar si alguno de los reclutados tiene la misma IP que el usuario if check_recruited_ip_conflict(recruited_friends, user_ip): return JsonResponse({'success': False, 'message': 'No puedes reclamar recompensas de amigos que tienen la misma IP.'}) # Ejecutar el comando SOAP command = f".send items {character_name} 'Recompensa de Recluta Amigo' 'Tu amigo alcanzó el Nivel 80' {reward.item_id}:{reward.item_quantity}" response = execute_soap_command(command) if response and "Mail sent to" in response: # Registrar la recompensa como reclamada ClaimedReward.objects.create( account_id=account_id, username=username, recruit_reward=reward, character_name=character_name, claimed_at=timezone.now(), ip_address=request.META.get('REMOTE_ADDR') ) claimed_rewards_count = ClaimedReward.objects.filter(account_id=account_id).count() return JsonResponse({ 'success': True, 'message': f"Recompensa '{reward.reward_name}' entregada a {character_name}.", 'claimed_count': claimed_rewards_count }) else: return JsonResponse({'success': False, 'message': 'Error al entregar la recompensa.'}) except RecruitReward.DoesNotExist: return JsonResponse({'success': False, 'message': 'Recompensa no encontrada.'}) # Renderizar la página para usuarios no logueados y logueados return render(request, 'recruit/recruit_a_friend.html', { 'account_status': account_status, 'all_rewards': all_rewards, 'available_rewards': available_rewards, 'characters': characters, 'claimed_rewards_count': claimed_rewards_count, 'is_logged_in': username is not None }) def check_recruited_ip_conflict(recruited_accounts, user_ip): """ Verifica si alguna de las cuentas reclutadas tiene la misma IP que la cuenta del reclutador. """ if not recruited_accounts: return False with connections['acore_auth'].cursor() as cursor: cursor.execute(""" SELECT last_ip FROM account WHERE id IN %s """, [tuple(recruited_accounts)]) recruited_ips = [ip[0] for ip in cursor.fetchall()] return user_ip in recruited_ips def get_recruited_friends_at_level_80(account_id, required_count): """ Obtiene una lista de IDs de amigos reclutados que han alcanzado el nivel 80 y no tienen la misma IP que el reclutador. """ # Primero obtener los IDs de cuentas reclutadas desde `acore_auth` with connections['acore_auth'].cursor() as auth_cursor: auth_cursor.execute(""" SELECT id, last_ip FROM account WHERE recruiter = %s """, [account_id]) recruited_accounts = auth_cursor.fetchall() if not recruited_accounts: return [] # Extraer IDs y IPs de las cuentas reclutadas recruited_ids = [acc[0] for acc in recruited_accounts] recruited_ips = {acc[0]: acc[1] for acc in recruited_accounts} # Obtener la IP del usuario actual with connections['acore_auth'].cursor() as cursor: cursor.execute("SELECT last_ip FROM account WHERE id = %s", [account_id]) user_ip = cursor.fetchone()[0] # Luego, verificar cuáles de esas cuentas tienen personajes al nivel 80 en `acore_characters` with connections['acore_characters'].cursor() as char_cursor: char_cursor.execute(""" SELECT DISTINCT account FROM characters WHERE level = 80 AND account IN %s LIMIT %s """, [tuple(recruited_ids), required_count]) recruited_at_level_80 = [acc[0] for acc in char_cursor.fetchall()] # Filtrar cuentas que no tienen la misma IP que el usuario actual valid_recruits = [acc for acc in recruited_at_level_80 if recruited_ips[acc] != user_ip] return valid_recruits