1
0
Fork 0
forked from Simnation/Main
This commit is contained in:
Nordi98 2025-08-04 06:51:25 +02:00
parent 60d3bab09d
commit 028317e2ec
5 changed files with 324 additions and 33 deletions

View file

@ -389,3 +389,28 @@ function manageLicensesMenu()
type = 'info'
})
end
-- Foto vom Spieler machen
RegisterNetEvent('license-system:client:takePlayerPhoto', function(targetId)
local targetPed = GetPlayerPed(GetPlayerFromServerId(targetId))
if targetPed and targetPed ~= 0 then
-- Mugshot erstellen
local mugshot = RegisterPedheadshot(targetPed)
-- Warten bis Mugshot geladen ist
while not IsPedheadshotReady(mugshot) do
Wait(100)
end
-- Mugshot-Textur holen
local mugshotTxd = GetPedheadshotTxdString(mugshot)
-- An Server senden
TriggerServerEvent('license-system:server:savePlayerPhoto', QBCore.Functions.GetPlayerData().citizenid, mugshotTxd)
-- Mugshot wieder freigeben
UnregisterPedheadshot(mugshot)
end
end)

View file

@ -5,56 +5,270 @@
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>License System</title>
<link rel="stylesheet" href="style.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.0.0/css/all.min.css">
<link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.4.0/css/all.min.css">
<link rel="preconnect" href="https://fonts.googleapis.com">
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
<link href="https://fonts.googleapis.com/css2?family=Inter:wght@300;400;500;600;700&display=swap" rel="stylesheet">
</head>
<body>
<!-- Hauptcontainer für Lizenz-Anzeige -->
<div id="license-container" class="hidden">
<div class="license-overlay" onclick="closeLicense()"></div>
<div class="license-card" id="license-card">
<!-- Sicherheitselemente -->
<div class="security-strip"></div>
<div class="hologram"></div>
<div class="microtext">SECURE DOCUMENT • OFFICIAL USE ONLY • GOVERNMENT ISSUED</div>
<!-- Header der Lizenz -->
<div class="license-header">
<div class="license-title"></div>
<div class="header-left">
<div class="license-title" id="license-title">Personalausweis</div>
<div class="license-subtitle">Bundesrepublik Deutschland</div>
</div>
<div class="header-right">
<div class="license-logo">
<i class="license-icon"></i>
<i class="license-icon" id="license-icon"></i>
</div>
<div class="government-seal">
<i class="fas fa-certificate"></i>
</div>
</div>
</div>
<!-- Hauptinhalt der Lizenz -->
<div class="license-content">
<div class="license-photo">
<!-- Foto-Bereich -->
<div class="license-photo-section">
<div class="license-photo" id="license-photo">
<img id="player-photo" class="hidden" alt="Spieler Foto">
<div id="photo-placeholder" class="photo-placeholder">
<i class="fas fa-user"></i>
</div>
</div>
<div class="photo-frame"></div>
</div>
<!-- Informations-Bereich -->
<div class="license-info">
<div class="info-section personal-info">
<h3 class="section-title">Persönliche Daten</h3>
<div class="info-row">
<span class="label">Name:</span>
<span class="value" id="license-name"></span>
<span class="label">
<i class="fas fa-user"></i>
Name:
</span>
<span class="value" id="license-name">Max Mustermann</span>
</div>
<div class="info-row">
<span class="label">Geburtsdatum:</span>
<span class="value" id="license-birthday"></span>
<span class="label">
<i class="fas fa-birthday-cake"></i>
Geburtsdatum:
</span>
<span class="value" id="license-birthday">01.01.1990</span>
</div>
<div class="info-row">
<span class="label">Geschlecht:</span>
<span class="value" id="license-gender"></span>
<span class="label">
<i class="fas fa-venus-mars"></i>
Geschlecht:
</span>
<span class="value" id="license-gender">Männlich</span>
</div>
</div>
<div class="info-section document-info">
<h3 class="section-title">Dokument-Informationen</h3>
<div class="info-row">
<span class="label">Ausgestellt:</span>
<span class="value" id="license-issue"></span>
<span class="label">
<i class="fas fa-calendar-plus"></i>
Ausgestellt:
</span>
<span class="value" id="license-issue">01.01.2024</span>
</div>
<div class="info-row">
<span class="label">Gültig bis:</span>
<span class="value" id="license-expire"></span>
<span class="label">
<i class="fas fa-calendar-times"></i>
Gültig bis:
</span>
<span class="value" id="license-expire">01.01.2034</span>
</div>
<div class="info-row">
<span class="label">
<i class="fas fa-hashtag"></i>
Dokument-ID:
</span>
<span class="value" id="license-id">#000001</span>
</div>
<div class="info-row" id="license-classes-row">
<span class="label">Klassen:</span>
<span class="value" id="license-classes"></span>
<span class="label">
<i class="fas fa-list"></i>
Klassen:
</span>
<span class="value" id="license-classes">A, B, C</span>
</div>
<div class="info-row">
<span class="label">
<i class="fas fa-user-tie"></i>
Ausgestellt von:
</span>
<span class="value" id="license-issuer">Behörde</span>
</div>
</div>
</div>
</div>
<!-- Footer der Lizenz -->
<div class="license-footer">
<div class="license-status" id="license-status"></div>
<button class="close-btn" onclick="closeLicense()">
<i class="fas fa-times"></i> Schließen
<div class="footer-left">
<div class="license-status" id="license-status">
<i class="status-icon"></i>
<span class="status-text">Gültig</span>
</div>
<div class="validity-indicator" id="validity-indicator">
<div class="validity-bar">
<div class="validity-fill" id="validity-fill"></div>
</div>
<span class="validity-text" id="validity-text">Noch 365 Tage gültig</span>
</div>
</div>
<div class="footer-center">
<div class="qr-code" id="qr-code">
<div class="qr-pattern">
<div class="qr-dot"></div>
<div class="qr-dot"></div>
<div class="qr-dot"></div>
<div class="qr-dot"></div>
<div class="qr-dot"></div>
<div class="qr-dot"></div>
<div class="qr-dot"></div>
<div class="qr-dot"></div>
<div class="qr-dot"></div>
</div>
<span class="qr-label">QR</span>
</div>
</div>
<div class="footer-right">
<button class="action-btn view-btn" onclick="flipCard()" title="Rückseite anzeigen">
<i class="fas fa-sync-alt"></i>
<span>Drehen</span>
</button>
<button class="action-btn close-btn" onclick="closeLicense()" title="Schließen">
<i class="fas fa-times"></i>
<span>Schließen</span>
</button>
</div>
</div>
<!-- Rückseite der Lizenz (für Führerschein-Klassen etc.) -->
<div class="license-back hidden" id="license-back">
<div class="back-header">
<h3>Zusätzliche Informationen</h3>
</div>
<div class="back-content">
<div class="classes-grid" id="classes-grid">
<!-- Wird dynamisch befüllt -->
</div>
<div class="restrictions" id="restrictions">
<h4>Beschränkungen:</h4>
<ul id="restrictions-list">
<!-- Wird dynamisch befüllt -->
</ul>
</div>
<div class="notes" id="notes">
<h4>Bemerkungen:</h4>
<p id="notes-text">Keine besonderen Bemerkungen</p>
</div>
</div>
<div class="back-footer">
<button class="action-btn" onclick="flipCard()">
<i class="fas fa-arrow-left"></i>
Zurück
</button>
</div>
</div>
</div>
</div>
<!-- Kamera-Interface für Foto-Aufnahme -->
<div id="camera-container" class="hidden">
<div class="camera-overlay" onclick="closeCamera()"></div>
<div class="camera-interface">
<div class="camera-header">
<h3>Foto für Lizenz aufnehmen</h3>
<button class="camera-close" onclick="closeCamera()">
<i class="fas fa-times"></i>
</button>
</div>
<div class="camera-content">
<div class="camera-preview">
<video id="camera-video" autoplay playsinline></video>
<canvas id="camera-canvas" class="hidden"></canvas>
<div class="camera-overlay-guide">
<div class="face-guide">
<div class="guide-circle"></div>
<p>Gesicht hier positionieren</p>
</div>
</div>
</div>
<div class="camera-controls">
<button class="camera-btn capture-btn" onclick="takePhoto()">
<i class="fas fa-camera"></i>
Foto aufnehmen
</button>
<button class="camera-btn cancel-btn" onclick="closeCamera()">
<i class="fas fa-ban"></i>
Abbrechen
</button>
</div>
</div>
</div>
</div>
<!-- Loading-Overlay -->
<div id="loading-overlay" class="hidden">
<div class="loading-spinner">
<div class="spinner"></div>
<p>Lizenz wird geladen...</p>
</div>
</div>
<!-- Notification-System -->
<div id="notification-container">
<!-- Notifications werden hier dynamisch eingefügt -->
</div>
<!-- Audio für Sound-Effekte -->
<audio id="card-flip-sound" preload="auto">
<source src="sounds/card_flip.mp3" type="audio/mpeg">
</audio>
<audio id="camera-shutter-sound" preload="auto">
<source src="sounds/camera_shutter.mp3" type="audio/mpeg">
</audio>
<!-- JavaScript -->
<script src="script.js"></script>
</body>
</html>

