WIP: whitelist, queue

This commit is contained in:
2026-03-23 12:24:24 +01:00
parent 7ecd952f08
commit 36370c4b80
7 changed files with 246 additions and 66 deletions

View File

@@ -1,14 +1,12 @@
from enum import Enum
from dataclasses import dataclass
from PySide6.QtGui import QColor
# ---------------------------------------------------------------------------
# Constants
# ---------------------------------------------------------------------------
NO_STAFF = True
NO_WHITELIST = True
FIVEMURL = "fivem://connect/prod.la-taniere.fun"
REDIRECT_URI = "http://localhost:5000/callback"
SCOPES = ["identify"]
CLIENT_ID = "1240007913175781508"
@@ -28,16 +26,29 @@ AUTENTICATION_SUCCESS_MESSAGE = """
# ENUMS
# ---------------------------------------------------------------------------
class Resources(Enum):
MP3 = ":/assets/the-beat-of-nature.mp3"
FONT = ":/assets/Avocado-Cake-Demo.otf"
MP3 = ':/assets/the-beat-of-nature.mp3'
FONT = ':/assets/Avocado-Cake-Demo.otf'
class Urls(Enum):
DISCORD = "https://discord.gg/A7eanmSkp2"
INTRANET = "https://la-taniere.fun/connexion/"
DISCORD = 'https://discord.gg/A7eanmSkp2'
INTRANET = 'https://la-taniere.fun/connexion/'
API_URL = 'https://prod.la-taniere.fun:30121/'
class ApiEndPoints(Enum):
QUEUE_STATUS = '/queue/status/'
QUEUE_LEAVE = '/queue/leave'
QUEUE_JOIN = '/queue/join'
class Glow(Enum):
COLOR = QColor(255, 140, 0, 255)
BLUR_BASE = 15
BLUR_PEAK = 70
ANIM_DURATION = 1200
# ---------------------------------------------------------------------------
# DATACLASS
# ---------------------------------------------------------------------------
@dataclass
class PlayerServerInfo:
is_staff: bool = False
is_whitelist: bool = False

View File

@@ -0,0 +1,20 @@
import subprocess
import os
from config.constants import FIVEMURL
class FiveMLauncher:
def __init__(self, fivem_path: str):
self.fivem_path = os.path.expandvars(fivem_path)
@staticmethod
def launch():
"""
if not os.path.exists(self.fivem_path):
raise FileNotFoundError("❌ FiveM.exe introuvable")
subprocess.Popen(self.fivem_path, shell=True)
"""
#subprocess.Popen(f"explorer {FIVEMURL}")
subprocess.Popen(r'explorer fivem://connect/prod.la-taniere.fun')

View File

@@ -0,0 +1,128 @@
import requests
from PySide6.QtCore import QThread, Signal
from config.constants import Urls, ApiEndPoints
class JoinQueueThread(QThread):
result = Signal(dict)
error = Signal(str)
def __init__(self, user_id: str):
super().__init__()
self.user_id = user_id
self.api_url = Urls.API_URL.value
def run(self):
try:
res = requests.post(
f"{self.api_url}{ApiEndPoints.QUEUE_JOIN.value}",
headers={"Content-Type": "application/json"},
json={"uuid": self.user_id}
)
self.result.emit(res.json())
except Exception as e:
self.error.emit(str(e))
class CheckStatusThread(QThread):
result = Signal(dict)
error = Signal(str)
def __init__(self, user_id: str):
super().__init__()
self.user_id = user_id
self.api_url = Urls.API_URL.value
def run(self):
try:
res = requests.get(f"{self.api_url}{ApiEndPoints.QUEUE_STATUS.value}{self.user_id}")
self.result.emit(res.json())
except Exception as e:
self.error.emit(str(e))
class LeaveQueueThread(QThread):
done = Signal()
error = Signal(str)
def __init__(self, user_id: str):
super().__init__()
self.user_id = user_id
self.api_url = Urls.API_URL.value
def run(self):
try:
requests.post(
f"{self.api_url}{ApiEndPoints.QUEUE_LEAVE.value}",
headers={"Content-Type": "application/json"},
json={"uuid": self.user_id}
)
self.done.emit()
except Exception as e:
self.error.emit(str(e))
class QueueManager(QThread):
"""
Équivalent de startQueue() — gère tout le cycle :
join → poll toutes les 5s → lance FiveM quand c'est le tour
"""
update_ui = Signal(str) # → updateQueueUI()
launch_game = Signal() # → launchFiveM()
error = Signal(str)
def __init__(self, user_id: str, parent=None):
super().__init__(parent)
self.user_id = user_id
self.api_url = Urls.API_URL.value
self._running = True
def stop(self):
self._running = False
def run(self):
# 1. Join queue
try:
res = requests.post(
f"{self.api_url}/queue/join",
headers={"Content-Type": "application/json"},
json={"uuid": self.user_id}
)
join = res.json()
except Exception as e:
self.error.emit(str(e))
return
# 2. Slot dispo directement
if join.get("status") == "ok":
self.update_ui.emit("Slot dispo, lancement du jeu...")
self.launch_game.emit()
return
# 3. En file d'attente → poll toutes les 5s
self.update_ui.emit(
f"⏳ Vous êtes en file d'attente : position {join.get('position')} / {join.get('queueSize')}"
)
while self._running:
self.sleep(5) # Équivalent setInterval 5000ms
if not self._running:
break
try:
res = requests.get(f"{self.api_url}/queue/status/{self.user_id}")
status = res.json()
except Exception as e:
self.error.emit(str(e))
return
if status.get("status") == "queued":
self.update_ui.emit(
f"⏳ Votre position : {status.get('position')} / {status.get('queueSize')}"
)
else:
self.update_ui.emit("🚀 C'est votre tour !")
self.launch_game.emit()
return

View File

@@ -2,6 +2,8 @@ import requests
from urllib3 import disable_warnings
from urllib3.exceptions import InsecureRequestWarning
from config.constants import PlayerServerInfo
# Supress only InsecureRequestWarning
disable_warnings(InsecureRequestWarning)
@@ -9,15 +11,11 @@ WHITELIST_URL_ENDPOINT = f'iswhitelist/'
class WhiteList:
@staticmethod
def checkwhitelist(url, discord_user_id: str) -> bool:
print('🗒️ Vérification de la whitelist...')
def checkwhitelist(url, discord_user_id: str) -> None:
response = requests.get(url + WHITELIST_URL_ENDPOINT + discord_user_id, verify=False)
api_data = response.json()
if api_data['whitelisted']:
print("👍 Vous êtes en whitelist")
return True
else:
print('🙅‍♂️ Désole mais vous n\'êtes pas whitelisté sur le serveur.')
return False
PlayerServerInfo.is_whitelist = api_data.get('whitelisted', False)
#PlayerServerInfo.is_staff = api_data.get('isStaff', False)
PlayerServerInfo.is_staff = True

View File

@@ -8,14 +8,15 @@ from PySide6.QtUiTools import QUiLoader
from PySide6.QtWidgets import QMainWindow, QSizePolicy
from config.config_manager import ConfigManager
from config.constants import NO_STAFF, Urls, NO_WHITELIST
from ui.custom_message_box import CustomMessageBox
from config.constants import PlayerServerInfo, Urls
from ui.hazard_stripes import HazardButton
from controllers.audio_controller import AudioController
from controllers.glow_animator import GlowAnimator
from controllers.window_dragger import WindowDragger
from discord import discord_oauth
from tools.utils import quit_application
from fivemserver.whitelistmanager import WhiteList
from fivemserver.fivemlauncher import FiveMLauncher
from fivemserver.queuemanager import QueueManager
from fake_patch_notes import patch_note
@@ -29,29 +30,29 @@ class MainWindow(QMainWindow):
self.config = config_manager
WhiteList.checkwhitelist(Urls.API_URL.value, self.config.get_discord_user())
if PlayerServerInfo.is_whitelist:
QueueManager(self.config.get_discord_user())
# UI
self.ui = QUiLoader().load(f"{bundle_dir}/ui/mainwindow_vertical_pager.ui", self)
self.setCentralWidget(self.ui.centralWidget())
self.setWindowFlags(Qt.WindowType.FramelessWindowHint | Qt.WindowType.Window)
self.setAttribute(Qt.WidgetAttribute.WA_TranslucentBackground)
# Par défaut on affiche la page normal pour la connexion au serveur
self.ui.stackedWidget.setCurrentIndex(0)
if NO_WHITELIST:
self.ui.stackedWidget.setCurrentIndex(2)
# msg = CustomMessageBox(
# title="La Tanière: Non whitelisté",
# message="\n\nTu n'est pas whitelisté sur le serveur\n\n"
# "Assure-toi de te faire whitelister.\n\n"
# "Lorsque cela sera fait, relance le launcher.",
# icon_type=CustomMessageBox.WARNING,
# buttons=CustomMessageBox.OK
# )
# msg.exec()
# quit_application()
# Si l'id discord = "" ou des espace, alors on affiche la page comme quoi faut être connecté à discord.
if config_manager.get_discord_user() == "" or config_manager.get_discord_user().isspace():
self.ui.queue_lbl.hide()
self.ui.queue_position.hide()
self.ui.stackedWidget.setCurrentIndex(1)
# Test bouton en contruction
en_chantier = True
en_chantier = False
# on set la css du bouton en fonction de la valeur de la variable en_chantier
self.set_en_chantier(en_chantier)
if en_chantier:
old_btn = self.ui.connexion_btn
parent_layout = self.ui.verticalLayout_6 # layout direct du bouton dans le .ui
@@ -74,7 +75,7 @@ class MainWindow(QMainWindow):
self.ui.connexion_btn.clicked.connect(self._on_connexion)
# centrage vertical du bouton connexion
if NO_STAFF:
if not PlayerServerInfo.is_staff:
self.ui.staff_btn.hide()
layout = self.ui.verticalLayout_6
# Trouver et modifier le spacer item
@@ -84,12 +85,6 @@ class MainWindow(QMainWindow):
item.spacerItem().changeSize(20, 15, QSizePolicy.Policy.Fixed, QSizePolicy.Policy.Fixed)
layout.invalidate() # Forcer le recalcul du layout
break
# self.ui.spacer_substitution.hide()
if config_manager.get_discord_user() == "" or config_manager.get_discord_user().isspace():
self.ui.queue_lbl.hide()
self.ui.queue_position.hide()
self.ui.stackedWidget.setCurrentIndex(1)
self.ui.info_text.setMarkdown(patch_note)
@@ -100,6 +95,15 @@ class MainWindow(QMainWindow):
self._connect_signals()
self._center_window()
# si le jouer n'est pas whitelisté, on affiche la page pour se faire whitelister
if not PlayerServerInfo.is_whitelist:
self.ui.stackedWidget.setCurrentIndex(2)
# pour le moment on cache les controle queue
self.ui.queue_lbl.setVisible(False)
self.ui.queue_position.setVisible(False)
self.show()
@@ -131,7 +135,7 @@ class MainWindow(QMainWindow):
# ------------------------------------------------------------------
def _on_connexion(self) -> None:
pass # à implémenter
FiveMLauncher.launch()
@staticmethod
def _on_discord() -> None:
@@ -169,3 +173,12 @@ class MainWindow(QMainWindow):
def closeEvent(self, event) -> None:
self.config.save()
super().closeEvent(event)
# ------------------------------------------------------------------
# Change ui on runtime
# ------------------------------------------------------------------
def set_en_chantier(self, valeur: bool):
self.en_chantier = valeur # ta variable Python
self.ui.connexion_btn.setProperty("en_chantier", valeur) # propriété Qt
self.ui.connexion_btn.style().unpolish(self.ui.connexion_btn)
self.ui.connexion_btn.style().polish(self.ui.connexion_btn)