Config = {} Config.Debug = false Config.Locale = 'de' Config.Ui = { alwaysLandscape = true, defaultPage = 'feed' } Config.Handles = { forceLowercase = true, pattern = '^[a-z0-9%._%-]+$', minLength = 2, maxLength = 32 } Config.Media = { provider = 'imgbb', -- Kein Schluessel im Code: die Datei liegt in der Versionsverwaltung. -- Der echte Wert gehoert in die server.cfg: -- set bleeter_imgbb_key "dein-schluessel" -- Ein Wert hier wirkt als Rueckfallebene, etwa fuer eine Testumgebung. imgbbApiKey = '', maxBytes = 2 * 1024 * 1024, allowedExtensions = { 'jpg', 'jpeg', 'png' }, allowExternalUrls = true, requireHttps = true, storage = 'external' } Config.Moderation = { restoreDays = 5 } Config.ProfileTypes = { private = 'Privat', small_business = 'Kleingewerbe', company = 'Unternehmen', authority = 'Behörde', lifeinvader = 'Lifeinvader' } Config.Navigation = { { key = 'feed', label = 'Feed', icon = 'home' }, { key = 'ads', label = 'Werbefeed', icon = 'megaphone' }, { key = 'followers', label = 'Follower', icon = 'users' }, { key = 'market', label = 'Marktplatz', icon = 'basket' }, { key = 'calendar', label = 'Kalender', icon = 'calendar' }, { key = 'business', label = 'Gewerbe', icon = 'briefcase' }, { key = 'profile', label = 'Profil', icon = 'user' }, { key = 'legal', label = 'Rechtliches',icon = 'book' } } -- ── Identität ───────────────────────────────────────────────────────────────── -- Alle Funktionen sind server-only und werden nur serverseitig aufgerufen. -- ESX, wenn vorhanden. Wird bei Bedarf geholt, nicht beim Laden: beim Start -- ist es je nach Reihenfolge noch nicht bereit. local _esx local function esx() if _esx then return _esx end if GetResourceState('es_extended') ~= 'started' then return nil end local ok, obj = pcall(function() return exports['es_extended']:getSharedObject() end) if ok then _esx = obj end return _esx end local function xPlayer(source) local api = esx() return api and api.GetPlayerFromId(source) or nil end function Config.GetIdentifier(source) -- ESX fuehrt seine eigene Identifierliste. Sie muss hier dieselbe sein, -- sonst findet ic-mail die Postfaecher dieser Person nicht. local player = xPlayer(source) if player and player.identifier then return player.identifier end return GetPlayerIdentifierByType(source, 'license') or GetPlayerIdentifiers(source)[1] end -- Charakter-Id. Auf einem ESX-Server ist das der ESX-Identifier; core-characters -- gibt es hier nicht, wird aber weiter unterstuetzt. function Config.GetCharacterId(source) if GetResourceState('core-characters') == 'started' then local ok, cid = pcall(function() return exports['core-characters']:GetCitizenId(source) end) if ok and cid and cid ~= '' then return cid end end return Config.GetIdentifier(source) end -- Anzeigename: ESX-Charaktername, sonst core-characters, sonst Spielername. function Config.GetCharacterName(source) local player = xPlayer(source) if player then if player.getName then local ok, name = pcall(player.getName) if ok and name and name ~= '' then return name end end if player.name and player.name ~= '' then return player.name end end if GetResourceState('core-characters') == 'started' then local ok, name = pcall(function() return exports['core-characters']:GetCharacterName(source) end) if ok and name and name ~= '' then return name end end return GetPlayerName(source) or ('Spieler %s'):format(source) end -- Primäre IC-Mailadresse aus ic-mail (single source of truth). -- Gibt '' zurück wenn noch keine Adresse konfiguriert wurde. function Config.GetMailAddress(source) local charId = Config.GetCharacterId(source) if not charId or charId == '' then return '' end if GetResourceState('ic-mail') == 'started' then local ok, addr = pcall(function() return exports['ic-mail']:GetPrimaryAddress(charId) end) if ok and addr and addr ~= '' then return addr end end -- Fallback: direkt aus DB (falls ic-mail nicht erreichbar) local ok2, row = pcall(function() return MySQL.single.await( 'SELECT address FROM ic_mail_accounts WHERE owner_identifier = ? AND account_type = ? AND is_active = 1 LIMIT 1', { charId, 'personal' } ) end) if ok2 and row and row.address and row.address ~= '' then return row.address end return '' end -- Telefonnummer aus zc_ifruit, Fallback: zc_ifruit Export function Config.GetPhoneNumber(source) local charId = Config.GetCharacterId(source) if charId and charId ~= '' then local ok, row = pcall(function() return MySQL.single.await( 'SELECT active_number FROM zc_ifruit_accounts WHERE char_id = ? LIMIT 1', { charId } ) end) if ok and row and row.active_number then return tostring(row.active_number) end end if GetResourceState('zc_ifruit') == 'started' then local ok2, num = pcall(function() return exports['zc_ifruit']:GetPhoneNumber(source) end) if ok2 and num then return tostring(num) end end return nil end