View file

@ -63,6 +63,21 @@ function showLicense(data) {
container.classList.remove('hidden');
}
// Foto anzeigen
const photoImg = document.getElementById('player-photo');
const photoPlaceholder = document.getElementById('photo-placeholder');
if (data.license.photo_url && data.license.photo_url !== '') {
// Echtes Foto anzeigen
photoImg.src = data.license.photo_url;
photoImg.classList.remove('hidden');
photoPlaceholder.classList.add('hidden');
} else {
// Platzhalter anzeigen
photoImg.classList.add('hidden');
photoPlaceholder.classList.remove('hidden');
}
// Geschlecht formatieren
function formatGender(gender) {
const genderMap = {

View file

@ -83,11 +83,28 @@ body {
display: flex;
align-items: center;
justify-content: center;
border: 2px solid rgba(255, 255, 255, 0.3);
overflow: hidden;
position: relative;
}
#player-photo {
width: 100%;
height: 100%;
object-fit: cover;
border-radius: 6px;
}
#photo-placeholder {
font-size: 48px;
color: rgba(255, 255, 255, 0.7);
flex-shrink: 0;
}
.hidden {
display: none !important;
}
.license-info {
flex: 1;
}

View file

@ -290,3 +290,23 @@ exports('hasLicenseClass', function(citizenid, class)
end
return false
end)
-- Spieler-Foto aus QBCore holen
RegisterNetEvent('license-system:server:getPlayerPhoto', function(targetId)
local src = source
local TargetPlayer = QBCore.Functions.GetPlayer(targetId)
if TargetPlayer then
-- Mugshot vom Spieler machen
TriggerClientEvent('license-system:client:takePlayerPhoto', src, targetId)
end
end)
-- Foto-URL speichern
RegisterNetEvent('license-system:server:savePlayerPhoto', function(citizenid, photoUrl)
MySQL.Async.execute('UPDATE player_licenses SET photo_url = ? WHERE citizenid = ? AND id = ?', {
photoUrl,
citizenid,
-- Hier die aktuelle Lizenz-ID
})
end)