--[[ ╔══════════════════════════════════════════════════════════╗ ║ WEBDISPLAY - CLIENT | Metropoles City RP ║ ╚══════════════════════════════════════════════════════════╝ ]] local screenStates = {} local function dbg(msg) if Config and Config.debug then outputDebugString("[WebDisplay] " .. tostring(msg), 3) end end -- ============================================================ -- RENDER LOOP -- ============================================================ local function onRender() if not localPlayer then return end local px, py, pz = getElementPosition(localPlayer) local camX, camY, camZ = getCameraMatrix() for id, state in pairs(screenStates) do if state.ready and state.browser and isElement(state.browser) then local scr = state.screenConfig local dist = getDistanceBetweenPoints3D( px, py, pz, scr.position.x, scr.position.y, scr.position.z ) -- Volume baseado na distancia local maxAudio = scr.audioDistance or 30 setBrowserVolume(state.browser, 1 - math.min(dist / maxAudio, 1)) if dist <= scr.renderDistance then local mx = scr.position.x local my = scr.position.y local topZ = scr.position.z + (scr.size.height / 2) local botZ = scr.position.z - (scr.size.height / 2) dxDrawMaterialLine3D( mx, my, topZ, mx, my, botZ, state.browser, scr.size.width, tocolor(255, 255, 255, 255), camX, camY, camZ ) end end end end -- ============================================================ -- CRIA BROWSER -- ============================================================ local function createScreenBrowser(scr) local scrId = scr.id local scrName = tostring(scr.name or scr.id) local scrUrl = scr.url if not scrUrl or scrUrl == "" then dbg("ERRO: [" .. scrName .. "] sem URL definida.") return end dbg("Criando browser [" .. scrName .. "] -> " .. scrUrl) local bW = Config.browser.width local bH = Config.browser.height -- false, false = browser local (nao remoto) -- funciona para URLs que estao na whitelist do cliente local browser = createBrowser(bW, bH, false, false) if not browser then dbg("ERRO: createBrowser retornou nil para [" .. scrName .. "]") return end screenStates[scrId] = { browser = browser, ready = false, screenConfig = scr, } addEventHandler("onClientBrowserCreated", browser, function() dbg("[" .. scrName .. "] browser criado, carregando URL...") loadBrowserURL(browser, scrUrl) end) addEventHandler("onClientBrowserDocumentReady", browser, function(url) dbg("[" .. scrName .. "] pagina pronta: " .. tostring(url)) if not isElement(browser) then return end setBrowserVolume(browser, 0) if screenStates[scrId] then screenStates[scrId].ready = true end end) addEventHandler("onClientBrowserLoadingFailed", browser, function(url, code, desc) dbg("[" .. scrName .. "] FALHA ao carregar | " .. tostring(code) .. " | " .. tostring(desc)) if screenStates[scrId] then screenStates[scrId].ready = false end end) end -- ============================================================ -- LIMPEZA -- ============================================================ local function cleanup() dbg("Limpando...") removeEventHandler("onClientRender", root, onRender) for id, state in pairs(screenStates) do if state.browser and isElement(state.browser) then destroyElement(state.browser) dbg("Browser [" .. tostring(id) .. "] destruido.") end end screenStates = {} end -- ============================================================ -- START / STOP -- ============================================================ addEventHandler("onClientResourceStart", resourceRoot, function() if not Config then outputDebugString("[WebDisplay] ERRO CRITICO: Config nil!", 1) return end if not Config.screens or #Config.screens == 0 then dbg("AVISO: Config.screens vazio.") return end dbg("Iniciando " .. #Config.screens .. " telao(es)...") for _, scr in ipairs(Config.screens) do if scr.enabled then createScreenBrowser(scr) else dbg("Tela [" .. tostring(scr.name) .. "] desativada.") end end addEventHandler("onClientRender", root, onRender) dbg("Render loop ativo.") end) addEventHandler("onClientResourceStop", resourceRoot, cleanup) -- ============================================================ -- COMANDOS (apenas admin) -- ============================================================ addCommandHandler("webdisplay", function(_, action, id, ...) if action == "reload" then cleanup() screenStates = {} for _, scr in ipairs(Config.screens) do if scr.enabled then createScreenBrowser(scr) end end addEventHandler("onClientRender", root, onRender) outputChatBox("[WebDisplay] Recarregado!", 100, 255, 100) elseif action == "url" and id then local newUrl = table.concat({...}, " ") local state = screenStates[id] if state and state.browser and isElement(state.browser) then state.ready = false loadBrowserURL(state.browser, newUrl) outputChatBox("[WebDisplay] URL de [" .. id .. "] atualizada.", 100, 200, 255) else outputChatBox("[WebDisplay] Telao [" .. id .. "] nao encontrado.", 255, 100, 100) end end end)